##// END OF EJS Templates
diff: deprecate -r option...
Martin von Zweigbergk -
r46723:aa4dbc14 default
parent child Browse files
Show More
@@ -1,7747 +1,7747 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import errno
10 import errno
11 import os
11 import os
12 import re
12 import re
13 import sys
13 import sys
14
14
15 from .i18n import _
15 from .i18n import _
16 from .node import (
16 from .node import (
17 hex,
17 hex,
18 nullid,
18 nullid,
19 nullrev,
19 nullrev,
20 short,
20 short,
21 wdirhex,
21 wdirhex,
22 wdirrev,
22 wdirrev,
23 )
23 )
24 from .pycompat import open
24 from .pycompat import open
25 from . import (
25 from . import (
26 archival,
26 archival,
27 bookmarks,
27 bookmarks,
28 bundle2,
28 bundle2,
29 bundlecaches,
29 bundlecaches,
30 changegroup,
30 changegroup,
31 cmdutil,
31 cmdutil,
32 copies,
32 copies,
33 debugcommands as debugcommandsmod,
33 debugcommands as debugcommandsmod,
34 destutil,
34 destutil,
35 dirstateguard,
35 dirstateguard,
36 discovery,
36 discovery,
37 encoding,
37 encoding,
38 error,
38 error,
39 exchange,
39 exchange,
40 extensions,
40 extensions,
41 filemerge,
41 filemerge,
42 formatter,
42 formatter,
43 graphmod,
43 graphmod,
44 grep as grepmod,
44 grep as grepmod,
45 hbisect,
45 hbisect,
46 help,
46 help,
47 hg,
47 hg,
48 logcmdutil,
48 logcmdutil,
49 merge as mergemod,
49 merge as mergemod,
50 mergestate as mergestatemod,
50 mergestate as mergestatemod,
51 narrowspec,
51 narrowspec,
52 obsolete,
52 obsolete,
53 obsutil,
53 obsutil,
54 patch,
54 patch,
55 phases,
55 phases,
56 pycompat,
56 pycompat,
57 rcutil,
57 rcutil,
58 registrar,
58 registrar,
59 requirements,
59 requirements,
60 revsetlang,
60 revsetlang,
61 rewriteutil,
61 rewriteutil,
62 scmutil,
62 scmutil,
63 server,
63 server,
64 shelve as shelvemod,
64 shelve as shelvemod,
65 state as statemod,
65 state as statemod,
66 streamclone,
66 streamclone,
67 tags as tagsmod,
67 tags as tagsmod,
68 ui as uimod,
68 ui as uimod,
69 util,
69 util,
70 verify as verifymod,
70 verify as verifymod,
71 vfs as vfsmod,
71 vfs as vfsmod,
72 wireprotoserver,
72 wireprotoserver,
73 )
73 )
74 from .utils import (
74 from .utils import (
75 dateutil,
75 dateutil,
76 stringutil,
76 stringutil,
77 )
77 )
78
78
79 table = {}
79 table = {}
80 table.update(debugcommandsmod.command._table)
80 table.update(debugcommandsmod.command._table)
81
81
82 command = registrar.command(table)
82 command = registrar.command(table)
83 INTENT_READONLY = registrar.INTENT_READONLY
83 INTENT_READONLY = registrar.INTENT_READONLY
84
84
85 # common command options
85 # common command options
86
86
87 globalopts = [
87 globalopts = [
88 (
88 (
89 b'R',
89 b'R',
90 b'repository',
90 b'repository',
91 b'',
91 b'',
92 _(b'repository root directory or name of overlay bundle file'),
92 _(b'repository root directory or name of overlay bundle file'),
93 _(b'REPO'),
93 _(b'REPO'),
94 ),
94 ),
95 (b'', b'cwd', b'', _(b'change working directory'), _(b'DIR')),
95 (b'', b'cwd', b'', _(b'change working directory'), _(b'DIR')),
96 (
96 (
97 b'y',
97 b'y',
98 b'noninteractive',
98 b'noninteractive',
99 None,
99 None,
100 _(
100 _(
101 b'do not prompt, automatically pick the first choice for all prompts'
101 b'do not prompt, automatically pick the first choice for all prompts'
102 ),
102 ),
103 ),
103 ),
104 (b'q', b'quiet', None, _(b'suppress output')),
104 (b'q', b'quiet', None, _(b'suppress output')),
105 (b'v', b'verbose', None, _(b'enable additional output')),
105 (b'v', b'verbose', None, _(b'enable additional output')),
106 (
106 (
107 b'',
107 b'',
108 b'color',
108 b'color',
109 b'',
109 b'',
110 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
110 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
111 # and should not be translated
111 # and should not be translated
112 _(b"when to colorize (boolean, always, auto, never, or debug)"),
112 _(b"when to colorize (boolean, always, auto, never, or debug)"),
113 _(b'TYPE'),
113 _(b'TYPE'),
114 ),
114 ),
115 (
115 (
116 b'',
116 b'',
117 b'config',
117 b'config',
118 [],
118 [],
119 _(b'set/override config option (use \'section.name=value\')'),
119 _(b'set/override config option (use \'section.name=value\')'),
120 _(b'CONFIG'),
120 _(b'CONFIG'),
121 ),
121 ),
122 (b'', b'debug', None, _(b'enable debugging output')),
122 (b'', b'debug', None, _(b'enable debugging output')),
123 (b'', b'debugger', None, _(b'start debugger')),
123 (b'', b'debugger', None, _(b'start debugger')),
124 (
124 (
125 b'',
125 b'',
126 b'encoding',
126 b'encoding',
127 encoding.encoding,
127 encoding.encoding,
128 _(b'set the charset encoding'),
128 _(b'set the charset encoding'),
129 _(b'ENCODE'),
129 _(b'ENCODE'),
130 ),
130 ),
131 (
131 (
132 b'',
132 b'',
133 b'encodingmode',
133 b'encodingmode',
134 encoding.encodingmode,
134 encoding.encodingmode,
135 _(b'set the charset encoding mode'),
135 _(b'set the charset encoding mode'),
136 _(b'MODE'),
136 _(b'MODE'),
137 ),
137 ),
138 (b'', b'traceback', None, _(b'always print a traceback on exception')),
138 (b'', b'traceback', None, _(b'always print a traceback on exception')),
139 (b'', b'time', None, _(b'time how long the command takes')),
139 (b'', b'time', None, _(b'time how long the command takes')),
140 (b'', b'profile', None, _(b'print command execution profile')),
140 (b'', b'profile', None, _(b'print command execution profile')),
141 (b'', b'version', None, _(b'output version information and exit')),
141 (b'', b'version', None, _(b'output version information and exit')),
142 (b'h', b'help', None, _(b'display help and exit')),
142 (b'h', b'help', None, _(b'display help and exit')),
143 (b'', b'hidden', False, _(b'consider hidden changesets')),
143 (b'', b'hidden', False, _(b'consider hidden changesets')),
144 (
144 (
145 b'',
145 b'',
146 b'pager',
146 b'pager',
147 b'auto',
147 b'auto',
148 _(b"when to paginate (boolean, always, auto, or never)"),
148 _(b"when to paginate (boolean, always, auto, or never)"),
149 _(b'TYPE'),
149 _(b'TYPE'),
150 ),
150 ),
151 ]
151 ]
152
152
153 dryrunopts = cmdutil.dryrunopts
153 dryrunopts = cmdutil.dryrunopts
154 remoteopts = cmdutil.remoteopts
154 remoteopts = cmdutil.remoteopts
155 walkopts = cmdutil.walkopts
155 walkopts = cmdutil.walkopts
156 commitopts = cmdutil.commitopts
156 commitopts = cmdutil.commitopts
157 commitopts2 = cmdutil.commitopts2
157 commitopts2 = cmdutil.commitopts2
158 commitopts3 = cmdutil.commitopts3
158 commitopts3 = cmdutil.commitopts3
159 formatteropts = cmdutil.formatteropts
159 formatteropts = cmdutil.formatteropts
160 templateopts = cmdutil.templateopts
160 templateopts = cmdutil.templateopts
161 logopts = cmdutil.logopts
161 logopts = cmdutil.logopts
162 diffopts = cmdutil.diffopts
162 diffopts = cmdutil.diffopts
163 diffwsopts = cmdutil.diffwsopts
163 diffwsopts = cmdutil.diffwsopts
164 diffopts2 = cmdutil.diffopts2
164 diffopts2 = cmdutil.diffopts2
165 mergetoolopts = cmdutil.mergetoolopts
165 mergetoolopts = cmdutil.mergetoolopts
166 similarityopts = cmdutil.similarityopts
166 similarityopts = cmdutil.similarityopts
167 subrepoopts = cmdutil.subrepoopts
167 subrepoopts = cmdutil.subrepoopts
168 debugrevlogopts = cmdutil.debugrevlogopts
168 debugrevlogopts = cmdutil.debugrevlogopts
169
169
170 # Commands start here, listed alphabetically
170 # Commands start here, listed alphabetically
171
171
172
172
173 @command(
173 @command(
174 b'abort',
174 b'abort',
175 dryrunopts,
175 dryrunopts,
176 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
176 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
177 helpbasic=True,
177 helpbasic=True,
178 )
178 )
179 def abort(ui, repo, **opts):
179 def abort(ui, repo, **opts):
180 """abort an unfinished operation (EXPERIMENTAL)
180 """abort an unfinished operation (EXPERIMENTAL)
181
181
182 Aborts a multistep operation like graft, histedit, rebase, merge,
182 Aborts a multistep operation like graft, histedit, rebase, merge,
183 and unshelve if they are in an unfinished state.
183 and unshelve if they are in an unfinished state.
184
184
185 use --dry-run/-n to dry run the command.
185 use --dry-run/-n to dry run the command.
186 """
186 """
187 dryrun = opts.get('dry_run')
187 dryrun = opts.get('dry_run')
188 abortstate = cmdutil.getunfinishedstate(repo)
188 abortstate = cmdutil.getunfinishedstate(repo)
189 if not abortstate:
189 if not abortstate:
190 raise error.StateError(_(b'no operation in progress'))
190 raise error.StateError(_(b'no operation in progress'))
191 if not abortstate.abortfunc:
191 if not abortstate.abortfunc:
192 raise error.InputError(
192 raise error.InputError(
193 (
193 (
194 _(b"%s in progress but does not support 'hg abort'")
194 _(b"%s in progress but does not support 'hg abort'")
195 % (abortstate._opname)
195 % (abortstate._opname)
196 ),
196 ),
197 hint=abortstate.hint(),
197 hint=abortstate.hint(),
198 )
198 )
199 if dryrun:
199 if dryrun:
200 ui.status(
200 ui.status(
201 _(b'%s in progress, will be aborted\n') % (abortstate._opname)
201 _(b'%s in progress, will be aborted\n') % (abortstate._opname)
202 )
202 )
203 return
203 return
204 return abortstate.abortfunc(ui, repo)
204 return abortstate.abortfunc(ui, repo)
205
205
206
206
207 @command(
207 @command(
208 b'add',
208 b'add',
209 walkopts + subrepoopts + dryrunopts,
209 walkopts + subrepoopts + dryrunopts,
210 _(b'[OPTION]... [FILE]...'),
210 _(b'[OPTION]... [FILE]...'),
211 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
211 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
212 helpbasic=True,
212 helpbasic=True,
213 inferrepo=True,
213 inferrepo=True,
214 )
214 )
215 def add(ui, repo, *pats, **opts):
215 def add(ui, repo, *pats, **opts):
216 """add the specified files on the next commit
216 """add the specified files on the next commit
217
217
218 Schedule files to be version controlled and added to the
218 Schedule files to be version controlled and added to the
219 repository.
219 repository.
220
220
221 The files will be added to the repository at the next commit. To
221 The files will be added to the repository at the next commit. To
222 undo an add before that, see :hg:`forget`.
222 undo an add before that, see :hg:`forget`.
223
223
224 If no names are given, add all files to the repository (except
224 If no names are given, add all files to the repository (except
225 files matching ``.hgignore``).
225 files matching ``.hgignore``).
226
226
227 .. container:: verbose
227 .. container:: verbose
228
228
229 Examples:
229 Examples:
230
230
231 - New (unknown) files are added
231 - New (unknown) files are added
232 automatically by :hg:`add`::
232 automatically by :hg:`add`::
233
233
234 $ ls
234 $ ls
235 foo.c
235 foo.c
236 $ hg status
236 $ hg status
237 ? foo.c
237 ? foo.c
238 $ hg add
238 $ hg add
239 adding foo.c
239 adding foo.c
240 $ hg status
240 $ hg status
241 A foo.c
241 A foo.c
242
242
243 - Specific files to be added can be specified::
243 - Specific files to be added can be specified::
244
244
245 $ ls
245 $ ls
246 bar.c foo.c
246 bar.c foo.c
247 $ hg status
247 $ hg status
248 ? bar.c
248 ? bar.c
249 ? foo.c
249 ? foo.c
250 $ hg add bar.c
250 $ hg add bar.c
251 $ hg status
251 $ hg status
252 A bar.c
252 A bar.c
253 ? foo.c
253 ? foo.c
254
254
255 Returns 0 if all files are successfully added.
255 Returns 0 if all files are successfully added.
256 """
256 """
257
257
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 matcher = scmutil.match(repo[None], pats, opts)
336 matcher = scmutil.match(repo[None], pats, opts)
337 relative = scmutil.anypats(pats, opts)
337 relative = scmutil.anypats(pats, opts)
338 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
338 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
339 return scmutil.addremove(repo, matcher, b"", uipathfn, opts)
339 return scmutil.addremove(repo, matcher, b"", uipathfn, opts)
340
340
341
341
342 @command(
342 @command(
343 b'annotate|blame',
343 b'annotate|blame',
344 [
344 [
345 (b'r', b'rev', b'', _(b'annotate the specified revision'), _(b'REV')),
345 (b'r', b'rev', b'', _(b'annotate the specified revision'), _(b'REV')),
346 (
346 (
347 b'',
347 b'',
348 b'follow',
348 b'follow',
349 None,
349 None,
350 _(b'follow copies/renames and list the filename (DEPRECATED)'),
350 _(b'follow copies/renames and list the filename (DEPRECATED)'),
351 ),
351 ),
352 (b'', b'no-follow', None, _(b"don't follow copies and renames")),
352 (b'', b'no-follow', None, _(b"don't follow copies and renames")),
353 (b'a', b'text', None, _(b'treat all files as text')),
353 (b'a', b'text', None, _(b'treat all files as text')),
354 (b'u', b'user', None, _(b'list the author (long with -v)')),
354 (b'u', b'user', None, _(b'list the author (long with -v)')),
355 (b'f', b'file', None, _(b'list the filename')),
355 (b'f', b'file', None, _(b'list the filename')),
356 (b'd', b'date', None, _(b'list the date (short with -q)')),
356 (b'd', b'date', None, _(b'list the date (short with -q)')),
357 (b'n', b'number', None, _(b'list the revision number (default)')),
357 (b'n', b'number', None, _(b'list the revision number (default)')),
358 (b'c', b'changeset', None, _(b'list the changeset')),
358 (b'c', b'changeset', None, _(b'list the changeset')),
359 (
359 (
360 b'l',
360 b'l',
361 b'line-number',
361 b'line-number',
362 None,
362 None,
363 _(b'show line number at the first appearance'),
363 _(b'show line number at the first appearance'),
364 ),
364 ),
365 (
365 (
366 b'',
366 b'',
367 b'skip',
367 b'skip',
368 [],
368 [],
369 _(b'revset to not display (EXPERIMENTAL)'),
369 _(b'revset to not display (EXPERIMENTAL)'),
370 _(b'REV'),
370 _(b'REV'),
371 ),
371 ),
372 ]
372 ]
373 + diffwsopts
373 + diffwsopts
374 + walkopts
374 + walkopts
375 + formatteropts,
375 + formatteropts,
376 _(b'[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
376 _(b'[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
377 helpcategory=command.CATEGORY_FILE_CONTENTS,
377 helpcategory=command.CATEGORY_FILE_CONTENTS,
378 helpbasic=True,
378 helpbasic=True,
379 inferrepo=True,
379 inferrepo=True,
380 )
380 )
381 def annotate(ui, repo, *pats, **opts):
381 def annotate(ui, repo, *pats, **opts):
382 """show changeset information by line for each file
382 """show changeset information by line for each file
383
383
384 List changes in files, showing the revision id responsible for
384 List changes in files, showing the revision id responsible for
385 each line.
385 each line.
386
386
387 This command is useful for discovering when a change was made and
387 This command is useful for discovering when a change was made and
388 by whom.
388 by whom.
389
389
390 If you include --file, --user, or --date, the revision number is
390 If you include --file, --user, or --date, the revision number is
391 suppressed unless you also include --number.
391 suppressed unless you also include --number.
392
392
393 Without the -a/--text option, annotate will avoid processing files
393 Without the -a/--text option, annotate will avoid processing files
394 it detects as binary. With -a, annotate will annotate the file
394 it detects as binary. With -a, annotate will annotate the file
395 anyway, although the results will probably be neither useful
395 anyway, although the results will probably be neither useful
396 nor desirable.
396 nor desirable.
397
397
398 .. container:: verbose
398 .. container:: verbose
399
399
400 Template:
400 Template:
401
401
402 The following keywords are supported in addition to the common template
402 The following keywords are supported in addition to the common template
403 keywords and functions. See also :hg:`help templates`.
403 keywords and functions. See also :hg:`help templates`.
404
404
405 :lines: List of lines with annotation data.
405 :lines: List of lines with annotation data.
406 :path: String. Repository-absolute path of the specified file.
406 :path: String. Repository-absolute path of the specified file.
407
407
408 And each entry of ``{lines}`` provides the following sub-keywords in
408 And each entry of ``{lines}`` provides the following sub-keywords in
409 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
409 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
410
410
411 :line: String. Line content.
411 :line: String. Line content.
412 :lineno: Integer. Line number at that revision.
412 :lineno: Integer. Line number at that revision.
413 :path: String. Repository-absolute path of the file at that revision.
413 :path: String. Repository-absolute path of the file at that revision.
414
414
415 See :hg:`help templates.operators` for the list expansion syntax.
415 See :hg:`help templates.operators` for the list expansion syntax.
416
416
417 Returns 0 on success.
417 Returns 0 on success.
418 """
418 """
419 opts = pycompat.byteskwargs(opts)
419 opts = pycompat.byteskwargs(opts)
420 if not pats:
420 if not pats:
421 raise error.InputError(
421 raise error.InputError(
422 _(b'at least one filename or pattern is required')
422 _(b'at least one filename or pattern is required')
423 )
423 )
424
424
425 if opts.get(b'follow'):
425 if opts.get(b'follow'):
426 # --follow is deprecated and now just an alias for -f/--file
426 # --follow is deprecated and now just an alias for -f/--file
427 # to mimic the behavior of Mercurial before version 1.5
427 # to mimic the behavior of Mercurial before version 1.5
428 opts[b'file'] = True
428 opts[b'file'] = True
429
429
430 if (
430 if (
431 not opts.get(b'user')
431 not opts.get(b'user')
432 and not opts.get(b'changeset')
432 and not opts.get(b'changeset')
433 and not opts.get(b'date')
433 and not opts.get(b'date')
434 and not opts.get(b'file')
434 and not opts.get(b'file')
435 ):
435 ):
436 opts[b'number'] = True
436 opts[b'number'] = True
437
437
438 linenumber = opts.get(b'line_number') is not None
438 linenumber = opts.get(b'line_number') is not None
439 if (
439 if (
440 linenumber
440 linenumber
441 and (not opts.get(b'changeset'))
441 and (not opts.get(b'changeset'))
442 and (not opts.get(b'number'))
442 and (not opts.get(b'number'))
443 ):
443 ):
444 raise error.InputError(_(b'at least one of -n/-c is required for -l'))
444 raise error.InputError(_(b'at least one of -n/-c is required for -l'))
445
445
446 rev = opts.get(b'rev')
446 rev = opts.get(b'rev')
447 if rev:
447 if rev:
448 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
448 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
449 ctx = scmutil.revsingle(repo, rev)
449 ctx = scmutil.revsingle(repo, rev)
450
450
451 ui.pager(b'annotate')
451 ui.pager(b'annotate')
452 rootfm = ui.formatter(b'annotate', opts)
452 rootfm = ui.formatter(b'annotate', opts)
453 if ui.debugflag:
453 if ui.debugflag:
454 shorthex = pycompat.identity
454 shorthex = pycompat.identity
455 else:
455 else:
456
456
457 def shorthex(h):
457 def shorthex(h):
458 return h[:12]
458 return h[:12]
459
459
460 if ui.quiet:
460 if ui.quiet:
461 datefunc = dateutil.shortdate
461 datefunc = dateutil.shortdate
462 else:
462 else:
463 datefunc = dateutil.datestr
463 datefunc = dateutil.datestr
464 if ctx.rev() is None:
464 if ctx.rev() is None:
465 if opts.get(b'changeset'):
465 if opts.get(b'changeset'):
466 # omit "+" suffix which is appended to node hex
466 # omit "+" suffix which is appended to node hex
467 def formatrev(rev):
467 def formatrev(rev):
468 if rev == wdirrev:
468 if rev == wdirrev:
469 return b'%d' % ctx.p1().rev()
469 return b'%d' % ctx.p1().rev()
470 else:
470 else:
471 return b'%d' % rev
471 return b'%d' % rev
472
472
473 else:
473 else:
474
474
475 def formatrev(rev):
475 def formatrev(rev):
476 if rev == wdirrev:
476 if rev == wdirrev:
477 return b'%d+' % ctx.p1().rev()
477 return b'%d+' % ctx.p1().rev()
478 else:
478 else:
479 return b'%d ' % rev
479 return b'%d ' % rev
480
480
481 def formathex(h):
481 def formathex(h):
482 if h == wdirhex:
482 if h == wdirhex:
483 return b'%s+' % shorthex(hex(ctx.p1().node()))
483 return b'%s+' % shorthex(hex(ctx.p1().node()))
484 else:
484 else:
485 return b'%s ' % shorthex(h)
485 return b'%s ' % shorthex(h)
486
486
487 else:
487 else:
488 formatrev = b'%d'.__mod__
488 formatrev = b'%d'.__mod__
489 formathex = shorthex
489 formathex = shorthex
490
490
491 opmap = [
491 opmap = [
492 (b'user', b' ', lambda x: x.fctx.user(), ui.shortuser),
492 (b'user', b' ', lambda x: x.fctx.user(), ui.shortuser),
493 (b'rev', b' ', lambda x: scmutil.intrev(x.fctx), formatrev),
493 (b'rev', b' ', lambda x: scmutil.intrev(x.fctx), formatrev),
494 (b'node', b' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
494 (b'node', b' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
495 (b'date', b' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
495 (b'date', b' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
496 (b'path', b' ', lambda x: x.fctx.path(), pycompat.bytestr),
496 (b'path', b' ', lambda x: x.fctx.path(), pycompat.bytestr),
497 (b'lineno', b':', lambda x: x.lineno, pycompat.bytestr),
497 (b'lineno', b':', lambda x: x.lineno, pycompat.bytestr),
498 ]
498 ]
499 opnamemap = {
499 opnamemap = {
500 b'rev': b'number',
500 b'rev': b'number',
501 b'node': b'changeset',
501 b'node': b'changeset',
502 b'path': b'file',
502 b'path': b'file',
503 b'lineno': b'line_number',
503 b'lineno': b'line_number',
504 }
504 }
505
505
506 if rootfm.isplain():
506 if rootfm.isplain():
507
507
508 def makefunc(get, fmt):
508 def makefunc(get, fmt):
509 return lambda x: fmt(get(x))
509 return lambda x: fmt(get(x))
510
510
511 else:
511 else:
512
512
513 def makefunc(get, fmt):
513 def makefunc(get, fmt):
514 return get
514 return get
515
515
516 datahint = rootfm.datahint()
516 datahint = rootfm.datahint()
517 funcmap = [
517 funcmap = [
518 (makefunc(get, fmt), sep)
518 (makefunc(get, fmt), sep)
519 for fn, sep, get, fmt in opmap
519 for fn, sep, get, fmt in opmap
520 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
520 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
521 ]
521 ]
522 funcmap[0] = (funcmap[0][0], b'') # no separator in front of first column
522 funcmap[0] = (funcmap[0][0], b'') # no separator in front of first column
523 fields = b' '.join(
523 fields = b' '.join(
524 fn
524 fn
525 for fn, sep, get, fmt in opmap
525 for fn, sep, get, fmt in opmap
526 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
526 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
527 )
527 )
528
528
529 def bad(x, y):
529 def bad(x, y):
530 raise error.Abort(b"%s: %s" % (x, y))
530 raise error.Abort(b"%s: %s" % (x, y))
531
531
532 m = scmutil.match(ctx, pats, opts, badfn=bad)
532 m = scmutil.match(ctx, pats, opts, badfn=bad)
533
533
534 follow = not opts.get(b'no_follow')
534 follow = not opts.get(b'no_follow')
535 diffopts = patch.difffeatureopts(
535 diffopts = patch.difffeatureopts(
536 ui, opts, section=b'annotate', whitespace=True
536 ui, opts, section=b'annotate', whitespace=True
537 )
537 )
538 skiprevs = opts.get(b'skip')
538 skiprevs = opts.get(b'skip')
539 if skiprevs:
539 if skiprevs:
540 skiprevs = scmutil.revrange(repo, skiprevs)
540 skiprevs = scmutil.revrange(repo, skiprevs)
541
541
542 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
542 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
543 for abs in ctx.walk(m):
543 for abs in ctx.walk(m):
544 fctx = ctx[abs]
544 fctx = ctx[abs]
545 rootfm.startitem()
545 rootfm.startitem()
546 rootfm.data(path=abs)
546 rootfm.data(path=abs)
547 if not opts.get(b'text') and fctx.isbinary():
547 if not opts.get(b'text') and fctx.isbinary():
548 rootfm.plain(_(b"%s: binary file\n") % uipathfn(abs))
548 rootfm.plain(_(b"%s: binary file\n") % uipathfn(abs))
549 continue
549 continue
550
550
551 fm = rootfm.nested(b'lines', tmpl=b'{rev}: {line}')
551 fm = rootfm.nested(b'lines', tmpl=b'{rev}: {line}')
552 lines = fctx.annotate(
552 lines = fctx.annotate(
553 follow=follow, skiprevs=skiprevs, diffopts=diffopts
553 follow=follow, skiprevs=skiprevs, diffopts=diffopts
554 )
554 )
555 if not lines:
555 if not lines:
556 fm.end()
556 fm.end()
557 continue
557 continue
558 formats = []
558 formats = []
559 pieces = []
559 pieces = []
560
560
561 for f, sep in funcmap:
561 for f, sep in funcmap:
562 l = [f(n) for n in lines]
562 l = [f(n) for n in lines]
563 if fm.isplain():
563 if fm.isplain():
564 sizes = [encoding.colwidth(x) for x in l]
564 sizes = [encoding.colwidth(x) for x in l]
565 ml = max(sizes)
565 ml = max(sizes)
566 formats.append([sep + b' ' * (ml - w) + b'%s' for w in sizes])
566 formats.append([sep + b' ' * (ml - w) + b'%s' for w in sizes])
567 else:
567 else:
568 formats.append([b'%s'] * len(l))
568 formats.append([b'%s'] * len(l))
569 pieces.append(l)
569 pieces.append(l)
570
570
571 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
571 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
572 fm.startitem()
572 fm.startitem()
573 fm.context(fctx=n.fctx)
573 fm.context(fctx=n.fctx)
574 fm.write(fields, b"".join(f), *p)
574 fm.write(fields, b"".join(f), *p)
575 if n.skip:
575 if n.skip:
576 fmt = b"* %s"
576 fmt = b"* %s"
577 else:
577 else:
578 fmt = b": %s"
578 fmt = b": %s"
579 fm.write(b'line', fmt, n.text)
579 fm.write(b'line', fmt, n.text)
580
580
581 if not lines[-1].text.endswith(b'\n'):
581 if not lines[-1].text.endswith(b'\n'):
582 fm.plain(b'\n')
582 fm.plain(b'\n')
583 fm.end()
583 fm.end()
584
584
585 rootfm.end()
585 rootfm.end()
586
586
587
587
588 @command(
588 @command(
589 b'archive',
589 b'archive',
590 [
590 [
591 (b'', b'no-decode', None, _(b'do not pass files through decoders')),
591 (b'', b'no-decode', None, _(b'do not pass files through decoders')),
592 (
592 (
593 b'p',
593 b'p',
594 b'prefix',
594 b'prefix',
595 b'',
595 b'',
596 _(b'directory prefix for files in archive'),
596 _(b'directory prefix for files in archive'),
597 _(b'PREFIX'),
597 _(b'PREFIX'),
598 ),
598 ),
599 (b'r', b'rev', b'', _(b'revision to distribute'), _(b'REV')),
599 (b'r', b'rev', b'', _(b'revision to distribute'), _(b'REV')),
600 (b't', b'type', b'', _(b'type of distribution to create'), _(b'TYPE')),
600 (b't', b'type', b'', _(b'type of distribution to create'), _(b'TYPE')),
601 ]
601 ]
602 + subrepoopts
602 + subrepoopts
603 + walkopts,
603 + walkopts,
604 _(b'[OPTION]... DEST'),
604 _(b'[OPTION]... DEST'),
605 helpcategory=command.CATEGORY_IMPORT_EXPORT,
605 helpcategory=command.CATEGORY_IMPORT_EXPORT,
606 )
606 )
607 def archive(ui, repo, dest, **opts):
607 def archive(ui, repo, dest, **opts):
608 """create an unversioned archive of a repository revision
608 """create an unversioned archive of a repository revision
609
609
610 By default, the revision used is the parent of the working
610 By default, the revision used is the parent of the working
611 directory; use -r/--rev to specify a different revision.
611 directory; use -r/--rev to specify a different revision.
612
612
613 The archive type is automatically detected based on file
613 The archive type is automatically detected based on file
614 extension (to override, use -t/--type).
614 extension (to override, use -t/--type).
615
615
616 .. container:: verbose
616 .. container:: verbose
617
617
618 Examples:
618 Examples:
619
619
620 - create a zip file containing the 1.0 release::
620 - create a zip file containing the 1.0 release::
621
621
622 hg archive -r 1.0 project-1.0.zip
622 hg archive -r 1.0 project-1.0.zip
623
623
624 - create a tarball excluding .hg files::
624 - create a tarball excluding .hg files::
625
625
626 hg archive project.tar.gz -X ".hg*"
626 hg archive project.tar.gz -X ".hg*"
627
627
628 Valid types are:
628 Valid types are:
629
629
630 :``files``: a directory full of files (default)
630 :``files``: a directory full of files (default)
631 :``tar``: tar archive, uncompressed
631 :``tar``: tar archive, uncompressed
632 :``tbz2``: tar archive, compressed using bzip2
632 :``tbz2``: tar archive, compressed using bzip2
633 :``tgz``: tar archive, compressed using gzip
633 :``tgz``: tar archive, compressed using gzip
634 :``txz``: tar archive, compressed using lzma (only in Python 3)
634 :``txz``: tar archive, compressed using lzma (only in Python 3)
635 :``uzip``: zip archive, uncompressed
635 :``uzip``: zip archive, uncompressed
636 :``zip``: zip archive, compressed using deflate
636 :``zip``: zip archive, compressed using deflate
637
637
638 The exact name of the destination archive or directory is given
638 The exact name of the destination archive or directory is given
639 using a format string; see :hg:`help export` for details.
639 using a format string; see :hg:`help export` for details.
640
640
641 Each member added to an archive file has a directory prefix
641 Each member added to an archive file has a directory prefix
642 prepended. Use -p/--prefix to specify a format string for the
642 prepended. Use -p/--prefix to specify a format string for the
643 prefix. The default is the basename of the archive, with suffixes
643 prefix. The default is the basename of the archive, with suffixes
644 removed.
644 removed.
645
645
646 Returns 0 on success.
646 Returns 0 on success.
647 """
647 """
648
648
649 opts = pycompat.byteskwargs(opts)
649 opts = pycompat.byteskwargs(opts)
650 rev = opts.get(b'rev')
650 rev = opts.get(b'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 = scmutil.revsingle(repo, rev)
653 ctx = scmutil.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(b'type') or archival.guesskind(dest) or b'files'
663 kind = opts.get(b'type') or archival.guesskind(dest) or b'files'
664 prefix = opts.get(b'prefix')
664 prefix = opts.get(b'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, [], opts)
674 match = scmutil.match(ctx, [], 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(b'no_decode'),
680 not opts.get(b'no_decode'),
681 match,
681 match,
682 prefix,
682 prefix,
683 subrepos=opts.get(b'subrepos'),
683 subrepos=opts.get(b'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 opts = pycompat.byteskwargs(opts)
778 opts = pycompat.byteskwargs(opts)
779
779
780 if rev and node:
780 if rev and node:
781 raise error.InputError(_(b"please specify just one revision"))
781 raise error.InputError(_(b"please specify just one revision"))
782
782
783 if not rev:
783 if not rev:
784 rev = node
784 rev = node
785
785
786 if not rev:
786 if not rev:
787 raise error.InputError(_(b"please specify a revision to backout"))
787 raise error.InputError(_(b"please specify a revision to backout"))
788
788
789 date = opts.get(b'date')
789 date = opts.get(b'date')
790 if date:
790 if date:
791 opts[b'date'] = dateutil.parsedate(date)
791 opts[b'date'] = dateutil.parsedate(date)
792
792
793 cmdutil.checkunfinished(repo)
793 cmdutil.checkunfinished(repo)
794 cmdutil.bailifchanged(repo)
794 cmdutil.bailifchanged(repo)
795 ctx = scmutil.revsingle(repo, rev)
795 ctx = scmutil.revsingle(repo, rev)
796 node = ctx.node()
796 node = ctx.node()
797
797
798 op1, op2 = repo.dirstate.parents()
798 op1, op2 = repo.dirstate.parents()
799 if not repo.changelog.isancestor(node, op1):
799 if not repo.changelog.isancestor(node, op1):
800 raise error.InputError(
800 raise error.InputError(
801 _(b'cannot backout change that is not an ancestor')
801 _(b'cannot backout change that is not an ancestor')
802 )
802 )
803
803
804 p1, p2 = repo.changelog.parents(node)
804 p1, p2 = repo.changelog.parents(node)
805 if p1 == nullid:
805 if p1 == nullid:
806 raise error.InputError(_(b'cannot backout a change with no parents'))
806 raise error.InputError(_(b'cannot backout a change with no parents'))
807 if p2 != nullid:
807 if p2 != nullid:
808 if not opts.get(b'parent'):
808 if not opts.get(b'parent'):
809 raise error.InputError(_(b'cannot backout a merge changeset'))
809 raise error.InputError(_(b'cannot backout a merge changeset'))
810 p = repo.lookup(opts[b'parent'])
810 p = repo.lookup(opts[b'parent'])
811 if p not in (p1, p2):
811 if p not in (p1, p2):
812 raise error.InputError(
812 raise error.InputError(
813 _(b'%s is not a parent of %s') % (short(p), short(node))
813 _(b'%s is not a parent of %s') % (short(p), short(node))
814 )
814 )
815 parent = p
815 parent = p
816 else:
816 else:
817 if opts.get(b'parent'):
817 if opts.get(b'parent'):
818 raise error.InputError(
818 raise error.InputError(
819 _(b'cannot use --parent on non-merge changeset')
819 _(b'cannot use --parent on non-merge changeset')
820 )
820 )
821 parent = p1
821 parent = p1
822
822
823 # the backout should appear on the same branch
823 # the backout should appear on the same branch
824 branch = repo.dirstate.branch()
824 branch = repo.dirstate.branch()
825 bheads = repo.branchheads(branch)
825 bheads = repo.branchheads(branch)
826 rctx = scmutil.revsingle(repo, hex(parent))
826 rctx = scmutil.revsingle(repo, hex(parent))
827 if not opts.get(b'merge') and op1 != node:
827 if not opts.get(b'merge') and op1 != node:
828 with dirstateguard.dirstateguard(repo, b'backout'):
828 with dirstateguard.dirstateguard(repo, b'backout'):
829 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
829 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
830 with ui.configoverride(overrides, b'backout'):
830 with ui.configoverride(overrides, b'backout'):
831 stats = mergemod.back_out(ctx, parent=repo[parent])
831 stats = mergemod.back_out(ctx, parent=repo[parent])
832 repo.setparents(op1, op2)
832 repo.setparents(op1, op2)
833 hg._showstats(repo, stats)
833 hg._showstats(repo, stats)
834 if stats.unresolvedcount:
834 if stats.unresolvedcount:
835 repo.ui.status(
835 repo.ui.status(
836 _(b"use 'hg resolve' to retry unresolved file merges\n")
836 _(b"use 'hg resolve' to retry unresolved file merges\n")
837 )
837 )
838 return 1
838 return 1
839 else:
839 else:
840 hg.clean(repo, node, show_stats=False)
840 hg.clean(repo, node, show_stats=False)
841 repo.dirstate.setbranch(branch)
841 repo.dirstate.setbranch(branch)
842 cmdutil.revert(ui, repo, rctx)
842 cmdutil.revert(ui, repo, rctx)
843
843
844 if opts.get(b'no_commit'):
844 if opts.get(b'no_commit'):
845 msg = _(b"changeset %s backed out, don't forget to commit.\n")
845 msg = _(b"changeset %s backed out, don't forget to commit.\n")
846 ui.status(msg % short(node))
846 ui.status(msg % short(node))
847 return 0
847 return 0
848
848
849 def commitfunc(ui, repo, message, match, opts):
849 def commitfunc(ui, repo, message, match, opts):
850 editform = b'backout'
850 editform = b'backout'
851 e = cmdutil.getcommiteditor(
851 e = cmdutil.getcommiteditor(
852 editform=editform, **pycompat.strkwargs(opts)
852 editform=editform, **pycompat.strkwargs(opts)
853 )
853 )
854 if not message:
854 if not message:
855 # we don't translate commit messages
855 # we don't translate commit messages
856 message = b"Backed out changeset %s" % short(node)
856 message = b"Backed out changeset %s" % short(node)
857 e = cmdutil.getcommiteditor(edit=True, editform=editform)
857 e = cmdutil.getcommiteditor(edit=True, editform=editform)
858 return repo.commit(
858 return repo.commit(
859 message, opts.get(b'user'), opts.get(b'date'), match, editor=e
859 message, opts.get(b'user'), opts.get(b'date'), match, editor=e
860 )
860 )
861
861
862 # save to detect changes
862 # save to detect changes
863 tip = repo.changelog.tip()
863 tip = repo.changelog.tip()
864
864
865 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
865 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
866 if not newnode:
866 if not newnode:
867 ui.status(_(b"nothing changed\n"))
867 ui.status(_(b"nothing changed\n"))
868 return 1
868 return 1
869 cmdutil.commitstatus(repo, newnode, branch, bheads, tip)
869 cmdutil.commitstatus(repo, newnode, branch, bheads, tip)
870
870
871 def nice(node):
871 def nice(node):
872 return b'%d:%s' % (repo.changelog.rev(node), short(node))
872 return b'%d:%s' % (repo.changelog.rev(node), short(node))
873
873
874 ui.status(
874 ui.status(
875 _(b'changeset %s backs out changeset %s\n')
875 _(b'changeset %s backs out changeset %s\n')
876 % (nice(newnode), nice(node))
876 % (nice(newnode), nice(node))
877 )
877 )
878 if opts.get(b'merge') and op1 != node:
878 if opts.get(b'merge') and op1 != node:
879 hg.clean(repo, op1, show_stats=False)
879 hg.clean(repo, op1, show_stats=False)
880 ui.status(_(b'merging with changeset %s\n') % nice(newnode))
880 ui.status(_(b'merging with changeset %s\n') % nice(newnode))
881 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
881 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
882 with ui.configoverride(overrides, b'backout'):
882 with ui.configoverride(overrides, b'backout'):
883 return hg.merge(repo[b'tip'])
883 return hg.merge(repo[b'tip'])
884 return 0
884 return 0
885
885
886
886
887 @command(
887 @command(
888 b'bisect',
888 b'bisect',
889 [
889 [
890 (b'r', b'reset', False, _(b'reset bisect state')),
890 (b'r', b'reset', False, _(b'reset bisect state')),
891 (b'g', b'good', False, _(b'mark changeset good')),
891 (b'g', b'good', False, _(b'mark changeset good')),
892 (b'b', b'bad', False, _(b'mark changeset bad')),
892 (b'b', b'bad', False, _(b'mark changeset bad')),
893 (b's', b'skip', False, _(b'skip testing changeset')),
893 (b's', b'skip', False, _(b'skip testing changeset')),
894 (b'e', b'extend', False, _(b'extend the bisect range')),
894 (b'e', b'extend', False, _(b'extend the bisect range')),
895 (
895 (
896 b'c',
896 b'c',
897 b'command',
897 b'command',
898 b'',
898 b'',
899 _(b'use command to check changeset state'),
899 _(b'use command to check changeset state'),
900 _(b'CMD'),
900 _(b'CMD'),
901 ),
901 ),
902 (b'U', b'noupdate', False, _(b'do not update to target')),
902 (b'U', b'noupdate', False, _(b'do not update to target')),
903 ],
903 ],
904 _(b"[-gbsr] [-U] [-c CMD] [REV]"),
904 _(b"[-gbsr] [-U] [-c CMD] [REV]"),
905 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
905 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
906 )
906 )
907 def bisect(
907 def bisect(
908 ui,
908 ui,
909 repo,
909 repo,
910 positional_1=None,
910 positional_1=None,
911 positional_2=None,
911 positional_2=None,
912 command=None,
912 command=None,
913 reset=None,
913 reset=None,
914 good=None,
914 good=None,
915 bad=None,
915 bad=None,
916 skip=None,
916 skip=None,
917 extend=None,
917 extend=None,
918 noupdate=None,
918 noupdate=None,
919 ):
919 ):
920 """subdivision search of changesets
920 """subdivision search of changesets
921
921
922 This command helps to find changesets which introduce problems. To
922 This command helps to find changesets which introduce problems. To
923 use, mark the earliest changeset you know exhibits the problem as
923 use, mark the earliest changeset you know exhibits the problem as
924 bad, then mark the latest changeset which is free from the problem
924 bad, then mark the latest changeset which is free from the problem
925 as good. Bisect will update your working directory to a revision
925 as good. Bisect will update your working directory to a revision
926 for testing (unless the -U/--noupdate option is specified). Once
926 for testing (unless the -U/--noupdate option is specified). Once
927 you have performed tests, mark the working directory as good or
927 you have performed tests, mark the working directory as good or
928 bad, and bisect will either update to another candidate changeset
928 bad, and bisect will either update to another candidate changeset
929 or announce that it has found the bad revision.
929 or announce that it has found the bad revision.
930
930
931 As a shortcut, you can also use the revision argument to mark a
931 As a shortcut, you can also use the revision argument to mark a
932 revision as good or bad without checking it out first.
932 revision as good or bad without checking it out first.
933
933
934 If you supply a command, it will be used for automatic bisection.
934 If you supply a command, it will be used for automatic bisection.
935 The environment variable HG_NODE will contain the ID of the
935 The environment variable HG_NODE will contain the ID of the
936 changeset being tested. The exit status of the command will be
936 changeset being tested. The exit status of the command will be
937 used to mark revisions as good or bad: status 0 means good, 125
937 used to mark revisions as good or bad: status 0 means good, 125
938 means to skip the revision, 127 (command not found) will abort the
938 means to skip the revision, 127 (command not found) will abort the
939 bisection, and any other non-zero exit status means the revision
939 bisection, and any other non-zero exit status means the revision
940 is bad.
940 is bad.
941
941
942 .. container:: verbose
942 .. container:: verbose
943
943
944 Some examples:
944 Some examples:
945
945
946 - start a bisection with known bad revision 34, and good revision 12::
946 - start a bisection with known bad revision 34, and good revision 12::
947
947
948 hg bisect --bad 34
948 hg bisect --bad 34
949 hg bisect --good 12
949 hg bisect --good 12
950
950
951 - advance the current bisection by marking current revision as good or
951 - advance the current bisection by marking current revision as good or
952 bad::
952 bad::
953
953
954 hg bisect --good
954 hg bisect --good
955 hg bisect --bad
955 hg bisect --bad
956
956
957 - mark the current revision, or a known revision, to be skipped (e.g. if
957 - mark the current revision, or a known revision, to be skipped (e.g. if
958 that revision is not usable because of another issue)::
958 that revision is not usable because of another issue)::
959
959
960 hg bisect --skip
960 hg bisect --skip
961 hg bisect --skip 23
961 hg bisect --skip 23
962
962
963 - skip all revisions that do not touch directories ``foo`` or ``bar``::
963 - skip all revisions that do not touch directories ``foo`` or ``bar``::
964
964
965 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
965 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
966
966
967 - forget the current bisection::
967 - forget the current bisection::
968
968
969 hg bisect --reset
969 hg bisect --reset
970
970
971 - use 'make && make tests' to automatically find the first broken
971 - use 'make && make tests' to automatically find the first broken
972 revision::
972 revision::
973
973
974 hg bisect --reset
974 hg bisect --reset
975 hg bisect --bad 34
975 hg bisect --bad 34
976 hg bisect --good 12
976 hg bisect --good 12
977 hg bisect --command "make && make tests"
977 hg bisect --command "make && make tests"
978
978
979 - see all changesets whose states are already known in the current
979 - see all changesets whose states are already known in the current
980 bisection::
980 bisection::
981
981
982 hg log -r "bisect(pruned)"
982 hg log -r "bisect(pruned)"
983
983
984 - see the changeset currently being bisected (especially useful
984 - see the changeset currently being bisected (especially useful
985 if running with -U/--noupdate)::
985 if running with -U/--noupdate)::
986
986
987 hg log -r "bisect(current)"
987 hg log -r "bisect(current)"
988
988
989 - see all changesets that took part in the current bisection::
989 - see all changesets that took part in the current bisection::
990
990
991 hg log -r "bisect(range)"
991 hg log -r "bisect(range)"
992
992
993 - you can even get a nice graph::
993 - you can even get a nice graph::
994
994
995 hg log --graph -r "bisect(range)"
995 hg log --graph -r "bisect(range)"
996
996
997 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
997 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
998
998
999 Returns 0 on success.
999 Returns 0 on success.
1000 """
1000 """
1001 rev = []
1001 rev = []
1002 # backward compatibility
1002 # backward compatibility
1003 if positional_1 in (b"good", b"bad", b"reset", b"init"):
1003 if positional_1 in (b"good", b"bad", b"reset", b"init"):
1004 ui.warn(_(b"(use of 'hg bisect <cmd>' is deprecated)\n"))
1004 ui.warn(_(b"(use of 'hg bisect <cmd>' is deprecated)\n"))
1005 cmd = positional_1
1005 cmd = positional_1
1006 rev.append(positional_2)
1006 rev.append(positional_2)
1007 if cmd == b"good":
1007 if cmd == b"good":
1008 good = True
1008 good = True
1009 elif cmd == b"bad":
1009 elif cmd == b"bad":
1010 bad = True
1010 bad = True
1011 else:
1011 else:
1012 reset = True
1012 reset = True
1013 elif positional_2:
1013 elif positional_2:
1014 raise error.InputError(_(b'incompatible arguments'))
1014 raise error.InputError(_(b'incompatible arguments'))
1015 elif positional_1 is not None:
1015 elif positional_1 is not None:
1016 rev.append(positional_1)
1016 rev.append(positional_1)
1017
1017
1018 incompatibles = {
1018 incompatibles = {
1019 b'--bad': bad,
1019 b'--bad': bad,
1020 b'--command': bool(command),
1020 b'--command': bool(command),
1021 b'--extend': extend,
1021 b'--extend': extend,
1022 b'--good': good,
1022 b'--good': good,
1023 b'--reset': reset,
1023 b'--reset': reset,
1024 b'--skip': skip,
1024 b'--skip': skip,
1025 }
1025 }
1026
1026
1027 enabled = [x for x in incompatibles if incompatibles[x]]
1027 enabled = [x for x in incompatibles if incompatibles[x]]
1028
1028
1029 if len(enabled) > 1:
1029 if len(enabled) > 1:
1030 raise error.InputError(
1030 raise error.InputError(
1031 _(b'%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
1031 _(b'%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
1032 )
1032 )
1033
1033
1034 if reset:
1034 if reset:
1035 hbisect.resetstate(repo)
1035 hbisect.resetstate(repo)
1036 return
1036 return
1037
1037
1038 state = hbisect.load_state(repo)
1038 state = hbisect.load_state(repo)
1039
1039
1040 if rev:
1040 if rev:
1041 nodes = [repo[i].node() for i in scmutil.revrange(repo, rev)]
1041 nodes = [repo[i].node() for i in scmutil.revrange(repo, rev)]
1042 else:
1042 else:
1043 nodes = [repo.lookup(b'.')]
1043 nodes = [repo.lookup(b'.')]
1044
1044
1045 # update state
1045 # update state
1046 if good or bad or skip:
1046 if good or bad or skip:
1047 if good:
1047 if good:
1048 state[b'good'] += nodes
1048 state[b'good'] += nodes
1049 elif bad:
1049 elif bad:
1050 state[b'bad'] += nodes
1050 state[b'bad'] += nodes
1051 elif skip:
1051 elif skip:
1052 state[b'skip'] += nodes
1052 state[b'skip'] += nodes
1053 hbisect.save_state(repo, state)
1053 hbisect.save_state(repo, state)
1054 if not (state[b'good'] and state[b'bad']):
1054 if not (state[b'good'] and state[b'bad']):
1055 return
1055 return
1056
1056
1057 def mayupdate(repo, node, show_stats=True):
1057 def mayupdate(repo, node, show_stats=True):
1058 """common used update sequence"""
1058 """common used update sequence"""
1059 if noupdate:
1059 if noupdate:
1060 return
1060 return
1061 cmdutil.checkunfinished(repo)
1061 cmdutil.checkunfinished(repo)
1062 cmdutil.bailifchanged(repo)
1062 cmdutil.bailifchanged(repo)
1063 return hg.clean(repo, node, show_stats=show_stats)
1063 return hg.clean(repo, node, show_stats=show_stats)
1064
1064
1065 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
1065 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
1066
1066
1067 if command:
1067 if command:
1068 changesets = 1
1068 changesets = 1
1069 if noupdate:
1069 if noupdate:
1070 try:
1070 try:
1071 node = state[b'current'][0]
1071 node = state[b'current'][0]
1072 except LookupError:
1072 except LookupError:
1073 raise error.StateError(
1073 raise error.StateError(
1074 _(
1074 _(
1075 b'current bisect revision is unknown - '
1075 b'current bisect revision is unknown - '
1076 b'start a new bisect to fix'
1076 b'start a new bisect to fix'
1077 )
1077 )
1078 )
1078 )
1079 else:
1079 else:
1080 node, p2 = repo.dirstate.parents()
1080 node, p2 = repo.dirstate.parents()
1081 if p2 != nullid:
1081 if p2 != nullid:
1082 raise error.StateError(_(b'current bisect revision is a merge'))
1082 raise error.StateError(_(b'current bisect revision is a merge'))
1083 if rev:
1083 if rev:
1084 if not nodes:
1084 if not nodes:
1085 raise error.Abort(_(b'empty revision set'))
1085 raise error.Abort(_(b'empty revision set'))
1086 node = repo[nodes.last()].node()
1086 node = repo[nodes.last()].node()
1087 with hbisect.restore_state(repo, state, node):
1087 with hbisect.restore_state(repo, state, node):
1088 while changesets:
1088 while changesets:
1089 # update state
1089 # update state
1090 state[b'current'] = [node]
1090 state[b'current'] = [node]
1091 hbisect.save_state(repo, state)
1091 hbisect.save_state(repo, state)
1092 status = ui.system(
1092 status = ui.system(
1093 command,
1093 command,
1094 environ={b'HG_NODE': hex(node)},
1094 environ={b'HG_NODE': hex(node)},
1095 blockedtag=b'bisect_check',
1095 blockedtag=b'bisect_check',
1096 )
1096 )
1097 if status == 125:
1097 if status == 125:
1098 transition = b"skip"
1098 transition = b"skip"
1099 elif status == 0:
1099 elif status == 0:
1100 transition = b"good"
1100 transition = b"good"
1101 # status < 0 means process was killed
1101 # status < 0 means process was killed
1102 elif status == 127:
1102 elif status == 127:
1103 raise error.Abort(_(b"failed to execute %s") % command)
1103 raise error.Abort(_(b"failed to execute %s") % command)
1104 elif status < 0:
1104 elif status < 0:
1105 raise error.Abort(_(b"%s killed") % command)
1105 raise error.Abort(_(b"%s killed") % command)
1106 else:
1106 else:
1107 transition = b"bad"
1107 transition = b"bad"
1108 state[transition].append(node)
1108 state[transition].append(node)
1109 ctx = repo[node]
1109 ctx = repo[node]
1110 ui.status(
1110 ui.status(
1111 _(b'changeset %d:%s: %s\n') % (ctx.rev(), ctx, transition)
1111 _(b'changeset %d:%s: %s\n') % (ctx.rev(), ctx, transition)
1112 )
1112 )
1113 hbisect.checkstate(state)
1113 hbisect.checkstate(state)
1114 # bisect
1114 # bisect
1115 nodes, changesets, bgood = hbisect.bisect(repo, state)
1115 nodes, changesets, bgood = hbisect.bisect(repo, state)
1116 # update to next check
1116 # update to next check
1117 node = nodes[0]
1117 node = nodes[0]
1118 mayupdate(repo, node, show_stats=False)
1118 mayupdate(repo, node, show_stats=False)
1119 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
1119 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
1120 return
1120 return
1121
1121
1122 hbisect.checkstate(state)
1122 hbisect.checkstate(state)
1123
1123
1124 # actually bisect
1124 # actually bisect
1125 nodes, changesets, good = hbisect.bisect(repo, state)
1125 nodes, changesets, good = hbisect.bisect(repo, state)
1126 if extend:
1126 if extend:
1127 if not changesets:
1127 if not changesets:
1128 extendnode = hbisect.extendrange(repo, state, nodes, good)
1128 extendnode = hbisect.extendrange(repo, state, nodes, good)
1129 if extendnode is not None:
1129 if extendnode is not None:
1130 ui.write(
1130 ui.write(
1131 _(b"Extending search to changeset %d:%s\n")
1131 _(b"Extending search to changeset %d:%s\n")
1132 % (extendnode.rev(), extendnode)
1132 % (extendnode.rev(), extendnode)
1133 )
1133 )
1134 state[b'current'] = [extendnode.node()]
1134 state[b'current'] = [extendnode.node()]
1135 hbisect.save_state(repo, state)
1135 hbisect.save_state(repo, state)
1136 return mayupdate(repo, extendnode.node())
1136 return mayupdate(repo, extendnode.node())
1137 raise error.StateError(_(b"nothing to extend"))
1137 raise error.StateError(_(b"nothing to extend"))
1138
1138
1139 if changesets == 0:
1139 if changesets == 0:
1140 hbisect.printresult(ui, repo, state, displayer, nodes, good)
1140 hbisect.printresult(ui, repo, state, displayer, nodes, good)
1141 else:
1141 else:
1142 assert len(nodes) == 1 # only a single node can be tested next
1142 assert len(nodes) == 1 # only a single node can be tested next
1143 node = nodes[0]
1143 node = nodes[0]
1144 # compute the approximate number of remaining tests
1144 # compute the approximate number of remaining tests
1145 tests, size = 0, 2
1145 tests, size = 0, 2
1146 while size <= changesets:
1146 while size <= changesets:
1147 tests, size = tests + 1, size * 2
1147 tests, size = tests + 1, size * 2
1148 rev = repo.changelog.rev(node)
1148 rev = repo.changelog.rev(node)
1149 ui.write(
1149 ui.write(
1150 _(
1150 _(
1151 b"Testing changeset %d:%s "
1151 b"Testing changeset %d:%s "
1152 b"(%d changesets remaining, ~%d tests)\n"
1152 b"(%d changesets remaining, ~%d tests)\n"
1153 )
1153 )
1154 % (rev, short(node), changesets, tests)
1154 % (rev, short(node), changesets, tests)
1155 )
1155 )
1156 state[b'current'] = [node]
1156 state[b'current'] = [node]
1157 hbisect.save_state(repo, state)
1157 hbisect.save_state(repo, state)
1158 return mayupdate(repo, node)
1158 return mayupdate(repo, node)
1159
1159
1160
1160
1161 @command(
1161 @command(
1162 b'bookmarks|bookmark',
1162 b'bookmarks|bookmark',
1163 [
1163 [
1164 (b'f', b'force', False, _(b'force')),
1164 (b'f', b'force', False, _(b'force')),
1165 (b'r', b'rev', b'', _(b'revision for bookmark action'), _(b'REV')),
1165 (b'r', b'rev', b'', _(b'revision for bookmark action'), _(b'REV')),
1166 (b'd', b'delete', False, _(b'delete a given bookmark')),
1166 (b'd', b'delete', False, _(b'delete a given bookmark')),
1167 (b'm', b'rename', b'', _(b'rename a given bookmark'), _(b'OLD')),
1167 (b'm', b'rename', b'', _(b'rename a given bookmark'), _(b'OLD')),
1168 (b'i', b'inactive', False, _(b'mark a bookmark inactive')),
1168 (b'i', b'inactive', False, _(b'mark a bookmark inactive')),
1169 (b'l', b'list', False, _(b'list existing bookmarks')),
1169 (b'l', b'list', False, _(b'list existing bookmarks')),
1170 ]
1170 ]
1171 + formatteropts,
1171 + formatteropts,
1172 _(b'hg bookmarks [OPTIONS]... [NAME]...'),
1172 _(b'hg bookmarks [OPTIONS]... [NAME]...'),
1173 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1173 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1174 )
1174 )
1175 def bookmark(ui, repo, *names, **opts):
1175 def bookmark(ui, repo, *names, **opts):
1176 """create a new bookmark or list existing bookmarks
1176 """create a new bookmark or list existing bookmarks
1177
1177
1178 Bookmarks are labels on changesets to help track lines of development.
1178 Bookmarks are labels on changesets to help track lines of development.
1179 Bookmarks are unversioned and can be moved, renamed and deleted.
1179 Bookmarks are unversioned and can be moved, renamed and deleted.
1180 Deleting or moving a bookmark has no effect on the associated changesets.
1180 Deleting or moving a bookmark has no effect on the associated changesets.
1181
1181
1182 Creating or updating to a bookmark causes it to be marked as 'active'.
1182 Creating or updating to a bookmark causes it to be marked as 'active'.
1183 The active bookmark is indicated with a '*'.
1183 The active bookmark is indicated with a '*'.
1184 When a commit is made, the active bookmark will advance to the new commit.
1184 When a commit is made, the active bookmark will advance to the new commit.
1185 A plain :hg:`update` will also advance an active bookmark, if possible.
1185 A plain :hg:`update` will also advance an active bookmark, if possible.
1186 Updating away from a bookmark will cause it to be deactivated.
1186 Updating away from a bookmark will cause it to be deactivated.
1187
1187
1188 Bookmarks can be pushed and pulled between repositories (see
1188 Bookmarks can be pushed and pulled between repositories (see
1189 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
1189 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
1190 diverged, a new 'divergent bookmark' of the form 'name@path' will
1190 diverged, a new 'divergent bookmark' of the form 'name@path' will
1191 be created. Using :hg:`merge` will resolve the divergence.
1191 be created. Using :hg:`merge` will resolve the divergence.
1192
1192
1193 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
1193 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
1194 the active bookmark's name.
1194 the active bookmark's name.
1195
1195
1196 A bookmark named '@' has the special property that :hg:`clone` will
1196 A bookmark named '@' has the special property that :hg:`clone` will
1197 check it out by default if it exists.
1197 check it out by default if it exists.
1198
1198
1199 .. container:: verbose
1199 .. container:: verbose
1200
1200
1201 Template:
1201 Template:
1202
1202
1203 The following keywords are supported in addition to the common template
1203 The following keywords are supported in addition to the common template
1204 keywords and functions such as ``{bookmark}``. See also
1204 keywords and functions such as ``{bookmark}``. See also
1205 :hg:`help templates`.
1205 :hg:`help templates`.
1206
1206
1207 :active: Boolean. True if the bookmark is active.
1207 :active: Boolean. True if the bookmark is active.
1208
1208
1209 Examples:
1209 Examples:
1210
1210
1211 - create an active bookmark for a new line of development::
1211 - create an active bookmark for a new line of development::
1212
1212
1213 hg book new-feature
1213 hg book new-feature
1214
1214
1215 - create an inactive bookmark as a place marker::
1215 - create an inactive bookmark as a place marker::
1216
1216
1217 hg book -i reviewed
1217 hg book -i reviewed
1218
1218
1219 - create an inactive bookmark on another changeset::
1219 - create an inactive bookmark on another changeset::
1220
1220
1221 hg book -r .^ tested
1221 hg book -r .^ tested
1222
1222
1223 - rename bookmark turkey to dinner::
1223 - rename bookmark turkey to dinner::
1224
1224
1225 hg book -m turkey dinner
1225 hg book -m turkey dinner
1226
1226
1227 - move the '@' bookmark from another branch::
1227 - move the '@' bookmark from another branch::
1228
1228
1229 hg book -f @
1229 hg book -f @
1230
1230
1231 - print only the active bookmark name::
1231 - print only the active bookmark name::
1232
1232
1233 hg book -ql .
1233 hg book -ql .
1234 """
1234 """
1235 opts = pycompat.byteskwargs(opts)
1235 opts = pycompat.byteskwargs(opts)
1236 force = opts.get(b'force')
1236 force = opts.get(b'force')
1237 rev = opts.get(b'rev')
1237 rev = opts.get(b'rev')
1238 inactive = opts.get(b'inactive') # meaning add/rename to inactive bookmark
1238 inactive = opts.get(b'inactive') # meaning add/rename to inactive bookmark
1239
1239
1240 action = cmdutil.check_at_most_one_arg(opts, b'delete', b'rename', b'list')
1240 action = cmdutil.check_at_most_one_arg(opts, b'delete', b'rename', b'list')
1241 if action:
1241 if action:
1242 cmdutil.check_incompatible_arguments(opts, action, [b'rev'])
1242 cmdutil.check_incompatible_arguments(opts, action, [b'rev'])
1243 elif names or rev:
1243 elif names or rev:
1244 action = b'add'
1244 action = b'add'
1245 elif inactive:
1245 elif inactive:
1246 action = b'inactive' # meaning deactivate
1246 action = b'inactive' # meaning deactivate
1247 else:
1247 else:
1248 action = b'list'
1248 action = b'list'
1249
1249
1250 cmdutil.check_incompatible_arguments(
1250 cmdutil.check_incompatible_arguments(
1251 opts, b'inactive', [b'delete', b'list']
1251 opts, b'inactive', [b'delete', b'list']
1252 )
1252 )
1253 if not names and action in {b'add', b'delete'}:
1253 if not names and action in {b'add', b'delete'}:
1254 raise error.InputError(_(b"bookmark name required"))
1254 raise error.InputError(_(b"bookmark name required"))
1255
1255
1256 if action in {b'add', b'delete', b'rename', b'inactive'}:
1256 if action in {b'add', b'delete', b'rename', b'inactive'}:
1257 with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
1257 with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
1258 if action == b'delete':
1258 if action == b'delete':
1259 names = pycompat.maplist(repo._bookmarks.expandname, names)
1259 names = pycompat.maplist(repo._bookmarks.expandname, names)
1260 bookmarks.delete(repo, tr, names)
1260 bookmarks.delete(repo, tr, names)
1261 elif action == b'rename':
1261 elif action == b'rename':
1262 if not names:
1262 if not names:
1263 raise error.InputError(_(b"new bookmark name required"))
1263 raise error.InputError(_(b"new bookmark name required"))
1264 elif len(names) > 1:
1264 elif len(names) > 1:
1265 raise error.InputError(
1265 raise error.InputError(
1266 _(b"only one new bookmark name allowed")
1266 _(b"only one new bookmark name allowed")
1267 )
1267 )
1268 oldname = repo._bookmarks.expandname(opts[b'rename'])
1268 oldname = repo._bookmarks.expandname(opts[b'rename'])
1269 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1269 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1270 elif action == b'add':
1270 elif action == b'add':
1271 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1271 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1272 elif action == b'inactive':
1272 elif action == b'inactive':
1273 if len(repo._bookmarks) == 0:
1273 if len(repo._bookmarks) == 0:
1274 ui.status(_(b"no bookmarks set\n"))
1274 ui.status(_(b"no bookmarks set\n"))
1275 elif not repo._activebookmark:
1275 elif not repo._activebookmark:
1276 ui.status(_(b"no active bookmark\n"))
1276 ui.status(_(b"no active bookmark\n"))
1277 else:
1277 else:
1278 bookmarks.deactivate(repo)
1278 bookmarks.deactivate(repo)
1279 elif action == b'list':
1279 elif action == b'list':
1280 names = pycompat.maplist(repo._bookmarks.expandname, names)
1280 names = pycompat.maplist(repo._bookmarks.expandname, names)
1281 with ui.formatter(b'bookmarks', opts) as fm:
1281 with ui.formatter(b'bookmarks', opts) as fm:
1282 bookmarks.printbookmarks(ui, repo, fm, names)
1282 bookmarks.printbookmarks(ui, repo, fm, names)
1283 else:
1283 else:
1284 raise error.ProgrammingError(b'invalid action: %s' % action)
1284 raise error.ProgrammingError(b'invalid action: %s' % action)
1285
1285
1286
1286
1287 @command(
1287 @command(
1288 b'branch',
1288 b'branch',
1289 [
1289 [
1290 (
1290 (
1291 b'f',
1291 b'f',
1292 b'force',
1292 b'force',
1293 None,
1293 None,
1294 _(b'set branch name even if it shadows an existing branch'),
1294 _(b'set branch name even if it shadows an existing branch'),
1295 ),
1295 ),
1296 (b'C', b'clean', None, _(b'reset branch name to parent branch name')),
1296 (b'C', b'clean', None, _(b'reset branch name to parent branch name')),
1297 (
1297 (
1298 b'r',
1298 b'r',
1299 b'rev',
1299 b'rev',
1300 [],
1300 [],
1301 _(b'change branches of the given revs (EXPERIMENTAL)'),
1301 _(b'change branches of the given revs (EXPERIMENTAL)'),
1302 ),
1302 ),
1303 ],
1303 ],
1304 _(b'[-fC] [NAME]'),
1304 _(b'[-fC] [NAME]'),
1305 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1305 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1306 )
1306 )
1307 def branch(ui, repo, label=None, **opts):
1307 def branch(ui, repo, label=None, **opts):
1308 """set or show the current branch name
1308 """set or show the current branch name
1309
1309
1310 .. note::
1310 .. note::
1311
1311
1312 Branch names are permanent and global. Use :hg:`bookmark` to create a
1312 Branch names are permanent and global. Use :hg:`bookmark` to create a
1313 light-weight bookmark instead. See :hg:`help glossary` for more
1313 light-weight bookmark instead. See :hg:`help glossary` for more
1314 information about named branches and bookmarks.
1314 information about named branches and bookmarks.
1315
1315
1316 With no argument, show the current branch name. With one argument,
1316 With no argument, show the current branch name. With one argument,
1317 set the working directory branch name (the branch will not exist
1317 set the working directory branch name (the branch will not exist
1318 in the repository until the next commit). Standard practice
1318 in the repository until the next commit). Standard practice
1319 recommends that primary development take place on the 'default'
1319 recommends that primary development take place on the 'default'
1320 branch.
1320 branch.
1321
1321
1322 Unless -f/--force is specified, branch will not let you set a
1322 Unless -f/--force is specified, branch will not let you set a
1323 branch name that already exists.
1323 branch name that already exists.
1324
1324
1325 Use -C/--clean to reset the working directory branch to that of
1325 Use -C/--clean to reset the working directory branch to that of
1326 the parent of the working directory, negating a previous branch
1326 the parent of the working directory, negating a previous branch
1327 change.
1327 change.
1328
1328
1329 Use the command :hg:`update` to switch to an existing branch. Use
1329 Use the command :hg:`update` to switch to an existing branch. Use
1330 :hg:`commit --close-branch` to mark this branch head as closed.
1330 :hg:`commit --close-branch` to mark this branch head as closed.
1331 When all heads of a branch are closed, the branch will be
1331 When all heads of a branch are closed, the branch will be
1332 considered closed.
1332 considered closed.
1333
1333
1334 Returns 0 on success.
1334 Returns 0 on success.
1335 """
1335 """
1336 opts = pycompat.byteskwargs(opts)
1336 opts = pycompat.byteskwargs(opts)
1337 revs = opts.get(b'rev')
1337 revs = opts.get(b'rev')
1338 if label:
1338 if label:
1339 label = label.strip()
1339 label = label.strip()
1340
1340
1341 if not opts.get(b'clean') and not label:
1341 if not opts.get(b'clean') and not label:
1342 if revs:
1342 if revs:
1343 raise error.InputError(
1343 raise error.InputError(
1344 _(b"no branch name specified for the revisions")
1344 _(b"no branch name specified for the revisions")
1345 )
1345 )
1346 ui.write(b"%s\n" % repo.dirstate.branch())
1346 ui.write(b"%s\n" % repo.dirstate.branch())
1347 return
1347 return
1348
1348
1349 with repo.wlock():
1349 with repo.wlock():
1350 if opts.get(b'clean'):
1350 if opts.get(b'clean'):
1351 label = repo[b'.'].branch()
1351 label = repo[b'.'].branch()
1352 repo.dirstate.setbranch(label)
1352 repo.dirstate.setbranch(label)
1353 ui.status(_(b'reset working directory to branch %s\n') % label)
1353 ui.status(_(b'reset working directory to branch %s\n') % label)
1354 elif label:
1354 elif label:
1355
1355
1356 scmutil.checknewlabel(repo, label, b'branch')
1356 scmutil.checknewlabel(repo, label, b'branch')
1357 if revs:
1357 if revs:
1358 return cmdutil.changebranch(ui, repo, revs, label, opts)
1358 return cmdutil.changebranch(ui, repo, revs, label, opts)
1359
1359
1360 if not opts.get(b'force') and label in repo.branchmap():
1360 if not opts.get(b'force') and label in repo.branchmap():
1361 if label not in [p.branch() for p in repo[None].parents()]:
1361 if label not in [p.branch() for p in repo[None].parents()]:
1362 raise error.InputError(
1362 raise error.InputError(
1363 _(b'a branch of the same name already exists'),
1363 _(b'a branch of the same name already exists'),
1364 # i18n: "it" refers to an existing branch
1364 # i18n: "it" refers to an existing branch
1365 hint=_(b"use 'hg update' to switch to it"),
1365 hint=_(b"use 'hg update' to switch to it"),
1366 )
1366 )
1367
1367
1368 repo.dirstate.setbranch(label)
1368 repo.dirstate.setbranch(label)
1369 ui.status(_(b'marked working directory as branch %s\n') % label)
1369 ui.status(_(b'marked working directory as branch %s\n') % label)
1370
1370
1371 # find any open named branches aside from default
1371 # find any open named branches aside from default
1372 for n, h, t, c in repo.branchmap().iterbranches():
1372 for n, h, t, c in repo.branchmap().iterbranches():
1373 if n != b"default" and not c:
1373 if n != b"default" and not c:
1374 return 0
1374 return 0
1375 ui.status(
1375 ui.status(
1376 _(
1376 _(
1377 b'(branches are permanent and global, '
1377 b'(branches are permanent and global, '
1378 b'did you want a bookmark?)\n'
1378 b'did you want a bookmark?)\n'
1379 )
1379 )
1380 )
1380 )
1381
1381
1382
1382
1383 @command(
1383 @command(
1384 b'branches',
1384 b'branches',
1385 [
1385 [
1386 (
1386 (
1387 b'a',
1387 b'a',
1388 b'active',
1388 b'active',
1389 False,
1389 False,
1390 _(b'show only branches that have unmerged heads (DEPRECATED)'),
1390 _(b'show only branches that have unmerged heads (DEPRECATED)'),
1391 ),
1391 ),
1392 (b'c', b'closed', False, _(b'show normal and closed branches')),
1392 (b'c', b'closed', False, _(b'show normal and closed branches')),
1393 (b'r', b'rev', [], _(b'show branch name(s) of the given rev')),
1393 (b'r', b'rev', [], _(b'show branch name(s) of the given rev')),
1394 ]
1394 ]
1395 + formatteropts,
1395 + formatteropts,
1396 _(b'[-c]'),
1396 _(b'[-c]'),
1397 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1397 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1398 intents={INTENT_READONLY},
1398 intents={INTENT_READONLY},
1399 )
1399 )
1400 def branches(ui, repo, active=False, closed=False, **opts):
1400 def branches(ui, repo, active=False, closed=False, **opts):
1401 """list repository named branches
1401 """list repository named branches
1402
1402
1403 List the repository's named branches, indicating which ones are
1403 List the repository's named branches, indicating which ones are
1404 inactive. If -c/--closed is specified, also list branches which have
1404 inactive. If -c/--closed is specified, also list branches which have
1405 been marked closed (see :hg:`commit --close-branch`).
1405 been marked closed (see :hg:`commit --close-branch`).
1406
1406
1407 Use the command :hg:`update` to switch to an existing branch.
1407 Use the command :hg:`update` to switch to an existing branch.
1408
1408
1409 .. container:: verbose
1409 .. container:: verbose
1410
1410
1411 Template:
1411 Template:
1412
1412
1413 The following keywords are supported in addition to the common template
1413 The following keywords are supported in addition to the common template
1414 keywords and functions such as ``{branch}``. See also
1414 keywords and functions such as ``{branch}``. See also
1415 :hg:`help templates`.
1415 :hg:`help templates`.
1416
1416
1417 :active: Boolean. True if the branch is active.
1417 :active: Boolean. True if the branch is active.
1418 :closed: Boolean. True if the branch is closed.
1418 :closed: Boolean. True if the branch is closed.
1419 :current: Boolean. True if it is the current branch.
1419 :current: Boolean. True if it is the current branch.
1420
1420
1421 Returns 0.
1421 Returns 0.
1422 """
1422 """
1423
1423
1424 opts = pycompat.byteskwargs(opts)
1424 opts = pycompat.byteskwargs(opts)
1425 revs = opts.get(b'rev')
1425 revs = opts.get(b'rev')
1426 selectedbranches = None
1426 selectedbranches = None
1427 if revs:
1427 if revs:
1428 revs = scmutil.revrange(repo, revs)
1428 revs = scmutil.revrange(repo, revs)
1429 getbi = repo.revbranchcache().branchinfo
1429 getbi = repo.revbranchcache().branchinfo
1430 selectedbranches = {getbi(r)[0] for r in revs}
1430 selectedbranches = {getbi(r)[0] for r in revs}
1431
1431
1432 ui.pager(b'branches')
1432 ui.pager(b'branches')
1433 fm = ui.formatter(b'branches', opts)
1433 fm = ui.formatter(b'branches', opts)
1434 hexfunc = fm.hexfunc
1434 hexfunc = fm.hexfunc
1435
1435
1436 allheads = set(repo.heads())
1436 allheads = set(repo.heads())
1437 branches = []
1437 branches = []
1438 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1438 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1439 if selectedbranches is not None and tag not in selectedbranches:
1439 if selectedbranches is not None and tag not in selectedbranches:
1440 continue
1440 continue
1441 isactive = False
1441 isactive = False
1442 if not isclosed:
1442 if not isclosed:
1443 openheads = set(repo.branchmap().iteropen(heads))
1443 openheads = set(repo.branchmap().iteropen(heads))
1444 isactive = bool(openheads & allheads)
1444 isactive = bool(openheads & allheads)
1445 branches.append((tag, repo[tip], isactive, not isclosed))
1445 branches.append((tag, repo[tip], isactive, not isclosed))
1446 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]), reverse=True)
1446 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]), reverse=True)
1447
1447
1448 for tag, ctx, isactive, isopen in branches:
1448 for tag, ctx, isactive, isopen in branches:
1449 if active and not isactive:
1449 if active and not isactive:
1450 continue
1450 continue
1451 if isactive:
1451 if isactive:
1452 label = b'branches.active'
1452 label = b'branches.active'
1453 notice = b''
1453 notice = b''
1454 elif not isopen:
1454 elif not isopen:
1455 if not closed:
1455 if not closed:
1456 continue
1456 continue
1457 label = b'branches.closed'
1457 label = b'branches.closed'
1458 notice = _(b' (closed)')
1458 notice = _(b' (closed)')
1459 else:
1459 else:
1460 label = b'branches.inactive'
1460 label = b'branches.inactive'
1461 notice = _(b' (inactive)')
1461 notice = _(b' (inactive)')
1462 current = tag == repo.dirstate.branch()
1462 current = tag == repo.dirstate.branch()
1463 if current:
1463 if current:
1464 label = b'branches.current'
1464 label = b'branches.current'
1465
1465
1466 fm.startitem()
1466 fm.startitem()
1467 fm.write(b'branch', b'%s', tag, label=label)
1467 fm.write(b'branch', b'%s', tag, label=label)
1468 rev = ctx.rev()
1468 rev = ctx.rev()
1469 padsize = max(31 - len(b"%d" % rev) - encoding.colwidth(tag), 0)
1469 padsize = max(31 - len(b"%d" % rev) - encoding.colwidth(tag), 0)
1470 fmt = b' ' * padsize + b' %d:%s'
1470 fmt = b' ' * padsize + b' %d:%s'
1471 fm.condwrite(
1471 fm.condwrite(
1472 not ui.quiet,
1472 not ui.quiet,
1473 b'rev node',
1473 b'rev node',
1474 fmt,
1474 fmt,
1475 rev,
1475 rev,
1476 hexfunc(ctx.node()),
1476 hexfunc(ctx.node()),
1477 label=b'log.changeset changeset.%s' % ctx.phasestr(),
1477 label=b'log.changeset changeset.%s' % ctx.phasestr(),
1478 )
1478 )
1479 fm.context(ctx=ctx)
1479 fm.context(ctx=ctx)
1480 fm.data(active=isactive, closed=not isopen, current=current)
1480 fm.data(active=isactive, closed=not isopen, current=current)
1481 if not ui.quiet:
1481 if not ui.quiet:
1482 fm.plain(notice)
1482 fm.plain(notice)
1483 fm.plain(b'\n')
1483 fm.plain(b'\n')
1484 fm.end()
1484 fm.end()
1485
1485
1486
1486
1487 @command(
1487 @command(
1488 b'bundle',
1488 b'bundle',
1489 [
1489 [
1490 (
1490 (
1491 b'f',
1491 b'f',
1492 b'force',
1492 b'force',
1493 None,
1493 None,
1494 _(b'run even when the destination is unrelated'),
1494 _(b'run even when the destination is unrelated'),
1495 ),
1495 ),
1496 (
1496 (
1497 b'r',
1497 b'r',
1498 b'rev',
1498 b'rev',
1499 [],
1499 [],
1500 _(b'a changeset intended to be added to the destination'),
1500 _(b'a changeset intended to be added to the destination'),
1501 _(b'REV'),
1501 _(b'REV'),
1502 ),
1502 ),
1503 (
1503 (
1504 b'b',
1504 b'b',
1505 b'branch',
1505 b'branch',
1506 [],
1506 [],
1507 _(b'a specific branch you would like to bundle'),
1507 _(b'a specific branch you would like to bundle'),
1508 _(b'BRANCH'),
1508 _(b'BRANCH'),
1509 ),
1509 ),
1510 (
1510 (
1511 b'',
1511 b'',
1512 b'base',
1512 b'base',
1513 [],
1513 [],
1514 _(b'a base changeset assumed to be available at the destination'),
1514 _(b'a base changeset assumed to be available at the destination'),
1515 _(b'REV'),
1515 _(b'REV'),
1516 ),
1516 ),
1517 (b'a', b'all', None, _(b'bundle all changesets in the repository')),
1517 (b'a', b'all', None, _(b'bundle all changesets in the repository')),
1518 (
1518 (
1519 b't',
1519 b't',
1520 b'type',
1520 b'type',
1521 b'bzip2',
1521 b'bzip2',
1522 _(b'bundle compression type to use'),
1522 _(b'bundle compression type to use'),
1523 _(b'TYPE'),
1523 _(b'TYPE'),
1524 ),
1524 ),
1525 ]
1525 ]
1526 + remoteopts,
1526 + remoteopts,
1527 _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1527 _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1528 helpcategory=command.CATEGORY_IMPORT_EXPORT,
1528 helpcategory=command.CATEGORY_IMPORT_EXPORT,
1529 )
1529 )
1530 def bundle(ui, repo, fname, dest=None, **opts):
1530 def bundle(ui, repo, fname, dest=None, **opts):
1531 """create a bundle file
1531 """create a bundle file
1532
1532
1533 Generate a bundle file containing data to be transferred to another
1533 Generate a bundle file containing data to be transferred to another
1534 repository.
1534 repository.
1535
1535
1536 To create a bundle containing all changesets, use -a/--all
1536 To create a bundle containing all changesets, use -a/--all
1537 (or --base null). Otherwise, hg assumes the destination will have
1537 (or --base null). Otherwise, hg assumes the destination will have
1538 all the nodes you specify with --base parameters. Otherwise, hg
1538 all the nodes you specify with --base parameters. Otherwise, hg
1539 will assume the repository has all the nodes in destination, or
1539 will assume the repository has all the nodes in destination, or
1540 default-push/default if no destination is specified, where destination
1540 default-push/default if no destination is specified, where destination
1541 is the repository you provide through DEST option.
1541 is the repository you provide through DEST option.
1542
1542
1543 You can change bundle format with the -t/--type option. See
1543 You can change bundle format with the -t/--type option. See
1544 :hg:`help bundlespec` for documentation on this format. By default,
1544 :hg:`help bundlespec` for documentation on this format. By default,
1545 the most appropriate format is used and compression defaults to
1545 the most appropriate format is used and compression defaults to
1546 bzip2.
1546 bzip2.
1547
1547
1548 The bundle file can then be transferred using conventional means
1548 The bundle file can then be transferred using conventional means
1549 and applied to another repository with the unbundle or pull
1549 and applied to another repository with the unbundle or pull
1550 command. This is useful when direct push and pull are not
1550 command. This is useful when direct push and pull are not
1551 available or when exporting an entire repository is undesirable.
1551 available or when exporting an entire repository is undesirable.
1552
1552
1553 Applying bundles preserves all changeset contents including
1553 Applying bundles preserves all changeset contents including
1554 permissions, copy/rename information, and revision history.
1554 permissions, copy/rename information, and revision history.
1555
1555
1556 Returns 0 on success, 1 if no changes found.
1556 Returns 0 on success, 1 if no changes found.
1557 """
1557 """
1558 opts = pycompat.byteskwargs(opts)
1558 opts = pycompat.byteskwargs(opts)
1559 revs = None
1559 revs = None
1560 if b'rev' in opts:
1560 if b'rev' in opts:
1561 revstrings = opts[b'rev']
1561 revstrings = opts[b'rev']
1562 revs = scmutil.revrange(repo, revstrings)
1562 revs = scmutil.revrange(repo, revstrings)
1563 if revstrings and not revs:
1563 if revstrings and not revs:
1564 raise error.InputError(_(b'no commits to bundle'))
1564 raise error.InputError(_(b'no commits to bundle'))
1565
1565
1566 bundletype = opts.get(b'type', b'bzip2').lower()
1566 bundletype = opts.get(b'type', b'bzip2').lower()
1567 try:
1567 try:
1568 bundlespec = bundlecaches.parsebundlespec(
1568 bundlespec = bundlecaches.parsebundlespec(
1569 repo, bundletype, strict=False
1569 repo, bundletype, strict=False
1570 )
1570 )
1571 except error.UnsupportedBundleSpecification as e:
1571 except error.UnsupportedBundleSpecification as e:
1572 raise error.InputError(
1572 raise error.InputError(
1573 pycompat.bytestr(e),
1573 pycompat.bytestr(e),
1574 hint=_(b"see 'hg help bundlespec' for supported values for --type"),
1574 hint=_(b"see 'hg help bundlespec' for supported values for --type"),
1575 )
1575 )
1576 cgversion = bundlespec.contentopts[b"cg.version"]
1576 cgversion = bundlespec.contentopts[b"cg.version"]
1577
1577
1578 # Packed bundles are a pseudo bundle format for now.
1578 # Packed bundles are a pseudo bundle format for now.
1579 if cgversion == b's1':
1579 if cgversion == b's1':
1580 raise error.InputError(
1580 raise error.InputError(
1581 _(b'packed bundles cannot be produced by "hg bundle"'),
1581 _(b'packed bundles cannot be produced by "hg bundle"'),
1582 hint=_(b"use 'hg debugcreatestreamclonebundle'"),
1582 hint=_(b"use 'hg debugcreatestreamclonebundle'"),
1583 )
1583 )
1584
1584
1585 if opts.get(b'all'):
1585 if opts.get(b'all'):
1586 if dest:
1586 if dest:
1587 raise error.InputError(
1587 raise error.InputError(
1588 _(b"--all is incompatible with specifying a destination")
1588 _(b"--all is incompatible with specifying a destination")
1589 )
1589 )
1590 if opts.get(b'base'):
1590 if opts.get(b'base'):
1591 ui.warn(_(b"ignoring --base because --all was specified\n"))
1591 ui.warn(_(b"ignoring --base because --all was specified\n"))
1592 base = [nullrev]
1592 base = [nullrev]
1593 else:
1593 else:
1594 base = scmutil.revrange(repo, opts.get(b'base'))
1594 base = scmutil.revrange(repo, opts.get(b'base'))
1595 if cgversion not in changegroup.supportedoutgoingversions(repo):
1595 if cgversion not in changegroup.supportedoutgoingversions(repo):
1596 raise error.Abort(
1596 raise error.Abort(
1597 _(b"repository does not support bundle version %s") % cgversion
1597 _(b"repository does not support bundle version %s") % cgversion
1598 )
1598 )
1599
1599
1600 if base:
1600 if base:
1601 if dest:
1601 if dest:
1602 raise error.InputError(
1602 raise error.InputError(
1603 _(b"--base is incompatible with specifying a destination")
1603 _(b"--base is incompatible with specifying a destination")
1604 )
1604 )
1605 common = [repo[rev].node() for rev in base]
1605 common = [repo[rev].node() for rev in base]
1606 heads = [repo[r].node() for r in revs] if revs else None
1606 heads = [repo[r].node() for r in revs] if revs else None
1607 outgoing = discovery.outgoing(repo, common, heads)
1607 outgoing = discovery.outgoing(repo, common, heads)
1608 else:
1608 else:
1609 dest = ui.expandpath(dest or b'default-push', dest or b'default')
1609 dest = ui.expandpath(dest or b'default-push', dest or b'default')
1610 dest, branches = hg.parseurl(dest, opts.get(b'branch'))
1610 dest, branches = hg.parseurl(dest, opts.get(b'branch'))
1611 other = hg.peer(repo, opts, dest)
1611 other = hg.peer(repo, opts, dest)
1612 revs = [repo[r].hex() for r in revs]
1612 revs = [repo[r].hex() for r in revs]
1613 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1613 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1614 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1614 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1615 outgoing = discovery.findcommonoutgoing(
1615 outgoing = discovery.findcommonoutgoing(
1616 repo,
1616 repo,
1617 other,
1617 other,
1618 onlyheads=heads,
1618 onlyheads=heads,
1619 force=opts.get(b'force'),
1619 force=opts.get(b'force'),
1620 portable=True,
1620 portable=True,
1621 )
1621 )
1622
1622
1623 if not outgoing.missing:
1623 if not outgoing.missing:
1624 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1624 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1625 return 1
1625 return 1
1626
1626
1627 if cgversion == b'01': # bundle1
1627 if cgversion == b'01': # bundle1
1628 bversion = b'HG10' + bundlespec.wirecompression
1628 bversion = b'HG10' + bundlespec.wirecompression
1629 bcompression = None
1629 bcompression = None
1630 elif cgversion in (b'02', b'03'):
1630 elif cgversion in (b'02', b'03'):
1631 bversion = b'HG20'
1631 bversion = b'HG20'
1632 bcompression = bundlespec.wirecompression
1632 bcompression = bundlespec.wirecompression
1633 else:
1633 else:
1634 raise error.ProgrammingError(
1634 raise error.ProgrammingError(
1635 b'bundle: unexpected changegroup version %s' % cgversion
1635 b'bundle: unexpected changegroup version %s' % cgversion
1636 )
1636 )
1637
1637
1638 # TODO compression options should be derived from bundlespec parsing.
1638 # TODO compression options should be derived from bundlespec parsing.
1639 # This is a temporary hack to allow adjusting bundle compression
1639 # This is a temporary hack to allow adjusting bundle compression
1640 # level without a) formalizing the bundlespec changes to declare it
1640 # level without a) formalizing the bundlespec changes to declare it
1641 # b) introducing a command flag.
1641 # b) introducing a command flag.
1642 compopts = {}
1642 compopts = {}
1643 complevel = ui.configint(
1643 complevel = ui.configint(
1644 b'experimental', b'bundlecomplevel.' + bundlespec.compression
1644 b'experimental', b'bundlecomplevel.' + bundlespec.compression
1645 )
1645 )
1646 if complevel is None:
1646 if complevel is None:
1647 complevel = ui.configint(b'experimental', b'bundlecomplevel')
1647 complevel = ui.configint(b'experimental', b'bundlecomplevel')
1648 if complevel is not None:
1648 if complevel is not None:
1649 compopts[b'level'] = complevel
1649 compopts[b'level'] = complevel
1650
1650
1651 # Allow overriding the bundling of obsmarker in phases through
1651 # Allow overriding the bundling of obsmarker in phases through
1652 # configuration while we don't have a bundle version that include them
1652 # configuration while we don't have a bundle version that include them
1653 if repo.ui.configbool(b'experimental', b'evolution.bundle-obsmarker'):
1653 if repo.ui.configbool(b'experimental', b'evolution.bundle-obsmarker'):
1654 bundlespec.contentopts[b'obsolescence'] = True
1654 bundlespec.contentopts[b'obsolescence'] = True
1655 if repo.ui.configbool(b'experimental', b'bundle-phases'):
1655 if repo.ui.configbool(b'experimental', b'bundle-phases'):
1656 bundlespec.contentopts[b'phases'] = True
1656 bundlespec.contentopts[b'phases'] = True
1657
1657
1658 bundle2.writenewbundle(
1658 bundle2.writenewbundle(
1659 ui,
1659 ui,
1660 repo,
1660 repo,
1661 b'bundle',
1661 b'bundle',
1662 fname,
1662 fname,
1663 bversion,
1663 bversion,
1664 outgoing,
1664 outgoing,
1665 bundlespec.contentopts,
1665 bundlespec.contentopts,
1666 compression=bcompression,
1666 compression=bcompression,
1667 compopts=compopts,
1667 compopts=compopts,
1668 )
1668 )
1669
1669
1670
1670
1671 @command(
1671 @command(
1672 b'cat',
1672 b'cat',
1673 [
1673 [
1674 (
1674 (
1675 b'o',
1675 b'o',
1676 b'output',
1676 b'output',
1677 b'',
1677 b'',
1678 _(b'print output to file with formatted name'),
1678 _(b'print output to file with formatted name'),
1679 _(b'FORMAT'),
1679 _(b'FORMAT'),
1680 ),
1680 ),
1681 (b'r', b'rev', b'', _(b'print the given revision'), _(b'REV')),
1681 (b'r', b'rev', b'', _(b'print the given revision'), _(b'REV')),
1682 (b'', b'decode', None, _(b'apply any matching decode filter')),
1682 (b'', b'decode', None, _(b'apply any matching decode filter')),
1683 ]
1683 ]
1684 + walkopts
1684 + walkopts
1685 + formatteropts,
1685 + formatteropts,
1686 _(b'[OPTION]... FILE...'),
1686 _(b'[OPTION]... FILE...'),
1687 helpcategory=command.CATEGORY_FILE_CONTENTS,
1687 helpcategory=command.CATEGORY_FILE_CONTENTS,
1688 inferrepo=True,
1688 inferrepo=True,
1689 intents={INTENT_READONLY},
1689 intents={INTENT_READONLY},
1690 )
1690 )
1691 def cat(ui, repo, file1, *pats, **opts):
1691 def cat(ui, repo, file1, *pats, **opts):
1692 """output the current or given revision of files
1692 """output the current or given revision of files
1693
1693
1694 Print the specified files as they were at the given revision. If
1694 Print the specified files as they were at the given revision. If
1695 no revision is given, the parent of the working directory is used.
1695 no revision is given, the parent of the working directory is used.
1696
1696
1697 Output may be to a file, in which case the name of the file is
1697 Output may be to a file, in which case the name of the file is
1698 given using a template string. See :hg:`help templates`. In addition
1698 given using a template string. See :hg:`help templates`. In addition
1699 to the common template keywords, the following formatting rules are
1699 to the common template keywords, the following formatting rules are
1700 supported:
1700 supported:
1701
1701
1702 :``%%``: literal "%" character
1702 :``%%``: literal "%" character
1703 :``%s``: basename of file being printed
1703 :``%s``: basename of file being printed
1704 :``%d``: dirname of file being printed, or '.' if in repository root
1704 :``%d``: dirname of file being printed, or '.' if in repository root
1705 :``%p``: root-relative path name of file being printed
1705 :``%p``: root-relative path name of file being printed
1706 :``%H``: changeset hash (40 hexadecimal digits)
1706 :``%H``: changeset hash (40 hexadecimal digits)
1707 :``%R``: changeset revision number
1707 :``%R``: changeset revision number
1708 :``%h``: short-form changeset hash (12 hexadecimal digits)
1708 :``%h``: short-form changeset hash (12 hexadecimal digits)
1709 :``%r``: zero-padded changeset revision number
1709 :``%r``: zero-padded changeset revision number
1710 :``%b``: basename of the exporting repository
1710 :``%b``: basename of the exporting repository
1711 :``\\``: literal "\\" character
1711 :``\\``: literal "\\" character
1712
1712
1713 .. container:: verbose
1713 .. container:: verbose
1714
1714
1715 Template:
1715 Template:
1716
1716
1717 The following keywords are supported in addition to the common template
1717 The following keywords are supported in addition to the common template
1718 keywords and functions. See also :hg:`help templates`.
1718 keywords and functions. See also :hg:`help templates`.
1719
1719
1720 :data: String. File content.
1720 :data: String. File content.
1721 :path: String. Repository-absolute path of the file.
1721 :path: String. Repository-absolute path of the file.
1722
1722
1723 Returns 0 on success.
1723 Returns 0 on success.
1724 """
1724 """
1725 opts = pycompat.byteskwargs(opts)
1725 opts = pycompat.byteskwargs(opts)
1726 rev = opts.get(b'rev')
1726 rev = opts.get(b'rev')
1727 if rev:
1727 if rev:
1728 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
1728 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
1729 ctx = scmutil.revsingle(repo, rev)
1729 ctx = scmutil.revsingle(repo, rev)
1730 m = scmutil.match(ctx, (file1,) + pats, opts)
1730 m = scmutil.match(ctx, (file1,) + pats, opts)
1731 fntemplate = opts.pop(b'output', b'')
1731 fntemplate = opts.pop(b'output', b'')
1732 if cmdutil.isstdiofilename(fntemplate):
1732 if cmdutil.isstdiofilename(fntemplate):
1733 fntemplate = b''
1733 fntemplate = b''
1734
1734
1735 if fntemplate:
1735 if fntemplate:
1736 fm = formatter.nullformatter(ui, b'cat', opts)
1736 fm = formatter.nullformatter(ui, b'cat', opts)
1737 else:
1737 else:
1738 ui.pager(b'cat')
1738 ui.pager(b'cat')
1739 fm = ui.formatter(b'cat', opts)
1739 fm = ui.formatter(b'cat', opts)
1740 with fm:
1740 with fm:
1741 return cmdutil.cat(
1741 return cmdutil.cat(
1742 ui, repo, ctx, m, fm, fntemplate, b'', **pycompat.strkwargs(opts)
1742 ui, repo, ctx, m, fm, fntemplate, b'', **pycompat.strkwargs(opts)
1743 )
1743 )
1744
1744
1745
1745
1746 @command(
1746 @command(
1747 b'clone',
1747 b'clone',
1748 [
1748 [
1749 (
1749 (
1750 b'U',
1750 b'U',
1751 b'noupdate',
1751 b'noupdate',
1752 None,
1752 None,
1753 _(
1753 _(
1754 b'the clone will include an empty working '
1754 b'the clone will include an empty working '
1755 b'directory (only a repository)'
1755 b'directory (only a repository)'
1756 ),
1756 ),
1757 ),
1757 ),
1758 (
1758 (
1759 b'u',
1759 b'u',
1760 b'updaterev',
1760 b'updaterev',
1761 b'',
1761 b'',
1762 _(b'revision, tag, or branch to check out'),
1762 _(b'revision, tag, or branch to check out'),
1763 _(b'REV'),
1763 _(b'REV'),
1764 ),
1764 ),
1765 (
1765 (
1766 b'r',
1766 b'r',
1767 b'rev',
1767 b'rev',
1768 [],
1768 [],
1769 _(
1769 _(
1770 b'do not clone everything, but include this changeset'
1770 b'do not clone everything, but include this changeset'
1771 b' and its ancestors'
1771 b' and its ancestors'
1772 ),
1772 ),
1773 _(b'REV'),
1773 _(b'REV'),
1774 ),
1774 ),
1775 (
1775 (
1776 b'b',
1776 b'b',
1777 b'branch',
1777 b'branch',
1778 [],
1778 [],
1779 _(
1779 _(
1780 b'do not clone everything, but include this branch\'s'
1780 b'do not clone everything, but include this branch\'s'
1781 b' changesets and their ancestors'
1781 b' changesets and their ancestors'
1782 ),
1782 ),
1783 _(b'BRANCH'),
1783 _(b'BRANCH'),
1784 ),
1784 ),
1785 (b'', b'pull', None, _(b'use pull protocol to copy metadata')),
1785 (b'', b'pull', None, _(b'use pull protocol to copy metadata')),
1786 (b'', b'uncompressed', None, _(b'an alias to --stream (DEPRECATED)')),
1786 (b'', b'uncompressed', None, _(b'an alias to --stream (DEPRECATED)')),
1787 (b'', b'stream', None, _(b'clone with minimal data processing')),
1787 (b'', b'stream', None, _(b'clone with minimal data processing')),
1788 ]
1788 ]
1789 + remoteopts,
1789 + remoteopts,
1790 _(b'[OPTION]... SOURCE [DEST]'),
1790 _(b'[OPTION]... SOURCE [DEST]'),
1791 helpcategory=command.CATEGORY_REPO_CREATION,
1791 helpcategory=command.CATEGORY_REPO_CREATION,
1792 helpbasic=True,
1792 helpbasic=True,
1793 norepo=True,
1793 norepo=True,
1794 )
1794 )
1795 def clone(ui, source, dest=None, **opts):
1795 def clone(ui, source, dest=None, **opts):
1796 """make a copy of an existing repository
1796 """make a copy of an existing repository
1797
1797
1798 Create a copy of an existing repository in a new directory.
1798 Create a copy of an existing repository in a new directory.
1799
1799
1800 If no destination directory name is specified, it defaults to the
1800 If no destination directory name is specified, it defaults to the
1801 basename of the source.
1801 basename of the source.
1802
1802
1803 The location of the source is added to the new repository's
1803 The location of the source is added to the new repository's
1804 ``.hg/hgrc`` file, as the default to be used for future pulls.
1804 ``.hg/hgrc`` file, as the default to be used for future pulls.
1805
1805
1806 Only local paths and ``ssh://`` URLs are supported as
1806 Only local paths and ``ssh://`` URLs are supported as
1807 destinations. For ``ssh://`` destinations, no working directory or
1807 destinations. For ``ssh://`` destinations, no working directory or
1808 ``.hg/hgrc`` will be created on the remote side.
1808 ``.hg/hgrc`` will be created on the remote side.
1809
1809
1810 If the source repository has a bookmark called '@' set, that
1810 If the source repository has a bookmark called '@' set, that
1811 revision will be checked out in the new repository by default.
1811 revision will be checked out in the new repository by default.
1812
1812
1813 To check out a particular version, use -u/--update, or
1813 To check out a particular version, use -u/--update, or
1814 -U/--noupdate to create a clone with no working directory.
1814 -U/--noupdate to create a clone with no working directory.
1815
1815
1816 To pull only a subset of changesets, specify one or more revisions
1816 To pull only a subset of changesets, specify one or more revisions
1817 identifiers with -r/--rev or branches with -b/--branch. The
1817 identifiers with -r/--rev or branches with -b/--branch. The
1818 resulting clone will contain only the specified changesets and
1818 resulting clone will contain only the specified changesets and
1819 their ancestors. These options (or 'clone src#rev dest') imply
1819 their ancestors. These options (or 'clone src#rev dest') imply
1820 --pull, even for local source repositories.
1820 --pull, even for local source repositories.
1821
1821
1822 In normal clone mode, the remote normalizes repository data into a common
1822 In normal clone mode, the remote normalizes repository data into a common
1823 exchange format and the receiving end translates this data into its local
1823 exchange format and the receiving end translates this data into its local
1824 storage format. --stream activates a different clone mode that essentially
1824 storage format. --stream activates a different clone mode that essentially
1825 copies repository files from the remote with minimal data processing. This
1825 copies repository files from the remote with minimal data processing. This
1826 significantly reduces the CPU cost of a clone both remotely and locally.
1826 significantly reduces the CPU cost of a clone both remotely and locally.
1827 However, it often increases the transferred data size by 30-40%. This can
1827 However, it often increases the transferred data size by 30-40%. This can
1828 result in substantially faster clones where I/O throughput is plentiful,
1828 result in substantially faster clones where I/O throughput is plentiful,
1829 especially for larger repositories. A side-effect of --stream clones is
1829 especially for larger repositories. A side-effect of --stream clones is
1830 that storage settings and requirements on the remote are applied locally:
1830 that storage settings and requirements on the remote are applied locally:
1831 a modern client may inherit legacy or inefficient storage used by the
1831 a modern client may inherit legacy or inefficient storage used by the
1832 remote or a legacy Mercurial client may not be able to clone from a
1832 remote or a legacy Mercurial client may not be able to clone from a
1833 modern Mercurial remote.
1833 modern Mercurial remote.
1834
1834
1835 .. note::
1835 .. note::
1836
1836
1837 Specifying a tag will include the tagged changeset but not the
1837 Specifying a tag will include the tagged changeset but not the
1838 changeset containing the tag.
1838 changeset containing the tag.
1839
1839
1840 .. container:: verbose
1840 .. container:: verbose
1841
1841
1842 For efficiency, hardlinks are used for cloning whenever the
1842 For efficiency, hardlinks are used for cloning whenever the
1843 source and destination are on the same filesystem (note this
1843 source and destination are on the same filesystem (note this
1844 applies only to the repository data, not to the working
1844 applies only to the repository data, not to the working
1845 directory). Some filesystems, such as AFS, implement hardlinking
1845 directory). Some filesystems, such as AFS, implement hardlinking
1846 incorrectly, but do not report errors. In these cases, use the
1846 incorrectly, but do not report errors. In these cases, use the
1847 --pull option to avoid hardlinking.
1847 --pull option to avoid hardlinking.
1848
1848
1849 Mercurial will update the working directory to the first applicable
1849 Mercurial will update the working directory to the first applicable
1850 revision from this list:
1850 revision from this list:
1851
1851
1852 a) null if -U or the source repository has no changesets
1852 a) null if -U or the source repository has no changesets
1853 b) if -u . and the source repository is local, the first parent of
1853 b) if -u . and the source repository is local, the first parent of
1854 the source repository's working directory
1854 the source repository's working directory
1855 c) the changeset specified with -u (if a branch name, this means the
1855 c) the changeset specified with -u (if a branch name, this means the
1856 latest head of that branch)
1856 latest head of that branch)
1857 d) the changeset specified with -r
1857 d) the changeset specified with -r
1858 e) the tipmost head specified with -b
1858 e) the tipmost head specified with -b
1859 f) the tipmost head specified with the url#branch source syntax
1859 f) the tipmost head specified with the url#branch source syntax
1860 g) the revision marked with the '@' bookmark, if present
1860 g) the revision marked with the '@' bookmark, if present
1861 h) the tipmost head of the default branch
1861 h) the tipmost head of the default branch
1862 i) tip
1862 i) tip
1863
1863
1864 When cloning from servers that support it, Mercurial may fetch
1864 When cloning from servers that support it, Mercurial may fetch
1865 pre-generated data from a server-advertised URL or inline from the
1865 pre-generated data from a server-advertised URL or inline from the
1866 same stream. When this is done, hooks operating on incoming changesets
1866 same stream. When this is done, hooks operating on incoming changesets
1867 and changegroups may fire more than once, once for each pre-generated
1867 and changegroups may fire more than once, once for each pre-generated
1868 bundle and as well as for any additional remaining data. In addition,
1868 bundle and as well as for any additional remaining data. In addition,
1869 if an error occurs, the repository may be rolled back to a partial
1869 if an error occurs, the repository may be rolled back to a partial
1870 clone. This behavior may change in future releases.
1870 clone. This behavior may change in future releases.
1871 See :hg:`help -e clonebundles` for more.
1871 See :hg:`help -e clonebundles` for more.
1872
1872
1873 Examples:
1873 Examples:
1874
1874
1875 - clone a remote repository to a new directory named hg/::
1875 - clone a remote repository to a new directory named hg/::
1876
1876
1877 hg clone https://www.mercurial-scm.org/repo/hg/
1877 hg clone https://www.mercurial-scm.org/repo/hg/
1878
1878
1879 - create a lightweight local clone::
1879 - create a lightweight local clone::
1880
1880
1881 hg clone project/ project-feature/
1881 hg clone project/ project-feature/
1882
1882
1883 - clone from an absolute path on an ssh server (note double-slash)::
1883 - clone from an absolute path on an ssh server (note double-slash)::
1884
1884
1885 hg clone ssh://user@server//home/projects/alpha/
1885 hg clone ssh://user@server//home/projects/alpha/
1886
1886
1887 - do a streaming clone while checking out a specified version::
1887 - do a streaming clone while checking out a specified version::
1888
1888
1889 hg clone --stream http://server/repo -u 1.5
1889 hg clone --stream http://server/repo -u 1.5
1890
1890
1891 - create a repository without changesets after a particular revision::
1891 - create a repository without changesets after a particular revision::
1892
1892
1893 hg clone -r 04e544 experimental/ good/
1893 hg clone -r 04e544 experimental/ good/
1894
1894
1895 - clone (and track) a particular named branch::
1895 - clone (and track) a particular named branch::
1896
1896
1897 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1897 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1898
1898
1899 See :hg:`help urls` for details on specifying URLs.
1899 See :hg:`help urls` for details on specifying URLs.
1900
1900
1901 Returns 0 on success.
1901 Returns 0 on success.
1902 """
1902 """
1903 opts = pycompat.byteskwargs(opts)
1903 opts = pycompat.byteskwargs(opts)
1904 cmdutil.check_at_most_one_arg(opts, b'noupdate', b'updaterev')
1904 cmdutil.check_at_most_one_arg(opts, b'noupdate', b'updaterev')
1905
1905
1906 # --include/--exclude can come from narrow or sparse.
1906 # --include/--exclude can come from narrow or sparse.
1907 includepats, excludepats = None, None
1907 includepats, excludepats = None, None
1908
1908
1909 # hg.clone() differentiates between None and an empty set. So make sure
1909 # hg.clone() differentiates between None and an empty set. So make sure
1910 # patterns are sets if narrow is requested without patterns.
1910 # patterns are sets if narrow is requested without patterns.
1911 if opts.get(b'narrow'):
1911 if opts.get(b'narrow'):
1912 includepats = set()
1912 includepats = set()
1913 excludepats = set()
1913 excludepats = set()
1914
1914
1915 if opts.get(b'include'):
1915 if opts.get(b'include'):
1916 includepats = narrowspec.parsepatterns(opts.get(b'include'))
1916 includepats = narrowspec.parsepatterns(opts.get(b'include'))
1917 if opts.get(b'exclude'):
1917 if opts.get(b'exclude'):
1918 excludepats = narrowspec.parsepatterns(opts.get(b'exclude'))
1918 excludepats = narrowspec.parsepatterns(opts.get(b'exclude'))
1919
1919
1920 r = hg.clone(
1920 r = hg.clone(
1921 ui,
1921 ui,
1922 opts,
1922 opts,
1923 source,
1923 source,
1924 dest,
1924 dest,
1925 pull=opts.get(b'pull'),
1925 pull=opts.get(b'pull'),
1926 stream=opts.get(b'stream') or opts.get(b'uncompressed'),
1926 stream=opts.get(b'stream') or opts.get(b'uncompressed'),
1927 revs=opts.get(b'rev'),
1927 revs=opts.get(b'rev'),
1928 update=opts.get(b'updaterev') or not opts.get(b'noupdate'),
1928 update=opts.get(b'updaterev') or not opts.get(b'noupdate'),
1929 branch=opts.get(b'branch'),
1929 branch=opts.get(b'branch'),
1930 shareopts=opts.get(b'shareopts'),
1930 shareopts=opts.get(b'shareopts'),
1931 storeincludepats=includepats,
1931 storeincludepats=includepats,
1932 storeexcludepats=excludepats,
1932 storeexcludepats=excludepats,
1933 depth=opts.get(b'depth') or None,
1933 depth=opts.get(b'depth') or None,
1934 )
1934 )
1935
1935
1936 return r is None
1936 return r is None
1937
1937
1938
1938
1939 @command(
1939 @command(
1940 b'commit|ci',
1940 b'commit|ci',
1941 [
1941 [
1942 (
1942 (
1943 b'A',
1943 b'A',
1944 b'addremove',
1944 b'addremove',
1945 None,
1945 None,
1946 _(b'mark new/missing files as added/removed before committing'),
1946 _(b'mark new/missing files as added/removed before committing'),
1947 ),
1947 ),
1948 (b'', b'close-branch', None, _(b'mark a branch head as closed')),
1948 (b'', b'close-branch', None, _(b'mark a branch head as closed')),
1949 (b'', b'amend', None, _(b'amend the parent of the working directory')),
1949 (b'', b'amend', None, _(b'amend the parent of the working directory')),
1950 (b's', b'secret', None, _(b'use the secret phase for committing')),
1950 (b's', b'secret', None, _(b'use the secret phase for committing')),
1951 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
1951 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
1952 (
1952 (
1953 b'',
1953 b'',
1954 b'force-close-branch',
1954 b'force-close-branch',
1955 None,
1955 None,
1956 _(b'forcibly close branch from a non-head changeset (ADVANCED)'),
1956 _(b'forcibly close branch from a non-head changeset (ADVANCED)'),
1957 ),
1957 ),
1958 (b'i', b'interactive', None, _(b'use interactive mode')),
1958 (b'i', b'interactive', None, _(b'use interactive mode')),
1959 ]
1959 ]
1960 + walkopts
1960 + walkopts
1961 + commitopts
1961 + commitopts
1962 + commitopts2
1962 + commitopts2
1963 + subrepoopts,
1963 + subrepoopts,
1964 _(b'[OPTION]... [FILE]...'),
1964 _(b'[OPTION]... [FILE]...'),
1965 helpcategory=command.CATEGORY_COMMITTING,
1965 helpcategory=command.CATEGORY_COMMITTING,
1966 helpbasic=True,
1966 helpbasic=True,
1967 inferrepo=True,
1967 inferrepo=True,
1968 )
1968 )
1969 def commit(ui, repo, *pats, **opts):
1969 def commit(ui, repo, *pats, **opts):
1970 """commit the specified files or all outstanding changes
1970 """commit the specified files or all outstanding changes
1971
1971
1972 Commit changes to the given files into the repository. Unlike a
1972 Commit changes to the given files into the repository. Unlike a
1973 centralized SCM, this operation is a local operation. See
1973 centralized SCM, this operation is a local operation. See
1974 :hg:`push` for a way to actively distribute your changes.
1974 :hg:`push` for a way to actively distribute your changes.
1975
1975
1976 If a list of files is omitted, all changes reported by :hg:`status`
1976 If a list of files is omitted, all changes reported by :hg:`status`
1977 will be committed.
1977 will be committed.
1978
1978
1979 If you are committing the result of a merge, do not provide any
1979 If you are committing the result of a merge, do not provide any
1980 filenames or -I/-X filters.
1980 filenames or -I/-X filters.
1981
1981
1982 If no commit message is specified, Mercurial starts your
1982 If no commit message is specified, Mercurial starts your
1983 configured editor where you can enter a message. In case your
1983 configured editor where you can enter a message. In case your
1984 commit fails, you will find a backup of your message in
1984 commit fails, you will find a backup of your message in
1985 ``.hg/last-message.txt``.
1985 ``.hg/last-message.txt``.
1986
1986
1987 The --close-branch flag can be used to mark the current branch
1987 The --close-branch flag can be used to mark the current branch
1988 head closed. When all heads of a branch are closed, the branch
1988 head closed. When all heads of a branch are closed, the branch
1989 will be considered closed and no longer listed.
1989 will be considered closed and no longer listed.
1990
1990
1991 The --amend flag can be used to amend the parent of the
1991 The --amend flag can be used to amend the parent of the
1992 working directory with a new commit that contains the changes
1992 working directory with a new commit that contains the changes
1993 in the parent in addition to those currently reported by :hg:`status`,
1993 in the parent in addition to those currently reported by :hg:`status`,
1994 if there are any. The old commit is stored in a backup bundle in
1994 if there are any. The old commit is stored in a backup bundle in
1995 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1995 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1996 on how to restore it).
1996 on how to restore it).
1997
1997
1998 Message, user and date are taken from the amended commit unless
1998 Message, user and date are taken from the amended commit unless
1999 specified. When a message isn't specified on the command line,
1999 specified. When a message isn't specified on the command line,
2000 the editor will open with the message of the amended commit.
2000 the editor will open with the message of the amended commit.
2001
2001
2002 It is not possible to amend public changesets (see :hg:`help phases`)
2002 It is not possible to amend public changesets (see :hg:`help phases`)
2003 or changesets that have children.
2003 or changesets that have children.
2004
2004
2005 See :hg:`help dates` for a list of formats valid for -d/--date.
2005 See :hg:`help dates` for a list of formats valid for -d/--date.
2006
2006
2007 Returns 0 on success, 1 if nothing changed.
2007 Returns 0 on success, 1 if nothing changed.
2008
2008
2009 .. container:: verbose
2009 .. container:: verbose
2010
2010
2011 Examples:
2011 Examples:
2012
2012
2013 - commit all files ending in .py::
2013 - commit all files ending in .py::
2014
2014
2015 hg commit --include "set:**.py"
2015 hg commit --include "set:**.py"
2016
2016
2017 - commit all non-binary files::
2017 - commit all non-binary files::
2018
2018
2019 hg commit --exclude "set:binary()"
2019 hg commit --exclude "set:binary()"
2020
2020
2021 - amend the current commit and set the date to now::
2021 - amend the current commit and set the date to now::
2022
2022
2023 hg commit --amend --date now
2023 hg commit --amend --date now
2024 """
2024 """
2025 with repo.wlock(), repo.lock():
2025 with repo.wlock(), repo.lock():
2026 return _docommit(ui, repo, *pats, **opts)
2026 return _docommit(ui, repo, *pats, **opts)
2027
2027
2028
2028
2029 def _docommit(ui, repo, *pats, **opts):
2029 def _docommit(ui, repo, *pats, **opts):
2030 if opts.get('interactive'):
2030 if opts.get('interactive'):
2031 opts.pop('interactive')
2031 opts.pop('interactive')
2032 ret = cmdutil.dorecord(
2032 ret = cmdutil.dorecord(
2033 ui, repo, commit, None, False, cmdutil.recordfilter, *pats, **opts
2033 ui, repo, commit, None, False, cmdutil.recordfilter, *pats, **opts
2034 )
2034 )
2035 # ret can be 0 (no changes to record) or the value returned by
2035 # ret can be 0 (no changes to record) or the value returned by
2036 # commit(), 1 if nothing changed or None on success.
2036 # commit(), 1 if nothing changed or None on success.
2037 return 1 if ret == 0 else ret
2037 return 1 if ret == 0 else ret
2038
2038
2039 opts = pycompat.byteskwargs(opts)
2039 opts = pycompat.byteskwargs(opts)
2040 if opts.get(b'subrepos'):
2040 if opts.get(b'subrepos'):
2041 cmdutil.check_incompatible_arguments(opts, b'subrepos', [b'amend'])
2041 cmdutil.check_incompatible_arguments(opts, b'subrepos', [b'amend'])
2042 # Let --subrepos on the command line override config setting.
2042 # Let --subrepos on the command line override config setting.
2043 ui.setconfig(b'ui', b'commitsubrepos', True, b'commit')
2043 ui.setconfig(b'ui', b'commitsubrepos', True, b'commit')
2044
2044
2045 cmdutil.checkunfinished(repo, commit=True)
2045 cmdutil.checkunfinished(repo, commit=True)
2046
2046
2047 branch = repo[None].branch()
2047 branch = repo[None].branch()
2048 bheads = repo.branchheads(branch)
2048 bheads = repo.branchheads(branch)
2049 tip = repo.changelog.tip()
2049 tip = repo.changelog.tip()
2050
2050
2051 extra = {}
2051 extra = {}
2052 if opts.get(b'close_branch') or opts.get(b'force_close_branch'):
2052 if opts.get(b'close_branch') or opts.get(b'force_close_branch'):
2053 extra[b'close'] = b'1'
2053 extra[b'close'] = b'1'
2054
2054
2055 if repo[b'.'].closesbranch():
2055 if repo[b'.'].closesbranch():
2056 raise error.InputError(
2056 raise error.InputError(
2057 _(b'current revision is already a branch closing head')
2057 _(b'current revision is already a branch closing head')
2058 )
2058 )
2059 elif not bheads:
2059 elif not bheads:
2060 raise error.InputError(
2060 raise error.InputError(
2061 _(b'branch "%s" has no heads to close') % branch
2061 _(b'branch "%s" has no heads to close') % branch
2062 )
2062 )
2063 elif (
2063 elif (
2064 branch == repo[b'.'].branch()
2064 branch == repo[b'.'].branch()
2065 and repo[b'.'].node() not in bheads
2065 and repo[b'.'].node() not in bheads
2066 and not opts.get(b'force_close_branch')
2066 and not opts.get(b'force_close_branch')
2067 ):
2067 ):
2068 hint = _(
2068 hint = _(
2069 b'use --force-close-branch to close branch from a non-head'
2069 b'use --force-close-branch to close branch from a non-head'
2070 b' changeset'
2070 b' changeset'
2071 )
2071 )
2072 raise error.InputError(_(b'can only close branch heads'), hint=hint)
2072 raise error.InputError(_(b'can only close branch heads'), hint=hint)
2073 elif opts.get(b'amend'):
2073 elif opts.get(b'amend'):
2074 if (
2074 if (
2075 repo[b'.'].p1().branch() != branch
2075 repo[b'.'].p1().branch() != branch
2076 and repo[b'.'].p2().branch() != branch
2076 and repo[b'.'].p2().branch() != branch
2077 ):
2077 ):
2078 raise error.InputError(_(b'can only close branch heads'))
2078 raise error.InputError(_(b'can only close branch heads'))
2079
2079
2080 if opts.get(b'amend'):
2080 if opts.get(b'amend'):
2081 if ui.configbool(b'ui', b'commitsubrepos'):
2081 if ui.configbool(b'ui', b'commitsubrepos'):
2082 raise error.InputError(
2082 raise error.InputError(
2083 _(b'cannot amend with ui.commitsubrepos enabled')
2083 _(b'cannot amend with ui.commitsubrepos enabled')
2084 )
2084 )
2085
2085
2086 old = repo[b'.']
2086 old = repo[b'.']
2087 rewriteutil.precheck(repo, [old.rev()], b'amend')
2087 rewriteutil.precheck(repo, [old.rev()], b'amend')
2088
2088
2089 # Currently histedit gets confused if an amend happens while histedit
2089 # Currently histedit gets confused if an amend happens while histedit
2090 # is in progress. Since we have a checkunfinished command, we are
2090 # is in progress. Since we have a checkunfinished command, we are
2091 # temporarily honoring it.
2091 # temporarily honoring it.
2092 #
2092 #
2093 # Note: eventually this guard will be removed. Please do not expect
2093 # Note: eventually this guard will be removed. Please do not expect
2094 # this behavior to remain.
2094 # this behavior to remain.
2095 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
2095 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
2096 cmdutil.checkunfinished(repo)
2096 cmdutil.checkunfinished(repo)
2097
2097
2098 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
2098 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
2099 if node == old.node():
2099 if node == old.node():
2100 ui.status(_(b"nothing changed\n"))
2100 ui.status(_(b"nothing changed\n"))
2101 return 1
2101 return 1
2102 else:
2102 else:
2103
2103
2104 def commitfunc(ui, repo, message, match, opts):
2104 def commitfunc(ui, repo, message, match, opts):
2105 overrides = {}
2105 overrides = {}
2106 if opts.get(b'secret'):
2106 if opts.get(b'secret'):
2107 overrides[(b'phases', b'new-commit')] = b'secret'
2107 overrides[(b'phases', b'new-commit')] = b'secret'
2108
2108
2109 baseui = repo.baseui
2109 baseui = repo.baseui
2110 with baseui.configoverride(overrides, b'commit'):
2110 with baseui.configoverride(overrides, b'commit'):
2111 with ui.configoverride(overrides, b'commit'):
2111 with ui.configoverride(overrides, b'commit'):
2112 editform = cmdutil.mergeeditform(
2112 editform = cmdutil.mergeeditform(
2113 repo[None], b'commit.normal'
2113 repo[None], b'commit.normal'
2114 )
2114 )
2115 editor = cmdutil.getcommiteditor(
2115 editor = cmdutil.getcommiteditor(
2116 editform=editform, **pycompat.strkwargs(opts)
2116 editform=editform, **pycompat.strkwargs(opts)
2117 )
2117 )
2118 return repo.commit(
2118 return repo.commit(
2119 message,
2119 message,
2120 opts.get(b'user'),
2120 opts.get(b'user'),
2121 opts.get(b'date'),
2121 opts.get(b'date'),
2122 match,
2122 match,
2123 editor=editor,
2123 editor=editor,
2124 extra=extra,
2124 extra=extra,
2125 )
2125 )
2126
2126
2127 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
2127 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
2128
2128
2129 if not node:
2129 if not node:
2130 stat = cmdutil.postcommitstatus(repo, pats, opts)
2130 stat = cmdutil.postcommitstatus(repo, pats, opts)
2131 if stat.deleted:
2131 if stat.deleted:
2132 ui.status(
2132 ui.status(
2133 _(
2133 _(
2134 b"nothing changed (%d missing files, see "
2134 b"nothing changed (%d missing files, see "
2135 b"'hg status')\n"
2135 b"'hg status')\n"
2136 )
2136 )
2137 % len(stat.deleted)
2137 % len(stat.deleted)
2138 )
2138 )
2139 else:
2139 else:
2140 ui.status(_(b"nothing changed\n"))
2140 ui.status(_(b"nothing changed\n"))
2141 return 1
2141 return 1
2142
2142
2143 cmdutil.commitstatus(repo, node, branch, bheads, tip, opts)
2143 cmdutil.commitstatus(repo, node, branch, bheads, tip, opts)
2144
2144
2145 if not ui.quiet and ui.configbool(b'commands', b'commit.post-status'):
2145 if not ui.quiet and ui.configbool(b'commands', b'commit.post-status'):
2146 status(
2146 status(
2147 ui,
2147 ui,
2148 repo,
2148 repo,
2149 modified=True,
2149 modified=True,
2150 added=True,
2150 added=True,
2151 removed=True,
2151 removed=True,
2152 deleted=True,
2152 deleted=True,
2153 unknown=True,
2153 unknown=True,
2154 subrepos=opts.get(b'subrepos'),
2154 subrepos=opts.get(b'subrepos'),
2155 )
2155 )
2156
2156
2157
2157
2158 @command(
2158 @command(
2159 b'config|showconfig|debugconfig',
2159 b'config|showconfig|debugconfig',
2160 [
2160 [
2161 (b'u', b'untrusted', None, _(b'show untrusted configuration options')),
2161 (b'u', b'untrusted', None, _(b'show untrusted configuration options')),
2162 (b'e', b'edit', None, _(b'edit user config')),
2162 (b'e', b'edit', None, _(b'edit user config')),
2163 (b'l', b'local', None, _(b'edit repository config')),
2163 (b'l', b'local', None, _(b'edit repository config')),
2164 (
2164 (
2165 b'',
2165 b'',
2166 b'shared',
2166 b'shared',
2167 None,
2167 None,
2168 _(b'edit shared source repository config (EXPERIMENTAL)'),
2168 _(b'edit shared source repository config (EXPERIMENTAL)'),
2169 ),
2169 ),
2170 (b'', b'non-shared', None, _(b'edit non shared config (EXPERIMENTAL)')),
2170 (b'', b'non-shared', None, _(b'edit non shared config (EXPERIMENTAL)')),
2171 (b'g', b'global', None, _(b'edit global config')),
2171 (b'g', b'global', None, _(b'edit global config')),
2172 ]
2172 ]
2173 + formatteropts,
2173 + formatteropts,
2174 _(b'[-u] [NAME]...'),
2174 _(b'[-u] [NAME]...'),
2175 helpcategory=command.CATEGORY_HELP,
2175 helpcategory=command.CATEGORY_HELP,
2176 optionalrepo=True,
2176 optionalrepo=True,
2177 intents={INTENT_READONLY},
2177 intents={INTENT_READONLY},
2178 )
2178 )
2179 def config(ui, repo, *values, **opts):
2179 def config(ui, repo, *values, **opts):
2180 """show combined config settings from all hgrc files
2180 """show combined config settings from all hgrc files
2181
2181
2182 With no arguments, print names and values of all config items.
2182 With no arguments, print names and values of all config items.
2183
2183
2184 With one argument of the form section.name, print just the value
2184 With one argument of the form section.name, print just the value
2185 of that config item.
2185 of that config item.
2186
2186
2187 With multiple arguments, print names and values of all config
2187 With multiple arguments, print names and values of all config
2188 items with matching section names or section.names.
2188 items with matching section names or section.names.
2189
2189
2190 With --edit, start an editor on the user-level config file. With
2190 With --edit, start an editor on the user-level config file. With
2191 --global, edit the system-wide config file. With --local, edit the
2191 --global, edit the system-wide config file. With --local, edit the
2192 repository-level config file.
2192 repository-level config file.
2193
2193
2194 With --debug, the source (filename and line number) is printed
2194 With --debug, the source (filename and line number) is printed
2195 for each config item.
2195 for each config item.
2196
2196
2197 See :hg:`help config` for more information about config files.
2197 See :hg:`help config` for more information about config files.
2198
2198
2199 .. container:: verbose
2199 .. container:: verbose
2200
2200
2201 --non-shared flag is used to edit `.hg/hgrc-not-shared` config file.
2201 --non-shared flag is used to edit `.hg/hgrc-not-shared` config file.
2202 This file is not shared across shares when in share-safe mode.
2202 This file is not shared across shares when in share-safe mode.
2203
2203
2204 Template:
2204 Template:
2205
2205
2206 The following keywords are supported. See also :hg:`help templates`.
2206 The following keywords are supported. See also :hg:`help templates`.
2207
2207
2208 :name: String. Config name.
2208 :name: String. Config name.
2209 :source: String. Filename and line number where the item is defined.
2209 :source: String. Filename and line number where the item is defined.
2210 :value: String. Config value.
2210 :value: String. Config value.
2211
2211
2212 The --shared flag can be used to edit the config file of shared source
2212 The --shared flag can be used to edit the config file of shared source
2213 repository. It only works when you have shared using the experimental
2213 repository. It only works when you have shared using the experimental
2214 share safe feature.
2214 share safe feature.
2215
2215
2216 Returns 0 on success, 1 if NAME does not exist.
2216 Returns 0 on success, 1 if NAME does not exist.
2217
2217
2218 """
2218 """
2219
2219
2220 opts = pycompat.byteskwargs(opts)
2220 opts = pycompat.byteskwargs(opts)
2221 editopts = (b'edit', b'local', b'global', b'shared', b'non_shared')
2221 editopts = (b'edit', b'local', b'global', b'shared', b'non_shared')
2222 if any(opts.get(o) for o in editopts):
2222 if any(opts.get(o) for o in editopts):
2223 cmdutil.check_at_most_one_arg(opts, *editopts[1:])
2223 cmdutil.check_at_most_one_arg(opts, *editopts[1:])
2224 if opts.get(b'local'):
2224 if opts.get(b'local'):
2225 if not repo:
2225 if not repo:
2226 raise error.InputError(
2226 raise error.InputError(
2227 _(b"can't use --local outside a repository")
2227 _(b"can't use --local outside a repository")
2228 )
2228 )
2229 paths = [repo.vfs.join(b'hgrc')]
2229 paths = [repo.vfs.join(b'hgrc')]
2230 elif opts.get(b'global'):
2230 elif opts.get(b'global'):
2231 paths = rcutil.systemrcpath()
2231 paths = rcutil.systemrcpath()
2232 elif opts.get(b'shared'):
2232 elif opts.get(b'shared'):
2233 if not repo.shared():
2233 if not repo.shared():
2234 raise error.InputError(
2234 raise error.InputError(
2235 _(b"repository is not shared; can't use --shared")
2235 _(b"repository is not shared; can't use --shared")
2236 )
2236 )
2237 if requirements.SHARESAFE_REQUIREMENT not in repo.requirements:
2237 if requirements.SHARESAFE_REQUIREMENT not in repo.requirements:
2238 raise error.InputError(
2238 raise error.InputError(
2239 _(
2239 _(
2240 b"share safe feature not enabled; "
2240 b"share safe feature not enabled; "
2241 b"unable to edit shared source repository config"
2241 b"unable to edit shared source repository config"
2242 )
2242 )
2243 )
2243 )
2244 paths = [vfsmod.vfs(repo.sharedpath).join(b'hgrc')]
2244 paths = [vfsmod.vfs(repo.sharedpath).join(b'hgrc')]
2245 elif opts.get(b'non_shared'):
2245 elif opts.get(b'non_shared'):
2246 paths = [repo.vfs.join(b'hgrc-not-shared')]
2246 paths = [repo.vfs.join(b'hgrc-not-shared')]
2247 else:
2247 else:
2248 paths = rcutil.userrcpath()
2248 paths = rcutil.userrcpath()
2249
2249
2250 for f in paths:
2250 for f in paths:
2251 if os.path.exists(f):
2251 if os.path.exists(f):
2252 break
2252 break
2253 else:
2253 else:
2254 if opts.get(b'global'):
2254 if opts.get(b'global'):
2255 samplehgrc = uimod.samplehgrcs[b'global']
2255 samplehgrc = uimod.samplehgrcs[b'global']
2256 elif opts.get(b'local'):
2256 elif opts.get(b'local'):
2257 samplehgrc = uimod.samplehgrcs[b'local']
2257 samplehgrc = uimod.samplehgrcs[b'local']
2258 else:
2258 else:
2259 samplehgrc = uimod.samplehgrcs[b'user']
2259 samplehgrc = uimod.samplehgrcs[b'user']
2260
2260
2261 f = paths[0]
2261 f = paths[0]
2262 fp = open(f, b"wb")
2262 fp = open(f, b"wb")
2263 fp.write(util.tonativeeol(samplehgrc))
2263 fp.write(util.tonativeeol(samplehgrc))
2264 fp.close()
2264 fp.close()
2265
2265
2266 editor = ui.geteditor()
2266 editor = ui.geteditor()
2267 ui.system(
2267 ui.system(
2268 b"%s \"%s\"" % (editor, f),
2268 b"%s \"%s\"" % (editor, f),
2269 onerr=error.InputError,
2269 onerr=error.InputError,
2270 errprefix=_(b"edit failed"),
2270 errprefix=_(b"edit failed"),
2271 blockedtag=b'config_edit',
2271 blockedtag=b'config_edit',
2272 )
2272 )
2273 return
2273 return
2274 ui.pager(b'config')
2274 ui.pager(b'config')
2275 fm = ui.formatter(b'config', opts)
2275 fm = ui.formatter(b'config', opts)
2276 for t, f in rcutil.rccomponents():
2276 for t, f in rcutil.rccomponents():
2277 if t == b'path':
2277 if t == b'path':
2278 ui.debug(b'read config from: %s\n' % f)
2278 ui.debug(b'read config from: %s\n' % f)
2279 elif t == b'resource':
2279 elif t == b'resource':
2280 ui.debug(b'read config from: resource:%s.%s\n' % (f[0], f[1]))
2280 ui.debug(b'read config from: resource:%s.%s\n' % (f[0], f[1]))
2281 elif t == b'items':
2281 elif t == b'items':
2282 # Don't print anything for 'items'.
2282 # Don't print anything for 'items'.
2283 pass
2283 pass
2284 else:
2284 else:
2285 raise error.ProgrammingError(b'unknown rctype: %s' % t)
2285 raise error.ProgrammingError(b'unknown rctype: %s' % t)
2286 untrusted = bool(opts.get(b'untrusted'))
2286 untrusted = bool(opts.get(b'untrusted'))
2287
2287
2288 selsections = selentries = []
2288 selsections = selentries = []
2289 if values:
2289 if values:
2290 selsections = [v for v in values if b'.' not in v]
2290 selsections = [v for v in values if b'.' not in v]
2291 selentries = [v for v in values if b'.' in v]
2291 selentries = [v for v in values if b'.' in v]
2292 uniquesel = len(selentries) == 1 and not selsections
2292 uniquesel = len(selentries) == 1 and not selsections
2293 selsections = set(selsections)
2293 selsections = set(selsections)
2294 selentries = set(selentries)
2294 selentries = set(selentries)
2295
2295
2296 matched = False
2296 matched = False
2297 for section, name, value in ui.walkconfig(untrusted=untrusted):
2297 for section, name, value in ui.walkconfig(untrusted=untrusted):
2298 source = ui.configsource(section, name, untrusted)
2298 source = ui.configsource(section, name, untrusted)
2299 value = pycompat.bytestr(value)
2299 value = pycompat.bytestr(value)
2300 defaultvalue = ui.configdefault(section, name)
2300 defaultvalue = ui.configdefault(section, name)
2301 if fm.isplain():
2301 if fm.isplain():
2302 source = source or b'none'
2302 source = source or b'none'
2303 value = value.replace(b'\n', b'\\n')
2303 value = value.replace(b'\n', b'\\n')
2304 entryname = section + b'.' + name
2304 entryname = section + b'.' + name
2305 if values and not (section in selsections or entryname in selentries):
2305 if values and not (section in selsections or entryname in selentries):
2306 continue
2306 continue
2307 fm.startitem()
2307 fm.startitem()
2308 fm.condwrite(ui.debugflag, b'source', b'%s: ', source)
2308 fm.condwrite(ui.debugflag, b'source', b'%s: ', source)
2309 if uniquesel:
2309 if uniquesel:
2310 fm.data(name=entryname)
2310 fm.data(name=entryname)
2311 fm.write(b'value', b'%s\n', value)
2311 fm.write(b'value', b'%s\n', value)
2312 else:
2312 else:
2313 fm.write(b'name value', b'%s=%s\n', entryname, value)
2313 fm.write(b'name value', b'%s=%s\n', entryname, value)
2314 if formatter.isprintable(defaultvalue):
2314 if formatter.isprintable(defaultvalue):
2315 fm.data(defaultvalue=defaultvalue)
2315 fm.data(defaultvalue=defaultvalue)
2316 elif isinstance(defaultvalue, list) and all(
2316 elif isinstance(defaultvalue, list) and all(
2317 formatter.isprintable(e) for e in defaultvalue
2317 formatter.isprintable(e) for e in defaultvalue
2318 ):
2318 ):
2319 fm.data(defaultvalue=fm.formatlist(defaultvalue, name=b'value'))
2319 fm.data(defaultvalue=fm.formatlist(defaultvalue, name=b'value'))
2320 # TODO: no idea how to process unsupported defaultvalue types
2320 # TODO: no idea how to process unsupported defaultvalue types
2321 matched = True
2321 matched = True
2322 fm.end()
2322 fm.end()
2323 if matched:
2323 if matched:
2324 return 0
2324 return 0
2325 return 1
2325 return 1
2326
2326
2327
2327
2328 @command(
2328 @command(
2329 b'continue',
2329 b'continue',
2330 dryrunopts,
2330 dryrunopts,
2331 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2331 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2332 helpbasic=True,
2332 helpbasic=True,
2333 )
2333 )
2334 def continuecmd(ui, repo, **opts):
2334 def continuecmd(ui, repo, **opts):
2335 """resumes an interrupted operation (EXPERIMENTAL)
2335 """resumes an interrupted operation (EXPERIMENTAL)
2336
2336
2337 Finishes a multistep operation like graft, histedit, rebase, merge,
2337 Finishes a multistep operation like graft, histedit, rebase, merge,
2338 and unshelve if they are in an interrupted state.
2338 and unshelve if they are in an interrupted state.
2339
2339
2340 use --dry-run/-n to dry run the command.
2340 use --dry-run/-n to dry run the command.
2341 """
2341 """
2342 dryrun = opts.get('dry_run')
2342 dryrun = opts.get('dry_run')
2343 contstate = cmdutil.getunfinishedstate(repo)
2343 contstate = cmdutil.getunfinishedstate(repo)
2344 if not contstate:
2344 if not contstate:
2345 raise error.StateError(_(b'no operation in progress'))
2345 raise error.StateError(_(b'no operation in progress'))
2346 if not contstate.continuefunc:
2346 if not contstate.continuefunc:
2347 raise error.StateError(
2347 raise error.StateError(
2348 (
2348 (
2349 _(b"%s in progress but does not support 'hg continue'")
2349 _(b"%s in progress but does not support 'hg continue'")
2350 % (contstate._opname)
2350 % (contstate._opname)
2351 ),
2351 ),
2352 hint=contstate.continuemsg(),
2352 hint=contstate.continuemsg(),
2353 )
2353 )
2354 if dryrun:
2354 if dryrun:
2355 ui.status(_(b'%s in progress, will be resumed\n') % (contstate._opname))
2355 ui.status(_(b'%s in progress, will be resumed\n') % (contstate._opname))
2356 return
2356 return
2357 return contstate.continuefunc(ui, repo)
2357 return contstate.continuefunc(ui, repo)
2358
2358
2359
2359
2360 @command(
2360 @command(
2361 b'copy|cp',
2361 b'copy|cp',
2362 [
2362 [
2363 (b'', b'forget', None, _(b'unmark a destination file as copied')),
2363 (b'', b'forget', None, _(b'unmark a destination file as copied')),
2364 (b'A', b'after', None, _(b'record a copy that has already occurred')),
2364 (b'A', b'after', None, _(b'record a copy that has already occurred')),
2365 (
2365 (
2366 b'',
2366 b'',
2367 b'at-rev',
2367 b'at-rev',
2368 b'',
2368 b'',
2369 _(b'(un)mark copies in the given revision (EXPERIMENTAL)'),
2369 _(b'(un)mark copies in the given revision (EXPERIMENTAL)'),
2370 _(b'REV'),
2370 _(b'REV'),
2371 ),
2371 ),
2372 (
2372 (
2373 b'f',
2373 b'f',
2374 b'force',
2374 b'force',
2375 None,
2375 None,
2376 _(b'forcibly copy over an existing managed file'),
2376 _(b'forcibly copy over an existing managed file'),
2377 ),
2377 ),
2378 ]
2378 ]
2379 + walkopts
2379 + walkopts
2380 + dryrunopts,
2380 + dryrunopts,
2381 _(b'[OPTION]... (SOURCE... DEST | --forget DEST...)'),
2381 _(b'[OPTION]... (SOURCE... DEST | --forget DEST...)'),
2382 helpcategory=command.CATEGORY_FILE_CONTENTS,
2382 helpcategory=command.CATEGORY_FILE_CONTENTS,
2383 )
2383 )
2384 def copy(ui, repo, *pats, **opts):
2384 def copy(ui, repo, *pats, **opts):
2385 """mark files as copied for the next commit
2385 """mark files as copied for the next commit
2386
2386
2387 Mark dest as having copies of source files. If dest is a
2387 Mark dest as having copies of source files. If dest is a
2388 directory, copies are put in that directory. If dest is a file,
2388 directory, copies are put in that directory. If dest is a file,
2389 the source must be a single file.
2389 the source must be a single file.
2390
2390
2391 By default, this command copies the contents of files as they
2391 By default, this command copies the contents of files as they
2392 exist in the working directory. If invoked with -A/--after, the
2392 exist in the working directory. If invoked with -A/--after, the
2393 operation is recorded, but no copying is performed.
2393 operation is recorded, but no copying is performed.
2394
2394
2395 To undo marking a destination file as copied, use --forget. With that
2395 To undo marking a destination file as copied, use --forget. With that
2396 option, all given (positional) arguments are unmarked as copies. The
2396 option, all given (positional) arguments are unmarked as copies. The
2397 destination file(s) will be left in place (still tracked).
2397 destination file(s) will be left in place (still tracked).
2398
2398
2399 This command takes effect with the next commit by default.
2399 This command takes effect with the next commit by default.
2400
2400
2401 Returns 0 on success, 1 if errors are encountered.
2401 Returns 0 on success, 1 if errors are encountered.
2402 """
2402 """
2403 opts = pycompat.byteskwargs(opts)
2403 opts = pycompat.byteskwargs(opts)
2404 with repo.wlock():
2404 with repo.wlock():
2405 return cmdutil.copy(ui, repo, pats, opts)
2405 return cmdutil.copy(ui, repo, pats, opts)
2406
2406
2407
2407
2408 @command(
2408 @command(
2409 b'debugcommands',
2409 b'debugcommands',
2410 [],
2410 [],
2411 _(b'[COMMAND]'),
2411 _(b'[COMMAND]'),
2412 helpcategory=command.CATEGORY_HELP,
2412 helpcategory=command.CATEGORY_HELP,
2413 norepo=True,
2413 norepo=True,
2414 )
2414 )
2415 def debugcommands(ui, cmd=b'', *args):
2415 def debugcommands(ui, cmd=b'', *args):
2416 """list all available commands and options"""
2416 """list all available commands and options"""
2417 for cmd, vals in sorted(pycompat.iteritems(table)):
2417 for cmd, vals in sorted(pycompat.iteritems(table)):
2418 cmd = cmd.split(b'|')[0]
2418 cmd = cmd.split(b'|')[0]
2419 opts = b', '.join([i[1] for i in vals[1]])
2419 opts = b', '.join([i[1] for i in vals[1]])
2420 ui.write(b'%s: %s\n' % (cmd, opts))
2420 ui.write(b'%s: %s\n' % (cmd, opts))
2421
2421
2422
2422
2423 @command(
2423 @command(
2424 b'debugcomplete',
2424 b'debugcomplete',
2425 [(b'o', b'options', None, _(b'show the command options'))],
2425 [(b'o', b'options', None, _(b'show the command options'))],
2426 _(b'[-o] CMD'),
2426 _(b'[-o] CMD'),
2427 helpcategory=command.CATEGORY_HELP,
2427 helpcategory=command.CATEGORY_HELP,
2428 norepo=True,
2428 norepo=True,
2429 )
2429 )
2430 def debugcomplete(ui, cmd=b'', **opts):
2430 def debugcomplete(ui, cmd=b'', **opts):
2431 """returns the completion list associated with the given command"""
2431 """returns the completion list associated with the given command"""
2432
2432
2433 if opts.get('options'):
2433 if opts.get('options'):
2434 options = []
2434 options = []
2435 otables = [globalopts]
2435 otables = [globalopts]
2436 if cmd:
2436 if cmd:
2437 aliases, entry = cmdutil.findcmd(cmd, table, False)
2437 aliases, entry = cmdutil.findcmd(cmd, table, False)
2438 otables.append(entry[1])
2438 otables.append(entry[1])
2439 for t in otables:
2439 for t in otables:
2440 for o in t:
2440 for o in t:
2441 if b"(DEPRECATED)" in o[3]:
2441 if b"(DEPRECATED)" in o[3]:
2442 continue
2442 continue
2443 if o[0]:
2443 if o[0]:
2444 options.append(b'-%s' % o[0])
2444 options.append(b'-%s' % o[0])
2445 options.append(b'--%s' % o[1])
2445 options.append(b'--%s' % o[1])
2446 ui.write(b"%s\n" % b"\n".join(options))
2446 ui.write(b"%s\n" % b"\n".join(options))
2447 return
2447 return
2448
2448
2449 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2449 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2450 if ui.verbose:
2450 if ui.verbose:
2451 cmdlist = [b' '.join(c[0]) for c in cmdlist.values()]
2451 cmdlist = [b' '.join(c[0]) for c in cmdlist.values()]
2452 ui.write(b"%s\n" % b"\n".join(sorted(cmdlist)))
2452 ui.write(b"%s\n" % b"\n".join(sorted(cmdlist)))
2453
2453
2454
2454
2455 @command(
2455 @command(
2456 b'diff',
2456 b'diff',
2457 [
2457 [
2458 (b'r', b'rev', [], _(b'revision'), _(b'REV')),
2458 (b'r', b'rev', [], _(b'revision (DEPRECATED)'), _(b'REV')),
2459 (b'', b'from', b'', _(b'revision to diff from'), _(b'REV1')),
2459 (b'', b'from', b'', _(b'revision to diff from'), _(b'REV1')),
2460 (b'', b'to', b'', _(b'revision to diff to'), _(b'REV2')),
2460 (b'', b'to', b'', _(b'revision to diff to'), _(b'REV2')),
2461 (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')),
2461 (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')),
2462 ]
2462 ]
2463 + diffopts
2463 + diffopts
2464 + diffopts2
2464 + diffopts2
2465 + walkopts
2465 + walkopts
2466 + subrepoopts,
2466 + subrepoopts,
2467 _(b'[OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...'),
2467 _(b'[OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...'),
2468 helpcategory=command.CATEGORY_FILE_CONTENTS,
2468 helpcategory=command.CATEGORY_FILE_CONTENTS,
2469 helpbasic=True,
2469 helpbasic=True,
2470 inferrepo=True,
2470 inferrepo=True,
2471 intents={INTENT_READONLY},
2471 intents={INTENT_READONLY},
2472 )
2472 )
2473 def diff(ui, repo, *pats, **opts):
2473 def diff(ui, repo, *pats, **opts):
2474 """diff repository (or selected files)
2474 """diff repository (or selected files)
2475
2475
2476 Show differences between revisions for the specified files.
2476 Show differences between revisions for the specified files.
2477
2477
2478 Differences between files are shown using the unified diff format.
2478 Differences between files are shown using the unified diff format.
2479
2479
2480 .. note::
2480 .. note::
2481
2481
2482 :hg:`diff` may generate unexpected results for merges, as it will
2482 :hg:`diff` may generate unexpected results for merges, as it will
2483 default to comparing against the working directory's first
2483 default to comparing against the working directory's first
2484 parent changeset if no revisions are specified.
2484 parent changeset if no revisions are specified.
2485
2485
2486 By default, the working directory files are compared to its first parent. To
2486 By default, the working directory files are compared to its first parent. To
2487 see the differences from another revision, use --from. To see the difference
2487 see the differences from another revision, use --from. To see the difference
2488 to another revision, use --to. For example, :hg:`diff --from .^` will show
2488 to another revision, use --to. For example, :hg:`diff --from .^` will show
2489 the differences from the working copy's grandparent to the working copy,
2489 the differences from the working copy's grandparent to the working copy,
2490 :hg:`diff --to .` will show the diff from the working copy to its parent
2490 :hg:`diff --to .` will show the diff from the working copy to its parent
2491 (i.e. the reverse of the default), and :hg:`diff --from 1.0 --to 1.2` will
2491 (i.e. the reverse of the default), and :hg:`diff --from 1.0 --to 1.2` will
2492 show the diff between those two revisions.
2492 show the diff between those two revisions.
2493
2493
2494 Alternatively you can specify -c/--change with a revision to see the changes
2494 Alternatively you can specify -c/--change with a revision to see the changes
2495 in that changeset relative to its first parent (i.e. :hg:`diff -c 42` is
2495 in that changeset relative to its first parent (i.e. :hg:`diff -c 42` is
2496 equivalent to :hg:`diff --from 42^ --to 42`)
2496 equivalent to :hg:`diff --from 42^ --to 42`)
2497
2497
2498 Without the -a/--text option, diff will avoid generating diffs of
2498 Without the -a/--text option, diff will avoid generating diffs of
2499 files it detects as binary. With -a, diff will generate a diff
2499 files it detects as binary. With -a, diff will generate a diff
2500 anyway, probably with undesirable results.
2500 anyway, probably with undesirable results.
2501
2501
2502 Use the -g/--git option to generate diffs in the git extended diff
2502 Use the -g/--git option to generate diffs in the git extended diff
2503 format. For more information, read :hg:`help diffs`.
2503 format. For more information, read :hg:`help diffs`.
2504
2504
2505 .. container:: verbose
2505 .. container:: verbose
2506
2506
2507 Examples:
2507 Examples:
2508
2508
2509 - compare a file in the current working directory to its parent::
2509 - compare a file in the current working directory to its parent::
2510
2510
2511 hg diff foo.c
2511 hg diff foo.c
2512
2512
2513 - compare two historical versions of a directory, with rename info::
2513 - compare two historical versions of a directory, with rename info::
2514
2514
2515 hg diff --git --from 1.0 --to 1.2 lib/
2515 hg diff --git --from 1.0 --to 1.2 lib/
2516
2516
2517 - get change stats relative to the last change on some date::
2517 - get change stats relative to the last change on some date::
2518
2518
2519 hg diff --stat --from "date('may 2')"
2519 hg diff --stat --from "date('may 2')"
2520
2520
2521 - diff all newly-added files that contain a keyword::
2521 - diff all newly-added files that contain a keyword::
2522
2522
2523 hg diff "set:added() and grep(GNU)"
2523 hg diff "set:added() and grep(GNU)"
2524
2524
2525 - compare a revision and its parents::
2525 - compare a revision and its parents::
2526
2526
2527 hg diff -c 9353 # compare against first parent
2527 hg diff -c 9353 # compare against first parent
2528 hg diff --from 9353^ --to 9353 # same using revset syntax
2528 hg diff --from 9353^ --to 9353 # same using revset syntax
2529 hg diff --from 9353^2 --to 9353 # compare against the second parent
2529 hg diff --from 9353^2 --to 9353 # compare against the second parent
2530
2530
2531 Returns 0 on success.
2531 Returns 0 on success.
2532 """
2532 """
2533
2533
2534 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
2534 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
2535 opts = pycompat.byteskwargs(opts)
2535 opts = pycompat.byteskwargs(opts)
2536 revs = opts.get(b'rev')
2536 revs = opts.get(b'rev')
2537 change = opts.get(b'change')
2537 change = opts.get(b'change')
2538 from_rev = opts.get(b'from')
2538 from_rev = opts.get(b'from')
2539 to_rev = opts.get(b'to')
2539 to_rev = opts.get(b'to')
2540 stat = opts.get(b'stat')
2540 stat = opts.get(b'stat')
2541 reverse = opts.get(b'reverse')
2541 reverse = opts.get(b'reverse')
2542
2542
2543 cmdutil.check_incompatible_arguments(opts, b'from', [b'rev', b'change'])
2543 cmdutil.check_incompatible_arguments(opts, b'from', [b'rev', b'change'])
2544 cmdutil.check_incompatible_arguments(opts, b'to', [b'rev', b'change'])
2544 cmdutil.check_incompatible_arguments(opts, b'to', [b'rev', b'change'])
2545 if change:
2545 if change:
2546 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
2546 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
2547 ctx2 = scmutil.revsingle(repo, change, None)
2547 ctx2 = scmutil.revsingle(repo, change, None)
2548 ctx1 = ctx2.p1()
2548 ctx1 = ctx2.p1()
2549 elif from_rev or to_rev:
2549 elif from_rev or to_rev:
2550 repo = scmutil.unhidehashlikerevs(
2550 repo = scmutil.unhidehashlikerevs(
2551 repo, [from_rev] + [to_rev], b'nowarn'
2551 repo, [from_rev] + [to_rev], b'nowarn'
2552 )
2552 )
2553 ctx1 = scmutil.revsingle(repo, from_rev, None)
2553 ctx1 = scmutil.revsingle(repo, from_rev, None)
2554 ctx2 = scmutil.revsingle(repo, to_rev, None)
2554 ctx2 = scmutil.revsingle(repo, to_rev, None)
2555 else:
2555 else:
2556 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
2556 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
2557 ctx1, ctx2 = scmutil.revpair(repo, revs)
2557 ctx1, ctx2 = scmutil.revpair(repo, revs)
2558
2558
2559 if reverse:
2559 if reverse:
2560 ctxleft = ctx2
2560 ctxleft = ctx2
2561 ctxright = ctx1
2561 ctxright = ctx1
2562 else:
2562 else:
2563 ctxleft = ctx1
2563 ctxleft = ctx1
2564 ctxright = ctx2
2564 ctxright = ctx2
2565
2565
2566 diffopts = patch.diffallopts(ui, opts)
2566 diffopts = patch.diffallopts(ui, opts)
2567 m = scmutil.match(ctx2, pats, opts)
2567 m = scmutil.match(ctx2, pats, opts)
2568 m = repo.narrowmatch(m)
2568 m = repo.narrowmatch(m)
2569 ui.pager(b'diff')
2569 ui.pager(b'diff')
2570 logcmdutil.diffordiffstat(
2570 logcmdutil.diffordiffstat(
2571 ui,
2571 ui,
2572 repo,
2572 repo,
2573 diffopts,
2573 diffopts,
2574 ctxleft,
2574 ctxleft,
2575 ctxright,
2575 ctxright,
2576 m,
2576 m,
2577 stat=stat,
2577 stat=stat,
2578 listsubrepos=opts.get(b'subrepos'),
2578 listsubrepos=opts.get(b'subrepos'),
2579 root=opts.get(b'root'),
2579 root=opts.get(b'root'),
2580 )
2580 )
2581
2581
2582
2582
2583 @command(
2583 @command(
2584 b'export',
2584 b'export',
2585 [
2585 [
2586 (
2586 (
2587 b'B',
2587 b'B',
2588 b'bookmark',
2588 b'bookmark',
2589 b'',
2589 b'',
2590 _(b'export changes only reachable by given bookmark'),
2590 _(b'export changes only reachable by given bookmark'),
2591 _(b'BOOKMARK'),
2591 _(b'BOOKMARK'),
2592 ),
2592 ),
2593 (
2593 (
2594 b'o',
2594 b'o',
2595 b'output',
2595 b'output',
2596 b'',
2596 b'',
2597 _(b'print output to file with formatted name'),
2597 _(b'print output to file with formatted name'),
2598 _(b'FORMAT'),
2598 _(b'FORMAT'),
2599 ),
2599 ),
2600 (b'', b'switch-parent', None, _(b'diff against the second parent')),
2600 (b'', b'switch-parent', None, _(b'diff against the second parent')),
2601 (b'r', b'rev', [], _(b'revisions to export'), _(b'REV')),
2601 (b'r', b'rev', [], _(b'revisions to export'), _(b'REV')),
2602 ]
2602 ]
2603 + diffopts
2603 + diffopts
2604 + formatteropts,
2604 + formatteropts,
2605 _(b'[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2605 _(b'[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2606 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2606 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2607 helpbasic=True,
2607 helpbasic=True,
2608 intents={INTENT_READONLY},
2608 intents={INTENT_READONLY},
2609 )
2609 )
2610 def export(ui, repo, *changesets, **opts):
2610 def export(ui, repo, *changesets, **opts):
2611 """dump the header and diffs for one or more changesets
2611 """dump the header and diffs for one or more changesets
2612
2612
2613 Print the changeset header and diffs for one or more revisions.
2613 Print the changeset header and diffs for one or more revisions.
2614 If no revision is given, the parent of the working directory is used.
2614 If no revision is given, the parent of the working directory is used.
2615
2615
2616 The information shown in the changeset header is: author, date,
2616 The information shown in the changeset header is: author, date,
2617 branch name (if non-default), changeset hash, parent(s) and commit
2617 branch name (if non-default), changeset hash, parent(s) and commit
2618 comment.
2618 comment.
2619
2619
2620 .. note::
2620 .. note::
2621
2621
2622 :hg:`export` may generate unexpected diff output for merge
2622 :hg:`export` may generate unexpected diff output for merge
2623 changesets, as it will compare the merge changeset against its
2623 changesets, as it will compare the merge changeset against its
2624 first parent only.
2624 first parent only.
2625
2625
2626 Output may be to a file, in which case the name of the file is
2626 Output may be to a file, in which case the name of the file is
2627 given using a template string. See :hg:`help templates`. In addition
2627 given using a template string. See :hg:`help templates`. In addition
2628 to the common template keywords, the following formatting rules are
2628 to the common template keywords, the following formatting rules are
2629 supported:
2629 supported:
2630
2630
2631 :``%%``: literal "%" character
2631 :``%%``: literal "%" character
2632 :``%H``: changeset hash (40 hexadecimal digits)
2632 :``%H``: changeset hash (40 hexadecimal digits)
2633 :``%N``: number of patches being generated
2633 :``%N``: number of patches being generated
2634 :``%R``: changeset revision number
2634 :``%R``: changeset revision number
2635 :``%b``: basename of the exporting repository
2635 :``%b``: basename of the exporting repository
2636 :``%h``: short-form changeset hash (12 hexadecimal digits)
2636 :``%h``: short-form changeset hash (12 hexadecimal digits)
2637 :``%m``: first line of the commit message (only alphanumeric characters)
2637 :``%m``: first line of the commit message (only alphanumeric characters)
2638 :``%n``: zero-padded sequence number, starting at 1
2638 :``%n``: zero-padded sequence number, starting at 1
2639 :``%r``: zero-padded changeset revision number
2639 :``%r``: zero-padded changeset revision number
2640 :``\\``: literal "\\" character
2640 :``\\``: literal "\\" character
2641
2641
2642 Without the -a/--text option, export will avoid generating diffs
2642 Without the -a/--text option, export will avoid generating diffs
2643 of files it detects as binary. With -a, export will generate a
2643 of files it detects as binary. With -a, export will generate a
2644 diff anyway, probably with undesirable results.
2644 diff anyway, probably with undesirable results.
2645
2645
2646 With -B/--bookmark changesets reachable by the given bookmark are
2646 With -B/--bookmark changesets reachable by the given bookmark are
2647 selected.
2647 selected.
2648
2648
2649 Use the -g/--git option to generate diffs in the git extended diff
2649 Use the -g/--git option to generate diffs in the git extended diff
2650 format. See :hg:`help diffs` for more information.
2650 format. See :hg:`help diffs` for more information.
2651
2651
2652 With the --switch-parent option, the diff will be against the
2652 With the --switch-parent option, the diff will be against the
2653 second parent. It can be useful to review a merge.
2653 second parent. It can be useful to review a merge.
2654
2654
2655 .. container:: verbose
2655 .. container:: verbose
2656
2656
2657 Template:
2657 Template:
2658
2658
2659 The following keywords are supported in addition to the common template
2659 The following keywords are supported in addition to the common template
2660 keywords and functions. See also :hg:`help templates`.
2660 keywords and functions. See also :hg:`help templates`.
2661
2661
2662 :diff: String. Diff content.
2662 :diff: String. Diff content.
2663 :parents: List of strings. Parent nodes of the changeset.
2663 :parents: List of strings. Parent nodes of the changeset.
2664
2664
2665 Examples:
2665 Examples:
2666
2666
2667 - use export and import to transplant a bugfix to the current
2667 - use export and import to transplant a bugfix to the current
2668 branch::
2668 branch::
2669
2669
2670 hg export -r 9353 | hg import -
2670 hg export -r 9353 | hg import -
2671
2671
2672 - export all the changesets between two revisions to a file with
2672 - export all the changesets between two revisions to a file with
2673 rename information::
2673 rename information::
2674
2674
2675 hg export --git -r 123:150 > changes.txt
2675 hg export --git -r 123:150 > changes.txt
2676
2676
2677 - split outgoing changes into a series of patches with
2677 - split outgoing changes into a series of patches with
2678 descriptive names::
2678 descriptive names::
2679
2679
2680 hg export -r "outgoing()" -o "%n-%m.patch"
2680 hg export -r "outgoing()" -o "%n-%m.patch"
2681
2681
2682 Returns 0 on success.
2682 Returns 0 on success.
2683 """
2683 """
2684 opts = pycompat.byteskwargs(opts)
2684 opts = pycompat.byteskwargs(opts)
2685 bookmark = opts.get(b'bookmark')
2685 bookmark = opts.get(b'bookmark')
2686 changesets += tuple(opts.get(b'rev', []))
2686 changesets += tuple(opts.get(b'rev', []))
2687
2687
2688 cmdutil.check_at_most_one_arg(opts, b'rev', b'bookmark')
2688 cmdutil.check_at_most_one_arg(opts, b'rev', b'bookmark')
2689
2689
2690 if bookmark:
2690 if bookmark:
2691 if bookmark not in repo._bookmarks:
2691 if bookmark not in repo._bookmarks:
2692 raise error.InputError(_(b"bookmark '%s' not found") % bookmark)
2692 raise error.InputError(_(b"bookmark '%s' not found") % bookmark)
2693
2693
2694 revs = scmutil.bookmarkrevs(repo, bookmark)
2694 revs = scmutil.bookmarkrevs(repo, bookmark)
2695 else:
2695 else:
2696 if not changesets:
2696 if not changesets:
2697 changesets = [b'.']
2697 changesets = [b'.']
2698
2698
2699 repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
2699 repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
2700 revs = scmutil.revrange(repo, changesets)
2700 revs = scmutil.revrange(repo, changesets)
2701
2701
2702 if not revs:
2702 if not revs:
2703 raise error.InputError(_(b"export requires at least one changeset"))
2703 raise error.InputError(_(b"export requires at least one changeset"))
2704 if len(revs) > 1:
2704 if len(revs) > 1:
2705 ui.note(_(b'exporting patches:\n'))
2705 ui.note(_(b'exporting patches:\n'))
2706 else:
2706 else:
2707 ui.note(_(b'exporting patch:\n'))
2707 ui.note(_(b'exporting patch:\n'))
2708
2708
2709 fntemplate = opts.get(b'output')
2709 fntemplate = opts.get(b'output')
2710 if cmdutil.isstdiofilename(fntemplate):
2710 if cmdutil.isstdiofilename(fntemplate):
2711 fntemplate = b''
2711 fntemplate = b''
2712
2712
2713 if fntemplate:
2713 if fntemplate:
2714 fm = formatter.nullformatter(ui, b'export', opts)
2714 fm = formatter.nullformatter(ui, b'export', opts)
2715 else:
2715 else:
2716 ui.pager(b'export')
2716 ui.pager(b'export')
2717 fm = ui.formatter(b'export', opts)
2717 fm = ui.formatter(b'export', opts)
2718 with fm:
2718 with fm:
2719 cmdutil.export(
2719 cmdutil.export(
2720 repo,
2720 repo,
2721 revs,
2721 revs,
2722 fm,
2722 fm,
2723 fntemplate=fntemplate,
2723 fntemplate=fntemplate,
2724 switch_parent=opts.get(b'switch_parent'),
2724 switch_parent=opts.get(b'switch_parent'),
2725 opts=patch.diffallopts(ui, opts),
2725 opts=patch.diffallopts(ui, opts),
2726 )
2726 )
2727
2727
2728
2728
2729 @command(
2729 @command(
2730 b'files',
2730 b'files',
2731 [
2731 [
2732 (
2732 (
2733 b'r',
2733 b'r',
2734 b'rev',
2734 b'rev',
2735 b'',
2735 b'',
2736 _(b'search the repository as it is in REV'),
2736 _(b'search the repository as it is in REV'),
2737 _(b'REV'),
2737 _(b'REV'),
2738 ),
2738 ),
2739 (
2739 (
2740 b'0',
2740 b'0',
2741 b'print0',
2741 b'print0',
2742 None,
2742 None,
2743 _(b'end filenames with NUL, for use with xargs'),
2743 _(b'end filenames with NUL, for use with xargs'),
2744 ),
2744 ),
2745 ]
2745 ]
2746 + walkopts
2746 + walkopts
2747 + formatteropts
2747 + formatteropts
2748 + subrepoopts,
2748 + subrepoopts,
2749 _(b'[OPTION]... [FILE]...'),
2749 _(b'[OPTION]... [FILE]...'),
2750 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2750 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2751 intents={INTENT_READONLY},
2751 intents={INTENT_READONLY},
2752 )
2752 )
2753 def files(ui, repo, *pats, **opts):
2753 def files(ui, repo, *pats, **opts):
2754 """list tracked files
2754 """list tracked files
2755
2755
2756 Print files under Mercurial control in the working directory or
2756 Print files under Mercurial control in the working directory or
2757 specified revision for given files (excluding removed files).
2757 specified revision for given files (excluding removed files).
2758 Files can be specified as filenames or filesets.
2758 Files can be specified as filenames or filesets.
2759
2759
2760 If no files are given to match, this command prints the names
2760 If no files are given to match, this command prints the names
2761 of all files under Mercurial control.
2761 of all files under Mercurial control.
2762
2762
2763 .. container:: verbose
2763 .. container:: verbose
2764
2764
2765 Template:
2765 Template:
2766
2766
2767 The following keywords are supported in addition to the common template
2767 The following keywords are supported in addition to the common template
2768 keywords and functions. See also :hg:`help templates`.
2768 keywords and functions. See also :hg:`help templates`.
2769
2769
2770 :flags: String. Character denoting file's symlink and executable bits.
2770 :flags: String. Character denoting file's symlink and executable bits.
2771 :path: String. Repository-absolute path of the file.
2771 :path: String. Repository-absolute path of the file.
2772 :size: Integer. Size of the file in bytes.
2772 :size: Integer. Size of the file in bytes.
2773
2773
2774 Examples:
2774 Examples:
2775
2775
2776 - list all files under the current directory::
2776 - list all files under the current directory::
2777
2777
2778 hg files .
2778 hg files .
2779
2779
2780 - shows sizes and flags for current revision::
2780 - shows sizes and flags for current revision::
2781
2781
2782 hg files -vr .
2782 hg files -vr .
2783
2783
2784 - list all files named README::
2784 - list all files named README::
2785
2785
2786 hg files -I "**/README"
2786 hg files -I "**/README"
2787
2787
2788 - list all binary files::
2788 - list all binary files::
2789
2789
2790 hg files "set:binary()"
2790 hg files "set:binary()"
2791
2791
2792 - find files containing a regular expression::
2792 - find files containing a regular expression::
2793
2793
2794 hg files "set:grep('bob')"
2794 hg files "set:grep('bob')"
2795
2795
2796 - search tracked file contents with xargs and grep::
2796 - search tracked file contents with xargs and grep::
2797
2797
2798 hg files -0 | xargs -0 grep foo
2798 hg files -0 | xargs -0 grep foo
2799
2799
2800 See :hg:`help patterns` and :hg:`help filesets` for more information
2800 See :hg:`help patterns` and :hg:`help filesets` for more information
2801 on specifying file patterns.
2801 on specifying file patterns.
2802
2802
2803 Returns 0 if a match is found, 1 otherwise.
2803 Returns 0 if a match is found, 1 otherwise.
2804
2804
2805 """
2805 """
2806
2806
2807 opts = pycompat.byteskwargs(opts)
2807 opts = pycompat.byteskwargs(opts)
2808 rev = opts.get(b'rev')
2808 rev = opts.get(b'rev')
2809 if rev:
2809 if rev:
2810 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
2810 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
2811 ctx = scmutil.revsingle(repo, rev, None)
2811 ctx = scmutil.revsingle(repo, rev, None)
2812
2812
2813 end = b'\n'
2813 end = b'\n'
2814 if opts.get(b'print0'):
2814 if opts.get(b'print0'):
2815 end = b'\0'
2815 end = b'\0'
2816 fmt = b'%s' + end
2816 fmt = b'%s' + end
2817
2817
2818 m = scmutil.match(ctx, pats, opts)
2818 m = scmutil.match(ctx, pats, opts)
2819 ui.pager(b'files')
2819 ui.pager(b'files')
2820 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2820 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2821 with ui.formatter(b'files', opts) as fm:
2821 with ui.formatter(b'files', opts) as fm:
2822 return cmdutil.files(
2822 return cmdutil.files(
2823 ui, ctx, m, uipathfn, fm, fmt, opts.get(b'subrepos')
2823 ui, ctx, m, uipathfn, fm, fmt, opts.get(b'subrepos')
2824 )
2824 )
2825
2825
2826
2826
2827 @command(
2827 @command(
2828 b'forget',
2828 b'forget',
2829 [
2829 [
2830 (b'i', b'interactive', None, _(b'use interactive mode')),
2830 (b'i', b'interactive', None, _(b'use interactive mode')),
2831 ]
2831 ]
2832 + walkopts
2832 + walkopts
2833 + dryrunopts,
2833 + dryrunopts,
2834 _(b'[OPTION]... FILE...'),
2834 _(b'[OPTION]... FILE...'),
2835 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2835 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2836 helpbasic=True,
2836 helpbasic=True,
2837 inferrepo=True,
2837 inferrepo=True,
2838 )
2838 )
2839 def forget(ui, repo, *pats, **opts):
2839 def forget(ui, repo, *pats, **opts):
2840 """forget the specified files on the next commit
2840 """forget the specified files on the next commit
2841
2841
2842 Mark the specified files so they will no longer be tracked
2842 Mark the specified files so they will no longer be tracked
2843 after the next commit.
2843 after the next commit.
2844
2844
2845 This only removes files from the current branch, not from the
2845 This only removes files from the current branch, not from the
2846 entire project history, and it does not delete them from the
2846 entire project history, and it does not delete them from the
2847 working directory.
2847 working directory.
2848
2848
2849 To delete the file from the working directory, see :hg:`remove`.
2849 To delete the file from the working directory, see :hg:`remove`.
2850
2850
2851 To undo a forget before the next commit, see :hg:`add`.
2851 To undo a forget before the next commit, see :hg:`add`.
2852
2852
2853 .. container:: verbose
2853 .. container:: verbose
2854
2854
2855 Examples:
2855 Examples:
2856
2856
2857 - forget newly-added binary files::
2857 - forget newly-added binary files::
2858
2858
2859 hg forget "set:added() and binary()"
2859 hg forget "set:added() and binary()"
2860
2860
2861 - forget files that would be excluded by .hgignore::
2861 - forget files that would be excluded by .hgignore::
2862
2862
2863 hg forget "set:hgignore()"
2863 hg forget "set:hgignore()"
2864
2864
2865 Returns 0 on success.
2865 Returns 0 on success.
2866 """
2866 """
2867
2867
2868 opts = pycompat.byteskwargs(opts)
2868 opts = pycompat.byteskwargs(opts)
2869 if not pats:
2869 if not pats:
2870 raise error.InputError(_(b'no files specified'))
2870 raise error.InputError(_(b'no files specified'))
2871
2871
2872 m = scmutil.match(repo[None], pats, opts)
2872 m = scmutil.match(repo[None], pats, opts)
2873 dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive')
2873 dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive')
2874 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2874 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2875 rejected = cmdutil.forget(
2875 rejected = cmdutil.forget(
2876 ui,
2876 ui,
2877 repo,
2877 repo,
2878 m,
2878 m,
2879 prefix=b"",
2879 prefix=b"",
2880 uipathfn=uipathfn,
2880 uipathfn=uipathfn,
2881 explicitonly=False,
2881 explicitonly=False,
2882 dryrun=dryrun,
2882 dryrun=dryrun,
2883 interactive=interactive,
2883 interactive=interactive,
2884 )[0]
2884 )[0]
2885 return rejected and 1 or 0
2885 return rejected and 1 or 0
2886
2886
2887
2887
2888 @command(
2888 @command(
2889 b'graft',
2889 b'graft',
2890 [
2890 [
2891 (b'r', b'rev', [], _(b'revisions to graft'), _(b'REV')),
2891 (b'r', b'rev', [], _(b'revisions to graft'), _(b'REV')),
2892 (
2892 (
2893 b'',
2893 b'',
2894 b'base',
2894 b'base',
2895 b'',
2895 b'',
2896 _(b'base revision when doing the graft merge (ADVANCED)'),
2896 _(b'base revision when doing the graft merge (ADVANCED)'),
2897 _(b'REV'),
2897 _(b'REV'),
2898 ),
2898 ),
2899 (b'c', b'continue', False, _(b'resume interrupted graft')),
2899 (b'c', b'continue', False, _(b'resume interrupted graft')),
2900 (b'', b'stop', False, _(b'stop interrupted graft')),
2900 (b'', b'stop', False, _(b'stop interrupted graft')),
2901 (b'', b'abort', False, _(b'abort interrupted graft')),
2901 (b'', b'abort', False, _(b'abort interrupted graft')),
2902 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
2902 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
2903 (b'', b'log', None, _(b'append graft info to log message')),
2903 (b'', b'log', None, _(b'append graft info to log message')),
2904 (
2904 (
2905 b'',
2905 b'',
2906 b'no-commit',
2906 b'no-commit',
2907 None,
2907 None,
2908 _(b"don't commit, just apply the changes in working directory"),
2908 _(b"don't commit, just apply the changes in working directory"),
2909 ),
2909 ),
2910 (b'f', b'force', False, _(b'force graft')),
2910 (b'f', b'force', False, _(b'force graft')),
2911 (
2911 (
2912 b'D',
2912 b'D',
2913 b'currentdate',
2913 b'currentdate',
2914 False,
2914 False,
2915 _(b'record the current date as commit date'),
2915 _(b'record the current date as commit date'),
2916 ),
2916 ),
2917 (
2917 (
2918 b'U',
2918 b'U',
2919 b'currentuser',
2919 b'currentuser',
2920 False,
2920 False,
2921 _(b'record the current user as committer'),
2921 _(b'record the current user as committer'),
2922 ),
2922 ),
2923 ]
2923 ]
2924 + commitopts2
2924 + commitopts2
2925 + mergetoolopts
2925 + mergetoolopts
2926 + dryrunopts,
2926 + dryrunopts,
2927 _(b'[OPTION]... [-r REV]... REV...'),
2927 _(b'[OPTION]... [-r REV]... REV...'),
2928 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2928 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2929 )
2929 )
2930 def graft(ui, repo, *revs, **opts):
2930 def graft(ui, repo, *revs, **opts):
2931 """copy changes from other branches onto the current branch
2931 """copy changes from other branches onto the current branch
2932
2932
2933 This command uses Mercurial's merge logic to copy individual
2933 This command uses Mercurial's merge logic to copy individual
2934 changes from other branches without merging branches in the
2934 changes from other branches without merging branches in the
2935 history graph. This is sometimes known as 'backporting' or
2935 history graph. This is sometimes known as 'backporting' or
2936 'cherry-picking'. By default, graft will copy user, date, and
2936 'cherry-picking'. By default, graft will copy user, date, and
2937 description from the source changesets.
2937 description from the source changesets.
2938
2938
2939 Changesets that are ancestors of the current revision, that have
2939 Changesets that are ancestors of the current revision, that have
2940 already been grafted, or that are merges will be skipped.
2940 already been grafted, or that are merges will be skipped.
2941
2941
2942 If --log is specified, log messages will have a comment appended
2942 If --log is specified, log messages will have a comment appended
2943 of the form::
2943 of the form::
2944
2944
2945 (grafted from CHANGESETHASH)
2945 (grafted from CHANGESETHASH)
2946
2946
2947 If --force is specified, revisions will be grafted even if they
2947 If --force is specified, revisions will be grafted even if they
2948 are already ancestors of, or have been grafted to, the destination.
2948 are already ancestors of, or have been grafted to, the destination.
2949 This is useful when the revisions have since been backed out.
2949 This is useful when the revisions have since been backed out.
2950
2950
2951 If a graft merge results in conflicts, the graft process is
2951 If a graft merge results in conflicts, the graft process is
2952 interrupted so that the current merge can be manually resolved.
2952 interrupted so that the current merge can be manually resolved.
2953 Once all conflicts are addressed, the graft process can be
2953 Once all conflicts are addressed, the graft process can be
2954 continued with the -c/--continue option.
2954 continued with the -c/--continue option.
2955
2955
2956 The -c/--continue option reapplies all the earlier options.
2956 The -c/--continue option reapplies all the earlier options.
2957
2957
2958 .. container:: verbose
2958 .. container:: verbose
2959
2959
2960 The --base option exposes more of how graft internally uses merge with a
2960 The --base option exposes more of how graft internally uses merge with a
2961 custom base revision. --base can be used to specify another ancestor than
2961 custom base revision. --base can be used to specify another ancestor than
2962 the first and only parent.
2962 the first and only parent.
2963
2963
2964 The command::
2964 The command::
2965
2965
2966 hg graft -r 345 --base 234
2966 hg graft -r 345 --base 234
2967
2967
2968 is thus pretty much the same as::
2968 is thus pretty much the same as::
2969
2969
2970 hg diff --from 234 --to 345 | hg import
2970 hg diff --from 234 --to 345 | hg import
2971
2971
2972 but using merge to resolve conflicts and track moved files.
2972 but using merge to resolve conflicts and track moved files.
2973
2973
2974 The result of a merge can thus be backported as a single commit by
2974 The result of a merge can thus be backported as a single commit by
2975 specifying one of the merge parents as base, and thus effectively
2975 specifying one of the merge parents as base, and thus effectively
2976 grafting the changes from the other side.
2976 grafting the changes from the other side.
2977
2977
2978 It is also possible to collapse multiple changesets and clean up history
2978 It is also possible to collapse multiple changesets and clean up history
2979 by specifying another ancestor as base, much like rebase --collapse
2979 by specifying another ancestor as base, much like rebase --collapse
2980 --keep.
2980 --keep.
2981
2981
2982 The commit message can be tweaked after the fact using commit --amend .
2982 The commit message can be tweaked after the fact using commit --amend .
2983
2983
2984 For using non-ancestors as the base to backout changes, see the backout
2984 For using non-ancestors as the base to backout changes, see the backout
2985 command and the hidden --parent option.
2985 command and the hidden --parent option.
2986
2986
2987 .. container:: verbose
2987 .. container:: verbose
2988
2988
2989 Examples:
2989 Examples:
2990
2990
2991 - copy a single change to the stable branch and edit its description::
2991 - copy a single change to the stable branch and edit its description::
2992
2992
2993 hg update stable
2993 hg update stable
2994 hg graft --edit 9393
2994 hg graft --edit 9393
2995
2995
2996 - graft a range of changesets with one exception, updating dates::
2996 - graft a range of changesets with one exception, updating dates::
2997
2997
2998 hg graft -D "2085::2093 and not 2091"
2998 hg graft -D "2085::2093 and not 2091"
2999
2999
3000 - continue a graft after resolving conflicts::
3000 - continue a graft after resolving conflicts::
3001
3001
3002 hg graft -c
3002 hg graft -c
3003
3003
3004 - show the source of a grafted changeset::
3004 - show the source of a grafted changeset::
3005
3005
3006 hg log --debug -r .
3006 hg log --debug -r .
3007
3007
3008 - show revisions sorted by date::
3008 - show revisions sorted by date::
3009
3009
3010 hg log -r "sort(all(), date)"
3010 hg log -r "sort(all(), date)"
3011
3011
3012 - backport the result of a merge as a single commit::
3012 - backport the result of a merge as a single commit::
3013
3013
3014 hg graft -r 123 --base 123^
3014 hg graft -r 123 --base 123^
3015
3015
3016 - land a feature branch as one changeset::
3016 - land a feature branch as one changeset::
3017
3017
3018 hg up -cr default
3018 hg up -cr default
3019 hg graft -r featureX --base "ancestor('featureX', 'default')"
3019 hg graft -r featureX --base "ancestor('featureX', 'default')"
3020
3020
3021 See :hg:`help revisions` for more about specifying revisions.
3021 See :hg:`help revisions` for more about specifying revisions.
3022
3022
3023 Returns 0 on successful completion, 1 if there are unresolved files.
3023 Returns 0 on successful completion, 1 if there are unresolved files.
3024 """
3024 """
3025 with repo.wlock():
3025 with repo.wlock():
3026 return _dograft(ui, repo, *revs, **opts)
3026 return _dograft(ui, repo, *revs, **opts)
3027
3027
3028
3028
3029 def _dograft(ui, repo, *revs, **opts):
3029 def _dograft(ui, repo, *revs, **opts):
3030 opts = pycompat.byteskwargs(opts)
3030 opts = pycompat.byteskwargs(opts)
3031 if revs and opts.get(b'rev'):
3031 if revs and opts.get(b'rev'):
3032 ui.warn(
3032 ui.warn(
3033 _(
3033 _(
3034 b'warning: inconsistent use of --rev might give unexpected '
3034 b'warning: inconsistent use of --rev might give unexpected '
3035 b'revision ordering!\n'
3035 b'revision ordering!\n'
3036 )
3036 )
3037 )
3037 )
3038
3038
3039 revs = list(revs)
3039 revs = list(revs)
3040 revs.extend(opts.get(b'rev'))
3040 revs.extend(opts.get(b'rev'))
3041 # a dict of data to be stored in state file
3041 # a dict of data to be stored in state file
3042 statedata = {}
3042 statedata = {}
3043 # list of new nodes created by ongoing graft
3043 # list of new nodes created by ongoing graft
3044 statedata[b'newnodes'] = []
3044 statedata[b'newnodes'] = []
3045
3045
3046 cmdutil.resolvecommitoptions(ui, opts)
3046 cmdutil.resolvecommitoptions(ui, opts)
3047
3047
3048 editor = cmdutil.getcommiteditor(
3048 editor = cmdutil.getcommiteditor(
3049 editform=b'graft', **pycompat.strkwargs(opts)
3049 editform=b'graft', **pycompat.strkwargs(opts)
3050 )
3050 )
3051
3051
3052 cmdutil.check_at_most_one_arg(opts, b'abort', b'stop', b'continue')
3052 cmdutil.check_at_most_one_arg(opts, b'abort', b'stop', b'continue')
3053
3053
3054 cont = False
3054 cont = False
3055 if opts.get(b'no_commit'):
3055 if opts.get(b'no_commit'):
3056 cmdutil.check_incompatible_arguments(
3056 cmdutil.check_incompatible_arguments(
3057 opts,
3057 opts,
3058 b'no_commit',
3058 b'no_commit',
3059 [b'edit', b'currentuser', b'currentdate', b'log'],
3059 [b'edit', b'currentuser', b'currentdate', b'log'],
3060 )
3060 )
3061
3061
3062 graftstate = statemod.cmdstate(repo, b'graftstate')
3062 graftstate = statemod.cmdstate(repo, b'graftstate')
3063
3063
3064 if opts.get(b'stop'):
3064 if opts.get(b'stop'):
3065 cmdutil.check_incompatible_arguments(
3065 cmdutil.check_incompatible_arguments(
3066 opts,
3066 opts,
3067 b'stop',
3067 b'stop',
3068 [
3068 [
3069 b'edit',
3069 b'edit',
3070 b'log',
3070 b'log',
3071 b'user',
3071 b'user',
3072 b'date',
3072 b'date',
3073 b'currentdate',
3073 b'currentdate',
3074 b'currentuser',
3074 b'currentuser',
3075 b'rev',
3075 b'rev',
3076 ],
3076 ],
3077 )
3077 )
3078 return _stopgraft(ui, repo, graftstate)
3078 return _stopgraft(ui, repo, graftstate)
3079 elif opts.get(b'abort'):
3079 elif opts.get(b'abort'):
3080 cmdutil.check_incompatible_arguments(
3080 cmdutil.check_incompatible_arguments(
3081 opts,
3081 opts,
3082 b'abort',
3082 b'abort',
3083 [
3083 [
3084 b'edit',
3084 b'edit',
3085 b'log',
3085 b'log',
3086 b'user',
3086 b'user',
3087 b'date',
3087 b'date',
3088 b'currentdate',
3088 b'currentdate',
3089 b'currentuser',
3089 b'currentuser',
3090 b'rev',
3090 b'rev',
3091 ],
3091 ],
3092 )
3092 )
3093 return cmdutil.abortgraft(ui, repo, graftstate)
3093 return cmdutil.abortgraft(ui, repo, graftstate)
3094 elif opts.get(b'continue'):
3094 elif opts.get(b'continue'):
3095 cont = True
3095 cont = True
3096 if revs:
3096 if revs:
3097 raise error.InputError(_(b"can't specify --continue and revisions"))
3097 raise error.InputError(_(b"can't specify --continue and revisions"))
3098 # read in unfinished revisions
3098 # read in unfinished revisions
3099 if graftstate.exists():
3099 if graftstate.exists():
3100 statedata = cmdutil.readgraftstate(repo, graftstate)
3100 statedata = cmdutil.readgraftstate(repo, graftstate)
3101 if statedata.get(b'date'):
3101 if statedata.get(b'date'):
3102 opts[b'date'] = statedata[b'date']
3102 opts[b'date'] = statedata[b'date']
3103 if statedata.get(b'user'):
3103 if statedata.get(b'user'):
3104 opts[b'user'] = statedata[b'user']
3104 opts[b'user'] = statedata[b'user']
3105 if statedata.get(b'log'):
3105 if statedata.get(b'log'):
3106 opts[b'log'] = True
3106 opts[b'log'] = True
3107 if statedata.get(b'no_commit'):
3107 if statedata.get(b'no_commit'):
3108 opts[b'no_commit'] = statedata.get(b'no_commit')
3108 opts[b'no_commit'] = statedata.get(b'no_commit')
3109 if statedata.get(b'base'):
3109 if statedata.get(b'base'):
3110 opts[b'base'] = statedata.get(b'base')
3110 opts[b'base'] = statedata.get(b'base')
3111 nodes = statedata[b'nodes']
3111 nodes = statedata[b'nodes']
3112 revs = [repo[node].rev() for node in nodes]
3112 revs = [repo[node].rev() for node in nodes]
3113 else:
3113 else:
3114 cmdutil.wrongtooltocontinue(repo, _(b'graft'))
3114 cmdutil.wrongtooltocontinue(repo, _(b'graft'))
3115 else:
3115 else:
3116 if not revs:
3116 if not revs:
3117 raise error.InputError(_(b'no revisions specified'))
3117 raise error.InputError(_(b'no revisions specified'))
3118 cmdutil.checkunfinished(repo)
3118 cmdutil.checkunfinished(repo)
3119 cmdutil.bailifchanged(repo)
3119 cmdutil.bailifchanged(repo)
3120 revs = scmutil.revrange(repo, revs)
3120 revs = scmutil.revrange(repo, revs)
3121
3121
3122 skipped = set()
3122 skipped = set()
3123 basectx = None
3123 basectx = None
3124 if opts.get(b'base'):
3124 if opts.get(b'base'):
3125 basectx = scmutil.revsingle(repo, opts[b'base'], None)
3125 basectx = scmutil.revsingle(repo, opts[b'base'], None)
3126 if basectx is None:
3126 if basectx is None:
3127 # check for merges
3127 # check for merges
3128 for rev in repo.revs(b'%ld and merge()', revs):
3128 for rev in repo.revs(b'%ld and merge()', revs):
3129 ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev)
3129 ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev)
3130 skipped.add(rev)
3130 skipped.add(rev)
3131 revs = [r for r in revs if r not in skipped]
3131 revs = [r for r in revs if r not in skipped]
3132 if not revs:
3132 if not revs:
3133 return -1
3133 return -1
3134 if basectx is not None and len(revs) != 1:
3134 if basectx is not None and len(revs) != 1:
3135 raise error.InputError(_(b'only one revision allowed with --base '))
3135 raise error.InputError(_(b'only one revision allowed with --base '))
3136
3136
3137 # Don't check in the --continue case, in effect retaining --force across
3137 # Don't check in the --continue case, in effect retaining --force across
3138 # --continues. That's because without --force, any revisions we decided to
3138 # --continues. That's because without --force, any revisions we decided to
3139 # skip would have been filtered out here, so they wouldn't have made their
3139 # skip would have been filtered out here, so they wouldn't have made their
3140 # way to the graftstate. With --force, any revisions we would have otherwise
3140 # way to the graftstate. With --force, any revisions we would have otherwise
3141 # skipped would not have been filtered out, and if they hadn't been applied
3141 # skipped would not have been filtered out, and if they hadn't been applied
3142 # already, they'd have been in the graftstate.
3142 # already, they'd have been in the graftstate.
3143 if not (cont or opts.get(b'force')) and basectx is None:
3143 if not (cont or opts.get(b'force')) and basectx is None:
3144 # check for ancestors of dest branch
3144 # check for ancestors of dest branch
3145 ancestors = repo.revs(b'%ld & (::.)', revs)
3145 ancestors = repo.revs(b'%ld & (::.)', revs)
3146 for rev in ancestors:
3146 for rev in ancestors:
3147 ui.warn(_(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev]))
3147 ui.warn(_(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev]))
3148
3148
3149 revs = [r for r in revs if r not in ancestors]
3149 revs = [r for r in revs if r not in ancestors]
3150
3150
3151 if not revs:
3151 if not revs:
3152 return -1
3152 return -1
3153
3153
3154 # analyze revs for earlier grafts
3154 # analyze revs for earlier grafts
3155 ids = {}
3155 ids = {}
3156 for ctx in repo.set(b"%ld", revs):
3156 for ctx in repo.set(b"%ld", revs):
3157 ids[ctx.hex()] = ctx.rev()
3157 ids[ctx.hex()] = ctx.rev()
3158 n = ctx.extra().get(b'source')
3158 n = ctx.extra().get(b'source')
3159 if n:
3159 if n:
3160 ids[n] = ctx.rev()
3160 ids[n] = ctx.rev()
3161
3161
3162 # check ancestors for earlier grafts
3162 # check ancestors for earlier grafts
3163 ui.debug(b'scanning for duplicate grafts\n')
3163 ui.debug(b'scanning for duplicate grafts\n')
3164
3164
3165 # The only changesets we can be sure doesn't contain grafts of any
3165 # The only changesets we can be sure doesn't contain grafts of any
3166 # revs, are the ones that are common ancestors of *all* revs:
3166 # revs, are the ones that are common ancestors of *all* revs:
3167 for rev in repo.revs(b'only(%d,ancestor(%ld))', repo[b'.'].rev(), revs):
3167 for rev in repo.revs(b'only(%d,ancestor(%ld))', repo[b'.'].rev(), revs):
3168 ctx = repo[rev]
3168 ctx = repo[rev]
3169 n = ctx.extra().get(b'source')
3169 n = ctx.extra().get(b'source')
3170 if n in ids:
3170 if n in ids:
3171 try:
3171 try:
3172 r = repo[n].rev()
3172 r = repo[n].rev()
3173 except error.RepoLookupError:
3173 except error.RepoLookupError:
3174 r = None
3174 r = None
3175 if r in revs:
3175 if r in revs:
3176 ui.warn(
3176 ui.warn(
3177 _(
3177 _(
3178 b'skipping revision %d:%s '
3178 b'skipping revision %d:%s '
3179 b'(already grafted to %d:%s)\n'
3179 b'(already grafted to %d:%s)\n'
3180 )
3180 )
3181 % (r, repo[r], rev, ctx)
3181 % (r, repo[r], rev, ctx)
3182 )
3182 )
3183 revs.remove(r)
3183 revs.remove(r)
3184 elif ids[n] in revs:
3184 elif ids[n] in revs:
3185 if r is None:
3185 if r is None:
3186 ui.warn(
3186 ui.warn(
3187 _(
3187 _(
3188 b'skipping already grafted revision %d:%s '
3188 b'skipping already grafted revision %d:%s '
3189 b'(%d:%s also has unknown origin %s)\n'
3189 b'(%d:%s also has unknown origin %s)\n'
3190 )
3190 )
3191 % (ids[n], repo[ids[n]], rev, ctx, n[:12])
3191 % (ids[n], repo[ids[n]], rev, ctx, n[:12])
3192 )
3192 )
3193 else:
3193 else:
3194 ui.warn(
3194 ui.warn(
3195 _(
3195 _(
3196 b'skipping already grafted revision %d:%s '
3196 b'skipping already grafted revision %d:%s '
3197 b'(%d:%s also has origin %d:%s)\n'
3197 b'(%d:%s also has origin %d:%s)\n'
3198 )
3198 )
3199 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
3199 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
3200 )
3200 )
3201 revs.remove(ids[n])
3201 revs.remove(ids[n])
3202 elif ctx.hex() in ids:
3202 elif ctx.hex() in ids:
3203 r = ids[ctx.hex()]
3203 r = ids[ctx.hex()]
3204 if r in revs:
3204 if r in revs:
3205 ui.warn(
3205 ui.warn(
3206 _(
3206 _(
3207 b'skipping already grafted revision %d:%s '
3207 b'skipping already grafted revision %d:%s '
3208 b'(was grafted from %d:%s)\n'
3208 b'(was grafted from %d:%s)\n'
3209 )
3209 )
3210 % (r, repo[r], rev, ctx)
3210 % (r, repo[r], rev, ctx)
3211 )
3211 )
3212 revs.remove(r)
3212 revs.remove(r)
3213 if not revs:
3213 if not revs:
3214 return -1
3214 return -1
3215
3215
3216 if opts.get(b'no_commit'):
3216 if opts.get(b'no_commit'):
3217 statedata[b'no_commit'] = True
3217 statedata[b'no_commit'] = True
3218 if opts.get(b'base'):
3218 if opts.get(b'base'):
3219 statedata[b'base'] = opts[b'base']
3219 statedata[b'base'] = opts[b'base']
3220 for pos, ctx in enumerate(repo.set(b"%ld", revs)):
3220 for pos, ctx in enumerate(repo.set(b"%ld", revs)):
3221 desc = b'%d:%s "%s"' % (
3221 desc = b'%d:%s "%s"' % (
3222 ctx.rev(),
3222 ctx.rev(),
3223 ctx,
3223 ctx,
3224 ctx.description().split(b'\n', 1)[0],
3224 ctx.description().split(b'\n', 1)[0],
3225 )
3225 )
3226 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3226 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3227 if names:
3227 if names:
3228 desc += b' (%s)' % b' '.join(names)
3228 desc += b' (%s)' % b' '.join(names)
3229 ui.status(_(b'grafting %s\n') % desc)
3229 ui.status(_(b'grafting %s\n') % desc)
3230 if opts.get(b'dry_run'):
3230 if opts.get(b'dry_run'):
3231 continue
3231 continue
3232
3232
3233 source = ctx.extra().get(b'source')
3233 source = ctx.extra().get(b'source')
3234 extra = {}
3234 extra = {}
3235 if source:
3235 if source:
3236 extra[b'source'] = source
3236 extra[b'source'] = source
3237 extra[b'intermediate-source'] = ctx.hex()
3237 extra[b'intermediate-source'] = ctx.hex()
3238 else:
3238 else:
3239 extra[b'source'] = ctx.hex()
3239 extra[b'source'] = ctx.hex()
3240 user = ctx.user()
3240 user = ctx.user()
3241 if opts.get(b'user'):
3241 if opts.get(b'user'):
3242 user = opts[b'user']
3242 user = opts[b'user']
3243 statedata[b'user'] = user
3243 statedata[b'user'] = user
3244 date = ctx.date()
3244 date = ctx.date()
3245 if opts.get(b'date'):
3245 if opts.get(b'date'):
3246 date = opts[b'date']
3246 date = opts[b'date']
3247 statedata[b'date'] = date
3247 statedata[b'date'] = date
3248 message = ctx.description()
3248 message = ctx.description()
3249 if opts.get(b'log'):
3249 if opts.get(b'log'):
3250 message += b'\n(grafted from %s)' % ctx.hex()
3250 message += b'\n(grafted from %s)' % ctx.hex()
3251 statedata[b'log'] = True
3251 statedata[b'log'] = True
3252
3252
3253 # we don't merge the first commit when continuing
3253 # we don't merge the first commit when continuing
3254 if not cont:
3254 if not cont:
3255 # perform the graft merge with p1(rev) as 'ancestor'
3255 # perform the graft merge with p1(rev) as 'ancestor'
3256 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
3256 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
3257 base = ctx.p1() if basectx is None else basectx
3257 base = ctx.p1() if basectx is None else basectx
3258 with ui.configoverride(overrides, b'graft'):
3258 with ui.configoverride(overrides, b'graft'):
3259 stats = mergemod.graft(repo, ctx, base, [b'local', b'graft'])
3259 stats = mergemod.graft(repo, ctx, base, [b'local', b'graft'])
3260 # report any conflicts
3260 # report any conflicts
3261 if stats.unresolvedcount > 0:
3261 if stats.unresolvedcount > 0:
3262 # write out state for --continue
3262 # write out state for --continue
3263 nodes = [repo[rev].hex() for rev in revs[pos:]]
3263 nodes = [repo[rev].hex() for rev in revs[pos:]]
3264 statedata[b'nodes'] = nodes
3264 statedata[b'nodes'] = nodes
3265 stateversion = 1
3265 stateversion = 1
3266 graftstate.save(stateversion, statedata)
3266 graftstate.save(stateversion, statedata)
3267 ui.error(_(b"abort: unresolved conflicts, can't continue\n"))
3267 ui.error(_(b"abort: unresolved conflicts, can't continue\n"))
3268 ui.error(_(b"(use 'hg resolve' and 'hg graft --continue')\n"))
3268 ui.error(_(b"(use 'hg resolve' and 'hg graft --continue')\n"))
3269 return 1
3269 return 1
3270 else:
3270 else:
3271 cont = False
3271 cont = False
3272
3272
3273 # commit if --no-commit is false
3273 # commit if --no-commit is false
3274 if not opts.get(b'no_commit'):
3274 if not opts.get(b'no_commit'):
3275 node = repo.commit(
3275 node = repo.commit(
3276 text=message, user=user, date=date, extra=extra, editor=editor
3276 text=message, user=user, date=date, extra=extra, editor=editor
3277 )
3277 )
3278 if node is None:
3278 if node is None:
3279 ui.warn(
3279 ui.warn(
3280 _(b'note: graft of %d:%s created no changes to commit\n')
3280 _(b'note: graft of %d:%s created no changes to commit\n')
3281 % (ctx.rev(), ctx)
3281 % (ctx.rev(), ctx)
3282 )
3282 )
3283 # checking that newnodes exist because old state files won't have it
3283 # checking that newnodes exist because old state files won't have it
3284 elif statedata.get(b'newnodes') is not None:
3284 elif statedata.get(b'newnodes') is not None:
3285 statedata[b'newnodes'].append(node)
3285 statedata[b'newnodes'].append(node)
3286
3286
3287 # remove state when we complete successfully
3287 # remove state when we complete successfully
3288 if not opts.get(b'dry_run'):
3288 if not opts.get(b'dry_run'):
3289 graftstate.delete()
3289 graftstate.delete()
3290
3290
3291 return 0
3291 return 0
3292
3292
3293
3293
3294 def _stopgraft(ui, repo, graftstate):
3294 def _stopgraft(ui, repo, graftstate):
3295 """stop the interrupted graft"""
3295 """stop the interrupted graft"""
3296 if not graftstate.exists():
3296 if not graftstate.exists():
3297 raise error.StateError(_(b"no interrupted graft found"))
3297 raise error.StateError(_(b"no interrupted graft found"))
3298 pctx = repo[b'.']
3298 pctx = repo[b'.']
3299 mergemod.clean_update(pctx)
3299 mergemod.clean_update(pctx)
3300 graftstate.delete()
3300 graftstate.delete()
3301 ui.status(_(b"stopped the interrupted graft\n"))
3301 ui.status(_(b"stopped the interrupted graft\n"))
3302 ui.status(_(b"working directory is now at %s\n") % pctx.hex()[:12])
3302 ui.status(_(b"working directory is now at %s\n") % pctx.hex()[:12])
3303 return 0
3303 return 0
3304
3304
3305
3305
3306 statemod.addunfinished(
3306 statemod.addunfinished(
3307 b'graft',
3307 b'graft',
3308 fname=b'graftstate',
3308 fname=b'graftstate',
3309 clearable=True,
3309 clearable=True,
3310 stopflag=True,
3310 stopflag=True,
3311 continueflag=True,
3311 continueflag=True,
3312 abortfunc=cmdutil.hgabortgraft,
3312 abortfunc=cmdutil.hgabortgraft,
3313 cmdhint=_(b"use 'hg graft --continue' or 'hg graft --stop' to stop"),
3313 cmdhint=_(b"use 'hg graft --continue' or 'hg graft --stop' to stop"),
3314 )
3314 )
3315
3315
3316
3316
3317 @command(
3317 @command(
3318 b'grep',
3318 b'grep',
3319 [
3319 [
3320 (b'0', b'print0', None, _(b'end fields with NUL')),
3320 (b'0', b'print0', None, _(b'end fields with NUL')),
3321 (b'', b'all', None, _(b'an alias to --diff (DEPRECATED)')),
3321 (b'', b'all', None, _(b'an alias to --diff (DEPRECATED)')),
3322 (
3322 (
3323 b'',
3323 b'',
3324 b'diff',
3324 b'diff',
3325 None,
3325 None,
3326 _(
3326 _(
3327 b'search revision differences for when the pattern was added '
3327 b'search revision differences for when the pattern was added '
3328 b'or removed'
3328 b'or removed'
3329 ),
3329 ),
3330 ),
3330 ),
3331 (b'a', b'text', None, _(b'treat all files as text')),
3331 (b'a', b'text', None, _(b'treat all files as text')),
3332 (
3332 (
3333 b'f',
3333 b'f',
3334 b'follow',
3334 b'follow',
3335 None,
3335 None,
3336 _(
3336 _(
3337 b'follow changeset history,'
3337 b'follow changeset history,'
3338 b' or file history across copies and renames'
3338 b' or file history across copies and renames'
3339 ),
3339 ),
3340 ),
3340 ),
3341 (b'i', b'ignore-case', None, _(b'ignore case when matching')),
3341 (b'i', b'ignore-case', None, _(b'ignore case when matching')),
3342 (
3342 (
3343 b'l',
3343 b'l',
3344 b'files-with-matches',
3344 b'files-with-matches',
3345 None,
3345 None,
3346 _(b'print only filenames and revisions that match'),
3346 _(b'print only filenames and revisions that match'),
3347 ),
3347 ),
3348 (b'n', b'line-number', None, _(b'print matching line numbers')),
3348 (b'n', b'line-number', None, _(b'print matching line numbers')),
3349 (
3349 (
3350 b'r',
3350 b'r',
3351 b'rev',
3351 b'rev',
3352 [],
3352 [],
3353 _(b'search files changed within revision range'),
3353 _(b'search files changed within revision range'),
3354 _(b'REV'),
3354 _(b'REV'),
3355 ),
3355 ),
3356 (
3356 (
3357 b'',
3357 b'',
3358 b'all-files',
3358 b'all-files',
3359 None,
3359 None,
3360 _(
3360 _(
3361 b'include all files in the changeset while grepping (DEPRECATED)'
3361 b'include all files in the changeset while grepping (DEPRECATED)'
3362 ),
3362 ),
3363 ),
3363 ),
3364 (b'u', b'user', None, _(b'list the author (long with -v)')),
3364 (b'u', b'user', None, _(b'list the author (long with -v)')),
3365 (b'd', b'date', None, _(b'list the date (short with -q)')),
3365 (b'd', b'date', None, _(b'list the date (short with -q)')),
3366 ]
3366 ]
3367 + formatteropts
3367 + formatteropts
3368 + walkopts,
3368 + walkopts,
3369 _(b'[--diff] [OPTION]... PATTERN [FILE]...'),
3369 _(b'[--diff] [OPTION]... PATTERN [FILE]...'),
3370 helpcategory=command.CATEGORY_FILE_CONTENTS,
3370 helpcategory=command.CATEGORY_FILE_CONTENTS,
3371 inferrepo=True,
3371 inferrepo=True,
3372 intents={INTENT_READONLY},
3372 intents={INTENT_READONLY},
3373 )
3373 )
3374 def grep(ui, repo, pattern, *pats, **opts):
3374 def grep(ui, repo, pattern, *pats, **opts):
3375 """search for a pattern in specified files
3375 """search for a pattern in specified files
3376
3376
3377 Search the working directory or revision history for a regular
3377 Search the working directory or revision history for a regular
3378 expression in the specified files for the entire repository.
3378 expression in the specified files for the entire repository.
3379
3379
3380 By default, grep searches the repository files in the working
3380 By default, grep searches the repository files in the working
3381 directory and prints the files where it finds a match. To specify
3381 directory and prints the files where it finds a match. To specify
3382 historical revisions instead of the working directory, use the
3382 historical revisions instead of the working directory, use the
3383 --rev flag.
3383 --rev flag.
3384
3384
3385 To search instead historical revision differences that contains a
3385 To search instead historical revision differences that contains a
3386 change in match status ("-" for a match that becomes a non-match,
3386 change in match status ("-" for a match that becomes a non-match,
3387 or "+" for a non-match that becomes a match), use the --diff flag.
3387 or "+" for a non-match that becomes a match), use the --diff flag.
3388
3388
3389 PATTERN can be any Python (roughly Perl-compatible) regular
3389 PATTERN can be any Python (roughly Perl-compatible) regular
3390 expression.
3390 expression.
3391
3391
3392 If no FILEs are specified and the --rev flag isn't supplied, all
3392 If no FILEs are specified and the --rev flag isn't supplied, all
3393 files in the working directory are searched. When using the --rev
3393 files in the working directory are searched. When using the --rev
3394 flag and specifying FILEs, use the --follow argument to also
3394 flag and specifying FILEs, use the --follow argument to also
3395 follow the specified FILEs across renames and copies.
3395 follow the specified FILEs across renames and copies.
3396
3396
3397 .. container:: verbose
3397 .. container:: verbose
3398
3398
3399 Template:
3399 Template:
3400
3400
3401 The following keywords are supported in addition to the common template
3401 The following keywords are supported in addition to the common template
3402 keywords and functions. See also :hg:`help templates`.
3402 keywords and functions. See also :hg:`help templates`.
3403
3403
3404 :change: String. Character denoting insertion ``+`` or removal ``-``.
3404 :change: String. Character denoting insertion ``+`` or removal ``-``.
3405 Available if ``--diff`` is specified.
3405 Available if ``--diff`` is specified.
3406 :lineno: Integer. Line number of the match.
3406 :lineno: Integer. Line number of the match.
3407 :path: String. Repository-absolute path of the file.
3407 :path: String. Repository-absolute path of the file.
3408 :texts: List of text chunks.
3408 :texts: List of text chunks.
3409
3409
3410 And each entry of ``{texts}`` provides the following sub-keywords.
3410 And each entry of ``{texts}`` provides the following sub-keywords.
3411
3411
3412 :matched: Boolean. True if the chunk matches the specified pattern.
3412 :matched: Boolean. True if the chunk matches the specified pattern.
3413 :text: String. Chunk content.
3413 :text: String. Chunk content.
3414
3414
3415 See :hg:`help templates.operators` for the list expansion syntax.
3415 See :hg:`help templates.operators` for the list expansion syntax.
3416
3416
3417 Returns 0 if a match is found, 1 otherwise.
3417 Returns 0 if a match is found, 1 otherwise.
3418
3418
3419 """
3419 """
3420 cmdutil.check_incompatible_arguments(opts, 'all_files', ['all', 'diff'])
3420 cmdutil.check_incompatible_arguments(opts, 'all_files', ['all', 'diff'])
3421 opts = pycompat.byteskwargs(opts)
3421 opts = pycompat.byteskwargs(opts)
3422 diff = opts.get(b'all') or opts.get(b'diff')
3422 diff = opts.get(b'all') or opts.get(b'diff')
3423 follow = opts.get(b'follow')
3423 follow = opts.get(b'follow')
3424 if opts.get(b'all_files') is None and not diff:
3424 if opts.get(b'all_files') is None and not diff:
3425 opts[b'all_files'] = True
3425 opts[b'all_files'] = True
3426 plaingrep = (
3426 plaingrep = (
3427 opts.get(b'all_files')
3427 opts.get(b'all_files')
3428 and not opts.get(b'rev')
3428 and not opts.get(b'rev')
3429 and not opts.get(b'follow')
3429 and not opts.get(b'follow')
3430 )
3430 )
3431 all_files = opts.get(b'all_files')
3431 all_files = opts.get(b'all_files')
3432 if plaingrep:
3432 if plaingrep:
3433 opts[b'rev'] = [b'wdir()']
3433 opts[b'rev'] = [b'wdir()']
3434
3434
3435 reflags = re.M
3435 reflags = re.M
3436 if opts.get(b'ignore_case'):
3436 if opts.get(b'ignore_case'):
3437 reflags |= re.I
3437 reflags |= re.I
3438 try:
3438 try:
3439 regexp = util.re.compile(pattern, reflags)
3439 regexp = util.re.compile(pattern, reflags)
3440 except re.error as inst:
3440 except re.error as inst:
3441 ui.warn(
3441 ui.warn(
3442 _(b"grep: invalid match pattern: %s\n") % pycompat.bytestr(inst)
3442 _(b"grep: invalid match pattern: %s\n") % pycompat.bytestr(inst)
3443 )
3443 )
3444 return 1
3444 return 1
3445 sep, eol = b':', b'\n'
3445 sep, eol = b':', b'\n'
3446 if opts.get(b'print0'):
3446 if opts.get(b'print0'):
3447 sep = eol = b'\0'
3447 sep = eol = b'\0'
3448
3448
3449 searcher = grepmod.grepsearcher(
3449 searcher = grepmod.grepsearcher(
3450 ui, repo, regexp, all_files=all_files, diff=diff, follow=follow
3450 ui, repo, regexp, all_files=all_files, diff=diff, follow=follow
3451 )
3451 )
3452
3452
3453 getfile = searcher._getfile
3453 getfile = searcher._getfile
3454
3454
3455 uipathfn = scmutil.getuipathfn(repo)
3455 uipathfn = scmutil.getuipathfn(repo)
3456
3456
3457 def display(fm, fn, ctx, pstates, states):
3457 def display(fm, fn, ctx, pstates, states):
3458 rev = scmutil.intrev(ctx)
3458 rev = scmutil.intrev(ctx)
3459 if fm.isplain():
3459 if fm.isplain():
3460 formatuser = ui.shortuser
3460 formatuser = ui.shortuser
3461 else:
3461 else:
3462 formatuser = pycompat.bytestr
3462 formatuser = pycompat.bytestr
3463 if ui.quiet:
3463 if ui.quiet:
3464 datefmt = b'%Y-%m-%d'
3464 datefmt = b'%Y-%m-%d'
3465 else:
3465 else:
3466 datefmt = b'%a %b %d %H:%M:%S %Y %1%2'
3466 datefmt = b'%a %b %d %H:%M:%S %Y %1%2'
3467 found = False
3467 found = False
3468
3468
3469 @util.cachefunc
3469 @util.cachefunc
3470 def binary():
3470 def binary():
3471 flog = getfile(fn)
3471 flog = getfile(fn)
3472 try:
3472 try:
3473 return stringutil.binary(flog.read(ctx.filenode(fn)))
3473 return stringutil.binary(flog.read(ctx.filenode(fn)))
3474 except error.WdirUnsupported:
3474 except error.WdirUnsupported:
3475 return ctx[fn].isbinary()
3475 return ctx[fn].isbinary()
3476
3476
3477 fieldnamemap = {b'linenumber': b'lineno'}
3477 fieldnamemap = {b'linenumber': b'lineno'}
3478 if diff:
3478 if diff:
3479 iter = grepmod.difflinestates(pstates, states)
3479 iter = grepmod.difflinestates(pstates, states)
3480 else:
3480 else:
3481 iter = [(b'', l) for l in states]
3481 iter = [(b'', l) for l in states]
3482 for change, l in iter:
3482 for change, l in iter:
3483 fm.startitem()
3483 fm.startitem()
3484 fm.context(ctx=ctx)
3484 fm.context(ctx=ctx)
3485 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
3485 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
3486 fm.plain(uipathfn(fn), label=b'grep.filename')
3486 fm.plain(uipathfn(fn), label=b'grep.filename')
3487
3487
3488 cols = [
3488 cols = [
3489 (b'rev', b'%d', rev, not plaingrep, b''),
3489 (b'rev', b'%d', rev, not plaingrep, b''),
3490 (
3490 (
3491 b'linenumber',
3491 b'linenumber',
3492 b'%d',
3492 b'%d',
3493 l.linenum,
3493 l.linenum,
3494 opts.get(b'line_number'),
3494 opts.get(b'line_number'),
3495 b'',
3495 b'',
3496 ),
3496 ),
3497 ]
3497 ]
3498 if diff:
3498 if diff:
3499 cols.append(
3499 cols.append(
3500 (
3500 (
3501 b'change',
3501 b'change',
3502 b'%s',
3502 b'%s',
3503 change,
3503 change,
3504 True,
3504 True,
3505 b'grep.inserted '
3505 b'grep.inserted '
3506 if change == b'+'
3506 if change == b'+'
3507 else b'grep.deleted ',
3507 else b'grep.deleted ',
3508 )
3508 )
3509 )
3509 )
3510 cols.extend(
3510 cols.extend(
3511 [
3511 [
3512 (
3512 (
3513 b'user',
3513 b'user',
3514 b'%s',
3514 b'%s',
3515 formatuser(ctx.user()),
3515 formatuser(ctx.user()),
3516 opts.get(b'user'),
3516 opts.get(b'user'),
3517 b'',
3517 b'',
3518 ),
3518 ),
3519 (
3519 (
3520 b'date',
3520 b'date',
3521 b'%s',
3521 b'%s',
3522 fm.formatdate(ctx.date(), datefmt),
3522 fm.formatdate(ctx.date(), datefmt),
3523 opts.get(b'date'),
3523 opts.get(b'date'),
3524 b'',
3524 b'',
3525 ),
3525 ),
3526 ]
3526 ]
3527 )
3527 )
3528 for name, fmt, data, cond, extra_label in cols:
3528 for name, fmt, data, cond, extra_label in cols:
3529 if cond:
3529 if cond:
3530 fm.plain(sep, label=b'grep.sep')
3530 fm.plain(sep, label=b'grep.sep')
3531 field = fieldnamemap.get(name, name)
3531 field = fieldnamemap.get(name, name)
3532 label = extra_label + (b'grep.%s' % name)
3532 label = extra_label + (b'grep.%s' % name)
3533 fm.condwrite(cond, field, fmt, data, label=label)
3533 fm.condwrite(cond, field, fmt, data, label=label)
3534 if not opts.get(b'files_with_matches'):
3534 if not opts.get(b'files_with_matches'):
3535 fm.plain(sep, label=b'grep.sep')
3535 fm.plain(sep, label=b'grep.sep')
3536 if not opts.get(b'text') and binary():
3536 if not opts.get(b'text') and binary():
3537 fm.plain(_(b" Binary file matches"))
3537 fm.plain(_(b" Binary file matches"))
3538 else:
3538 else:
3539 displaymatches(fm.nested(b'texts', tmpl=b'{text}'), l)
3539 displaymatches(fm.nested(b'texts', tmpl=b'{text}'), l)
3540 fm.plain(eol)
3540 fm.plain(eol)
3541 found = True
3541 found = True
3542 if opts.get(b'files_with_matches'):
3542 if opts.get(b'files_with_matches'):
3543 break
3543 break
3544 return found
3544 return found
3545
3545
3546 def displaymatches(fm, l):
3546 def displaymatches(fm, l):
3547 p = 0
3547 p = 0
3548 for s, e in l.findpos(regexp):
3548 for s, e in l.findpos(regexp):
3549 if p < s:
3549 if p < s:
3550 fm.startitem()
3550 fm.startitem()
3551 fm.write(b'text', b'%s', l.line[p:s])
3551 fm.write(b'text', b'%s', l.line[p:s])
3552 fm.data(matched=False)
3552 fm.data(matched=False)
3553 fm.startitem()
3553 fm.startitem()
3554 fm.write(b'text', b'%s', l.line[s:e], label=b'grep.match')
3554 fm.write(b'text', b'%s', l.line[s:e], label=b'grep.match')
3555 fm.data(matched=True)
3555 fm.data(matched=True)
3556 p = e
3556 p = e
3557 if p < len(l.line):
3557 if p < len(l.line):
3558 fm.startitem()
3558 fm.startitem()
3559 fm.write(b'text', b'%s', l.line[p:])
3559 fm.write(b'text', b'%s', l.line[p:])
3560 fm.data(matched=False)
3560 fm.data(matched=False)
3561 fm.end()
3561 fm.end()
3562
3562
3563 found = False
3563 found = False
3564
3564
3565 wopts = logcmdutil.walkopts(
3565 wopts = logcmdutil.walkopts(
3566 pats=pats,
3566 pats=pats,
3567 opts=opts,
3567 opts=opts,
3568 revspec=opts[b'rev'],
3568 revspec=opts[b'rev'],
3569 include_pats=opts[b'include'],
3569 include_pats=opts[b'include'],
3570 exclude_pats=opts[b'exclude'],
3570 exclude_pats=opts[b'exclude'],
3571 follow=follow,
3571 follow=follow,
3572 force_changelog_traversal=all_files,
3572 force_changelog_traversal=all_files,
3573 filter_revisions_by_pats=not all_files,
3573 filter_revisions_by_pats=not all_files,
3574 )
3574 )
3575 revs, makefilematcher = logcmdutil.makewalker(repo, wopts)
3575 revs, makefilematcher = logcmdutil.makewalker(repo, wopts)
3576
3576
3577 ui.pager(b'grep')
3577 ui.pager(b'grep')
3578 fm = ui.formatter(b'grep', opts)
3578 fm = ui.formatter(b'grep', opts)
3579 for fn, ctx, pstates, states in searcher.searchfiles(revs, makefilematcher):
3579 for fn, ctx, pstates, states in searcher.searchfiles(revs, makefilematcher):
3580 r = display(fm, fn, ctx, pstates, states)
3580 r = display(fm, fn, ctx, pstates, states)
3581 found = found or r
3581 found = found or r
3582 if r and not diff and not all_files:
3582 if r and not diff and not all_files:
3583 searcher.skipfile(fn, ctx.rev())
3583 searcher.skipfile(fn, ctx.rev())
3584 fm.end()
3584 fm.end()
3585
3585
3586 return not found
3586 return not found
3587
3587
3588
3588
3589 @command(
3589 @command(
3590 b'heads',
3590 b'heads',
3591 [
3591 [
3592 (
3592 (
3593 b'r',
3593 b'r',
3594 b'rev',
3594 b'rev',
3595 b'',
3595 b'',
3596 _(b'show only heads which are descendants of STARTREV'),
3596 _(b'show only heads which are descendants of STARTREV'),
3597 _(b'STARTREV'),
3597 _(b'STARTREV'),
3598 ),
3598 ),
3599 (b't', b'topo', False, _(b'show topological heads only')),
3599 (b't', b'topo', False, _(b'show topological heads only')),
3600 (
3600 (
3601 b'a',
3601 b'a',
3602 b'active',
3602 b'active',
3603 False,
3603 False,
3604 _(b'show active branchheads only (DEPRECATED)'),
3604 _(b'show active branchheads only (DEPRECATED)'),
3605 ),
3605 ),
3606 (b'c', b'closed', False, _(b'show normal and closed branch heads')),
3606 (b'c', b'closed', False, _(b'show normal and closed branch heads')),
3607 ]
3607 ]
3608 + templateopts,
3608 + templateopts,
3609 _(b'[-ct] [-r STARTREV] [REV]...'),
3609 _(b'[-ct] [-r STARTREV] [REV]...'),
3610 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3610 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3611 intents={INTENT_READONLY},
3611 intents={INTENT_READONLY},
3612 )
3612 )
3613 def heads(ui, repo, *branchrevs, **opts):
3613 def heads(ui, repo, *branchrevs, **opts):
3614 """show branch heads
3614 """show branch heads
3615
3615
3616 With no arguments, show all open branch heads in the repository.
3616 With no arguments, show all open branch heads in the repository.
3617 Branch heads are changesets that have no descendants on the
3617 Branch heads are changesets that have no descendants on the
3618 same branch. They are where development generally takes place and
3618 same branch. They are where development generally takes place and
3619 are the usual targets for update and merge operations.
3619 are the usual targets for update and merge operations.
3620
3620
3621 If one or more REVs are given, only open branch heads on the
3621 If one or more REVs are given, only open branch heads on the
3622 branches associated with the specified changesets are shown. This
3622 branches associated with the specified changesets are shown. This
3623 means that you can use :hg:`heads .` to see the heads on the
3623 means that you can use :hg:`heads .` to see the heads on the
3624 currently checked-out branch.
3624 currently checked-out branch.
3625
3625
3626 If -c/--closed is specified, also show branch heads marked closed
3626 If -c/--closed is specified, also show branch heads marked closed
3627 (see :hg:`commit --close-branch`).
3627 (see :hg:`commit --close-branch`).
3628
3628
3629 If STARTREV is specified, only those heads that are descendants of
3629 If STARTREV is specified, only those heads that are descendants of
3630 STARTREV will be displayed.
3630 STARTREV will be displayed.
3631
3631
3632 If -t/--topo is specified, named branch mechanics will be ignored and only
3632 If -t/--topo is specified, named branch mechanics will be ignored and only
3633 topological heads (changesets with no children) will be shown.
3633 topological heads (changesets with no children) will be shown.
3634
3634
3635 Returns 0 if matching heads are found, 1 if not.
3635 Returns 0 if matching heads are found, 1 if not.
3636 """
3636 """
3637
3637
3638 opts = pycompat.byteskwargs(opts)
3638 opts = pycompat.byteskwargs(opts)
3639 start = None
3639 start = None
3640 rev = opts.get(b'rev')
3640 rev = opts.get(b'rev')
3641 if rev:
3641 if rev:
3642 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3642 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3643 start = scmutil.revsingle(repo, rev, None).node()
3643 start = scmutil.revsingle(repo, rev, None).node()
3644
3644
3645 if opts.get(b'topo'):
3645 if opts.get(b'topo'):
3646 heads = [repo[h] for h in repo.heads(start)]
3646 heads = [repo[h] for h in repo.heads(start)]
3647 else:
3647 else:
3648 heads = []
3648 heads = []
3649 for branch in repo.branchmap():
3649 for branch in repo.branchmap():
3650 heads += repo.branchheads(branch, start, opts.get(b'closed'))
3650 heads += repo.branchheads(branch, start, opts.get(b'closed'))
3651 heads = [repo[h] for h in heads]
3651 heads = [repo[h] for h in heads]
3652
3652
3653 if branchrevs:
3653 if branchrevs:
3654 branches = {
3654 branches = {
3655 repo[r].branch() for r in scmutil.revrange(repo, branchrevs)
3655 repo[r].branch() for r in scmutil.revrange(repo, branchrevs)
3656 }
3656 }
3657 heads = [h for h in heads if h.branch() in branches]
3657 heads = [h for h in heads if h.branch() in branches]
3658
3658
3659 if opts.get(b'active') and branchrevs:
3659 if opts.get(b'active') and branchrevs:
3660 dagheads = repo.heads(start)
3660 dagheads = repo.heads(start)
3661 heads = [h for h in heads if h.node() in dagheads]
3661 heads = [h for h in heads if h.node() in dagheads]
3662
3662
3663 if branchrevs:
3663 if branchrevs:
3664 haveheads = {h.branch() for h in heads}
3664 haveheads = {h.branch() for h in heads}
3665 if branches - haveheads:
3665 if branches - haveheads:
3666 headless = b', '.join(b for b in branches - haveheads)
3666 headless = b', '.join(b for b in branches - haveheads)
3667 msg = _(b'no open branch heads found on branches %s')
3667 msg = _(b'no open branch heads found on branches %s')
3668 if opts.get(b'rev'):
3668 if opts.get(b'rev'):
3669 msg += _(b' (started at %s)') % opts[b'rev']
3669 msg += _(b' (started at %s)') % opts[b'rev']
3670 ui.warn((msg + b'\n') % headless)
3670 ui.warn((msg + b'\n') % headless)
3671
3671
3672 if not heads:
3672 if not heads:
3673 return 1
3673 return 1
3674
3674
3675 ui.pager(b'heads')
3675 ui.pager(b'heads')
3676 heads = sorted(heads, key=lambda x: -(x.rev()))
3676 heads = sorted(heads, key=lambda x: -(x.rev()))
3677 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3677 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3678 for ctx in heads:
3678 for ctx in heads:
3679 displayer.show(ctx)
3679 displayer.show(ctx)
3680 displayer.close()
3680 displayer.close()
3681
3681
3682
3682
3683 @command(
3683 @command(
3684 b'help',
3684 b'help',
3685 [
3685 [
3686 (b'e', b'extension', None, _(b'show only help for extensions')),
3686 (b'e', b'extension', None, _(b'show only help for extensions')),
3687 (b'c', b'command', None, _(b'show only help for commands')),
3687 (b'c', b'command', None, _(b'show only help for commands')),
3688 (b'k', b'keyword', None, _(b'show topics matching keyword')),
3688 (b'k', b'keyword', None, _(b'show topics matching keyword')),
3689 (
3689 (
3690 b's',
3690 b's',
3691 b'system',
3691 b'system',
3692 [],
3692 [],
3693 _(b'show help for specific platform(s)'),
3693 _(b'show help for specific platform(s)'),
3694 _(b'PLATFORM'),
3694 _(b'PLATFORM'),
3695 ),
3695 ),
3696 ],
3696 ],
3697 _(b'[-eck] [-s PLATFORM] [TOPIC]'),
3697 _(b'[-eck] [-s PLATFORM] [TOPIC]'),
3698 helpcategory=command.CATEGORY_HELP,
3698 helpcategory=command.CATEGORY_HELP,
3699 norepo=True,
3699 norepo=True,
3700 intents={INTENT_READONLY},
3700 intents={INTENT_READONLY},
3701 )
3701 )
3702 def help_(ui, name=None, **opts):
3702 def help_(ui, name=None, **opts):
3703 """show help for a given topic or a help overview
3703 """show help for a given topic or a help overview
3704
3704
3705 With no arguments, print a list of commands with short help messages.
3705 With no arguments, print a list of commands with short help messages.
3706
3706
3707 Given a topic, extension, or command name, print help for that
3707 Given a topic, extension, or command name, print help for that
3708 topic.
3708 topic.
3709
3709
3710 Returns 0 if successful.
3710 Returns 0 if successful.
3711 """
3711 """
3712
3712
3713 keep = opts.get('system') or []
3713 keep = opts.get('system') or []
3714 if len(keep) == 0:
3714 if len(keep) == 0:
3715 if pycompat.sysplatform.startswith(b'win'):
3715 if pycompat.sysplatform.startswith(b'win'):
3716 keep.append(b'windows')
3716 keep.append(b'windows')
3717 elif pycompat.sysplatform == b'OpenVMS':
3717 elif pycompat.sysplatform == b'OpenVMS':
3718 keep.append(b'vms')
3718 keep.append(b'vms')
3719 elif pycompat.sysplatform == b'plan9':
3719 elif pycompat.sysplatform == b'plan9':
3720 keep.append(b'plan9')
3720 keep.append(b'plan9')
3721 else:
3721 else:
3722 keep.append(b'unix')
3722 keep.append(b'unix')
3723 keep.append(pycompat.sysplatform.lower())
3723 keep.append(pycompat.sysplatform.lower())
3724 if ui.verbose:
3724 if ui.verbose:
3725 keep.append(b'verbose')
3725 keep.append(b'verbose')
3726
3726
3727 commands = sys.modules[__name__]
3727 commands = sys.modules[__name__]
3728 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3728 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3729 ui.pager(b'help')
3729 ui.pager(b'help')
3730 ui.write(formatted)
3730 ui.write(formatted)
3731
3731
3732
3732
3733 @command(
3733 @command(
3734 b'identify|id',
3734 b'identify|id',
3735 [
3735 [
3736 (b'r', b'rev', b'', _(b'identify the specified revision'), _(b'REV')),
3736 (b'r', b'rev', b'', _(b'identify the specified revision'), _(b'REV')),
3737 (b'n', b'num', None, _(b'show local revision number')),
3737 (b'n', b'num', None, _(b'show local revision number')),
3738 (b'i', b'id', None, _(b'show global revision id')),
3738 (b'i', b'id', None, _(b'show global revision id')),
3739 (b'b', b'branch', None, _(b'show branch')),
3739 (b'b', b'branch', None, _(b'show branch')),
3740 (b't', b'tags', None, _(b'show tags')),
3740 (b't', b'tags', None, _(b'show tags')),
3741 (b'B', b'bookmarks', None, _(b'show bookmarks')),
3741 (b'B', b'bookmarks', None, _(b'show bookmarks')),
3742 ]
3742 ]
3743 + remoteopts
3743 + remoteopts
3744 + formatteropts,
3744 + formatteropts,
3745 _(b'[-nibtB] [-r REV] [SOURCE]'),
3745 _(b'[-nibtB] [-r REV] [SOURCE]'),
3746 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3746 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3747 optionalrepo=True,
3747 optionalrepo=True,
3748 intents={INTENT_READONLY},
3748 intents={INTENT_READONLY},
3749 )
3749 )
3750 def identify(
3750 def identify(
3751 ui,
3751 ui,
3752 repo,
3752 repo,
3753 source=None,
3753 source=None,
3754 rev=None,
3754 rev=None,
3755 num=None,
3755 num=None,
3756 id=None,
3756 id=None,
3757 branch=None,
3757 branch=None,
3758 tags=None,
3758 tags=None,
3759 bookmarks=None,
3759 bookmarks=None,
3760 **opts
3760 **opts
3761 ):
3761 ):
3762 """identify the working directory or specified revision
3762 """identify the working directory or specified revision
3763
3763
3764 Print a summary identifying the repository state at REV using one or
3764 Print a summary identifying the repository state at REV using one or
3765 two parent hash identifiers, followed by a "+" if the working
3765 two parent hash identifiers, followed by a "+" if the working
3766 directory has uncommitted changes, the branch name (if not default),
3766 directory has uncommitted changes, the branch name (if not default),
3767 a list of tags, and a list of bookmarks.
3767 a list of tags, and a list of bookmarks.
3768
3768
3769 When REV is not given, print a summary of the current state of the
3769 When REV is not given, print a summary of the current state of the
3770 repository including the working directory. Specify -r. to get information
3770 repository including the working directory. Specify -r. to get information
3771 of the working directory parent without scanning uncommitted changes.
3771 of the working directory parent without scanning uncommitted changes.
3772
3772
3773 Specifying a path to a repository root or Mercurial bundle will
3773 Specifying a path to a repository root or Mercurial bundle will
3774 cause lookup to operate on that repository/bundle.
3774 cause lookup to operate on that repository/bundle.
3775
3775
3776 .. container:: verbose
3776 .. container:: verbose
3777
3777
3778 Template:
3778 Template:
3779
3779
3780 The following keywords are supported in addition to the common template
3780 The following keywords are supported in addition to the common template
3781 keywords and functions. See also :hg:`help templates`.
3781 keywords and functions. See also :hg:`help templates`.
3782
3782
3783 :dirty: String. Character ``+`` denoting if the working directory has
3783 :dirty: String. Character ``+`` denoting if the working directory has
3784 uncommitted changes.
3784 uncommitted changes.
3785 :id: String. One or two nodes, optionally followed by ``+``.
3785 :id: String. One or two nodes, optionally followed by ``+``.
3786 :parents: List of strings. Parent nodes of the changeset.
3786 :parents: List of strings. Parent nodes of the changeset.
3787
3787
3788 Examples:
3788 Examples:
3789
3789
3790 - generate a build identifier for the working directory::
3790 - generate a build identifier for the working directory::
3791
3791
3792 hg id --id > build-id.dat
3792 hg id --id > build-id.dat
3793
3793
3794 - find the revision corresponding to a tag::
3794 - find the revision corresponding to a tag::
3795
3795
3796 hg id -n -r 1.3
3796 hg id -n -r 1.3
3797
3797
3798 - check the most recent revision of a remote repository::
3798 - check the most recent revision of a remote repository::
3799
3799
3800 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3800 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3801
3801
3802 See :hg:`log` for generating more information about specific revisions,
3802 See :hg:`log` for generating more information about specific revisions,
3803 including full hash identifiers.
3803 including full hash identifiers.
3804
3804
3805 Returns 0 if successful.
3805 Returns 0 if successful.
3806 """
3806 """
3807
3807
3808 opts = pycompat.byteskwargs(opts)
3808 opts = pycompat.byteskwargs(opts)
3809 if not repo and not source:
3809 if not repo and not source:
3810 raise error.InputError(
3810 raise error.InputError(
3811 _(b"there is no Mercurial repository here (.hg not found)")
3811 _(b"there is no Mercurial repository here (.hg not found)")
3812 )
3812 )
3813
3813
3814 default = not (num or id or branch or tags or bookmarks)
3814 default = not (num or id or branch or tags or bookmarks)
3815 output = []
3815 output = []
3816 revs = []
3816 revs = []
3817
3817
3818 if source:
3818 if source:
3819 source, branches = hg.parseurl(ui.expandpath(source))
3819 source, branches = hg.parseurl(ui.expandpath(source))
3820 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3820 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3821 repo = peer.local()
3821 repo = peer.local()
3822 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3822 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3823
3823
3824 fm = ui.formatter(b'identify', opts)
3824 fm = ui.formatter(b'identify', opts)
3825 fm.startitem()
3825 fm.startitem()
3826
3826
3827 if not repo:
3827 if not repo:
3828 if num or branch or tags:
3828 if num or branch or tags:
3829 raise error.InputError(
3829 raise error.InputError(
3830 _(b"can't query remote revision number, branch, or tags")
3830 _(b"can't query remote revision number, branch, or tags")
3831 )
3831 )
3832 if not rev and revs:
3832 if not rev and revs:
3833 rev = revs[0]
3833 rev = revs[0]
3834 if not rev:
3834 if not rev:
3835 rev = b"tip"
3835 rev = b"tip"
3836
3836
3837 remoterev = peer.lookup(rev)
3837 remoterev = peer.lookup(rev)
3838 hexrev = fm.hexfunc(remoterev)
3838 hexrev = fm.hexfunc(remoterev)
3839 if default or id:
3839 if default or id:
3840 output = [hexrev]
3840 output = [hexrev]
3841 fm.data(id=hexrev)
3841 fm.data(id=hexrev)
3842
3842
3843 @util.cachefunc
3843 @util.cachefunc
3844 def getbms():
3844 def getbms():
3845 bms = []
3845 bms = []
3846
3846
3847 if b'bookmarks' in peer.listkeys(b'namespaces'):
3847 if b'bookmarks' in peer.listkeys(b'namespaces'):
3848 hexremoterev = hex(remoterev)
3848 hexremoterev = hex(remoterev)
3849 bms = [
3849 bms = [
3850 bm
3850 bm
3851 for bm, bmr in pycompat.iteritems(
3851 for bm, bmr in pycompat.iteritems(
3852 peer.listkeys(b'bookmarks')
3852 peer.listkeys(b'bookmarks')
3853 )
3853 )
3854 if bmr == hexremoterev
3854 if bmr == hexremoterev
3855 ]
3855 ]
3856
3856
3857 return sorted(bms)
3857 return sorted(bms)
3858
3858
3859 if fm.isplain():
3859 if fm.isplain():
3860 if bookmarks:
3860 if bookmarks:
3861 output.extend(getbms())
3861 output.extend(getbms())
3862 elif default and not ui.quiet:
3862 elif default and not ui.quiet:
3863 # multiple bookmarks for a single parent separated by '/'
3863 # multiple bookmarks for a single parent separated by '/'
3864 bm = b'/'.join(getbms())
3864 bm = b'/'.join(getbms())
3865 if bm:
3865 if bm:
3866 output.append(bm)
3866 output.append(bm)
3867 else:
3867 else:
3868 fm.data(node=hex(remoterev))
3868 fm.data(node=hex(remoterev))
3869 if bookmarks or b'bookmarks' in fm.datahint():
3869 if bookmarks or b'bookmarks' in fm.datahint():
3870 fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
3870 fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
3871 else:
3871 else:
3872 if rev:
3872 if rev:
3873 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3873 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3874 ctx = scmutil.revsingle(repo, rev, None)
3874 ctx = scmutil.revsingle(repo, rev, None)
3875
3875
3876 if ctx.rev() is None:
3876 if ctx.rev() is None:
3877 ctx = repo[None]
3877 ctx = repo[None]
3878 parents = ctx.parents()
3878 parents = ctx.parents()
3879 taglist = []
3879 taglist = []
3880 for p in parents:
3880 for p in parents:
3881 taglist.extend(p.tags())
3881 taglist.extend(p.tags())
3882
3882
3883 dirty = b""
3883 dirty = b""
3884 if ctx.dirty(missing=True, merge=False, branch=False):
3884 if ctx.dirty(missing=True, merge=False, branch=False):
3885 dirty = b'+'
3885 dirty = b'+'
3886 fm.data(dirty=dirty)
3886 fm.data(dirty=dirty)
3887
3887
3888 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3888 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3889 if default or id:
3889 if default or id:
3890 output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
3890 output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
3891 fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
3891 fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
3892
3892
3893 if num:
3893 if num:
3894 numoutput = [b"%d" % p.rev() for p in parents]
3894 numoutput = [b"%d" % p.rev() for p in parents]
3895 output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
3895 output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
3896
3896
3897 fm.data(
3897 fm.data(
3898 parents=fm.formatlist(
3898 parents=fm.formatlist(
3899 [fm.hexfunc(p.node()) for p in parents], name=b'node'
3899 [fm.hexfunc(p.node()) for p in parents], name=b'node'
3900 )
3900 )
3901 )
3901 )
3902 else:
3902 else:
3903 hexoutput = fm.hexfunc(ctx.node())
3903 hexoutput = fm.hexfunc(ctx.node())
3904 if default or id:
3904 if default or id:
3905 output = [hexoutput]
3905 output = [hexoutput]
3906 fm.data(id=hexoutput)
3906 fm.data(id=hexoutput)
3907
3907
3908 if num:
3908 if num:
3909 output.append(pycompat.bytestr(ctx.rev()))
3909 output.append(pycompat.bytestr(ctx.rev()))
3910 taglist = ctx.tags()
3910 taglist = ctx.tags()
3911
3911
3912 if default and not ui.quiet:
3912 if default and not ui.quiet:
3913 b = ctx.branch()
3913 b = ctx.branch()
3914 if b != b'default':
3914 if b != b'default':
3915 output.append(b"(%s)" % b)
3915 output.append(b"(%s)" % b)
3916
3916
3917 # multiple tags for a single parent separated by '/'
3917 # multiple tags for a single parent separated by '/'
3918 t = b'/'.join(taglist)
3918 t = b'/'.join(taglist)
3919 if t:
3919 if t:
3920 output.append(t)
3920 output.append(t)
3921
3921
3922 # multiple bookmarks for a single parent separated by '/'
3922 # multiple bookmarks for a single parent separated by '/'
3923 bm = b'/'.join(ctx.bookmarks())
3923 bm = b'/'.join(ctx.bookmarks())
3924 if bm:
3924 if bm:
3925 output.append(bm)
3925 output.append(bm)
3926 else:
3926 else:
3927 if branch:
3927 if branch:
3928 output.append(ctx.branch())
3928 output.append(ctx.branch())
3929
3929
3930 if tags:
3930 if tags:
3931 output.extend(taglist)
3931 output.extend(taglist)
3932
3932
3933 if bookmarks:
3933 if bookmarks:
3934 output.extend(ctx.bookmarks())
3934 output.extend(ctx.bookmarks())
3935
3935
3936 fm.data(node=ctx.hex())
3936 fm.data(node=ctx.hex())
3937 fm.data(branch=ctx.branch())
3937 fm.data(branch=ctx.branch())
3938 fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
3938 fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
3939 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
3939 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
3940 fm.context(ctx=ctx)
3940 fm.context(ctx=ctx)
3941
3941
3942 fm.plain(b"%s\n" % b' '.join(output))
3942 fm.plain(b"%s\n" % b' '.join(output))
3943 fm.end()
3943 fm.end()
3944
3944
3945
3945
3946 @command(
3946 @command(
3947 b'import|patch',
3947 b'import|patch',
3948 [
3948 [
3949 (
3949 (
3950 b'p',
3950 b'p',
3951 b'strip',
3951 b'strip',
3952 1,
3952 1,
3953 _(
3953 _(
3954 b'directory strip option for patch. This has the same '
3954 b'directory strip option for patch. This has the same '
3955 b'meaning as the corresponding patch option'
3955 b'meaning as the corresponding patch option'
3956 ),
3956 ),
3957 _(b'NUM'),
3957 _(b'NUM'),
3958 ),
3958 ),
3959 (b'b', b'base', b'', _(b'base path (DEPRECATED)'), _(b'PATH')),
3959 (b'b', b'base', b'', _(b'base path (DEPRECATED)'), _(b'PATH')),
3960 (b'', b'secret', None, _(b'use the secret phase for committing')),
3960 (b'', b'secret', None, _(b'use the secret phase for committing')),
3961 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
3961 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
3962 (
3962 (
3963 b'f',
3963 b'f',
3964 b'force',
3964 b'force',
3965 None,
3965 None,
3966 _(b'skip check for outstanding uncommitted changes (DEPRECATED)'),
3966 _(b'skip check for outstanding uncommitted changes (DEPRECATED)'),
3967 ),
3967 ),
3968 (
3968 (
3969 b'',
3969 b'',
3970 b'no-commit',
3970 b'no-commit',
3971 None,
3971 None,
3972 _(b"don't commit, just update the working directory"),
3972 _(b"don't commit, just update the working directory"),
3973 ),
3973 ),
3974 (
3974 (
3975 b'',
3975 b'',
3976 b'bypass',
3976 b'bypass',
3977 None,
3977 None,
3978 _(b"apply patch without touching the working directory"),
3978 _(b"apply patch without touching the working directory"),
3979 ),
3979 ),
3980 (b'', b'partial', None, _(b'commit even if some hunks fail')),
3980 (b'', b'partial', None, _(b'commit even if some hunks fail')),
3981 (b'', b'exact', None, _(b'abort if patch would apply lossily')),
3981 (b'', b'exact', None, _(b'abort if patch would apply lossily')),
3982 (b'', b'prefix', b'', _(b'apply patch to subdirectory'), _(b'DIR')),
3982 (b'', b'prefix', b'', _(b'apply patch to subdirectory'), _(b'DIR')),
3983 (
3983 (
3984 b'',
3984 b'',
3985 b'import-branch',
3985 b'import-branch',
3986 None,
3986 None,
3987 _(b'use any branch information in patch (implied by --exact)'),
3987 _(b'use any branch information in patch (implied by --exact)'),
3988 ),
3988 ),
3989 ]
3989 ]
3990 + commitopts
3990 + commitopts
3991 + commitopts2
3991 + commitopts2
3992 + similarityopts,
3992 + similarityopts,
3993 _(b'[OPTION]... PATCH...'),
3993 _(b'[OPTION]... PATCH...'),
3994 helpcategory=command.CATEGORY_IMPORT_EXPORT,
3994 helpcategory=command.CATEGORY_IMPORT_EXPORT,
3995 )
3995 )
3996 def import_(ui, repo, patch1=None, *patches, **opts):
3996 def import_(ui, repo, patch1=None, *patches, **opts):
3997 """import an ordered set of patches
3997 """import an ordered set of patches
3998
3998
3999 Import a list of patches and commit them individually (unless
3999 Import a list of patches and commit them individually (unless
4000 --no-commit is specified).
4000 --no-commit is specified).
4001
4001
4002 To read a patch from standard input (stdin), use "-" as the patch
4002 To read a patch from standard input (stdin), use "-" as the patch
4003 name. If a URL is specified, the patch will be downloaded from
4003 name. If a URL is specified, the patch will be downloaded from
4004 there.
4004 there.
4005
4005
4006 Import first applies changes to the working directory (unless
4006 Import first applies changes to the working directory (unless
4007 --bypass is specified), import will abort if there are outstanding
4007 --bypass is specified), import will abort if there are outstanding
4008 changes.
4008 changes.
4009
4009
4010 Use --bypass to apply and commit patches directly to the
4010 Use --bypass to apply and commit patches directly to the
4011 repository, without affecting the working directory. Without
4011 repository, without affecting the working directory. Without
4012 --exact, patches will be applied on top of the working directory
4012 --exact, patches will be applied on top of the working directory
4013 parent revision.
4013 parent revision.
4014
4014
4015 You can import a patch straight from a mail message. Even patches
4015 You can import a patch straight from a mail message. Even patches
4016 as attachments work (to use the body part, it must have type
4016 as attachments work (to use the body part, it must have type
4017 text/plain or text/x-patch). From and Subject headers of email
4017 text/plain or text/x-patch). From and Subject headers of email
4018 message are used as default committer and commit message. All
4018 message are used as default committer and commit message. All
4019 text/plain body parts before first diff are added to the commit
4019 text/plain body parts before first diff are added to the commit
4020 message.
4020 message.
4021
4021
4022 If the imported patch was generated by :hg:`export`, user and
4022 If the imported patch was generated by :hg:`export`, user and
4023 description from patch override values from message headers and
4023 description from patch override values from message headers and
4024 body. Values given on command line with -m/--message and -u/--user
4024 body. Values given on command line with -m/--message and -u/--user
4025 override these.
4025 override these.
4026
4026
4027 If --exact is specified, import will set the working directory to
4027 If --exact is specified, import will set the working directory to
4028 the parent of each patch before applying it, and will abort if the
4028 the parent of each patch before applying it, and will abort if the
4029 resulting changeset has a different ID than the one recorded in
4029 resulting changeset has a different ID than the one recorded in
4030 the patch. This will guard against various ways that portable
4030 the patch. This will guard against various ways that portable
4031 patch formats and mail systems might fail to transfer Mercurial
4031 patch formats and mail systems might fail to transfer Mercurial
4032 data or metadata. See :hg:`bundle` for lossless transmission.
4032 data or metadata. See :hg:`bundle` for lossless transmission.
4033
4033
4034 Use --partial to ensure a changeset will be created from the patch
4034 Use --partial to ensure a changeset will be created from the patch
4035 even if some hunks fail to apply. Hunks that fail to apply will be
4035 even if some hunks fail to apply. Hunks that fail to apply will be
4036 written to a <target-file>.rej file. Conflicts can then be resolved
4036 written to a <target-file>.rej file. Conflicts can then be resolved
4037 by hand before :hg:`commit --amend` is run to update the created
4037 by hand before :hg:`commit --amend` is run to update the created
4038 changeset. This flag exists to let people import patches that
4038 changeset. This flag exists to let people import patches that
4039 partially apply without losing the associated metadata (author,
4039 partially apply without losing the associated metadata (author,
4040 date, description, ...).
4040 date, description, ...).
4041
4041
4042 .. note::
4042 .. note::
4043
4043
4044 When no hunks apply cleanly, :hg:`import --partial` will create
4044 When no hunks apply cleanly, :hg:`import --partial` will create
4045 an empty changeset, importing only the patch metadata.
4045 an empty changeset, importing only the patch metadata.
4046
4046
4047 With -s/--similarity, hg will attempt to discover renames and
4047 With -s/--similarity, hg will attempt to discover renames and
4048 copies in the patch in the same way as :hg:`addremove`.
4048 copies in the patch in the same way as :hg:`addremove`.
4049
4049
4050 It is possible to use external patch programs to perform the patch
4050 It is possible to use external patch programs to perform the patch
4051 by setting the ``ui.patch`` configuration option. For the default
4051 by setting the ``ui.patch`` configuration option. For the default
4052 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4052 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4053 See :hg:`help config` for more information about configuration
4053 See :hg:`help config` for more information about configuration
4054 files and how to use these options.
4054 files and how to use these options.
4055
4055
4056 See :hg:`help dates` for a list of formats valid for -d/--date.
4056 See :hg:`help dates` for a list of formats valid for -d/--date.
4057
4057
4058 .. container:: verbose
4058 .. container:: verbose
4059
4059
4060 Examples:
4060 Examples:
4061
4061
4062 - import a traditional patch from a website and detect renames::
4062 - import a traditional patch from a website and detect renames::
4063
4063
4064 hg import -s 80 http://example.com/bugfix.patch
4064 hg import -s 80 http://example.com/bugfix.patch
4065
4065
4066 - import a changeset from an hgweb server::
4066 - import a changeset from an hgweb server::
4067
4067
4068 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
4068 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
4069
4069
4070 - import all the patches in an Unix-style mbox::
4070 - import all the patches in an Unix-style mbox::
4071
4071
4072 hg import incoming-patches.mbox
4072 hg import incoming-patches.mbox
4073
4073
4074 - import patches from stdin::
4074 - import patches from stdin::
4075
4075
4076 hg import -
4076 hg import -
4077
4077
4078 - attempt to exactly restore an exported changeset (not always
4078 - attempt to exactly restore an exported changeset (not always
4079 possible)::
4079 possible)::
4080
4080
4081 hg import --exact proposed-fix.patch
4081 hg import --exact proposed-fix.patch
4082
4082
4083 - use an external tool to apply a patch which is too fuzzy for
4083 - use an external tool to apply a patch which is too fuzzy for
4084 the default internal tool.
4084 the default internal tool.
4085
4085
4086 hg import --config ui.patch="patch --merge" fuzzy.patch
4086 hg import --config ui.patch="patch --merge" fuzzy.patch
4087
4087
4088 - change the default fuzzing from 2 to a less strict 7
4088 - change the default fuzzing from 2 to a less strict 7
4089
4089
4090 hg import --config ui.fuzz=7 fuzz.patch
4090 hg import --config ui.fuzz=7 fuzz.patch
4091
4091
4092 Returns 0 on success, 1 on partial success (see --partial).
4092 Returns 0 on success, 1 on partial success (see --partial).
4093 """
4093 """
4094
4094
4095 cmdutil.check_incompatible_arguments(
4095 cmdutil.check_incompatible_arguments(
4096 opts, 'no_commit', ['bypass', 'secret']
4096 opts, 'no_commit', ['bypass', 'secret']
4097 )
4097 )
4098 cmdutil.check_incompatible_arguments(opts, 'exact', ['edit', 'prefix'])
4098 cmdutil.check_incompatible_arguments(opts, 'exact', ['edit', 'prefix'])
4099 opts = pycompat.byteskwargs(opts)
4099 opts = pycompat.byteskwargs(opts)
4100 if not patch1:
4100 if not patch1:
4101 raise error.InputError(_(b'need at least one patch to import'))
4101 raise error.InputError(_(b'need at least one patch to import'))
4102
4102
4103 patches = (patch1,) + patches
4103 patches = (patch1,) + patches
4104
4104
4105 date = opts.get(b'date')
4105 date = opts.get(b'date')
4106 if date:
4106 if date:
4107 opts[b'date'] = dateutil.parsedate(date)
4107 opts[b'date'] = dateutil.parsedate(date)
4108
4108
4109 exact = opts.get(b'exact')
4109 exact = opts.get(b'exact')
4110 update = not opts.get(b'bypass')
4110 update = not opts.get(b'bypass')
4111 try:
4111 try:
4112 sim = float(opts.get(b'similarity') or 0)
4112 sim = float(opts.get(b'similarity') or 0)
4113 except ValueError:
4113 except ValueError:
4114 raise error.InputError(_(b'similarity must be a number'))
4114 raise error.InputError(_(b'similarity must be a number'))
4115 if sim < 0 or sim > 100:
4115 if sim < 0 or sim > 100:
4116 raise error.InputError(_(b'similarity must be between 0 and 100'))
4116 raise error.InputError(_(b'similarity must be between 0 and 100'))
4117 if sim and not update:
4117 if sim and not update:
4118 raise error.InputError(_(b'cannot use --similarity with --bypass'))
4118 raise error.InputError(_(b'cannot use --similarity with --bypass'))
4119
4119
4120 base = opts[b"base"]
4120 base = opts[b"base"]
4121 msgs = []
4121 msgs = []
4122 ret = 0
4122 ret = 0
4123
4123
4124 with repo.wlock():
4124 with repo.wlock():
4125 if update:
4125 if update:
4126 cmdutil.checkunfinished(repo)
4126 cmdutil.checkunfinished(repo)
4127 if exact or not opts.get(b'force'):
4127 if exact or not opts.get(b'force'):
4128 cmdutil.bailifchanged(repo)
4128 cmdutil.bailifchanged(repo)
4129
4129
4130 if not opts.get(b'no_commit'):
4130 if not opts.get(b'no_commit'):
4131 lock = repo.lock
4131 lock = repo.lock
4132 tr = lambda: repo.transaction(b'import')
4132 tr = lambda: repo.transaction(b'import')
4133 dsguard = util.nullcontextmanager
4133 dsguard = util.nullcontextmanager
4134 else:
4134 else:
4135 lock = util.nullcontextmanager
4135 lock = util.nullcontextmanager
4136 tr = util.nullcontextmanager
4136 tr = util.nullcontextmanager
4137 dsguard = lambda: dirstateguard.dirstateguard(repo, b'import')
4137 dsguard = lambda: dirstateguard.dirstateguard(repo, b'import')
4138 with lock(), tr(), dsguard():
4138 with lock(), tr(), dsguard():
4139 parents = repo[None].parents()
4139 parents = repo[None].parents()
4140 for patchurl in patches:
4140 for patchurl in patches:
4141 if patchurl == b'-':
4141 if patchurl == b'-':
4142 ui.status(_(b'applying patch from stdin\n'))
4142 ui.status(_(b'applying patch from stdin\n'))
4143 patchfile = ui.fin
4143 patchfile = ui.fin
4144 patchurl = b'stdin' # for error message
4144 patchurl = b'stdin' # for error message
4145 else:
4145 else:
4146 patchurl = os.path.join(base, patchurl)
4146 patchurl = os.path.join(base, patchurl)
4147 ui.status(_(b'applying %s\n') % patchurl)
4147 ui.status(_(b'applying %s\n') % patchurl)
4148 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
4148 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
4149
4149
4150 haspatch = False
4150 haspatch = False
4151 for hunk in patch.split(patchfile):
4151 for hunk in patch.split(patchfile):
4152 with patch.extract(ui, hunk) as patchdata:
4152 with patch.extract(ui, hunk) as patchdata:
4153 msg, node, rej = cmdutil.tryimportone(
4153 msg, node, rej = cmdutil.tryimportone(
4154 ui, repo, patchdata, parents, opts, msgs, hg.clean
4154 ui, repo, patchdata, parents, opts, msgs, hg.clean
4155 )
4155 )
4156 if msg:
4156 if msg:
4157 haspatch = True
4157 haspatch = True
4158 ui.note(msg + b'\n')
4158 ui.note(msg + b'\n')
4159 if update or exact:
4159 if update or exact:
4160 parents = repo[None].parents()
4160 parents = repo[None].parents()
4161 else:
4161 else:
4162 parents = [repo[node]]
4162 parents = [repo[node]]
4163 if rej:
4163 if rej:
4164 ui.write_err(_(b"patch applied partially\n"))
4164 ui.write_err(_(b"patch applied partially\n"))
4165 ui.write_err(
4165 ui.write_err(
4166 _(
4166 _(
4167 b"(fix the .rej files and run "
4167 b"(fix the .rej files and run "
4168 b"`hg commit --amend`)\n"
4168 b"`hg commit --amend`)\n"
4169 )
4169 )
4170 )
4170 )
4171 ret = 1
4171 ret = 1
4172 break
4172 break
4173
4173
4174 if not haspatch:
4174 if not haspatch:
4175 raise error.InputError(_(b'%s: no diffs found') % patchurl)
4175 raise error.InputError(_(b'%s: no diffs found') % patchurl)
4176
4176
4177 if msgs:
4177 if msgs:
4178 repo.savecommitmessage(b'\n* * *\n'.join(msgs))
4178 repo.savecommitmessage(b'\n* * *\n'.join(msgs))
4179 return ret
4179 return ret
4180
4180
4181
4181
4182 @command(
4182 @command(
4183 b'incoming|in',
4183 b'incoming|in',
4184 [
4184 [
4185 (
4185 (
4186 b'f',
4186 b'f',
4187 b'force',
4187 b'force',
4188 None,
4188 None,
4189 _(b'run even if remote repository is unrelated'),
4189 _(b'run even if remote repository is unrelated'),
4190 ),
4190 ),
4191 (b'n', b'newest-first', None, _(b'show newest record first')),
4191 (b'n', b'newest-first', None, _(b'show newest record first')),
4192 (b'', b'bundle', b'', _(b'file to store the bundles into'), _(b'FILE')),
4192 (b'', b'bundle', b'', _(b'file to store the bundles into'), _(b'FILE')),
4193 (
4193 (
4194 b'r',
4194 b'r',
4195 b'rev',
4195 b'rev',
4196 [],
4196 [],
4197 _(b'a remote changeset intended to be added'),
4197 _(b'a remote changeset intended to be added'),
4198 _(b'REV'),
4198 _(b'REV'),
4199 ),
4199 ),
4200 (b'B', b'bookmarks', False, _(b"compare bookmarks")),
4200 (b'B', b'bookmarks', False, _(b"compare bookmarks")),
4201 (
4201 (
4202 b'b',
4202 b'b',
4203 b'branch',
4203 b'branch',
4204 [],
4204 [],
4205 _(b'a specific branch you would like to pull'),
4205 _(b'a specific branch you would like to pull'),
4206 _(b'BRANCH'),
4206 _(b'BRANCH'),
4207 ),
4207 ),
4208 ]
4208 ]
4209 + logopts
4209 + logopts
4210 + remoteopts
4210 + remoteopts
4211 + subrepoopts,
4211 + subrepoopts,
4212 _(b'[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
4212 _(b'[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
4213 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4213 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4214 )
4214 )
4215 def incoming(ui, repo, source=b"default", **opts):
4215 def incoming(ui, repo, source=b"default", **opts):
4216 """show new changesets found in source
4216 """show new changesets found in source
4217
4217
4218 Show new changesets found in the specified path/URL or the default
4218 Show new changesets found in the specified path/URL or the default
4219 pull location. These are the changesets that would have been pulled
4219 pull location. These are the changesets that would have been pulled
4220 by :hg:`pull` at the time you issued this command.
4220 by :hg:`pull` at the time you issued this command.
4221
4221
4222 See pull for valid source format details.
4222 See pull for valid source format details.
4223
4223
4224 .. container:: verbose
4224 .. container:: verbose
4225
4225
4226 With -B/--bookmarks, the result of bookmark comparison between
4226 With -B/--bookmarks, the result of bookmark comparison between
4227 local and remote repositories is displayed. With -v/--verbose,
4227 local and remote repositories is displayed. With -v/--verbose,
4228 status is also displayed for each bookmark like below::
4228 status is also displayed for each bookmark like below::
4229
4229
4230 BM1 01234567890a added
4230 BM1 01234567890a added
4231 BM2 1234567890ab advanced
4231 BM2 1234567890ab advanced
4232 BM3 234567890abc diverged
4232 BM3 234567890abc diverged
4233 BM4 34567890abcd changed
4233 BM4 34567890abcd changed
4234
4234
4235 The action taken locally when pulling depends on the
4235 The action taken locally when pulling depends on the
4236 status of each bookmark:
4236 status of each bookmark:
4237
4237
4238 :``added``: pull will create it
4238 :``added``: pull will create it
4239 :``advanced``: pull will update it
4239 :``advanced``: pull will update it
4240 :``diverged``: pull will create a divergent bookmark
4240 :``diverged``: pull will create a divergent bookmark
4241 :``changed``: result depends on remote changesets
4241 :``changed``: result depends on remote changesets
4242
4242
4243 From the point of view of pulling behavior, bookmark
4243 From the point of view of pulling behavior, bookmark
4244 existing only in the remote repository are treated as ``added``,
4244 existing only in the remote repository are treated as ``added``,
4245 even if it is in fact locally deleted.
4245 even if it is in fact locally deleted.
4246
4246
4247 .. container:: verbose
4247 .. container:: verbose
4248
4248
4249 For remote repository, using --bundle avoids downloading the
4249 For remote repository, using --bundle avoids downloading the
4250 changesets twice if the incoming is followed by a pull.
4250 changesets twice if the incoming is followed by a pull.
4251
4251
4252 Examples:
4252 Examples:
4253
4253
4254 - show incoming changes with patches and full description::
4254 - show incoming changes with patches and full description::
4255
4255
4256 hg incoming -vp
4256 hg incoming -vp
4257
4257
4258 - show incoming changes excluding merges, store a bundle::
4258 - show incoming changes excluding merges, store a bundle::
4259
4259
4260 hg in -vpM --bundle incoming.hg
4260 hg in -vpM --bundle incoming.hg
4261 hg pull incoming.hg
4261 hg pull incoming.hg
4262
4262
4263 - briefly list changes inside a bundle::
4263 - briefly list changes inside a bundle::
4264
4264
4265 hg in changes.hg -T "{desc|firstline}\\n"
4265 hg in changes.hg -T "{desc|firstline}\\n"
4266
4266
4267 Returns 0 if there are incoming changes, 1 otherwise.
4267 Returns 0 if there are incoming changes, 1 otherwise.
4268 """
4268 """
4269 opts = pycompat.byteskwargs(opts)
4269 opts = pycompat.byteskwargs(opts)
4270 if opts.get(b'graph'):
4270 if opts.get(b'graph'):
4271 logcmdutil.checkunsupportedgraphflags([], opts)
4271 logcmdutil.checkunsupportedgraphflags([], opts)
4272
4272
4273 def display(other, chlist, displayer):
4273 def display(other, chlist, displayer):
4274 revdag = logcmdutil.graphrevs(other, chlist, opts)
4274 revdag = logcmdutil.graphrevs(other, chlist, opts)
4275 logcmdutil.displaygraph(
4275 logcmdutil.displaygraph(
4276 ui, repo, revdag, displayer, graphmod.asciiedges
4276 ui, repo, revdag, displayer, graphmod.asciiedges
4277 )
4277 )
4278
4278
4279 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4279 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4280 return 0
4280 return 0
4281
4281
4282 cmdutil.check_incompatible_arguments(opts, b'subrepos', [b'bundle'])
4282 cmdutil.check_incompatible_arguments(opts, b'subrepos', [b'bundle'])
4283
4283
4284 if opts.get(b'bookmarks'):
4284 if opts.get(b'bookmarks'):
4285 source, branches = hg.parseurl(
4285 source, branches = hg.parseurl(
4286 ui.expandpath(source), opts.get(b'branch')
4286 ui.expandpath(source), opts.get(b'branch')
4287 )
4287 )
4288 other = hg.peer(repo, opts, source)
4288 other = hg.peer(repo, opts, source)
4289 if b'bookmarks' not in other.listkeys(b'namespaces'):
4289 if b'bookmarks' not in other.listkeys(b'namespaces'):
4290 ui.warn(_(b"remote doesn't support bookmarks\n"))
4290 ui.warn(_(b"remote doesn't support bookmarks\n"))
4291 return 0
4291 return 0
4292 ui.pager(b'incoming')
4292 ui.pager(b'incoming')
4293 ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
4293 ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
4294 return bookmarks.incoming(ui, repo, other)
4294 return bookmarks.incoming(ui, repo, other)
4295
4295
4296 repo._subtoppath = ui.expandpath(source)
4296 repo._subtoppath = ui.expandpath(source)
4297 try:
4297 try:
4298 return hg.incoming(ui, repo, source, opts)
4298 return hg.incoming(ui, repo, source, opts)
4299 finally:
4299 finally:
4300 del repo._subtoppath
4300 del repo._subtoppath
4301
4301
4302
4302
4303 @command(
4303 @command(
4304 b'init',
4304 b'init',
4305 remoteopts,
4305 remoteopts,
4306 _(b'[-e CMD] [--remotecmd CMD] [DEST]'),
4306 _(b'[-e CMD] [--remotecmd CMD] [DEST]'),
4307 helpcategory=command.CATEGORY_REPO_CREATION,
4307 helpcategory=command.CATEGORY_REPO_CREATION,
4308 helpbasic=True,
4308 helpbasic=True,
4309 norepo=True,
4309 norepo=True,
4310 )
4310 )
4311 def init(ui, dest=b".", **opts):
4311 def init(ui, dest=b".", **opts):
4312 """create a new repository in the given directory
4312 """create a new repository in the given directory
4313
4313
4314 Initialize a new repository in the given directory. If the given
4314 Initialize a new repository in the given directory. If the given
4315 directory does not exist, it will be created.
4315 directory does not exist, it will be created.
4316
4316
4317 If no directory is given, the current directory is used.
4317 If no directory is given, the current directory is used.
4318
4318
4319 It is possible to specify an ``ssh://`` URL as the destination.
4319 It is possible to specify an ``ssh://`` URL as the destination.
4320 See :hg:`help urls` for more information.
4320 See :hg:`help urls` for more information.
4321
4321
4322 Returns 0 on success.
4322 Returns 0 on success.
4323 """
4323 """
4324 opts = pycompat.byteskwargs(opts)
4324 opts = pycompat.byteskwargs(opts)
4325 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4325 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4326
4326
4327
4327
4328 @command(
4328 @command(
4329 b'locate',
4329 b'locate',
4330 [
4330 [
4331 (
4331 (
4332 b'r',
4332 b'r',
4333 b'rev',
4333 b'rev',
4334 b'',
4334 b'',
4335 _(b'search the repository as it is in REV'),
4335 _(b'search the repository as it is in REV'),
4336 _(b'REV'),
4336 _(b'REV'),
4337 ),
4337 ),
4338 (
4338 (
4339 b'0',
4339 b'0',
4340 b'print0',
4340 b'print0',
4341 None,
4341 None,
4342 _(b'end filenames with NUL, for use with xargs'),
4342 _(b'end filenames with NUL, for use with xargs'),
4343 ),
4343 ),
4344 (
4344 (
4345 b'f',
4345 b'f',
4346 b'fullpath',
4346 b'fullpath',
4347 None,
4347 None,
4348 _(b'print complete paths from the filesystem root'),
4348 _(b'print complete paths from the filesystem root'),
4349 ),
4349 ),
4350 ]
4350 ]
4351 + walkopts,
4351 + walkopts,
4352 _(b'[OPTION]... [PATTERN]...'),
4352 _(b'[OPTION]... [PATTERN]...'),
4353 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4353 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4354 )
4354 )
4355 def locate(ui, repo, *pats, **opts):
4355 def locate(ui, repo, *pats, **opts):
4356 """locate files matching specific patterns (DEPRECATED)
4356 """locate files matching specific patterns (DEPRECATED)
4357
4357
4358 Print files under Mercurial control in the working directory whose
4358 Print files under Mercurial control in the working directory whose
4359 names match the given patterns.
4359 names match the given patterns.
4360
4360
4361 By default, this command searches all directories in the working
4361 By default, this command searches all directories in the working
4362 directory. To search just the current directory and its
4362 directory. To search just the current directory and its
4363 subdirectories, use "--include .".
4363 subdirectories, use "--include .".
4364
4364
4365 If no patterns are given to match, this command prints the names
4365 If no patterns are given to match, this command prints the names
4366 of all files under Mercurial control in the working directory.
4366 of all files under Mercurial control in the working directory.
4367
4367
4368 If you want to feed the output of this command into the "xargs"
4368 If you want to feed the output of this command into the "xargs"
4369 command, use the -0 option to both this command and "xargs". This
4369 command, use the -0 option to both this command and "xargs". This
4370 will avoid the problem of "xargs" treating single filenames that
4370 will avoid the problem of "xargs" treating single filenames that
4371 contain whitespace as multiple filenames.
4371 contain whitespace as multiple filenames.
4372
4372
4373 See :hg:`help files` for a more versatile command.
4373 See :hg:`help files` for a more versatile command.
4374
4374
4375 Returns 0 if a match is found, 1 otherwise.
4375 Returns 0 if a match is found, 1 otherwise.
4376 """
4376 """
4377 opts = pycompat.byteskwargs(opts)
4377 opts = pycompat.byteskwargs(opts)
4378 if opts.get(b'print0'):
4378 if opts.get(b'print0'):
4379 end = b'\0'
4379 end = b'\0'
4380 else:
4380 else:
4381 end = b'\n'
4381 end = b'\n'
4382 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
4382 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
4383
4383
4384 ret = 1
4384 ret = 1
4385 m = scmutil.match(
4385 m = scmutil.match(
4386 ctx, pats, opts, default=b'relglob', badfn=lambda x, y: False
4386 ctx, pats, opts, default=b'relglob', badfn=lambda x, y: False
4387 )
4387 )
4388
4388
4389 ui.pager(b'locate')
4389 ui.pager(b'locate')
4390 if ctx.rev() is None:
4390 if ctx.rev() is None:
4391 # When run on the working copy, "locate" includes removed files, so
4391 # When run on the working copy, "locate" includes removed files, so
4392 # we get the list of files from the dirstate.
4392 # we get the list of files from the dirstate.
4393 filesgen = sorted(repo.dirstate.matches(m))
4393 filesgen = sorted(repo.dirstate.matches(m))
4394 else:
4394 else:
4395 filesgen = ctx.matches(m)
4395 filesgen = ctx.matches(m)
4396 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
4396 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
4397 for abs in filesgen:
4397 for abs in filesgen:
4398 if opts.get(b'fullpath'):
4398 if opts.get(b'fullpath'):
4399 ui.write(repo.wjoin(abs), end)
4399 ui.write(repo.wjoin(abs), end)
4400 else:
4400 else:
4401 ui.write(uipathfn(abs), end)
4401 ui.write(uipathfn(abs), end)
4402 ret = 0
4402 ret = 0
4403
4403
4404 return ret
4404 return ret
4405
4405
4406
4406
4407 @command(
4407 @command(
4408 b'log|history',
4408 b'log|history',
4409 [
4409 [
4410 (
4410 (
4411 b'f',
4411 b'f',
4412 b'follow',
4412 b'follow',
4413 None,
4413 None,
4414 _(
4414 _(
4415 b'follow changeset history, or file history across copies and renames'
4415 b'follow changeset history, or file history across copies and renames'
4416 ),
4416 ),
4417 ),
4417 ),
4418 (
4418 (
4419 b'',
4419 b'',
4420 b'follow-first',
4420 b'follow-first',
4421 None,
4421 None,
4422 _(b'only follow the first parent of merge changesets (DEPRECATED)'),
4422 _(b'only follow the first parent of merge changesets (DEPRECATED)'),
4423 ),
4423 ),
4424 (
4424 (
4425 b'd',
4425 b'd',
4426 b'date',
4426 b'date',
4427 b'',
4427 b'',
4428 _(b'show revisions matching date spec'),
4428 _(b'show revisions matching date spec'),
4429 _(b'DATE'),
4429 _(b'DATE'),
4430 ),
4430 ),
4431 (b'C', b'copies', None, _(b'show copied files')),
4431 (b'C', b'copies', None, _(b'show copied files')),
4432 (
4432 (
4433 b'k',
4433 b'k',
4434 b'keyword',
4434 b'keyword',
4435 [],
4435 [],
4436 _(b'do case-insensitive search for a given text'),
4436 _(b'do case-insensitive search for a given text'),
4437 _(b'TEXT'),
4437 _(b'TEXT'),
4438 ),
4438 ),
4439 (
4439 (
4440 b'r',
4440 b'r',
4441 b'rev',
4441 b'rev',
4442 [],
4442 [],
4443 _(b'show the specified revision or revset'),
4443 _(b'show the specified revision or revset'),
4444 _(b'REV'),
4444 _(b'REV'),
4445 ),
4445 ),
4446 (
4446 (
4447 b'L',
4447 b'L',
4448 b'line-range',
4448 b'line-range',
4449 [],
4449 [],
4450 _(b'follow line range of specified file (EXPERIMENTAL)'),
4450 _(b'follow line range of specified file (EXPERIMENTAL)'),
4451 _(b'FILE,RANGE'),
4451 _(b'FILE,RANGE'),
4452 ),
4452 ),
4453 (
4453 (
4454 b'',
4454 b'',
4455 b'removed',
4455 b'removed',
4456 None,
4456 None,
4457 _(b'include revisions where files were removed'),
4457 _(b'include revisions where files were removed'),
4458 ),
4458 ),
4459 (
4459 (
4460 b'm',
4460 b'm',
4461 b'only-merges',
4461 b'only-merges',
4462 None,
4462 None,
4463 _(b'show only merges (DEPRECATED) (use -r "merge()" instead)'),
4463 _(b'show only merges (DEPRECATED) (use -r "merge()" instead)'),
4464 ),
4464 ),
4465 (b'u', b'user', [], _(b'revisions committed by user'), _(b'USER')),
4465 (b'u', b'user', [], _(b'revisions committed by user'), _(b'USER')),
4466 (
4466 (
4467 b'',
4467 b'',
4468 b'only-branch',
4468 b'only-branch',
4469 [],
4469 [],
4470 _(
4470 _(
4471 b'show only changesets within the given named branch (DEPRECATED)'
4471 b'show only changesets within the given named branch (DEPRECATED)'
4472 ),
4472 ),
4473 _(b'BRANCH'),
4473 _(b'BRANCH'),
4474 ),
4474 ),
4475 (
4475 (
4476 b'b',
4476 b'b',
4477 b'branch',
4477 b'branch',
4478 [],
4478 [],
4479 _(b'show changesets within the given named branch'),
4479 _(b'show changesets within the given named branch'),
4480 _(b'BRANCH'),
4480 _(b'BRANCH'),
4481 ),
4481 ),
4482 (
4482 (
4483 b'B',
4483 b'B',
4484 b'bookmark',
4484 b'bookmark',
4485 [],
4485 [],
4486 _(b"show changesets within the given bookmark"),
4486 _(b"show changesets within the given bookmark"),
4487 _(b'BOOKMARK'),
4487 _(b'BOOKMARK'),
4488 ),
4488 ),
4489 (
4489 (
4490 b'P',
4490 b'P',
4491 b'prune',
4491 b'prune',
4492 [],
4492 [],
4493 _(b'do not display revision or any of its ancestors'),
4493 _(b'do not display revision or any of its ancestors'),
4494 _(b'REV'),
4494 _(b'REV'),
4495 ),
4495 ),
4496 ]
4496 ]
4497 + logopts
4497 + logopts
4498 + walkopts,
4498 + walkopts,
4499 _(b'[OPTION]... [FILE]'),
4499 _(b'[OPTION]... [FILE]'),
4500 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4500 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4501 helpbasic=True,
4501 helpbasic=True,
4502 inferrepo=True,
4502 inferrepo=True,
4503 intents={INTENT_READONLY},
4503 intents={INTENT_READONLY},
4504 )
4504 )
4505 def log(ui, repo, *pats, **opts):
4505 def log(ui, repo, *pats, **opts):
4506 """show revision history of entire repository or files
4506 """show revision history of entire repository or files
4507
4507
4508 Print the revision history of the specified files or the entire
4508 Print the revision history of the specified files or the entire
4509 project.
4509 project.
4510
4510
4511 If no revision range is specified, the default is ``tip:0`` unless
4511 If no revision range is specified, the default is ``tip:0`` unless
4512 --follow is set, in which case the working directory parent is
4512 --follow is set, in which case the working directory parent is
4513 used as the starting revision.
4513 used as the starting revision.
4514
4514
4515 File history is shown without following rename or copy history of
4515 File history is shown without following rename or copy history of
4516 files. Use -f/--follow with a filename to follow history across
4516 files. Use -f/--follow with a filename to follow history across
4517 renames and copies. --follow without a filename will only show
4517 renames and copies. --follow without a filename will only show
4518 ancestors of the starting revision.
4518 ancestors of the starting revision.
4519
4519
4520 By default this command prints revision number and changeset id,
4520 By default this command prints revision number and changeset id,
4521 tags, non-trivial parents, user, date and time, and a summary for
4521 tags, non-trivial parents, user, date and time, and a summary for
4522 each commit. When the -v/--verbose switch is used, the list of
4522 each commit. When the -v/--verbose switch is used, the list of
4523 changed files and full commit message are shown.
4523 changed files and full commit message are shown.
4524
4524
4525 With --graph the revisions are shown as an ASCII art DAG with the most
4525 With --graph the revisions are shown as an ASCII art DAG with the most
4526 recent changeset at the top.
4526 recent changeset at the top.
4527 'o' is a changeset, '@' is a working directory parent, '%' is a changeset
4527 'o' is a changeset, '@' is a working directory parent, '%' is a changeset
4528 involved in an unresolved merge conflict, '_' closes a branch,
4528 involved in an unresolved merge conflict, '_' closes a branch,
4529 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
4529 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
4530 changeset from the lines below is a parent of the 'o' merge on the same
4530 changeset from the lines below is a parent of the 'o' merge on the same
4531 line.
4531 line.
4532 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
4532 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
4533 of a '|' indicates one or more revisions in a path are omitted.
4533 of a '|' indicates one or more revisions in a path are omitted.
4534
4534
4535 .. container:: verbose
4535 .. container:: verbose
4536
4536
4537 Use -L/--line-range FILE,M:N options to follow the history of lines
4537 Use -L/--line-range FILE,M:N options to follow the history of lines
4538 from M to N in FILE. With -p/--patch only diff hunks affecting
4538 from M to N in FILE. With -p/--patch only diff hunks affecting
4539 specified line range will be shown. This option requires --follow;
4539 specified line range will be shown. This option requires --follow;
4540 it can be specified multiple times. Currently, this option is not
4540 it can be specified multiple times. Currently, this option is not
4541 compatible with --graph. This option is experimental.
4541 compatible with --graph. This option is experimental.
4542
4542
4543 .. note::
4543 .. note::
4544
4544
4545 :hg:`log --patch` may generate unexpected diff output for merge
4545 :hg:`log --patch` may generate unexpected diff output for merge
4546 changesets, as it will only compare the merge changeset against
4546 changesets, as it will only compare the merge changeset against
4547 its first parent. Also, only files different from BOTH parents
4547 its first parent. Also, only files different from BOTH parents
4548 will appear in files:.
4548 will appear in files:.
4549
4549
4550 .. note::
4550 .. note::
4551
4551
4552 For performance reasons, :hg:`log FILE` may omit duplicate changes
4552 For performance reasons, :hg:`log FILE` may omit duplicate changes
4553 made on branches and will not show removals or mode changes. To
4553 made on branches and will not show removals or mode changes. To
4554 see all such changes, use the --removed switch.
4554 see all such changes, use the --removed switch.
4555
4555
4556 .. container:: verbose
4556 .. container:: verbose
4557
4557
4558 .. note::
4558 .. note::
4559
4559
4560 The history resulting from -L/--line-range options depends on diff
4560 The history resulting from -L/--line-range options depends on diff
4561 options; for instance if white-spaces are ignored, respective changes
4561 options; for instance if white-spaces are ignored, respective changes
4562 with only white-spaces in specified line range will not be listed.
4562 with only white-spaces in specified line range will not be listed.
4563
4563
4564 .. container:: verbose
4564 .. container:: verbose
4565
4565
4566 Some examples:
4566 Some examples:
4567
4567
4568 - changesets with full descriptions and file lists::
4568 - changesets with full descriptions and file lists::
4569
4569
4570 hg log -v
4570 hg log -v
4571
4571
4572 - changesets ancestral to the working directory::
4572 - changesets ancestral to the working directory::
4573
4573
4574 hg log -f
4574 hg log -f
4575
4575
4576 - last 10 commits on the current branch::
4576 - last 10 commits on the current branch::
4577
4577
4578 hg log -l 10 -b .
4578 hg log -l 10 -b .
4579
4579
4580 - changesets showing all modifications of a file, including removals::
4580 - changesets showing all modifications of a file, including removals::
4581
4581
4582 hg log --removed file.c
4582 hg log --removed file.c
4583
4583
4584 - all changesets that touch a directory, with diffs, excluding merges::
4584 - all changesets that touch a directory, with diffs, excluding merges::
4585
4585
4586 hg log -Mp lib/
4586 hg log -Mp lib/
4587
4587
4588 - all revision numbers that match a keyword::
4588 - all revision numbers that match a keyword::
4589
4589
4590 hg log -k bug --template "{rev}\\n"
4590 hg log -k bug --template "{rev}\\n"
4591
4591
4592 - the full hash identifier of the working directory parent::
4592 - the full hash identifier of the working directory parent::
4593
4593
4594 hg log -r . --template "{node}\\n"
4594 hg log -r . --template "{node}\\n"
4595
4595
4596 - list available log templates::
4596 - list available log templates::
4597
4597
4598 hg log -T list
4598 hg log -T list
4599
4599
4600 - check if a given changeset is included in a tagged release::
4600 - check if a given changeset is included in a tagged release::
4601
4601
4602 hg log -r "a21ccf and ancestor(1.9)"
4602 hg log -r "a21ccf and ancestor(1.9)"
4603
4603
4604 - find all changesets by some user in a date range::
4604 - find all changesets by some user in a date range::
4605
4605
4606 hg log -k alice -d "may 2008 to jul 2008"
4606 hg log -k alice -d "may 2008 to jul 2008"
4607
4607
4608 - summary of all changesets after the last tag::
4608 - summary of all changesets after the last tag::
4609
4609
4610 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4610 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4611
4611
4612 - changesets touching lines 13 to 23 for file.c::
4612 - changesets touching lines 13 to 23 for file.c::
4613
4613
4614 hg log -L file.c,13:23
4614 hg log -L file.c,13:23
4615
4615
4616 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
4616 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
4617 main.c with patch::
4617 main.c with patch::
4618
4618
4619 hg log -L file.c,13:23 -L main.c,2:6 -p
4619 hg log -L file.c,13:23 -L main.c,2:6 -p
4620
4620
4621 See :hg:`help dates` for a list of formats valid for -d/--date.
4621 See :hg:`help dates` for a list of formats valid for -d/--date.
4622
4622
4623 See :hg:`help revisions` for more about specifying and ordering
4623 See :hg:`help revisions` for more about specifying and ordering
4624 revisions.
4624 revisions.
4625
4625
4626 See :hg:`help templates` for more about pre-packaged styles and
4626 See :hg:`help templates` for more about pre-packaged styles and
4627 specifying custom templates. The default template used by the log
4627 specifying custom templates. The default template used by the log
4628 command can be customized via the ``command-templates.log`` configuration
4628 command can be customized via the ``command-templates.log`` configuration
4629 setting.
4629 setting.
4630
4630
4631 Returns 0 on success.
4631 Returns 0 on success.
4632
4632
4633 """
4633 """
4634 opts = pycompat.byteskwargs(opts)
4634 opts = pycompat.byteskwargs(opts)
4635 linerange = opts.get(b'line_range')
4635 linerange = opts.get(b'line_range')
4636
4636
4637 if linerange and not opts.get(b'follow'):
4637 if linerange and not opts.get(b'follow'):
4638 raise error.InputError(_(b'--line-range requires --follow'))
4638 raise error.InputError(_(b'--line-range requires --follow'))
4639
4639
4640 if linerange and pats:
4640 if linerange and pats:
4641 # TODO: take pats as patterns with no line-range filter
4641 # TODO: take pats as patterns with no line-range filter
4642 raise error.InputError(
4642 raise error.InputError(
4643 _(b'FILE arguments are not compatible with --line-range option')
4643 _(b'FILE arguments are not compatible with --line-range option')
4644 )
4644 )
4645
4645
4646 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
4646 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
4647 walk_opts = logcmdutil.parseopts(ui, pats, opts)
4647 walk_opts = logcmdutil.parseopts(ui, pats, opts)
4648 revs, differ = logcmdutil.getrevs(repo, walk_opts)
4648 revs, differ = logcmdutil.getrevs(repo, walk_opts)
4649 if linerange:
4649 if linerange:
4650 # TODO: should follow file history from logcmdutil._initialrevs(),
4650 # TODO: should follow file history from logcmdutil._initialrevs(),
4651 # then filter the result by logcmdutil._makerevset() and --limit
4651 # then filter the result by logcmdutil._makerevset() and --limit
4652 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
4652 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
4653
4653
4654 getcopies = None
4654 getcopies = None
4655 if opts.get(b'copies'):
4655 if opts.get(b'copies'):
4656 endrev = None
4656 endrev = None
4657 if revs:
4657 if revs:
4658 endrev = revs.max() + 1
4658 endrev = revs.max() + 1
4659 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
4659 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
4660
4660
4661 ui.pager(b'log')
4661 ui.pager(b'log')
4662 displayer = logcmdutil.changesetdisplayer(
4662 displayer = logcmdutil.changesetdisplayer(
4663 ui, repo, opts, differ, buffered=True
4663 ui, repo, opts, differ, buffered=True
4664 )
4664 )
4665 if opts.get(b'graph'):
4665 if opts.get(b'graph'):
4666 displayfn = logcmdutil.displaygraphrevs
4666 displayfn = logcmdutil.displaygraphrevs
4667 else:
4667 else:
4668 displayfn = logcmdutil.displayrevs
4668 displayfn = logcmdutil.displayrevs
4669 displayfn(ui, repo, revs, displayer, getcopies)
4669 displayfn(ui, repo, revs, displayer, getcopies)
4670
4670
4671
4671
4672 @command(
4672 @command(
4673 b'manifest',
4673 b'manifest',
4674 [
4674 [
4675 (b'r', b'rev', b'', _(b'revision to display'), _(b'REV')),
4675 (b'r', b'rev', b'', _(b'revision to display'), _(b'REV')),
4676 (b'', b'all', False, _(b"list files from all revisions")),
4676 (b'', b'all', False, _(b"list files from all revisions")),
4677 ]
4677 ]
4678 + formatteropts,
4678 + formatteropts,
4679 _(b'[-r REV]'),
4679 _(b'[-r REV]'),
4680 helpcategory=command.CATEGORY_MAINTENANCE,
4680 helpcategory=command.CATEGORY_MAINTENANCE,
4681 intents={INTENT_READONLY},
4681 intents={INTENT_READONLY},
4682 )
4682 )
4683 def manifest(ui, repo, node=None, rev=None, **opts):
4683 def manifest(ui, repo, node=None, rev=None, **opts):
4684 """output the current or given revision of the project manifest
4684 """output the current or given revision of the project manifest
4685
4685
4686 Print a list of version controlled files for the given revision.
4686 Print a list of version controlled files for the given revision.
4687 If no revision is given, the first parent of the working directory
4687 If no revision is given, the first parent of the working directory
4688 is used, or the null revision if no revision is checked out.
4688 is used, or the null revision if no revision is checked out.
4689
4689
4690 With -v, print file permissions, symlink and executable bits.
4690 With -v, print file permissions, symlink and executable bits.
4691 With --debug, print file revision hashes.
4691 With --debug, print file revision hashes.
4692
4692
4693 If option --all is specified, the list of all files from all revisions
4693 If option --all is specified, the list of all files from all revisions
4694 is printed. This includes deleted and renamed files.
4694 is printed. This includes deleted and renamed files.
4695
4695
4696 Returns 0 on success.
4696 Returns 0 on success.
4697 """
4697 """
4698 opts = pycompat.byteskwargs(opts)
4698 opts = pycompat.byteskwargs(opts)
4699 fm = ui.formatter(b'manifest', opts)
4699 fm = ui.formatter(b'manifest', opts)
4700
4700
4701 if opts.get(b'all'):
4701 if opts.get(b'all'):
4702 if rev or node:
4702 if rev or node:
4703 raise error.InputError(_(b"can't specify a revision with --all"))
4703 raise error.InputError(_(b"can't specify a revision with --all"))
4704
4704
4705 res = set()
4705 res = set()
4706 for rev in repo:
4706 for rev in repo:
4707 ctx = repo[rev]
4707 ctx = repo[rev]
4708 res |= set(ctx.files())
4708 res |= set(ctx.files())
4709
4709
4710 ui.pager(b'manifest')
4710 ui.pager(b'manifest')
4711 for f in sorted(res):
4711 for f in sorted(res):
4712 fm.startitem()
4712 fm.startitem()
4713 fm.write(b"path", b'%s\n', f)
4713 fm.write(b"path", b'%s\n', f)
4714 fm.end()
4714 fm.end()
4715 return
4715 return
4716
4716
4717 if rev and node:
4717 if rev and node:
4718 raise error.InputError(_(b"please specify just one revision"))
4718 raise error.InputError(_(b"please specify just one revision"))
4719
4719
4720 if not node:
4720 if not node:
4721 node = rev
4721 node = rev
4722
4722
4723 char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'}
4723 char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'}
4724 mode = {b'l': b'644', b'x': b'755', b'': b'644', b't': b'755'}
4724 mode = {b'l': b'644', b'x': b'755', b'': b'644', b't': b'755'}
4725 if node:
4725 if node:
4726 repo = scmutil.unhidehashlikerevs(repo, [node], b'nowarn')
4726 repo = scmutil.unhidehashlikerevs(repo, [node], b'nowarn')
4727 ctx = scmutil.revsingle(repo, node)
4727 ctx = scmutil.revsingle(repo, node)
4728 mf = ctx.manifest()
4728 mf = ctx.manifest()
4729 ui.pager(b'manifest')
4729 ui.pager(b'manifest')
4730 for f in ctx:
4730 for f in ctx:
4731 fm.startitem()
4731 fm.startitem()
4732 fm.context(ctx=ctx)
4732 fm.context(ctx=ctx)
4733 fl = ctx[f].flags()
4733 fl = ctx[f].flags()
4734 fm.condwrite(ui.debugflag, b'hash', b'%s ', hex(mf[f]))
4734 fm.condwrite(ui.debugflag, b'hash', b'%s ', hex(mf[f]))
4735 fm.condwrite(ui.verbose, b'mode type', b'%s %1s ', mode[fl], char[fl])
4735 fm.condwrite(ui.verbose, b'mode type', b'%s %1s ', mode[fl], char[fl])
4736 fm.write(b'path', b'%s\n', f)
4736 fm.write(b'path', b'%s\n', f)
4737 fm.end()
4737 fm.end()
4738
4738
4739
4739
4740 @command(
4740 @command(
4741 b'merge',
4741 b'merge',
4742 [
4742 [
4743 (
4743 (
4744 b'f',
4744 b'f',
4745 b'force',
4745 b'force',
4746 None,
4746 None,
4747 _(b'force a merge including outstanding changes (DEPRECATED)'),
4747 _(b'force a merge including outstanding changes (DEPRECATED)'),
4748 ),
4748 ),
4749 (b'r', b'rev', b'', _(b'revision to merge'), _(b'REV')),
4749 (b'r', b'rev', b'', _(b'revision to merge'), _(b'REV')),
4750 (
4750 (
4751 b'P',
4751 b'P',
4752 b'preview',
4752 b'preview',
4753 None,
4753 None,
4754 _(b'review revisions to merge (no merge is performed)'),
4754 _(b'review revisions to merge (no merge is performed)'),
4755 ),
4755 ),
4756 (b'', b'abort', None, _(b'abort the ongoing merge')),
4756 (b'', b'abort', None, _(b'abort the ongoing merge')),
4757 ]
4757 ]
4758 + mergetoolopts,
4758 + mergetoolopts,
4759 _(b'[-P] [[-r] REV]'),
4759 _(b'[-P] [[-r] REV]'),
4760 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
4760 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
4761 helpbasic=True,
4761 helpbasic=True,
4762 )
4762 )
4763 def merge(ui, repo, node=None, **opts):
4763 def merge(ui, repo, node=None, **opts):
4764 """merge another revision into working directory
4764 """merge another revision into working directory
4765
4765
4766 The current working directory is updated with all changes made in
4766 The current working directory is updated with all changes made in
4767 the requested revision since the last common predecessor revision.
4767 the requested revision since the last common predecessor revision.
4768
4768
4769 Files that changed between either parent are marked as changed for
4769 Files that changed between either parent are marked as changed for
4770 the next commit and a commit must be performed before any further
4770 the next commit and a commit must be performed before any further
4771 updates to the repository are allowed. The next commit will have
4771 updates to the repository are allowed. The next commit will have
4772 two parents.
4772 two parents.
4773
4773
4774 ``--tool`` can be used to specify the merge tool used for file
4774 ``--tool`` can be used to specify the merge tool used for file
4775 merges. It overrides the HGMERGE environment variable and your
4775 merges. It overrides the HGMERGE environment variable and your
4776 configuration files. See :hg:`help merge-tools` for options.
4776 configuration files. See :hg:`help merge-tools` for options.
4777
4777
4778 If no revision is specified, the working directory's parent is a
4778 If no revision is specified, the working directory's parent is a
4779 head revision, and the current branch contains exactly one other
4779 head revision, and the current branch contains exactly one other
4780 head, the other head is merged with by default. Otherwise, an
4780 head, the other head is merged with by default. Otherwise, an
4781 explicit revision with which to merge must be provided.
4781 explicit revision with which to merge must be provided.
4782
4782
4783 See :hg:`help resolve` for information on handling file conflicts.
4783 See :hg:`help resolve` for information on handling file conflicts.
4784
4784
4785 To undo an uncommitted merge, use :hg:`merge --abort` which
4785 To undo an uncommitted merge, use :hg:`merge --abort` which
4786 will check out a clean copy of the original merge parent, losing
4786 will check out a clean copy of the original merge parent, losing
4787 all changes.
4787 all changes.
4788
4788
4789 Returns 0 on success, 1 if there are unresolved files.
4789 Returns 0 on success, 1 if there are unresolved files.
4790 """
4790 """
4791
4791
4792 opts = pycompat.byteskwargs(opts)
4792 opts = pycompat.byteskwargs(opts)
4793 abort = opts.get(b'abort')
4793 abort = opts.get(b'abort')
4794 if abort and repo.dirstate.p2() == nullid:
4794 if abort and repo.dirstate.p2() == nullid:
4795 cmdutil.wrongtooltocontinue(repo, _(b'merge'))
4795 cmdutil.wrongtooltocontinue(repo, _(b'merge'))
4796 cmdutil.check_incompatible_arguments(opts, b'abort', [b'rev', b'preview'])
4796 cmdutil.check_incompatible_arguments(opts, b'abort', [b'rev', b'preview'])
4797 if abort:
4797 if abort:
4798 state = cmdutil.getunfinishedstate(repo)
4798 state = cmdutil.getunfinishedstate(repo)
4799 if state and state._opname != b'merge':
4799 if state and state._opname != b'merge':
4800 raise error.StateError(
4800 raise error.StateError(
4801 _(b'cannot abort merge with %s in progress') % (state._opname),
4801 _(b'cannot abort merge with %s in progress') % (state._opname),
4802 hint=state.hint(),
4802 hint=state.hint(),
4803 )
4803 )
4804 if node:
4804 if node:
4805 raise error.InputError(_(b"cannot specify a node with --abort"))
4805 raise error.InputError(_(b"cannot specify a node with --abort"))
4806 return hg.abortmerge(repo.ui, repo)
4806 return hg.abortmerge(repo.ui, repo)
4807
4807
4808 if opts.get(b'rev') and node:
4808 if opts.get(b'rev') and node:
4809 raise error.InputError(_(b"please specify just one revision"))
4809 raise error.InputError(_(b"please specify just one revision"))
4810 if not node:
4810 if not node:
4811 node = opts.get(b'rev')
4811 node = opts.get(b'rev')
4812
4812
4813 if node:
4813 if node:
4814 ctx = scmutil.revsingle(repo, node)
4814 ctx = scmutil.revsingle(repo, node)
4815 else:
4815 else:
4816 if ui.configbool(b'commands', b'merge.require-rev'):
4816 if ui.configbool(b'commands', b'merge.require-rev'):
4817 raise error.InputError(
4817 raise error.InputError(
4818 _(
4818 _(
4819 b'configuration requires specifying revision to merge '
4819 b'configuration requires specifying revision to merge '
4820 b'with'
4820 b'with'
4821 )
4821 )
4822 )
4822 )
4823 ctx = repo[destutil.destmerge(repo)]
4823 ctx = repo[destutil.destmerge(repo)]
4824
4824
4825 if ctx.node() is None:
4825 if ctx.node() is None:
4826 raise error.InputError(
4826 raise error.InputError(
4827 _(b'merging with the working copy has no effect')
4827 _(b'merging with the working copy has no effect')
4828 )
4828 )
4829
4829
4830 if opts.get(b'preview'):
4830 if opts.get(b'preview'):
4831 # find nodes that are ancestors of p2 but not of p1
4831 # find nodes that are ancestors of p2 but not of p1
4832 p1 = repo[b'.'].node()
4832 p1 = repo[b'.'].node()
4833 p2 = ctx.node()
4833 p2 = ctx.node()
4834 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4834 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4835
4835
4836 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4836 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4837 for node in nodes:
4837 for node in nodes:
4838 displayer.show(repo[node])
4838 displayer.show(repo[node])
4839 displayer.close()
4839 displayer.close()
4840 return 0
4840 return 0
4841
4841
4842 # ui.forcemerge is an internal variable, do not document
4842 # ui.forcemerge is an internal variable, do not document
4843 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
4843 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
4844 with ui.configoverride(overrides, b'merge'):
4844 with ui.configoverride(overrides, b'merge'):
4845 force = opts.get(b'force')
4845 force = opts.get(b'force')
4846 labels = [b'working copy', b'merge rev']
4846 labels = [b'working copy', b'merge rev']
4847 return hg.merge(ctx, force=force, labels=labels)
4847 return hg.merge(ctx, force=force, labels=labels)
4848
4848
4849
4849
4850 statemod.addunfinished(
4850 statemod.addunfinished(
4851 b'merge',
4851 b'merge',
4852 fname=None,
4852 fname=None,
4853 clearable=True,
4853 clearable=True,
4854 allowcommit=True,
4854 allowcommit=True,
4855 cmdmsg=_(b'outstanding uncommitted merge'),
4855 cmdmsg=_(b'outstanding uncommitted merge'),
4856 abortfunc=hg.abortmerge,
4856 abortfunc=hg.abortmerge,
4857 statushint=_(
4857 statushint=_(
4858 b'To continue: hg commit\nTo abort: hg merge --abort'
4858 b'To continue: hg commit\nTo abort: hg merge --abort'
4859 ),
4859 ),
4860 cmdhint=_(b"use 'hg commit' or 'hg merge --abort'"),
4860 cmdhint=_(b"use 'hg commit' or 'hg merge --abort'"),
4861 )
4861 )
4862
4862
4863
4863
4864 @command(
4864 @command(
4865 b'outgoing|out',
4865 b'outgoing|out',
4866 [
4866 [
4867 (
4867 (
4868 b'f',
4868 b'f',
4869 b'force',
4869 b'force',
4870 None,
4870 None,
4871 _(b'run even when the destination is unrelated'),
4871 _(b'run even when the destination is unrelated'),
4872 ),
4872 ),
4873 (
4873 (
4874 b'r',
4874 b'r',
4875 b'rev',
4875 b'rev',
4876 [],
4876 [],
4877 _(b'a changeset intended to be included in the destination'),
4877 _(b'a changeset intended to be included in the destination'),
4878 _(b'REV'),
4878 _(b'REV'),
4879 ),
4879 ),
4880 (b'n', b'newest-first', None, _(b'show newest record first')),
4880 (b'n', b'newest-first', None, _(b'show newest record first')),
4881 (b'B', b'bookmarks', False, _(b'compare bookmarks')),
4881 (b'B', b'bookmarks', False, _(b'compare bookmarks')),
4882 (
4882 (
4883 b'b',
4883 b'b',
4884 b'branch',
4884 b'branch',
4885 [],
4885 [],
4886 _(b'a specific branch you would like to push'),
4886 _(b'a specific branch you would like to push'),
4887 _(b'BRANCH'),
4887 _(b'BRANCH'),
4888 ),
4888 ),
4889 ]
4889 ]
4890 + logopts
4890 + logopts
4891 + remoteopts
4891 + remoteopts
4892 + subrepoopts,
4892 + subrepoopts,
4893 _(b'[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4893 _(b'[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4894 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4894 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4895 )
4895 )
4896 def outgoing(ui, repo, dest=None, **opts):
4896 def outgoing(ui, repo, dest=None, **opts):
4897 """show changesets not found in the destination
4897 """show changesets not found in the destination
4898
4898
4899 Show changesets not found in the specified destination repository
4899 Show changesets not found in the specified destination repository
4900 or the default push location. These are the changesets that would
4900 or the default push location. These are the changesets that would
4901 be pushed if a push was requested.
4901 be pushed if a push was requested.
4902
4902
4903 See pull for details of valid destination formats.
4903 See pull for details of valid destination formats.
4904
4904
4905 .. container:: verbose
4905 .. container:: verbose
4906
4906
4907 With -B/--bookmarks, the result of bookmark comparison between
4907 With -B/--bookmarks, the result of bookmark comparison between
4908 local and remote repositories is displayed. With -v/--verbose,
4908 local and remote repositories is displayed. With -v/--verbose,
4909 status is also displayed for each bookmark like below::
4909 status is also displayed for each bookmark like below::
4910
4910
4911 BM1 01234567890a added
4911 BM1 01234567890a added
4912 BM2 deleted
4912 BM2 deleted
4913 BM3 234567890abc advanced
4913 BM3 234567890abc advanced
4914 BM4 34567890abcd diverged
4914 BM4 34567890abcd diverged
4915 BM5 4567890abcde changed
4915 BM5 4567890abcde changed
4916
4916
4917 The action taken when pushing depends on the
4917 The action taken when pushing depends on the
4918 status of each bookmark:
4918 status of each bookmark:
4919
4919
4920 :``added``: push with ``-B`` will create it
4920 :``added``: push with ``-B`` will create it
4921 :``deleted``: push with ``-B`` will delete it
4921 :``deleted``: push with ``-B`` will delete it
4922 :``advanced``: push will update it
4922 :``advanced``: push will update it
4923 :``diverged``: push with ``-B`` will update it
4923 :``diverged``: push with ``-B`` will update it
4924 :``changed``: push with ``-B`` will update it
4924 :``changed``: push with ``-B`` will update it
4925
4925
4926 From the point of view of pushing behavior, bookmarks
4926 From the point of view of pushing behavior, bookmarks
4927 existing only in the remote repository are treated as
4927 existing only in the remote repository are treated as
4928 ``deleted``, even if it is in fact added remotely.
4928 ``deleted``, even if it is in fact added remotely.
4929
4929
4930 Returns 0 if there are outgoing changes, 1 otherwise.
4930 Returns 0 if there are outgoing changes, 1 otherwise.
4931 """
4931 """
4932 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4932 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4933 # style URLs, so don't overwrite dest.
4933 # style URLs, so don't overwrite dest.
4934 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
4934 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
4935 if not path:
4935 if not path:
4936 raise error.ConfigError(
4936 raise error.ConfigError(
4937 _(b'default repository not configured!'),
4937 _(b'default repository not configured!'),
4938 hint=_(b"see 'hg help config.paths'"),
4938 hint=_(b"see 'hg help config.paths'"),
4939 )
4939 )
4940
4940
4941 opts = pycompat.byteskwargs(opts)
4941 opts = pycompat.byteskwargs(opts)
4942 if opts.get(b'graph'):
4942 if opts.get(b'graph'):
4943 logcmdutil.checkunsupportedgraphflags([], opts)
4943 logcmdutil.checkunsupportedgraphflags([], opts)
4944 o, other = hg._outgoing(ui, repo, dest, opts)
4944 o, other = hg._outgoing(ui, repo, dest, opts)
4945 if not o:
4945 if not o:
4946 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4946 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4947 return
4947 return
4948
4948
4949 revdag = logcmdutil.graphrevs(repo, o, opts)
4949 revdag = logcmdutil.graphrevs(repo, o, opts)
4950 ui.pager(b'outgoing')
4950 ui.pager(b'outgoing')
4951 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4951 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4952 logcmdutil.displaygraph(
4952 logcmdutil.displaygraph(
4953 ui, repo, revdag, displayer, graphmod.asciiedges
4953 ui, repo, revdag, displayer, graphmod.asciiedges
4954 )
4954 )
4955 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4955 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4956 return 0
4956 return 0
4957
4957
4958 if opts.get(b'bookmarks'):
4958 if opts.get(b'bookmarks'):
4959 dest = path.pushloc or path.loc
4959 dest = path.pushloc or path.loc
4960 other = hg.peer(repo, opts, dest)
4960 other = hg.peer(repo, opts, dest)
4961 if b'bookmarks' not in other.listkeys(b'namespaces'):
4961 if b'bookmarks' not in other.listkeys(b'namespaces'):
4962 ui.warn(_(b"remote doesn't support bookmarks\n"))
4962 ui.warn(_(b"remote doesn't support bookmarks\n"))
4963 return 0
4963 return 0
4964 ui.status(_(b'comparing with %s\n') % util.hidepassword(dest))
4964 ui.status(_(b'comparing with %s\n') % util.hidepassword(dest))
4965 ui.pager(b'outgoing')
4965 ui.pager(b'outgoing')
4966 return bookmarks.outgoing(ui, repo, other)
4966 return bookmarks.outgoing(ui, repo, other)
4967
4967
4968 repo._subtoppath = path.pushloc or path.loc
4968 repo._subtoppath = path.pushloc or path.loc
4969 try:
4969 try:
4970 return hg.outgoing(ui, repo, dest, opts)
4970 return hg.outgoing(ui, repo, dest, opts)
4971 finally:
4971 finally:
4972 del repo._subtoppath
4972 del repo._subtoppath
4973
4973
4974
4974
4975 @command(
4975 @command(
4976 b'parents',
4976 b'parents',
4977 [
4977 [
4978 (
4978 (
4979 b'r',
4979 b'r',
4980 b'rev',
4980 b'rev',
4981 b'',
4981 b'',
4982 _(b'show parents of the specified revision'),
4982 _(b'show parents of the specified revision'),
4983 _(b'REV'),
4983 _(b'REV'),
4984 ),
4984 ),
4985 ]
4985 ]
4986 + templateopts,
4986 + templateopts,
4987 _(b'[-r REV] [FILE]'),
4987 _(b'[-r REV] [FILE]'),
4988 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4988 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4989 inferrepo=True,
4989 inferrepo=True,
4990 )
4990 )
4991 def parents(ui, repo, file_=None, **opts):
4991 def parents(ui, repo, file_=None, **opts):
4992 """show the parents of the working directory or revision (DEPRECATED)
4992 """show the parents of the working directory or revision (DEPRECATED)
4993
4993
4994 Print the working directory's parent revisions. If a revision is
4994 Print the working directory's parent revisions. If a revision is
4995 given via -r/--rev, the parent of that revision will be printed.
4995 given via -r/--rev, the parent of that revision will be printed.
4996 If a file argument is given, the revision in which the file was
4996 If a file argument is given, the revision in which the file was
4997 last changed (before the working directory revision or the
4997 last changed (before the working directory revision or the
4998 argument to --rev if given) is printed.
4998 argument to --rev if given) is printed.
4999
4999
5000 This command is equivalent to::
5000 This command is equivalent to::
5001
5001
5002 hg log -r "p1()+p2()" or
5002 hg log -r "p1()+p2()" or
5003 hg log -r "p1(REV)+p2(REV)" or
5003 hg log -r "p1(REV)+p2(REV)" or
5004 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
5004 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
5005 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
5005 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
5006
5006
5007 See :hg:`summary` and :hg:`help revsets` for related information.
5007 See :hg:`summary` and :hg:`help revsets` for related information.
5008
5008
5009 Returns 0 on success.
5009 Returns 0 on success.
5010 """
5010 """
5011
5011
5012 opts = pycompat.byteskwargs(opts)
5012 opts = pycompat.byteskwargs(opts)
5013 rev = opts.get(b'rev')
5013 rev = opts.get(b'rev')
5014 if rev:
5014 if rev:
5015 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
5015 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
5016 ctx = scmutil.revsingle(repo, rev, None)
5016 ctx = scmutil.revsingle(repo, rev, None)
5017
5017
5018 if file_:
5018 if file_:
5019 m = scmutil.match(ctx, (file_,), opts)
5019 m = scmutil.match(ctx, (file_,), opts)
5020 if m.anypats() or len(m.files()) != 1:
5020 if m.anypats() or len(m.files()) != 1:
5021 raise error.InputError(_(b'can only specify an explicit filename'))
5021 raise error.InputError(_(b'can only specify an explicit filename'))
5022 file_ = m.files()[0]
5022 file_ = m.files()[0]
5023 filenodes = []
5023 filenodes = []
5024 for cp in ctx.parents():
5024 for cp in ctx.parents():
5025 if not cp:
5025 if not cp:
5026 continue
5026 continue
5027 try:
5027 try:
5028 filenodes.append(cp.filenode(file_))
5028 filenodes.append(cp.filenode(file_))
5029 except error.LookupError:
5029 except error.LookupError:
5030 pass
5030 pass
5031 if not filenodes:
5031 if not filenodes:
5032 raise error.InputError(_(b"'%s' not found in manifest") % file_)
5032 raise error.InputError(_(b"'%s' not found in manifest") % file_)
5033 p = []
5033 p = []
5034 for fn in filenodes:
5034 for fn in filenodes:
5035 fctx = repo.filectx(file_, fileid=fn)
5035 fctx = repo.filectx(file_, fileid=fn)
5036 p.append(fctx.node())
5036 p.append(fctx.node())
5037 else:
5037 else:
5038 p = [cp.node() for cp in ctx.parents()]
5038 p = [cp.node() for cp in ctx.parents()]
5039
5039
5040 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5040 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5041 for n in p:
5041 for n in p:
5042 if n != nullid:
5042 if n != nullid:
5043 displayer.show(repo[n])
5043 displayer.show(repo[n])
5044 displayer.close()
5044 displayer.close()
5045
5045
5046
5046
5047 @command(
5047 @command(
5048 b'paths',
5048 b'paths',
5049 formatteropts,
5049 formatteropts,
5050 _(b'[NAME]'),
5050 _(b'[NAME]'),
5051 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5051 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5052 optionalrepo=True,
5052 optionalrepo=True,
5053 intents={INTENT_READONLY},
5053 intents={INTENT_READONLY},
5054 )
5054 )
5055 def paths(ui, repo, search=None, **opts):
5055 def paths(ui, repo, search=None, **opts):
5056 """show aliases for remote repositories
5056 """show aliases for remote repositories
5057
5057
5058 Show definition of symbolic path name NAME. If no name is given,
5058 Show definition of symbolic path name NAME. If no name is given,
5059 show definition of all available names.
5059 show definition of all available names.
5060
5060
5061 Option -q/--quiet suppresses all output when searching for NAME
5061 Option -q/--quiet suppresses all output when searching for NAME
5062 and shows only the path names when listing all definitions.
5062 and shows only the path names when listing all definitions.
5063
5063
5064 Path names are defined in the [paths] section of your
5064 Path names are defined in the [paths] section of your
5065 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5065 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5066 repository, ``.hg/hgrc`` is used, too.
5066 repository, ``.hg/hgrc`` is used, too.
5067
5067
5068 The path names ``default`` and ``default-push`` have a special
5068 The path names ``default`` and ``default-push`` have a special
5069 meaning. When performing a push or pull operation, they are used
5069 meaning. When performing a push or pull operation, they are used
5070 as fallbacks if no location is specified on the command-line.
5070 as fallbacks if no location is specified on the command-line.
5071 When ``default-push`` is set, it will be used for push and
5071 When ``default-push`` is set, it will be used for push and
5072 ``default`` will be used for pull; otherwise ``default`` is used
5072 ``default`` will be used for pull; otherwise ``default`` is used
5073 as the fallback for both. When cloning a repository, the clone
5073 as the fallback for both. When cloning a repository, the clone
5074 source is written as ``default`` in ``.hg/hgrc``.
5074 source is written as ``default`` in ``.hg/hgrc``.
5075
5075
5076 .. note::
5076 .. note::
5077
5077
5078 ``default`` and ``default-push`` apply to all inbound (e.g.
5078 ``default`` and ``default-push`` apply to all inbound (e.g.
5079 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
5079 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
5080 and :hg:`bundle`) operations.
5080 and :hg:`bundle`) operations.
5081
5081
5082 See :hg:`help urls` for more information.
5082 See :hg:`help urls` for more information.
5083
5083
5084 .. container:: verbose
5084 .. container:: verbose
5085
5085
5086 Template:
5086 Template:
5087
5087
5088 The following keywords are supported. See also :hg:`help templates`.
5088 The following keywords are supported. See also :hg:`help templates`.
5089
5089
5090 :name: String. Symbolic name of the path alias.
5090 :name: String. Symbolic name of the path alias.
5091 :pushurl: String. URL for push operations.
5091 :pushurl: String. URL for push operations.
5092 :url: String. URL or directory path for the other operations.
5092 :url: String. URL or directory path for the other operations.
5093
5093
5094 Returns 0 on success.
5094 Returns 0 on success.
5095 """
5095 """
5096
5096
5097 opts = pycompat.byteskwargs(opts)
5097 opts = pycompat.byteskwargs(opts)
5098 ui.pager(b'paths')
5098 ui.pager(b'paths')
5099 if search:
5099 if search:
5100 pathitems = [
5100 pathitems = [
5101 (name, path)
5101 (name, path)
5102 for name, path in pycompat.iteritems(ui.paths)
5102 for name, path in pycompat.iteritems(ui.paths)
5103 if name == search
5103 if name == search
5104 ]
5104 ]
5105 else:
5105 else:
5106 pathitems = sorted(pycompat.iteritems(ui.paths))
5106 pathitems = sorted(pycompat.iteritems(ui.paths))
5107
5107
5108 fm = ui.formatter(b'paths', opts)
5108 fm = ui.formatter(b'paths', opts)
5109 if fm.isplain():
5109 if fm.isplain():
5110 hidepassword = util.hidepassword
5110 hidepassword = util.hidepassword
5111 else:
5111 else:
5112 hidepassword = bytes
5112 hidepassword = bytes
5113 if ui.quiet:
5113 if ui.quiet:
5114 namefmt = b'%s\n'
5114 namefmt = b'%s\n'
5115 else:
5115 else:
5116 namefmt = b'%s = '
5116 namefmt = b'%s = '
5117 showsubopts = not search and not ui.quiet
5117 showsubopts = not search and not ui.quiet
5118
5118
5119 for name, path in pathitems:
5119 for name, path in pathitems:
5120 fm.startitem()
5120 fm.startitem()
5121 fm.condwrite(not search, b'name', namefmt, name)
5121 fm.condwrite(not search, b'name', namefmt, name)
5122 fm.condwrite(not ui.quiet, b'url', b'%s\n', hidepassword(path.rawloc))
5122 fm.condwrite(not ui.quiet, b'url', b'%s\n', hidepassword(path.rawloc))
5123 for subopt, value in sorted(path.suboptions.items()):
5123 for subopt, value in sorted(path.suboptions.items()):
5124 assert subopt not in (b'name', b'url')
5124 assert subopt not in (b'name', b'url')
5125 if showsubopts:
5125 if showsubopts:
5126 fm.plain(b'%s:%s = ' % (name, subopt))
5126 fm.plain(b'%s:%s = ' % (name, subopt))
5127 fm.condwrite(showsubopts, subopt, b'%s\n', value)
5127 fm.condwrite(showsubopts, subopt, b'%s\n', value)
5128
5128
5129 fm.end()
5129 fm.end()
5130
5130
5131 if search and not pathitems:
5131 if search and not pathitems:
5132 if not ui.quiet:
5132 if not ui.quiet:
5133 ui.warn(_(b"not found!\n"))
5133 ui.warn(_(b"not found!\n"))
5134 return 1
5134 return 1
5135 else:
5135 else:
5136 return 0
5136 return 0
5137
5137
5138
5138
5139 @command(
5139 @command(
5140 b'phase',
5140 b'phase',
5141 [
5141 [
5142 (b'p', b'public', False, _(b'set changeset phase to public')),
5142 (b'p', b'public', False, _(b'set changeset phase to public')),
5143 (b'd', b'draft', False, _(b'set changeset phase to draft')),
5143 (b'd', b'draft', False, _(b'set changeset phase to draft')),
5144 (b's', b'secret', False, _(b'set changeset phase to secret')),
5144 (b's', b'secret', False, _(b'set changeset phase to secret')),
5145 (b'f', b'force', False, _(b'allow to move boundary backward')),
5145 (b'f', b'force', False, _(b'allow to move boundary backward')),
5146 (b'r', b'rev', [], _(b'target revision'), _(b'REV')),
5146 (b'r', b'rev', [], _(b'target revision'), _(b'REV')),
5147 ],
5147 ],
5148 _(b'[-p|-d|-s] [-f] [-r] [REV...]'),
5148 _(b'[-p|-d|-s] [-f] [-r] [REV...]'),
5149 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5149 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5150 )
5150 )
5151 def phase(ui, repo, *revs, **opts):
5151 def phase(ui, repo, *revs, **opts):
5152 """set or show the current phase name
5152 """set or show the current phase name
5153
5153
5154 With no argument, show the phase name of the current revision(s).
5154 With no argument, show the phase name of the current revision(s).
5155
5155
5156 With one of -p/--public, -d/--draft or -s/--secret, change the
5156 With one of -p/--public, -d/--draft or -s/--secret, change the
5157 phase value of the specified revisions.
5157 phase value of the specified revisions.
5158
5158
5159 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
5159 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
5160 lower phase to a higher phase. Phases are ordered as follows::
5160 lower phase to a higher phase. Phases are ordered as follows::
5161
5161
5162 public < draft < secret
5162 public < draft < secret
5163
5163
5164 Returns 0 on success, 1 if some phases could not be changed.
5164 Returns 0 on success, 1 if some phases could not be changed.
5165
5165
5166 (For more information about the phases concept, see :hg:`help phases`.)
5166 (For more information about the phases concept, see :hg:`help phases`.)
5167 """
5167 """
5168 opts = pycompat.byteskwargs(opts)
5168 opts = pycompat.byteskwargs(opts)
5169 # search for a unique phase argument
5169 # search for a unique phase argument
5170 targetphase = None
5170 targetphase = None
5171 for idx, name in enumerate(phases.cmdphasenames):
5171 for idx, name in enumerate(phases.cmdphasenames):
5172 if opts[name]:
5172 if opts[name]:
5173 if targetphase is not None:
5173 if targetphase is not None:
5174 raise error.InputError(_(b'only one phase can be specified'))
5174 raise error.InputError(_(b'only one phase can be specified'))
5175 targetphase = idx
5175 targetphase = idx
5176
5176
5177 # look for specified revision
5177 # look for specified revision
5178 revs = list(revs)
5178 revs = list(revs)
5179 revs.extend(opts[b'rev'])
5179 revs.extend(opts[b'rev'])
5180 if not revs:
5180 if not revs:
5181 # display both parents as the second parent phase can influence
5181 # display both parents as the second parent phase can influence
5182 # the phase of a merge commit
5182 # the phase of a merge commit
5183 revs = [c.rev() for c in repo[None].parents()]
5183 revs = [c.rev() for c in repo[None].parents()]
5184
5184
5185 revs = scmutil.revrange(repo, revs)
5185 revs = scmutil.revrange(repo, revs)
5186
5186
5187 ret = 0
5187 ret = 0
5188 if targetphase is None:
5188 if targetphase is None:
5189 # display
5189 # display
5190 for r in revs:
5190 for r in revs:
5191 ctx = repo[r]
5191 ctx = repo[r]
5192 ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5192 ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5193 else:
5193 else:
5194 with repo.lock(), repo.transaction(b"phase") as tr:
5194 with repo.lock(), repo.transaction(b"phase") as tr:
5195 # set phase
5195 # set phase
5196 if not revs:
5196 if not revs:
5197 raise error.InputError(_(b'empty revision set'))
5197 raise error.InputError(_(b'empty revision set'))
5198 nodes = [repo[r].node() for r in revs]
5198 nodes = [repo[r].node() for r in revs]
5199 # moving revision from public to draft may hide them
5199 # moving revision from public to draft may hide them
5200 # We have to check result on an unfiltered repository
5200 # We have to check result on an unfiltered repository
5201 unfi = repo.unfiltered()
5201 unfi = repo.unfiltered()
5202 getphase = unfi._phasecache.phase
5202 getphase = unfi._phasecache.phase
5203 olddata = [getphase(unfi, r) for r in unfi]
5203 olddata = [getphase(unfi, r) for r in unfi]
5204 phases.advanceboundary(repo, tr, targetphase, nodes)
5204 phases.advanceboundary(repo, tr, targetphase, nodes)
5205 if opts[b'force']:
5205 if opts[b'force']:
5206 phases.retractboundary(repo, tr, targetphase, nodes)
5206 phases.retractboundary(repo, tr, targetphase, nodes)
5207 getphase = unfi._phasecache.phase
5207 getphase = unfi._phasecache.phase
5208 newdata = [getphase(unfi, r) for r in unfi]
5208 newdata = [getphase(unfi, r) for r in unfi]
5209 changes = sum(newdata[r] != olddata[r] for r in unfi)
5209 changes = sum(newdata[r] != olddata[r] for r in unfi)
5210 cl = unfi.changelog
5210 cl = unfi.changelog
5211 rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
5211 rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
5212 if rejected:
5212 if rejected:
5213 ui.warn(
5213 ui.warn(
5214 _(
5214 _(
5215 b'cannot move %i changesets to a higher '
5215 b'cannot move %i changesets to a higher '
5216 b'phase, use --force\n'
5216 b'phase, use --force\n'
5217 )
5217 )
5218 % len(rejected)
5218 % len(rejected)
5219 )
5219 )
5220 ret = 1
5220 ret = 1
5221 if changes:
5221 if changes:
5222 msg = _(b'phase changed for %i changesets\n') % changes
5222 msg = _(b'phase changed for %i changesets\n') % changes
5223 if ret:
5223 if ret:
5224 ui.status(msg)
5224 ui.status(msg)
5225 else:
5225 else:
5226 ui.note(msg)
5226 ui.note(msg)
5227 else:
5227 else:
5228 ui.warn(_(b'no phases changed\n'))
5228 ui.warn(_(b'no phases changed\n'))
5229 return ret
5229 return ret
5230
5230
5231
5231
5232 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
5232 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
5233 """Run after a changegroup has been added via pull/unbundle
5233 """Run after a changegroup has been added via pull/unbundle
5234
5234
5235 This takes arguments below:
5235 This takes arguments below:
5236
5236
5237 :modheads: change of heads by pull/unbundle
5237 :modheads: change of heads by pull/unbundle
5238 :optupdate: updating working directory is needed or not
5238 :optupdate: updating working directory is needed or not
5239 :checkout: update destination revision (or None to default destination)
5239 :checkout: update destination revision (or None to default destination)
5240 :brev: a name, which might be a bookmark to be activated after updating
5240 :brev: a name, which might be a bookmark to be activated after updating
5241 """
5241 """
5242 if modheads == 0:
5242 if modheads == 0:
5243 return
5243 return
5244 if optupdate:
5244 if optupdate:
5245 try:
5245 try:
5246 return hg.updatetotally(ui, repo, checkout, brev)
5246 return hg.updatetotally(ui, repo, checkout, brev)
5247 except error.UpdateAbort as inst:
5247 except error.UpdateAbort as inst:
5248 msg = _(b"not updating: %s") % stringutil.forcebytestr(inst)
5248 msg = _(b"not updating: %s") % stringutil.forcebytestr(inst)
5249 hint = inst.hint
5249 hint = inst.hint
5250 raise error.UpdateAbort(msg, hint=hint)
5250 raise error.UpdateAbort(msg, hint=hint)
5251 if modheads is not None and modheads > 1:
5251 if modheads is not None and modheads > 1:
5252 currentbranchheads = len(repo.branchheads())
5252 currentbranchheads = len(repo.branchheads())
5253 if currentbranchheads == modheads:
5253 if currentbranchheads == modheads:
5254 ui.status(
5254 ui.status(
5255 _(b"(run 'hg heads' to see heads, 'hg merge' to merge)\n")
5255 _(b"(run 'hg heads' to see heads, 'hg merge' to merge)\n")
5256 )
5256 )
5257 elif currentbranchheads > 1:
5257 elif currentbranchheads > 1:
5258 ui.status(
5258 ui.status(
5259 _(b"(run 'hg heads .' to see heads, 'hg merge' to merge)\n")
5259 _(b"(run 'hg heads .' to see heads, 'hg merge' to merge)\n")
5260 )
5260 )
5261 else:
5261 else:
5262 ui.status(_(b"(run 'hg heads' to see heads)\n"))
5262 ui.status(_(b"(run 'hg heads' to see heads)\n"))
5263 elif not ui.configbool(b'commands', b'update.requiredest'):
5263 elif not ui.configbool(b'commands', b'update.requiredest'):
5264 ui.status(_(b"(run 'hg update' to get a working copy)\n"))
5264 ui.status(_(b"(run 'hg update' to get a working copy)\n"))
5265
5265
5266
5266
5267 @command(
5267 @command(
5268 b'pull',
5268 b'pull',
5269 [
5269 [
5270 (
5270 (
5271 b'u',
5271 b'u',
5272 b'update',
5272 b'update',
5273 None,
5273 None,
5274 _(b'update to new branch head if new descendants were pulled'),
5274 _(b'update to new branch head if new descendants were pulled'),
5275 ),
5275 ),
5276 (
5276 (
5277 b'f',
5277 b'f',
5278 b'force',
5278 b'force',
5279 None,
5279 None,
5280 _(b'run even when remote repository is unrelated'),
5280 _(b'run even when remote repository is unrelated'),
5281 ),
5281 ),
5282 (
5282 (
5283 b'',
5283 b'',
5284 b'confirm',
5284 b'confirm',
5285 None,
5285 None,
5286 _(b'confirm pull before applying changes'),
5286 _(b'confirm pull before applying changes'),
5287 ),
5287 ),
5288 (
5288 (
5289 b'r',
5289 b'r',
5290 b'rev',
5290 b'rev',
5291 [],
5291 [],
5292 _(b'a remote changeset intended to be added'),
5292 _(b'a remote changeset intended to be added'),
5293 _(b'REV'),
5293 _(b'REV'),
5294 ),
5294 ),
5295 (b'B', b'bookmark', [], _(b"bookmark to pull"), _(b'BOOKMARK')),
5295 (b'B', b'bookmark', [], _(b"bookmark to pull"), _(b'BOOKMARK')),
5296 (
5296 (
5297 b'b',
5297 b'b',
5298 b'branch',
5298 b'branch',
5299 [],
5299 [],
5300 _(b'a specific branch you would like to pull'),
5300 _(b'a specific branch you would like to pull'),
5301 _(b'BRANCH'),
5301 _(b'BRANCH'),
5302 ),
5302 ),
5303 ]
5303 ]
5304 + remoteopts,
5304 + remoteopts,
5305 _(b'[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
5305 _(b'[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
5306 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5306 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5307 helpbasic=True,
5307 helpbasic=True,
5308 )
5308 )
5309 def pull(ui, repo, source=b"default", **opts):
5309 def pull(ui, repo, source=b"default", **opts):
5310 """pull changes from the specified source
5310 """pull changes from the specified source
5311
5311
5312 Pull changes from a remote repository to a local one.
5312 Pull changes from a remote repository to a local one.
5313
5313
5314 This finds all changes from the repository at the specified path
5314 This finds all changes from the repository at the specified path
5315 or URL and adds them to a local repository (the current one unless
5315 or URL and adds them to a local repository (the current one unless
5316 -R is specified). By default, this does not update the copy of the
5316 -R is specified). By default, this does not update the copy of the
5317 project in the working directory.
5317 project in the working directory.
5318
5318
5319 When cloning from servers that support it, Mercurial may fetch
5319 When cloning from servers that support it, Mercurial may fetch
5320 pre-generated data. When this is done, hooks operating on incoming
5320 pre-generated data. When this is done, hooks operating on incoming
5321 changesets and changegroups may fire more than once, once for each
5321 changesets and changegroups may fire more than once, once for each
5322 pre-generated bundle and as well as for any additional remaining
5322 pre-generated bundle and as well as for any additional remaining
5323 data. See :hg:`help -e clonebundles` for more.
5323 data. See :hg:`help -e clonebundles` for more.
5324
5324
5325 Use :hg:`incoming` if you want to see what would have been added
5325 Use :hg:`incoming` if you want to see what would have been added
5326 by a pull at the time you issued this command. If you then decide
5326 by a pull at the time you issued this command. If you then decide
5327 to add those changes to the repository, you should use :hg:`pull
5327 to add those changes to the repository, you should use :hg:`pull
5328 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5328 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5329
5329
5330 If SOURCE is omitted, the 'default' path will be used.
5330 If SOURCE is omitted, the 'default' path will be used.
5331 See :hg:`help urls` for more information.
5331 See :hg:`help urls` for more information.
5332
5332
5333 Specifying bookmark as ``.`` is equivalent to specifying the active
5333 Specifying bookmark as ``.`` is equivalent to specifying the active
5334 bookmark's name.
5334 bookmark's name.
5335
5335
5336 Returns 0 on success, 1 if an update had unresolved files.
5336 Returns 0 on success, 1 if an update had unresolved files.
5337 """
5337 """
5338
5338
5339 opts = pycompat.byteskwargs(opts)
5339 opts = pycompat.byteskwargs(opts)
5340 if ui.configbool(b'commands', b'update.requiredest') and opts.get(
5340 if ui.configbool(b'commands', b'update.requiredest') and opts.get(
5341 b'update'
5341 b'update'
5342 ):
5342 ):
5343 msg = _(b'update destination required by configuration')
5343 msg = _(b'update destination required by configuration')
5344 hint = _(b'use hg pull followed by hg update DEST')
5344 hint = _(b'use hg pull followed by hg update DEST')
5345 raise error.InputError(msg, hint=hint)
5345 raise error.InputError(msg, hint=hint)
5346
5346
5347 source, branches = hg.parseurl(ui.expandpath(source), opts.get(b'branch'))
5347 source, branches = hg.parseurl(ui.expandpath(source), opts.get(b'branch'))
5348 ui.status(_(b'pulling from %s\n') % util.hidepassword(source))
5348 ui.status(_(b'pulling from %s\n') % util.hidepassword(source))
5349 ui.flush()
5349 ui.flush()
5350 other = hg.peer(repo, opts, source)
5350 other = hg.peer(repo, opts, source)
5351 try:
5351 try:
5352 revs, checkout = hg.addbranchrevs(
5352 revs, checkout = hg.addbranchrevs(
5353 repo, other, branches, opts.get(b'rev')
5353 repo, other, branches, opts.get(b'rev')
5354 )
5354 )
5355
5355
5356 pullopargs = {}
5356 pullopargs = {}
5357
5357
5358 nodes = None
5358 nodes = None
5359 if opts.get(b'bookmark') or revs:
5359 if opts.get(b'bookmark') or revs:
5360 # The list of bookmark used here is the same used to actually update
5360 # The list of bookmark used here is the same used to actually update
5361 # the bookmark names, to avoid the race from issue 4689 and we do
5361 # the bookmark names, to avoid the race from issue 4689 and we do
5362 # all lookup and bookmark queries in one go so they see the same
5362 # all lookup and bookmark queries in one go so they see the same
5363 # version of the server state (issue 4700).
5363 # version of the server state (issue 4700).
5364 nodes = []
5364 nodes = []
5365 fnodes = []
5365 fnodes = []
5366 revs = revs or []
5366 revs = revs or []
5367 if revs and not other.capable(b'lookup'):
5367 if revs and not other.capable(b'lookup'):
5368 err = _(
5368 err = _(
5369 b"other repository doesn't support revision lookup, "
5369 b"other repository doesn't support revision lookup, "
5370 b"so a rev cannot be specified."
5370 b"so a rev cannot be specified."
5371 )
5371 )
5372 raise error.Abort(err)
5372 raise error.Abort(err)
5373 with other.commandexecutor() as e:
5373 with other.commandexecutor() as e:
5374 fremotebookmarks = e.callcommand(
5374 fremotebookmarks = e.callcommand(
5375 b'listkeys', {b'namespace': b'bookmarks'}
5375 b'listkeys', {b'namespace': b'bookmarks'}
5376 )
5376 )
5377 for r in revs:
5377 for r in revs:
5378 fnodes.append(e.callcommand(b'lookup', {b'key': r}))
5378 fnodes.append(e.callcommand(b'lookup', {b'key': r}))
5379 remotebookmarks = fremotebookmarks.result()
5379 remotebookmarks = fremotebookmarks.result()
5380 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
5380 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
5381 pullopargs[b'remotebookmarks'] = remotebookmarks
5381 pullopargs[b'remotebookmarks'] = remotebookmarks
5382 for b in opts.get(b'bookmark', []):
5382 for b in opts.get(b'bookmark', []):
5383 b = repo._bookmarks.expandname(b)
5383 b = repo._bookmarks.expandname(b)
5384 if b not in remotebookmarks:
5384 if b not in remotebookmarks:
5385 raise error.InputError(
5385 raise error.InputError(
5386 _(b'remote bookmark %s not found!') % b
5386 _(b'remote bookmark %s not found!') % b
5387 )
5387 )
5388 nodes.append(remotebookmarks[b])
5388 nodes.append(remotebookmarks[b])
5389 for i, rev in enumerate(revs):
5389 for i, rev in enumerate(revs):
5390 node = fnodes[i].result()
5390 node = fnodes[i].result()
5391 nodes.append(node)
5391 nodes.append(node)
5392 if rev == checkout:
5392 if rev == checkout:
5393 checkout = node
5393 checkout = node
5394
5394
5395 wlock = util.nullcontextmanager()
5395 wlock = util.nullcontextmanager()
5396 if opts.get(b'update'):
5396 if opts.get(b'update'):
5397 wlock = repo.wlock()
5397 wlock = repo.wlock()
5398 with wlock:
5398 with wlock:
5399 pullopargs.update(opts.get(b'opargs', {}))
5399 pullopargs.update(opts.get(b'opargs', {}))
5400 modheads = exchange.pull(
5400 modheads = exchange.pull(
5401 repo,
5401 repo,
5402 other,
5402 other,
5403 heads=nodes,
5403 heads=nodes,
5404 force=opts.get(b'force'),
5404 force=opts.get(b'force'),
5405 bookmarks=opts.get(b'bookmark', ()),
5405 bookmarks=opts.get(b'bookmark', ()),
5406 opargs=pullopargs,
5406 opargs=pullopargs,
5407 confirm=opts.get(b'confirm'),
5407 confirm=opts.get(b'confirm'),
5408 ).cgresult
5408 ).cgresult
5409
5409
5410 # brev is a name, which might be a bookmark to be activated at
5410 # brev is a name, which might be a bookmark to be activated at
5411 # the end of the update. In other words, it is an explicit
5411 # the end of the update. In other words, it is an explicit
5412 # destination of the update
5412 # destination of the update
5413 brev = None
5413 brev = None
5414
5414
5415 if checkout:
5415 if checkout:
5416 checkout = repo.unfiltered().changelog.rev(checkout)
5416 checkout = repo.unfiltered().changelog.rev(checkout)
5417
5417
5418 # order below depends on implementation of
5418 # order below depends on implementation of
5419 # hg.addbranchrevs(). opts['bookmark'] is ignored,
5419 # hg.addbranchrevs(). opts['bookmark'] is ignored,
5420 # because 'checkout' is determined without it.
5420 # because 'checkout' is determined without it.
5421 if opts.get(b'rev'):
5421 if opts.get(b'rev'):
5422 brev = opts[b'rev'][0]
5422 brev = opts[b'rev'][0]
5423 elif opts.get(b'branch'):
5423 elif opts.get(b'branch'):
5424 brev = opts[b'branch'][0]
5424 brev = opts[b'branch'][0]
5425 else:
5425 else:
5426 brev = branches[0]
5426 brev = branches[0]
5427 repo._subtoppath = source
5427 repo._subtoppath = source
5428 try:
5428 try:
5429 ret = postincoming(
5429 ret = postincoming(
5430 ui, repo, modheads, opts.get(b'update'), checkout, brev
5430 ui, repo, modheads, opts.get(b'update'), checkout, brev
5431 )
5431 )
5432 except error.FilteredRepoLookupError as exc:
5432 except error.FilteredRepoLookupError as exc:
5433 msg = _(b'cannot update to target: %s') % exc.args[0]
5433 msg = _(b'cannot update to target: %s') % exc.args[0]
5434 exc.args = (msg,) + exc.args[1:]
5434 exc.args = (msg,) + exc.args[1:]
5435 raise
5435 raise
5436 finally:
5436 finally:
5437 del repo._subtoppath
5437 del repo._subtoppath
5438
5438
5439 finally:
5439 finally:
5440 other.close()
5440 other.close()
5441 return ret
5441 return ret
5442
5442
5443
5443
5444 @command(
5444 @command(
5445 b'push',
5445 b'push',
5446 [
5446 [
5447 (b'f', b'force', None, _(b'force push')),
5447 (b'f', b'force', None, _(b'force push')),
5448 (
5448 (
5449 b'r',
5449 b'r',
5450 b'rev',
5450 b'rev',
5451 [],
5451 [],
5452 _(b'a changeset intended to be included in the destination'),
5452 _(b'a changeset intended to be included in the destination'),
5453 _(b'REV'),
5453 _(b'REV'),
5454 ),
5454 ),
5455 (b'B', b'bookmark', [], _(b"bookmark to push"), _(b'BOOKMARK')),
5455 (b'B', b'bookmark', [], _(b"bookmark to push"), _(b'BOOKMARK')),
5456 (b'', b'all-bookmarks', None, _(b"push all bookmarks (EXPERIMENTAL)")),
5456 (b'', b'all-bookmarks', None, _(b"push all bookmarks (EXPERIMENTAL)")),
5457 (
5457 (
5458 b'b',
5458 b'b',
5459 b'branch',
5459 b'branch',
5460 [],
5460 [],
5461 _(b'a specific branch you would like to push'),
5461 _(b'a specific branch you would like to push'),
5462 _(b'BRANCH'),
5462 _(b'BRANCH'),
5463 ),
5463 ),
5464 (b'', b'new-branch', False, _(b'allow pushing a new branch')),
5464 (b'', b'new-branch', False, _(b'allow pushing a new branch')),
5465 (
5465 (
5466 b'',
5466 b'',
5467 b'pushvars',
5467 b'pushvars',
5468 [],
5468 [],
5469 _(b'variables that can be sent to server (ADVANCED)'),
5469 _(b'variables that can be sent to server (ADVANCED)'),
5470 ),
5470 ),
5471 (
5471 (
5472 b'',
5472 b'',
5473 b'publish',
5473 b'publish',
5474 False,
5474 False,
5475 _(b'push the changeset as public (EXPERIMENTAL)'),
5475 _(b'push the changeset as public (EXPERIMENTAL)'),
5476 ),
5476 ),
5477 ]
5477 ]
5478 + remoteopts,
5478 + remoteopts,
5479 _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
5479 _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
5480 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5480 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5481 helpbasic=True,
5481 helpbasic=True,
5482 )
5482 )
5483 def push(ui, repo, dest=None, **opts):
5483 def push(ui, repo, dest=None, **opts):
5484 """push changes to the specified destination
5484 """push changes to the specified destination
5485
5485
5486 Push changesets from the local repository to the specified
5486 Push changesets from the local repository to the specified
5487 destination.
5487 destination.
5488
5488
5489 This operation is symmetrical to pull: it is identical to a pull
5489 This operation is symmetrical to pull: it is identical to a pull
5490 in the destination repository from the current one.
5490 in the destination repository from the current one.
5491
5491
5492 By default, push will not allow creation of new heads at the
5492 By default, push will not allow creation of new heads at the
5493 destination, since multiple heads would make it unclear which head
5493 destination, since multiple heads would make it unclear which head
5494 to use. In this situation, it is recommended to pull and merge
5494 to use. In this situation, it is recommended to pull and merge
5495 before pushing.
5495 before pushing.
5496
5496
5497 Use --new-branch if you want to allow push to create a new named
5497 Use --new-branch if you want to allow push to create a new named
5498 branch that is not present at the destination. This allows you to
5498 branch that is not present at the destination. This allows you to
5499 only create a new branch without forcing other changes.
5499 only create a new branch without forcing other changes.
5500
5500
5501 .. note::
5501 .. note::
5502
5502
5503 Extra care should be taken with the -f/--force option,
5503 Extra care should be taken with the -f/--force option,
5504 which will push all new heads on all branches, an action which will
5504 which will push all new heads on all branches, an action which will
5505 almost always cause confusion for collaborators.
5505 almost always cause confusion for collaborators.
5506
5506
5507 If -r/--rev is used, the specified revision and all its ancestors
5507 If -r/--rev is used, the specified revision and all its ancestors
5508 will be pushed to the remote repository.
5508 will be pushed to the remote repository.
5509
5509
5510 If -B/--bookmark is used, the specified bookmarked revision, its
5510 If -B/--bookmark is used, the specified bookmarked revision, its
5511 ancestors, and the bookmark will be pushed to the remote
5511 ancestors, and the bookmark will be pushed to the remote
5512 repository. Specifying ``.`` is equivalent to specifying the active
5512 repository. Specifying ``.`` is equivalent to specifying the active
5513 bookmark's name. Use the --all-bookmarks option for pushing all
5513 bookmark's name. Use the --all-bookmarks option for pushing all
5514 current bookmarks.
5514 current bookmarks.
5515
5515
5516 Please see :hg:`help urls` for important details about ``ssh://``
5516 Please see :hg:`help urls` for important details about ``ssh://``
5517 URLs. If DESTINATION is omitted, a default path will be used.
5517 URLs. If DESTINATION is omitted, a default path will be used.
5518
5518
5519 .. container:: verbose
5519 .. container:: verbose
5520
5520
5521 The --pushvars option sends strings to the server that become
5521 The --pushvars option sends strings to the server that become
5522 environment variables prepended with ``HG_USERVAR_``. For example,
5522 environment variables prepended with ``HG_USERVAR_``. For example,
5523 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
5523 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
5524 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
5524 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
5525
5525
5526 pushvars can provide for user-overridable hooks as well as set debug
5526 pushvars can provide for user-overridable hooks as well as set debug
5527 levels. One example is having a hook that blocks commits containing
5527 levels. One example is having a hook that blocks commits containing
5528 conflict markers, but enables the user to override the hook if the file
5528 conflict markers, but enables the user to override the hook if the file
5529 is using conflict markers for testing purposes or the file format has
5529 is using conflict markers for testing purposes or the file format has
5530 strings that look like conflict markers.
5530 strings that look like conflict markers.
5531
5531
5532 By default, servers will ignore `--pushvars`. To enable it add the
5532 By default, servers will ignore `--pushvars`. To enable it add the
5533 following to your configuration file::
5533 following to your configuration file::
5534
5534
5535 [push]
5535 [push]
5536 pushvars.server = true
5536 pushvars.server = true
5537
5537
5538 Returns 0 if push was successful, 1 if nothing to push.
5538 Returns 0 if push was successful, 1 if nothing to push.
5539 """
5539 """
5540
5540
5541 opts = pycompat.byteskwargs(opts)
5541 opts = pycompat.byteskwargs(opts)
5542
5542
5543 if opts.get(b'all_bookmarks'):
5543 if opts.get(b'all_bookmarks'):
5544 cmdutil.check_incompatible_arguments(
5544 cmdutil.check_incompatible_arguments(
5545 opts,
5545 opts,
5546 b'all_bookmarks',
5546 b'all_bookmarks',
5547 [b'bookmark', b'rev'],
5547 [b'bookmark', b'rev'],
5548 )
5548 )
5549 opts[b'bookmark'] = list(repo._bookmarks)
5549 opts[b'bookmark'] = list(repo._bookmarks)
5550
5550
5551 if opts.get(b'bookmark'):
5551 if opts.get(b'bookmark'):
5552 ui.setconfig(b'bookmarks', b'pushing', opts[b'bookmark'], b'push')
5552 ui.setconfig(b'bookmarks', b'pushing', opts[b'bookmark'], b'push')
5553 for b in opts[b'bookmark']:
5553 for b in opts[b'bookmark']:
5554 # translate -B options to -r so changesets get pushed
5554 # translate -B options to -r so changesets get pushed
5555 b = repo._bookmarks.expandname(b)
5555 b = repo._bookmarks.expandname(b)
5556 if b in repo._bookmarks:
5556 if b in repo._bookmarks:
5557 opts.setdefault(b'rev', []).append(b)
5557 opts.setdefault(b'rev', []).append(b)
5558 else:
5558 else:
5559 # if we try to push a deleted bookmark, translate it to null
5559 # if we try to push a deleted bookmark, translate it to null
5560 # this lets simultaneous -r, -b options continue working
5560 # this lets simultaneous -r, -b options continue working
5561 opts.setdefault(b'rev', []).append(b"null")
5561 opts.setdefault(b'rev', []).append(b"null")
5562
5562
5563 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
5563 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
5564 if not path:
5564 if not path:
5565 raise error.ConfigError(
5565 raise error.ConfigError(
5566 _(b'default repository not configured!'),
5566 _(b'default repository not configured!'),
5567 hint=_(b"see 'hg help config.paths'"),
5567 hint=_(b"see 'hg help config.paths'"),
5568 )
5568 )
5569 dest = path.pushloc or path.loc
5569 dest = path.pushloc or path.loc
5570 branches = (path.branch, opts.get(b'branch') or [])
5570 branches = (path.branch, opts.get(b'branch') or [])
5571 ui.status(_(b'pushing to %s\n') % util.hidepassword(dest))
5571 ui.status(_(b'pushing to %s\n') % util.hidepassword(dest))
5572 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get(b'rev'))
5572 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get(b'rev'))
5573 other = hg.peer(repo, opts, dest)
5573 other = hg.peer(repo, opts, dest)
5574
5574
5575 if revs:
5575 if revs:
5576 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
5576 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
5577 if not revs:
5577 if not revs:
5578 raise error.InputError(
5578 raise error.InputError(
5579 _(b"specified revisions evaluate to an empty set"),
5579 _(b"specified revisions evaluate to an empty set"),
5580 hint=_(b"use different revision arguments"),
5580 hint=_(b"use different revision arguments"),
5581 )
5581 )
5582 elif path.pushrev:
5582 elif path.pushrev:
5583 # It doesn't make any sense to specify ancestor revisions. So limit
5583 # It doesn't make any sense to specify ancestor revisions. So limit
5584 # to DAG heads to make discovery simpler.
5584 # to DAG heads to make discovery simpler.
5585 expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
5585 expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
5586 revs = scmutil.revrange(repo, [expr])
5586 revs = scmutil.revrange(repo, [expr])
5587 revs = [repo[rev].node() for rev in revs]
5587 revs = [repo[rev].node() for rev in revs]
5588 if not revs:
5588 if not revs:
5589 raise error.InputError(
5589 raise error.InputError(
5590 _(b'default push revset for path evaluates to an empty set')
5590 _(b'default push revset for path evaluates to an empty set')
5591 )
5591 )
5592 elif ui.configbool(b'commands', b'push.require-revs'):
5592 elif ui.configbool(b'commands', b'push.require-revs'):
5593 raise error.InputError(
5593 raise error.InputError(
5594 _(b'no revisions specified to push'),
5594 _(b'no revisions specified to push'),
5595 hint=_(b'did you mean "hg push -r ."?'),
5595 hint=_(b'did you mean "hg push -r ."?'),
5596 )
5596 )
5597
5597
5598 repo._subtoppath = dest
5598 repo._subtoppath = dest
5599 try:
5599 try:
5600 # push subrepos depth-first for coherent ordering
5600 # push subrepos depth-first for coherent ordering
5601 c = repo[b'.']
5601 c = repo[b'.']
5602 subs = c.substate # only repos that are committed
5602 subs = c.substate # only repos that are committed
5603 for s in sorted(subs):
5603 for s in sorted(subs):
5604 result = c.sub(s).push(opts)
5604 result = c.sub(s).push(opts)
5605 if result == 0:
5605 if result == 0:
5606 return not result
5606 return not result
5607 finally:
5607 finally:
5608 del repo._subtoppath
5608 del repo._subtoppath
5609
5609
5610 opargs = dict(opts.get(b'opargs', {})) # copy opargs since we may mutate it
5610 opargs = dict(opts.get(b'opargs', {})) # copy opargs since we may mutate it
5611 opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
5611 opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
5612
5612
5613 pushop = exchange.push(
5613 pushop = exchange.push(
5614 repo,
5614 repo,
5615 other,
5615 other,
5616 opts.get(b'force'),
5616 opts.get(b'force'),
5617 revs=revs,
5617 revs=revs,
5618 newbranch=opts.get(b'new_branch'),
5618 newbranch=opts.get(b'new_branch'),
5619 bookmarks=opts.get(b'bookmark', ()),
5619 bookmarks=opts.get(b'bookmark', ()),
5620 publish=opts.get(b'publish'),
5620 publish=opts.get(b'publish'),
5621 opargs=opargs,
5621 opargs=opargs,
5622 )
5622 )
5623
5623
5624 result = not pushop.cgresult
5624 result = not pushop.cgresult
5625
5625
5626 if pushop.bkresult is not None:
5626 if pushop.bkresult is not None:
5627 if pushop.bkresult == 2:
5627 if pushop.bkresult == 2:
5628 result = 2
5628 result = 2
5629 elif not result and pushop.bkresult:
5629 elif not result and pushop.bkresult:
5630 result = 2
5630 result = 2
5631
5631
5632 return result
5632 return result
5633
5633
5634
5634
5635 @command(
5635 @command(
5636 b'recover',
5636 b'recover',
5637 [
5637 [
5638 (b'', b'verify', False, b"run `hg verify` after successful recover"),
5638 (b'', b'verify', False, b"run `hg verify` after successful recover"),
5639 ],
5639 ],
5640 helpcategory=command.CATEGORY_MAINTENANCE,
5640 helpcategory=command.CATEGORY_MAINTENANCE,
5641 )
5641 )
5642 def recover(ui, repo, **opts):
5642 def recover(ui, repo, **opts):
5643 """roll back an interrupted transaction
5643 """roll back an interrupted transaction
5644
5644
5645 Recover from an interrupted commit or pull.
5645 Recover from an interrupted commit or pull.
5646
5646
5647 This command tries to fix the repository status after an
5647 This command tries to fix the repository status after an
5648 interrupted operation. It should only be necessary when Mercurial
5648 interrupted operation. It should only be necessary when Mercurial
5649 suggests it.
5649 suggests it.
5650
5650
5651 Returns 0 if successful, 1 if nothing to recover or verify fails.
5651 Returns 0 if successful, 1 if nothing to recover or verify fails.
5652 """
5652 """
5653 ret = repo.recover()
5653 ret = repo.recover()
5654 if ret:
5654 if ret:
5655 if opts['verify']:
5655 if opts['verify']:
5656 return hg.verify(repo)
5656 return hg.verify(repo)
5657 else:
5657 else:
5658 msg = _(
5658 msg = _(
5659 b"(verify step skipped, run `hg verify` to check your "
5659 b"(verify step skipped, run `hg verify` to check your "
5660 b"repository content)\n"
5660 b"repository content)\n"
5661 )
5661 )
5662 ui.warn(msg)
5662 ui.warn(msg)
5663 return 0
5663 return 0
5664 return 1
5664 return 1
5665
5665
5666
5666
5667 @command(
5667 @command(
5668 b'remove|rm',
5668 b'remove|rm',
5669 [
5669 [
5670 (b'A', b'after', None, _(b'record delete for missing files')),
5670 (b'A', b'after', None, _(b'record delete for missing files')),
5671 (b'f', b'force', None, _(b'forget added files, delete modified files')),
5671 (b'f', b'force', None, _(b'forget added files, delete modified files')),
5672 ]
5672 ]
5673 + subrepoopts
5673 + subrepoopts
5674 + walkopts
5674 + walkopts
5675 + dryrunopts,
5675 + dryrunopts,
5676 _(b'[OPTION]... FILE...'),
5676 _(b'[OPTION]... FILE...'),
5677 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5677 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5678 helpbasic=True,
5678 helpbasic=True,
5679 inferrepo=True,
5679 inferrepo=True,
5680 )
5680 )
5681 def remove(ui, repo, *pats, **opts):
5681 def remove(ui, repo, *pats, **opts):
5682 """remove the specified files on the next commit
5682 """remove the specified files on the next commit
5683
5683
5684 Schedule the indicated files for removal from the current branch.
5684 Schedule the indicated files for removal from the current branch.
5685
5685
5686 This command schedules the files to be removed at the next commit.
5686 This command schedules the files to be removed at the next commit.
5687 To undo a remove before that, see :hg:`revert`. To undo added
5687 To undo a remove before that, see :hg:`revert`. To undo added
5688 files, see :hg:`forget`.
5688 files, see :hg:`forget`.
5689
5689
5690 .. container:: verbose
5690 .. container:: verbose
5691
5691
5692 -A/--after can be used to remove only files that have already
5692 -A/--after can be used to remove only files that have already
5693 been deleted, -f/--force can be used to force deletion, and -Af
5693 been deleted, -f/--force can be used to force deletion, and -Af
5694 can be used to remove files from the next revision without
5694 can be used to remove files from the next revision without
5695 deleting them from the working directory.
5695 deleting them from the working directory.
5696
5696
5697 The following table details the behavior of remove for different
5697 The following table details the behavior of remove for different
5698 file states (columns) and option combinations (rows). The file
5698 file states (columns) and option combinations (rows). The file
5699 states are Added [A], Clean [C], Modified [M] and Missing [!]
5699 states are Added [A], Clean [C], Modified [M] and Missing [!]
5700 (as reported by :hg:`status`). The actions are Warn, Remove
5700 (as reported by :hg:`status`). The actions are Warn, Remove
5701 (from branch) and Delete (from disk):
5701 (from branch) and Delete (from disk):
5702
5702
5703 ========= == == == ==
5703 ========= == == == ==
5704 opt/state A C M !
5704 opt/state A C M !
5705 ========= == == == ==
5705 ========= == == == ==
5706 none W RD W R
5706 none W RD W R
5707 -f R RD RD R
5707 -f R RD RD R
5708 -A W W W R
5708 -A W W W R
5709 -Af R R R R
5709 -Af R R R R
5710 ========= == == == ==
5710 ========= == == == ==
5711
5711
5712 .. note::
5712 .. note::
5713
5713
5714 :hg:`remove` never deletes files in Added [A] state from the
5714 :hg:`remove` never deletes files in Added [A] state from the
5715 working directory, not even if ``--force`` is specified.
5715 working directory, not even if ``--force`` is specified.
5716
5716
5717 Returns 0 on success, 1 if any warnings encountered.
5717 Returns 0 on success, 1 if any warnings encountered.
5718 """
5718 """
5719
5719
5720 opts = pycompat.byteskwargs(opts)
5720 opts = pycompat.byteskwargs(opts)
5721 after, force = opts.get(b'after'), opts.get(b'force')
5721 after, force = opts.get(b'after'), opts.get(b'force')
5722 dryrun = opts.get(b'dry_run')
5722 dryrun = opts.get(b'dry_run')
5723 if not pats and not after:
5723 if not pats and not after:
5724 raise error.InputError(_(b'no files specified'))
5724 raise error.InputError(_(b'no files specified'))
5725
5725
5726 m = scmutil.match(repo[None], pats, opts)
5726 m = scmutil.match(repo[None], pats, opts)
5727 subrepos = opts.get(b'subrepos')
5727 subrepos = opts.get(b'subrepos')
5728 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
5728 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
5729 return cmdutil.remove(
5729 return cmdutil.remove(
5730 ui, repo, m, b"", uipathfn, after, force, subrepos, dryrun=dryrun
5730 ui, repo, m, b"", uipathfn, after, force, subrepos, dryrun=dryrun
5731 )
5731 )
5732
5732
5733
5733
5734 @command(
5734 @command(
5735 b'rename|move|mv',
5735 b'rename|move|mv',
5736 [
5736 [
5737 (b'A', b'after', None, _(b'record a rename that has already occurred')),
5737 (b'A', b'after', None, _(b'record a rename that has already occurred')),
5738 (
5738 (
5739 b'',
5739 b'',
5740 b'at-rev',
5740 b'at-rev',
5741 b'',
5741 b'',
5742 _(b'(un)mark renames in the given revision (EXPERIMENTAL)'),
5742 _(b'(un)mark renames in the given revision (EXPERIMENTAL)'),
5743 _(b'REV'),
5743 _(b'REV'),
5744 ),
5744 ),
5745 (
5745 (
5746 b'f',
5746 b'f',
5747 b'force',
5747 b'force',
5748 None,
5748 None,
5749 _(b'forcibly move over an existing managed file'),
5749 _(b'forcibly move over an existing managed file'),
5750 ),
5750 ),
5751 ]
5751 ]
5752 + walkopts
5752 + walkopts
5753 + dryrunopts,
5753 + dryrunopts,
5754 _(b'[OPTION]... SOURCE... DEST'),
5754 _(b'[OPTION]... SOURCE... DEST'),
5755 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5755 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5756 )
5756 )
5757 def rename(ui, repo, *pats, **opts):
5757 def rename(ui, repo, *pats, **opts):
5758 """rename files; equivalent of copy + remove
5758 """rename files; equivalent of copy + remove
5759
5759
5760 Mark dest as copies of sources; mark sources for deletion. If dest
5760 Mark dest as copies of sources; mark sources for deletion. If dest
5761 is a directory, copies are put in that directory. If dest is a
5761 is a directory, copies are put in that directory. If dest is a
5762 file, there can only be one source.
5762 file, there can only be one source.
5763
5763
5764 By default, this command copies the contents of files as they
5764 By default, this command copies the contents of files as they
5765 exist in the working directory. If invoked with -A/--after, the
5765 exist in the working directory. If invoked with -A/--after, the
5766 operation is recorded, but no copying is performed.
5766 operation is recorded, but no copying is performed.
5767
5767
5768 This command takes effect at the next commit. To undo a rename
5768 This command takes effect at the next commit. To undo a rename
5769 before that, see :hg:`revert`.
5769 before that, see :hg:`revert`.
5770
5770
5771 Returns 0 on success, 1 if errors are encountered.
5771 Returns 0 on success, 1 if errors are encountered.
5772 """
5772 """
5773 opts = pycompat.byteskwargs(opts)
5773 opts = pycompat.byteskwargs(opts)
5774 with repo.wlock():
5774 with repo.wlock():
5775 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5775 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5776
5776
5777
5777
5778 @command(
5778 @command(
5779 b'resolve',
5779 b'resolve',
5780 [
5780 [
5781 (b'a', b'all', None, _(b'select all unresolved files')),
5781 (b'a', b'all', None, _(b'select all unresolved files')),
5782 (b'l', b'list', None, _(b'list state of files needing merge')),
5782 (b'l', b'list', None, _(b'list state of files needing merge')),
5783 (b'm', b'mark', None, _(b'mark files as resolved')),
5783 (b'm', b'mark', None, _(b'mark files as resolved')),
5784 (b'u', b'unmark', None, _(b'mark files as unresolved')),
5784 (b'u', b'unmark', None, _(b'mark files as unresolved')),
5785 (b'n', b'no-status', None, _(b'hide status prefix')),
5785 (b'n', b'no-status', None, _(b'hide status prefix')),
5786 (b'', b're-merge', None, _(b're-merge files')),
5786 (b'', b're-merge', None, _(b're-merge files')),
5787 ]
5787 ]
5788 + mergetoolopts
5788 + mergetoolopts
5789 + walkopts
5789 + walkopts
5790 + formatteropts,
5790 + formatteropts,
5791 _(b'[OPTION]... [FILE]...'),
5791 _(b'[OPTION]... [FILE]...'),
5792 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5792 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5793 inferrepo=True,
5793 inferrepo=True,
5794 )
5794 )
5795 def resolve(ui, repo, *pats, **opts):
5795 def resolve(ui, repo, *pats, **opts):
5796 """redo merges or set/view the merge status of files
5796 """redo merges or set/view the merge status of files
5797
5797
5798 Merges with unresolved conflicts are often the result of
5798 Merges with unresolved conflicts are often the result of
5799 non-interactive merging using the ``internal:merge`` configuration
5799 non-interactive merging using the ``internal:merge`` configuration
5800 setting, or a command-line merge tool like ``diff3``. The resolve
5800 setting, or a command-line merge tool like ``diff3``. The resolve
5801 command is used to manage the files involved in a merge, after
5801 command is used to manage the files involved in a merge, after
5802 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5802 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5803 working directory must have two parents). See :hg:`help
5803 working directory must have two parents). See :hg:`help
5804 merge-tools` for information on configuring merge tools.
5804 merge-tools` for information on configuring merge tools.
5805
5805
5806 The resolve command can be used in the following ways:
5806 The resolve command can be used in the following ways:
5807
5807
5808 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
5808 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
5809 the specified files, discarding any previous merge attempts. Re-merging
5809 the specified files, discarding any previous merge attempts. Re-merging
5810 is not performed for files already marked as resolved. Use ``--all/-a``
5810 is not performed for files already marked as resolved. Use ``--all/-a``
5811 to select all unresolved files. ``--tool`` can be used to specify
5811 to select all unresolved files. ``--tool`` can be used to specify
5812 the merge tool used for the given files. It overrides the HGMERGE
5812 the merge tool used for the given files. It overrides the HGMERGE
5813 environment variable and your configuration files. Previous file
5813 environment variable and your configuration files. Previous file
5814 contents are saved with a ``.orig`` suffix.
5814 contents are saved with a ``.orig`` suffix.
5815
5815
5816 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5816 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5817 (e.g. after having manually fixed-up the files). The default is
5817 (e.g. after having manually fixed-up the files). The default is
5818 to mark all unresolved files.
5818 to mark all unresolved files.
5819
5819
5820 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5820 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5821 default is to mark all resolved files.
5821 default is to mark all resolved files.
5822
5822
5823 - :hg:`resolve -l`: list files which had or still have conflicts.
5823 - :hg:`resolve -l`: list files which had or still have conflicts.
5824 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5824 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5825 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
5825 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
5826 the list. See :hg:`help filesets` for details.
5826 the list. See :hg:`help filesets` for details.
5827
5827
5828 .. note::
5828 .. note::
5829
5829
5830 Mercurial will not let you commit files with unresolved merge
5830 Mercurial will not let you commit files with unresolved merge
5831 conflicts. You must use :hg:`resolve -m ...` before you can
5831 conflicts. You must use :hg:`resolve -m ...` before you can
5832 commit after a conflicting merge.
5832 commit after a conflicting merge.
5833
5833
5834 .. container:: verbose
5834 .. container:: verbose
5835
5835
5836 Template:
5836 Template:
5837
5837
5838 The following keywords are supported in addition to the common template
5838 The following keywords are supported in addition to the common template
5839 keywords and functions. See also :hg:`help templates`.
5839 keywords and functions. See also :hg:`help templates`.
5840
5840
5841 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
5841 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
5842 :path: String. Repository-absolute path of the file.
5842 :path: String. Repository-absolute path of the file.
5843
5843
5844 Returns 0 on success, 1 if any files fail a resolve attempt.
5844 Returns 0 on success, 1 if any files fail a resolve attempt.
5845 """
5845 """
5846
5846
5847 opts = pycompat.byteskwargs(opts)
5847 opts = pycompat.byteskwargs(opts)
5848 confirm = ui.configbool(b'commands', b'resolve.confirm')
5848 confirm = ui.configbool(b'commands', b'resolve.confirm')
5849 flaglist = b'all mark unmark list no_status re_merge'.split()
5849 flaglist = b'all mark unmark list no_status re_merge'.split()
5850 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
5850 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
5851
5851
5852 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
5852 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
5853 if actioncount > 1:
5853 if actioncount > 1:
5854 raise error.InputError(_(b"too many actions specified"))
5854 raise error.InputError(_(b"too many actions specified"))
5855 elif actioncount == 0 and ui.configbool(
5855 elif actioncount == 0 and ui.configbool(
5856 b'commands', b'resolve.explicit-re-merge'
5856 b'commands', b'resolve.explicit-re-merge'
5857 ):
5857 ):
5858 hint = _(b'use --mark, --unmark, --list or --re-merge')
5858 hint = _(b'use --mark, --unmark, --list or --re-merge')
5859 raise error.InputError(_(b'no action specified'), hint=hint)
5859 raise error.InputError(_(b'no action specified'), hint=hint)
5860 if pats and all:
5860 if pats and all:
5861 raise error.InputError(_(b"can't specify --all and patterns"))
5861 raise error.InputError(_(b"can't specify --all and patterns"))
5862 if not (all or pats or show or mark or unmark):
5862 if not (all or pats or show or mark or unmark):
5863 raise error.InputError(
5863 raise error.InputError(
5864 _(b'no files or directories specified'),
5864 _(b'no files or directories specified'),
5865 hint=b'use --all to re-merge all unresolved files',
5865 hint=b'use --all to re-merge all unresolved files',
5866 )
5866 )
5867
5867
5868 if confirm:
5868 if confirm:
5869 if all:
5869 if all:
5870 if ui.promptchoice(
5870 if ui.promptchoice(
5871 _(b're-merge all unresolved files (yn)?$$ &Yes $$ &No')
5871 _(b're-merge all unresolved files (yn)?$$ &Yes $$ &No')
5872 ):
5872 ):
5873 raise error.CanceledError(_(b'user quit'))
5873 raise error.CanceledError(_(b'user quit'))
5874 if mark and not pats:
5874 if mark and not pats:
5875 if ui.promptchoice(
5875 if ui.promptchoice(
5876 _(
5876 _(
5877 b'mark all unresolved files as resolved (yn)?'
5877 b'mark all unresolved files as resolved (yn)?'
5878 b'$$ &Yes $$ &No'
5878 b'$$ &Yes $$ &No'
5879 )
5879 )
5880 ):
5880 ):
5881 raise error.CanceledError(_(b'user quit'))
5881 raise error.CanceledError(_(b'user quit'))
5882 if unmark and not pats:
5882 if unmark and not pats:
5883 if ui.promptchoice(
5883 if ui.promptchoice(
5884 _(
5884 _(
5885 b'mark all resolved files as unresolved (yn)?'
5885 b'mark all resolved files as unresolved (yn)?'
5886 b'$$ &Yes $$ &No'
5886 b'$$ &Yes $$ &No'
5887 )
5887 )
5888 ):
5888 ):
5889 raise error.CanceledError(_(b'user quit'))
5889 raise error.CanceledError(_(b'user quit'))
5890
5890
5891 uipathfn = scmutil.getuipathfn(repo)
5891 uipathfn = scmutil.getuipathfn(repo)
5892
5892
5893 if show:
5893 if show:
5894 ui.pager(b'resolve')
5894 ui.pager(b'resolve')
5895 fm = ui.formatter(b'resolve', opts)
5895 fm = ui.formatter(b'resolve', opts)
5896 ms = mergestatemod.mergestate.read(repo)
5896 ms = mergestatemod.mergestate.read(repo)
5897 wctx = repo[None]
5897 wctx = repo[None]
5898 m = scmutil.match(wctx, pats, opts)
5898 m = scmutil.match(wctx, pats, opts)
5899
5899
5900 # Labels and keys based on merge state. Unresolved path conflicts show
5900 # Labels and keys based on merge state. Unresolved path conflicts show
5901 # as 'P'. Resolved path conflicts show as 'R', the same as normal
5901 # as 'P'. Resolved path conflicts show as 'R', the same as normal
5902 # resolved conflicts.
5902 # resolved conflicts.
5903 mergestateinfo = {
5903 mergestateinfo = {
5904 mergestatemod.MERGE_RECORD_UNRESOLVED: (
5904 mergestatemod.MERGE_RECORD_UNRESOLVED: (
5905 b'resolve.unresolved',
5905 b'resolve.unresolved',
5906 b'U',
5906 b'U',
5907 ),
5907 ),
5908 mergestatemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
5908 mergestatemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
5909 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH: (
5909 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH: (
5910 b'resolve.unresolved',
5910 b'resolve.unresolved',
5911 b'P',
5911 b'P',
5912 ),
5912 ),
5913 mergestatemod.MERGE_RECORD_RESOLVED_PATH: (
5913 mergestatemod.MERGE_RECORD_RESOLVED_PATH: (
5914 b'resolve.resolved',
5914 b'resolve.resolved',
5915 b'R',
5915 b'R',
5916 ),
5916 ),
5917 }
5917 }
5918
5918
5919 for f in ms:
5919 for f in ms:
5920 if not m(f):
5920 if not m(f):
5921 continue
5921 continue
5922
5922
5923 label, key = mergestateinfo[ms[f]]
5923 label, key = mergestateinfo[ms[f]]
5924 fm.startitem()
5924 fm.startitem()
5925 fm.context(ctx=wctx)
5925 fm.context(ctx=wctx)
5926 fm.condwrite(not nostatus, b'mergestatus', b'%s ', key, label=label)
5926 fm.condwrite(not nostatus, b'mergestatus', b'%s ', key, label=label)
5927 fm.data(path=f)
5927 fm.data(path=f)
5928 fm.plain(b'%s\n' % uipathfn(f), label=label)
5928 fm.plain(b'%s\n' % uipathfn(f), label=label)
5929 fm.end()
5929 fm.end()
5930 return 0
5930 return 0
5931
5931
5932 with repo.wlock():
5932 with repo.wlock():
5933 ms = mergestatemod.mergestate.read(repo)
5933 ms = mergestatemod.mergestate.read(repo)
5934
5934
5935 if not (ms.active() or repo.dirstate.p2() != nullid):
5935 if not (ms.active() or repo.dirstate.p2() != nullid):
5936 raise error.StateError(
5936 raise error.StateError(
5937 _(b'resolve command not applicable when not merging')
5937 _(b'resolve command not applicable when not merging')
5938 )
5938 )
5939
5939
5940 wctx = repo[None]
5940 wctx = repo[None]
5941 m = scmutil.match(wctx, pats, opts)
5941 m = scmutil.match(wctx, pats, opts)
5942 ret = 0
5942 ret = 0
5943 didwork = False
5943 didwork = False
5944
5944
5945 tocomplete = []
5945 tocomplete = []
5946 hasconflictmarkers = []
5946 hasconflictmarkers = []
5947 if mark:
5947 if mark:
5948 markcheck = ui.config(b'commands', b'resolve.mark-check')
5948 markcheck = ui.config(b'commands', b'resolve.mark-check')
5949 if markcheck not in [b'warn', b'abort']:
5949 if markcheck not in [b'warn', b'abort']:
5950 # Treat all invalid / unrecognized values as 'none'.
5950 # Treat all invalid / unrecognized values as 'none'.
5951 markcheck = False
5951 markcheck = False
5952 for f in ms:
5952 for f in ms:
5953 if not m(f):
5953 if not m(f):
5954 continue
5954 continue
5955
5955
5956 didwork = True
5956 didwork = True
5957
5957
5958 # path conflicts must be resolved manually
5958 # path conflicts must be resolved manually
5959 if ms[f] in (
5959 if ms[f] in (
5960 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
5960 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
5961 mergestatemod.MERGE_RECORD_RESOLVED_PATH,
5961 mergestatemod.MERGE_RECORD_RESOLVED_PATH,
5962 ):
5962 ):
5963 if mark:
5963 if mark:
5964 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED_PATH)
5964 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED_PATH)
5965 elif unmark:
5965 elif unmark:
5966 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED_PATH)
5966 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED_PATH)
5967 elif ms[f] == mergestatemod.MERGE_RECORD_UNRESOLVED_PATH:
5967 elif ms[f] == mergestatemod.MERGE_RECORD_UNRESOLVED_PATH:
5968 ui.warn(
5968 ui.warn(
5969 _(b'%s: path conflict must be resolved manually\n')
5969 _(b'%s: path conflict must be resolved manually\n')
5970 % uipathfn(f)
5970 % uipathfn(f)
5971 )
5971 )
5972 continue
5972 continue
5973
5973
5974 if mark:
5974 if mark:
5975 if markcheck:
5975 if markcheck:
5976 fdata = repo.wvfs.tryread(f)
5976 fdata = repo.wvfs.tryread(f)
5977 if (
5977 if (
5978 filemerge.hasconflictmarkers(fdata)
5978 filemerge.hasconflictmarkers(fdata)
5979 and ms[f] != mergestatemod.MERGE_RECORD_RESOLVED
5979 and ms[f] != mergestatemod.MERGE_RECORD_RESOLVED
5980 ):
5980 ):
5981 hasconflictmarkers.append(f)
5981 hasconflictmarkers.append(f)
5982 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED)
5982 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED)
5983 elif unmark:
5983 elif unmark:
5984 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED)
5984 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED)
5985 else:
5985 else:
5986 # backup pre-resolve (merge uses .orig for its own purposes)
5986 # backup pre-resolve (merge uses .orig for its own purposes)
5987 a = repo.wjoin(f)
5987 a = repo.wjoin(f)
5988 try:
5988 try:
5989 util.copyfile(a, a + b".resolve")
5989 util.copyfile(a, a + b".resolve")
5990 except (IOError, OSError) as inst:
5990 except (IOError, OSError) as inst:
5991 if inst.errno != errno.ENOENT:
5991 if inst.errno != errno.ENOENT:
5992 raise
5992 raise
5993
5993
5994 try:
5994 try:
5995 # preresolve file
5995 # preresolve file
5996 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
5996 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
5997 with ui.configoverride(overrides, b'resolve'):
5997 with ui.configoverride(overrides, b'resolve'):
5998 complete, r = ms.preresolve(f, wctx)
5998 complete, r = ms.preresolve(f, wctx)
5999 if not complete:
5999 if not complete:
6000 tocomplete.append(f)
6000 tocomplete.append(f)
6001 elif r:
6001 elif r:
6002 ret = 1
6002 ret = 1
6003 finally:
6003 finally:
6004 ms.commit()
6004 ms.commit()
6005
6005
6006 # replace filemerge's .orig file with our resolve file, but only
6006 # replace filemerge's .orig file with our resolve file, but only
6007 # for merges that are complete
6007 # for merges that are complete
6008 if complete:
6008 if complete:
6009 try:
6009 try:
6010 util.rename(
6010 util.rename(
6011 a + b".resolve", scmutil.backuppath(ui, repo, f)
6011 a + b".resolve", scmutil.backuppath(ui, repo, f)
6012 )
6012 )
6013 except OSError as inst:
6013 except OSError as inst:
6014 if inst.errno != errno.ENOENT:
6014 if inst.errno != errno.ENOENT:
6015 raise
6015 raise
6016
6016
6017 if hasconflictmarkers:
6017 if hasconflictmarkers:
6018 ui.warn(
6018 ui.warn(
6019 _(
6019 _(
6020 b'warning: the following files still have conflict '
6020 b'warning: the following files still have conflict '
6021 b'markers:\n'
6021 b'markers:\n'
6022 )
6022 )
6023 + b''.join(
6023 + b''.join(
6024 b' ' + uipathfn(f) + b'\n' for f in hasconflictmarkers
6024 b' ' + uipathfn(f) + b'\n' for f in hasconflictmarkers
6025 )
6025 )
6026 )
6026 )
6027 if markcheck == b'abort' and not all and not pats:
6027 if markcheck == b'abort' and not all and not pats:
6028 raise error.StateError(
6028 raise error.StateError(
6029 _(b'conflict markers detected'),
6029 _(b'conflict markers detected'),
6030 hint=_(b'use --all to mark anyway'),
6030 hint=_(b'use --all to mark anyway'),
6031 )
6031 )
6032
6032
6033 for f in tocomplete:
6033 for f in tocomplete:
6034 try:
6034 try:
6035 # resolve file
6035 # resolve file
6036 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
6036 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
6037 with ui.configoverride(overrides, b'resolve'):
6037 with ui.configoverride(overrides, b'resolve'):
6038 r = ms.resolve(f, wctx)
6038 r = ms.resolve(f, wctx)
6039 if r:
6039 if r:
6040 ret = 1
6040 ret = 1
6041 finally:
6041 finally:
6042 ms.commit()
6042 ms.commit()
6043
6043
6044 # replace filemerge's .orig file with our resolve file
6044 # replace filemerge's .orig file with our resolve file
6045 a = repo.wjoin(f)
6045 a = repo.wjoin(f)
6046 try:
6046 try:
6047 util.rename(a + b".resolve", scmutil.backuppath(ui, repo, f))
6047 util.rename(a + b".resolve", scmutil.backuppath(ui, repo, f))
6048 except OSError as inst:
6048 except OSError as inst:
6049 if inst.errno != errno.ENOENT:
6049 if inst.errno != errno.ENOENT:
6050 raise
6050 raise
6051
6051
6052 ms.commit()
6052 ms.commit()
6053 branchmerge = repo.dirstate.p2() != nullid
6053 branchmerge = repo.dirstate.p2() != nullid
6054 mergestatemod.recordupdates(repo, ms.actions(), branchmerge, None)
6054 mergestatemod.recordupdates(repo, ms.actions(), branchmerge, None)
6055
6055
6056 if not didwork and pats:
6056 if not didwork and pats:
6057 hint = None
6057 hint = None
6058 if not any([p for p in pats if p.find(b':') >= 0]):
6058 if not any([p for p in pats if p.find(b':') >= 0]):
6059 pats = [b'path:%s' % p for p in pats]
6059 pats = [b'path:%s' % p for p in pats]
6060 m = scmutil.match(wctx, pats, opts)
6060 m = scmutil.match(wctx, pats, opts)
6061 for f in ms:
6061 for f in ms:
6062 if not m(f):
6062 if not m(f):
6063 continue
6063 continue
6064
6064
6065 def flag(o):
6065 def flag(o):
6066 if o == b're_merge':
6066 if o == b're_merge':
6067 return b'--re-merge '
6067 return b'--re-merge '
6068 return b'-%s ' % o[0:1]
6068 return b'-%s ' % o[0:1]
6069
6069
6070 flags = b''.join([flag(o) for o in flaglist if opts.get(o)])
6070 flags = b''.join([flag(o) for o in flaglist if opts.get(o)])
6071 hint = _(b"(try: hg resolve %s%s)\n") % (
6071 hint = _(b"(try: hg resolve %s%s)\n") % (
6072 flags,
6072 flags,
6073 b' '.join(pats),
6073 b' '.join(pats),
6074 )
6074 )
6075 break
6075 break
6076 ui.warn(_(b"arguments do not match paths that need resolving\n"))
6076 ui.warn(_(b"arguments do not match paths that need resolving\n"))
6077 if hint:
6077 if hint:
6078 ui.warn(hint)
6078 ui.warn(hint)
6079
6079
6080 unresolvedf = list(ms.unresolved())
6080 unresolvedf = list(ms.unresolved())
6081 if not unresolvedf:
6081 if not unresolvedf:
6082 ui.status(_(b'(no more unresolved files)\n'))
6082 ui.status(_(b'(no more unresolved files)\n'))
6083 cmdutil.checkafterresolved(repo)
6083 cmdutil.checkafterresolved(repo)
6084
6084
6085 return ret
6085 return ret
6086
6086
6087
6087
6088 @command(
6088 @command(
6089 b'revert',
6089 b'revert',
6090 [
6090 [
6091 (b'a', b'all', None, _(b'revert all changes when no arguments given')),
6091 (b'a', b'all', None, _(b'revert all changes when no arguments given')),
6092 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
6092 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
6093 (b'r', b'rev', b'', _(b'revert to the specified revision'), _(b'REV')),
6093 (b'r', b'rev', b'', _(b'revert to the specified revision'), _(b'REV')),
6094 (b'C', b'no-backup', None, _(b'do not save backup copies of files')),
6094 (b'C', b'no-backup', None, _(b'do not save backup copies of files')),
6095 (b'i', b'interactive', None, _(b'interactively select the changes')),
6095 (b'i', b'interactive', None, _(b'interactively select the changes')),
6096 ]
6096 ]
6097 + walkopts
6097 + walkopts
6098 + dryrunopts,
6098 + dryrunopts,
6099 _(b'[OPTION]... [-r REV] [NAME]...'),
6099 _(b'[OPTION]... [-r REV] [NAME]...'),
6100 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6100 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6101 )
6101 )
6102 def revert(ui, repo, *pats, **opts):
6102 def revert(ui, repo, *pats, **opts):
6103 """restore files to their checkout state
6103 """restore files to their checkout state
6104
6104
6105 .. note::
6105 .. note::
6106
6106
6107 To check out earlier revisions, you should use :hg:`update REV`.
6107 To check out earlier revisions, you should use :hg:`update REV`.
6108 To cancel an uncommitted merge (and lose your changes),
6108 To cancel an uncommitted merge (and lose your changes),
6109 use :hg:`merge --abort`.
6109 use :hg:`merge --abort`.
6110
6110
6111 With no revision specified, revert the specified files or directories
6111 With no revision specified, revert the specified files or directories
6112 to the contents they had in the parent of the working directory.
6112 to the contents they had in the parent of the working directory.
6113 This restores the contents of files to an unmodified
6113 This restores the contents of files to an unmodified
6114 state and unschedules adds, removes, copies, and renames. If the
6114 state and unschedules adds, removes, copies, and renames. If the
6115 working directory has two parents, you must explicitly specify a
6115 working directory has two parents, you must explicitly specify a
6116 revision.
6116 revision.
6117
6117
6118 Using the -r/--rev or -d/--date options, revert the given files or
6118 Using the -r/--rev or -d/--date options, revert the given files or
6119 directories to their states as of a specific revision. Because
6119 directories to their states as of a specific revision. Because
6120 revert does not change the working directory parents, this will
6120 revert does not change the working directory parents, this will
6121 cause these files to appear modified. This can be helpful to "back
6121 cause these files to appear modified. This can be helpful to "back
6122 out" some or all of an earlier change. See :hg:`backout` for a
6122 out" some or all of an earlier change. See :hg:`backout` for a
6123 related method.
6123 related method.
6124
6124
6125 Modified files are saved with a .orig suffix before reverting.
6125 Modified files are saved with a .orig suffix before reverting.
6126 To disable these backups, use --no-backup. It is possible to store
6126 To disable these backups, use --no-backup. It is possible to store
6127 the backup files in a custom directory relative to the root of the
6127 the backup files in a custom directory relative to the root of the
6128 repository by setting the ``ui.origbackuppath`` configuration
6128 repository by setting the ``ui.origbackuppath`` configuration
6129 option.
6129 option.
6130
6130
6131 See :hg:`help dates` for a list of formats valid for -d/--date.
6131 See :hg:`help dates` for a list of formats valid for -d/--date.
6132
6132
6133 See :hg:`help backout` for a way to reverse the effect of an
6133 See :hg:`help backout` for a way to reverse the effect of an
6134 earlier changeset.
6134 earlier changeset.
6135
6135
6136 Returns 0 on success.
6136 Returns 0 on success.
6137 """
6137 """
6138
6138
6139 opts = pycompat.byteskwargs(opts)
6139 opts = pycompat.byteskwargs(opts)
6140 if opts.get(b"date"):
6140 if opts.get(b"date"):
6141 cmdutil.check_incompatible_arguments(opts, b'date', [b'rev'])
6141 cmdutil.check_incompatible_arguments(opts, b'date', [b'rev'])
6142 opts[b"rev"] = cmdutil.finddate(ui, repo, opts[b"date"])
6142 opts[b"rev"] = cmdutil.finddate(ui, repo, opts[b"date"])
6143
6143
6144 parent, p2 = repo.dirstate.parents()
6144 parent, p2 = repo.dirstate.parents()
6145 if not opts.get(b'rev') and p2 != nullid:
6145 if not opts.get(b'rev') and p2 != nullid:
6146 # revert after merge is a trap for new users (issue2915)
6146 # revert after merge is a trap for new users (issue2915)
6147 raise error.InputError(
6147 raise error.InputError(
6148 _(b'uncommitted merge with no revision specified'),
6148 _(b'uncommitted merge with no revision specified'),
6149 hint=_(b"use 'hg update' or see 'hg help revert'"),
6149 hint=_(b"use 'hg update' or see 'hg help revert'"),
6150 )
6150 )
6151
6151
6152 rev = opts.get(b'rev')
6152 rev = opts.get(b'rev')
6153 if rev:
6153 if rev:
6154 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
6154 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
6155 ctx = scmutil.revsingle(repo, rev)
6155 ctx = scmutil.revsingle(repo, rev)
6156
6156
6157 if not (
6157 if not (
6158 pats
6158 pats
6159 or opts.get(b'include')
6159 or opts.get(b'include')
6160 or opts.get(b'exclude')
6160 or opts.get(b'exclude')
6161 or opts.get(b'all')
6161 or opts.get(b'all')
6162 or opts.get(b'interactive')
6162 or opts.get(b'interactive')
6163 ):
6163 ):
6164 msg = _(b"no files or directories specified")
6164 msg = _(b"no files or directories specified")
6165 if p2 != nullid:
6165 if p2 != nullid:
6166 hint = _(
6166 hint = _(
6167 b"uncommitted merge, use --all to discard all changes,"
6167 b"uncommitted merge, use --all to discard all changes,"
6168 b" or 'hg update -C .' to abort the merge"
6168 b" or 'hg update -C .' to abort the merge"
6169 )
6169 )
6170 raise error.InputError(msg, hint=hint)
6170 raise error.InputError(msg, hint=hint)
6171 dirty = any(repo.status())
6171 dirty = any(repo.status())
6172 node = ctx.node()
6172 node = ctx.node()
6173 if node != parent:
6173 if node != parent:
6174 if dirty:
6174 if dirty:
6175 hint = (
6175 hint = (
6176 _(
6176 _(
6177 b"uncommitted changes, use --all to discard all"
6177 b"uncommitted changes, use --all to discard all"
6178 b" changes, or 'hg update %d' to update"
6178 b" changes, or 'hg update %d' to update"
6179 )
6179 )
6180 % ctx.rev()
6180 % ctx.rev()
6181 )
6181 )
6182 else:
6182 else:
6183 hint = (
6183 hint = (
6184 _(
6184 _(
6185 b"use --all to revert all files,"
6185 b"use --all to revert all files,"
6186 b" or 'hg update %d' to update"
6186 b" or 'hg update %d' to update"
6187 )
6187 )
6188 % ctx.rev()
6188 % ctx.rev()
6189 )
6189 )
6190 elif dirty:
6190 elif dirty:
6191 hint = _(b"uncommitted changes, use --all to discard all changes")
6191 hint = _(b"uncommitted changes, use --all to discard all changes")
6192 else:
6192 else:
6193 hint = _(b"use --all to revert all files")
6193 hint = _(b"use --all to revert all files")
6194 raise error.InputError(msg, hint=hint)
6194 raise error.InputError(msg, hint=hint)
6195
6195
6196 return cmdutil.revert(ui, repo, ctx, *pats, **pycompat.strkwargs(opts))
6196 return cmdutil.revert(ui, repo, ctx, *pats, **pycompat.strkwargs(opts))
6197
6197
6198
6198
6199 @command(
6199 @command(
6200 b'rollback',
6200 b'rollback',
6201 dryrunopts + [(b'f', b'force', False, _(b'ignore safety measures'))],
6201 dryrunopts + [(b'f', b'force', False, _(b'ignore safety measures'))],
6202 helpcategory=command.CATEGORY_MAINTENANCE,
6202 helpcategory=command.CATEGORY_MAINTENANCE,
6203 )
6203 )
6204 def rollback(ui, repo, **opts):
6204 def rollback(ui, repo, **opts):
6205 """roll back the last transaction (DANGEROUS) (DEPRECATED)
6205 """roll back the last transaction (DANGEROUS) (DEPRECATED)
6206
6206
6207 Please use :hg:`commit --amend` instead of rollback to correct
6207 Please use :hg:`commit --amend` instead of rollback to correct
6208 mistakes in the last commit.
6208 mistakes in the last commit.
6209
6209
6210 This command should be used with care. There is only one level of
6210 This command should be used with care. There is only one level of
6211 rollback, and there is no way to undo a rollback. It will also
6211 rollback, and there is no way to undo a rollback. It will also
6212 restore the dirstate at the time of the last transaction, losing
6212 restore the dirstate at the time of the last transaction, losing
6213 any dirstate changes since that time. This command does not alter
6213 any dirstate changes since that time. This command does not alter
6214 the working directory.
6214 the working directory.
6215
6215
6216 Transactions are used to encapsulate the effects of all commands
6216 Transactions are used to encapsulate the effects of all commands
6217 that create new changesets or propagate existing changesets into a
6217 that create new changesets or propagate existing changesets into a
6218 repository.
6218 repository.
6219
6219
6220 .. container:: verbose
6220 .. container:: verbose
6221
6221
6222 For example, the following commands are transactional, and their
6222 For example, the following commands are transactional, and their
6223 effects can be rolled back:
6223 effects can be rolled back:
6224
6224
6225 - commit
6225 - commit
6226 - import
6226 - import
6227 - pull
6227 - pull
6228 - push (with this repository as the destination)
6228 - push (with this repository as the destination)
6229 - unbundle
6229 - unbundle
6230
6230
6231 To avoid permanent data loss, rollback will refuse to rollback a
6231 To avoid permanent data loss, rollback will refuse to rollback a
6232 commit transaction if it isn't checked out. Use --force to
6232 commit transaction if it isn't checked out. Use --force to
6233 override this protection.
6233 override this protection.
6234
6234
6235 The rollback command can be entirely disabled by setting the
6235 The rollback command can be entirely disabled by setting the
6236 ``ui.rollback`` configuration setting to false. If you're here
6236 ``ui.rollback`` configuration setting to false. If you're here
6237 because you want to use rollback and it's disabled, you can
6237 because you want to use rollback and it's disabled, you can
6238 re-enable the command by setting ``ui.rollback`` to true.
6238 re-enable the command by setting ``ui.rollback`` to true.
6239
6239
6240 This command is not intended for use on public repositories. Once
6240 This command is not intended for use on public repositories. Once
6241 changes are visible for pull by other users, rolling a transaction
6241 changes are visible for pull by other users, rolling a transaction
6242 back locally is ineffective (someone else may already have pulled
6242 back locally is ineffective (someone else may already have pulled
6243 the changes). Furthermore, a race is possible with readers of the
6243 the changes). Furthermore, a race is possible with readers of the
6244 repository; for example an in-progress pull from the repository
6244 repository; for example an in-progress pull from the repository
6245 may fail if a rollback is performed.
6245 may fail if a rollback is performed.
6246
6246
6247 Returns 0 on success, 1 if no rollback data is available.
6247 Returns 0 on success, 1 if no rollback data is available.
6248 """
6248 """
6249 if not ui.configbool(b'ui', b'rollback'):
6249 if not ui.configbool(b'ui', b'rollback'):
6250 raise error.Abort(
6250 raise error.Abort(
6251 _(b'rollback is disabled because it is unsafe'),
6251 _(b'rollback is disabled because it is unsafe'),
6252 hint=b'see `hg help -v rollback` for information',
6252 hint=b'see `hg help -v rollback` for information',
6253 )
6253 )
6254 return repo.rollback(dryrun=opts.get('dry_run'), force=opts.get('force'))
6254 return repo.rollback(dryrun=opts.get('dry_run'), force=opts.get('force'))
6255
6255
6256
6256
6257 @command(
6257 @command(
6258 b'root',
6258 b'root',
6259 [] + formatteropts,
6259 [] + formatteropts,
6260 intents={INTENT_READONLY},
6260 intents={INTENT_READONLY},
6261 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6261 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6262 )
6262 )
6263 def root(ui, repo, **opts):
6263 def root(ui, repo, **opts):
6264 """print the root (top) of the current working directory
6264 """print the root (top) of the current working directory
6265
6265
6266 Print the root directory of the current repository.
6266 Print the root directory of the current repository.
6267
6267
6268 .. container:: verbose
6268 .. container:: verbose
6269
6269
6270 Template:
6270 Template:
6271
6271
6272 The following keywords are supported in addition to the common template
6272 The following keywords are supported in addition to the common template
6273 keywords and functions. See also :hg:`help templates`.
6273 keywords and functions. See also :hg:`help templates`.
6274
6274
6275 :hgpath: String. Path to the .hg directory.
6275 :hgpath: String. Path to the .hg directory.
6276 :storepath: String. Path to the directory holding versioned data.
6276 :storepath: String. Path to the directory holding versioned data.
6277
6277
6278 Returns 0 on success.
6278 Returns 0 on success.
6279 """
6279 """
6280 opts = pycompat.byteskwargs(opts)
6280 opts = pycompat.byteskwargs(opts)
6281 with ui.formatter(b'root', opts) as fm:
6281 with ui.formatter(b'root', opts) as fm:
6282 fm.startitem()
6282 fm.startitem()
6283 fm.write(b'reporoot', b'%s\n', repo.root)
6283 fm.write(b'reporoot', b'%s\n', repo.root)
6284 fm.data(hgpath=repo.path, storepath=repo.spath)
6284 fm.data(hgpath=repo.path, storepath=repo.spath)
6285
6285
6286
6286
6287 @command(
6287 @command(
6288 b'serve',
6288 b'serve',
6289 [
6289 [
6290 (
6290 (
6291 b'A',
6291 b'A',
6292 b'accesslog',
6292 b'accesslog',
6293 b'',
6293 b'',
6294 _(b'name of access log file to write to'),
6294 _(b'name of access log file to write to'),
6295 _(b'FILE'),
6295 _(b'FILE'),
6296 ),
6296 ),
6297 (b'd', b'daemon', None, _(b'run server in background')),
6297 (b'd', b'daemon', None, _(b'run server in background')),
6298 (b'', b'daemon-postexec', [], _(b'used internally by daemon mode')),
6298 (b'', b'daemon-postexec', [], _(b'used internally by daemon mode')),
6299 (
6299 (
6300 b'E',
6300 b'E',
6301 b'errorlog',
6301 b'errorlog',
6302 b'',
6302 b'',
6303 _(b'name of error log file to write to'),
6303 _(b'name of error log file to write to'),
6304 _(b'FILE'),
6304 _(b'FILE'),
6305 ),
6305 ),
6306 # use string type, then we can check if something was passed
6306 # use string type, then we can check if something was passed
6307 (
6307 (
6308 b'p',
6308 b'p',
6309 b'port',
6309 b'port',
6310 b'',
6310 b'',
6311 _(b'port to listen on (default: 8000)'),
6311 _(b'port to listen on (default: 8000)'),
6312 _(b'PORT'),
6312 _(b'PORT'),
6313 ),
6313 ),
6314 (
6314 (
6315 b'a',
6315 b'a',
6316 b'address',
6316 b'address',
6317 b'',
6317 b'',
6318 _(b'address to listen on (default: all interfaces)'),
6318 _(b'address to listen on (default: all interfaces)'),
6319 _(b'ADDR'),
6319 _(b'ADDR'),
6320 ),
6320 ),
6321 (
6321 (
6322 b'',
6322 b'',
6323 b'prefix',
6323 b'prefix',
6324 b'',
6324 b'',
6325 _(b'prefix path to serve from (default: server root)'),
6325 _(b'prefix path to serve from (default: server root)'),
6326 _(b'PREFIX'),
6326 _(b'PREFIX'),
6327 ),
6327 ),
6328 (
6328 (
6329 b'n',
6329 b'n',
6330 b'name',
6330 b'name',
6331 b'',
6331 b'',
6332 _(b'name to show in web pages (default: working directory)'),
6332 _(b'name to show in web pages (default: working directory)'),
6333 _(b'NAME'),
6333 _(b'NAME'),
6334 ),
6334 ),
6335 (
6335 (
6336 b'',
6336 b'',
6337 b'web-conf',
6337 b'web-conf',
6338 b'',
6338 b'',
6339 _(b"name of the hgweb config file (see 'hg help hgweb')"),
6339 _(b"name of the hgweb config file (see 'hg help hgweb')"),
6340 _(b'FILE'),
6340 _(b'FILE'),
6341 ),
6341 ),
6342 (
6342 (
6343 b'',
6343 b'',
6344 b'webdir-conf',
6344 b'webdir-conf',
6345 b'',
6345 b'',
6346 _(b'name of the hgweb config file (DEPRECATED)'),
6346 _(b'name of the hgweb config file (DEPRECATED)'),
6347 _(b'FILE'),
6347 _(b'FILE'),
6348 ),
6348 ),
6349 (
6349 (
6350 b'',
6350 b'',
6351 b'pid-file',
6351 b'pid-file',
6352 b'',
6352 b'',
6353 _(b'name of file to write process ID to'),
6353 _(b'name of file to write process ID to'),
6354 _(b'FILE'),
6354 _(b'FILE'),
6355 ),
6355 ),
6356 (b'', b'stdio', None, _(b'for remote clients (ADVANCED)')),
6356 (b'', b'stdio', None, _(b'for remote clients (ADVANCED)')),
6357 (
6357 (
6358 b'',
6358 b'',
6359 b'cmdserver',
6359 b'cmdserver',
6360 b'',
6360 b'',
6361 _(b'for remote clients (ADVANCED)'),
6361 _(b'for remote clients (ADVANCED)'),
6362 _(b'MODE'),
6362 _(b'MODE'),
6363 ),
6363 ),
6364 (b't', b'templates', b'', _(b'web templates to use'), _(b'TEMPLATE')),
6364 (b't', b'templates', b'', _(b'web templates to use'), _(b'TEMPLATE')),
6365 (b'', b'style', b'', _(b'template style to use'), _(b'STYLE')),
6365 (b'', b'style', b'', _(b'template style to use'), _(b'STYLE')),
6366 (b'6', b'ipv6', None, _(b'use IPv6 in addition to IPv4')),
6366 (b'6', b'ipv6', None, _(b'use IPv6 in addition to IPv4')),
6367 (b'', b'certificate', b'', _(b'SSL certificate file'), _(b'FILE')),
6367 (b'', b'certificate', b'', _(b'SSL certificate file'), _(b'FILE')),
6368 (b'', b'print-url', None, _(b'start and print only the URL')),
6368 (b'', b'print-url', None, _(b'start and print only the URL')),
6369 ]
6369 ]
6370 + subrepoopts,
6370 + subrepoopts,
6371 _(b'[OPTION]...'),
6371 _(b'[OPTION]...'),
6372 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
6372 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
6373 helpbasic=True,
6373 helpbasic=True,
6374 optionalrepo=True,
6374 optionalrepo=True,
6375 )
6375 )
6376 def serve(ui, repo, **opts):
6376 def serve(ui, repo, **opts):
6377 """start stand-alone webserver
6377 """start stand-alone webserver
6378
6378
6379 Start a local HTTP repository browser and pull server. You can use
6379 Start a local HTTP repository browser and pull server. You can use
6380 this for ad-hoc sharing and browsing of repositories. It is
6380 this for ad-hoc sharing and browsing of repositories. It is
6381 recommended to use a real web server to serve a repository for
6381 recommended to use a real web server to serve a repository for
6382 longer periods of time.
6382 longer periods of time.
6383
6383
6384 Please note that the server does not implement access control.
6384 Please note that the server does not implement access control.
6385 This means that, by default, anybody can read from the server and
6385 This means that, by default, anybody can read from the server and
6386 nobody can write to it by default. Set the ``web.allow-push``
6386 nobody can write to it by default. Set the ``web.allow-push``
6387 option to ``*`` to allow everybody to push to the server. You
6387 option to ``*`` to allow everybody to push to the server. You
6388 should use a real web server if you need to authenticate users.
6388 should use a real web server if you need to authenticate users.
6389
6389
6390 By default, the server logs accesses to stdout and errors to
6390 By default, the server logs accesses to stdout and errors to
6391 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
6391 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
6392 files.
6392 files.
6393
6393
6394 To have the server choose a free port number to listen on, specify
6394 To have the server choose a free port number to listen on, specify
6395 a port number of 0; in this case, the server will print the port
6395 a port number of 0; in this case, the server will print the port
6396 number it uses.
6396 number it uses.
6397
6397
6398 Returns 0 on success.
6398 Returns 0 on success.
6399 """
6399 """
6400
6400
6401 cmdutil.check_incompatible_arguments(opts, 'stdio', ['cmdserver'])
6401 cmdutil.check_incompatible_arguments(opts, 'stdio', ['cmdserver'])
6402 opts = pycompat.byteskwargs(opts)
6402 opts = pycompat.byteskwargs(opts)
6403 if opts[b"print_url"] and ui.verbose:
6403 if opts[b"print_url"] and ui.verbose:
6404 raise error.InputError(_(b"cannot use --print-url with --verbose"))
6404 raise error.InputError(_(b"cannot use --print-url with --verbose"))
6405
6405
6406 if opts[b"stdio"]:
6406 if opts[b"stdio"]:
6407 if repo is None:
6407 if repo is None:
6408 raise error.RepoError(
6408 raise error.RepoError(
6409 _(b"there is no Mercurial repository here (.hg not found)")
6409 _(b"there is no Mercurial repository here (.hg not found)")
6410 )
6410 )
6411 s = wireprotoserver.sshserver(ui, repo)
6411 s = wireprotoserver.sshserver(ui, repo)
6412 s.serve_forever()
6412 s.serve_forever()
6413 return
6413 return
6414
6414
6415 service = server.createservice(ui, repo, opts)
6415 service = server.createservice(ui, repo, opts)
6416 return server.runservice(opts, initfn=service.init, runfn=service.run)
6416 return server.runservice(opts, initfn=service.init, runfn=service.run)
6417
6417
6418
6418
6419 @command(
6419 @command(
6420 b'shelve',
6420 b'shelve',
6421 [
6421 [
6422 (
6422 (
6423 b'A',
6423 b'A',
6424 b'addremove',
6424 b'addremove',
6425 None,
6425 None,
6426 _(b'mark new/missing files as added/removed before shelving'),
6426 _(b'mark new/missing files as added/removed before shelving'),
6427 ),
6427 ),
6428 (b'u', b'unknown', None, _(b'store unknown files in the shelve')),
6428 (b'u', b'unknown', None, _(b'store unknown files in the shelve')),
6429 (b'', b'cleanup', None, _(b'delete all shelved changes')),
6429 (b'', b'cleanup', None, _(b'delete all shelved changes')),
6430 (
6430 (
6431 b'',
6431 b'',
6432 b'date',
6432 b'date',
6433 b'',
6433 b'',
6434 _(b'shelve with the specified commit date'),
6434 _(b'shelve with the specified commit date'),
6435 _(b'DATE'),
6435 _(b'DATE'),
6436 ),
6436 ),
6437 (b'd', b'delete', None, _(b'delete the named shelved change(s)')),
6437 (b'd', b'delete', None, _(b'delete the named shelved change(s)')),
6438 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
6438 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
6439 (
6439 (
6440 b'k',
6440 b'k',
6441 b'keep',
6441 b'keep',
6442 False,
6442 False,
6443 _(b'shelve, but keep changes in the working directory'),
6443 _(b'shelve, but keep changes in the working directory'),
6444 ),
6444 ),
6445 (b'l', b'list', None, _(b'list current shelves')),
6445 (b'l', b'list', None, _(b'list current shelves')),
6446 (b'm', b'message', b'', _(b'use text as shelve message'), _(b'TEXT')),
6446 (b'm', b'message', b'', _(b'use text as shelve message'), _(b'TEXT')),
6447 (
6447 (
6448 b'n',
6448 b'n',
6449 b'name',
6449 b'name',
6450 b'',
6450 b'',
6451 _(b'use the given name for the shelved commit'),
6451 _(b'use the given name for the shelved commit'),
6452 _(b'NAME'),
6452 _(b'NAME'),
6453 ),
6453 ),
6454 (
6454 (
6455 b'p',
6455 b'p',
6456 b'patch',
6456 b'patch',
6457 None,
6457 None,
6458 _(
6458 _(
6459 b'output patches for changes (provide the names of the shelved '
6459 b'output patches for changes (provide the names of the shelved '
6460 b'changes as positional arguments)'
6460 b'changes as positional arguments)'
6461 ),
6461 ),
6462 ),
6462 ),
6463 (b'i', b'interactive', None, _(b'interactive mode')),
6463 (b'i', b'interactive', None, _(b'interactive mode')),
6464 (
6464 (
6465 b'',
6465 b'',
6466 b'stat',
6466 b'stat',
6467 None,
6467 None,
6468 _(
6468 _(
6469 b'output diffstat-style summary of changes (provide the names of '
6469 b'output diffstat-style summary of changes (provide the names of '
6470 b'the shelved changes as positional arguments)'
6470 b'the shelved changes as positional arguments)'
6471 ),
6471 ),
6472 ),
6472 ),
6473 ]
6473 ]
6474 + cmdutil.walkopts,
6474 + cmdutil.walkopts,
6475 _(b'hg shelve [OPTION]... [FILE]...'),
6475 _(b'hg shelve [OPTION]... [FILE]...'),
6476 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6476 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6477 )
6477 )
6478 def shelve(ui, repo, *pats, **opts):
6478 def shelve(ui, repo, *pats, **opts):
6479 """save and set aside changes from the working directory
6479 """save and set aside changes from the working directory
6480
6480
6481 Shelving takes files that "hg status" reports as not clean, saves
6481 Shelving takes files that "hg status" reports as not clean, saves
6482 the modifications to a bundle (a shelved change), and reverts the
6482 the modifications to a bundle (a shelved change), and reverts the
6483 files so that their state in the working directory becomes clean.
6483 files so that their state in the working directory becomes clean.
6484
6484
6485 To restore these changes to the working directory, using "hg
6485 To restore these changes to the working directory, using "hg
6486 unshelve"; this will work even if you switch to a different
6486 unshelve"; this will work even if you switch to a different
6487 commit.
6487 commit.
6488
6488
6489 When no files are specified, "hg shelve" saves all not-clean
6489 When no files are specified, "hg shelve" saves all not-clean
6490 files. If specific files or directories are named, only changes to
6490 files. If specific files or directories are named, only changes to
6491 those files are shelved.
6491 those files are shelved.
6492
6492
6493 In bare shelve (when no files are specified, without interactive,
6493 In bare shelve (when no files are specified, without interactive,
6494 include and exclude option), shelving remembers information if the
6494 include and exclude option), shelving remembers information if the
6495 working directory was on newly created branch, in other words working
6495 working directory was on newly created branch, in other words working
6496 directory was on different branch than its first parent. In this
6496 directory was on different branch than its first parent. In this
6497 situation unshelving restores branch information to the working directory.
6497 situation unshelving restores branch information to the working directory.
6498
6498
6499 Each shelved change has a name that makes it easier to find later.
6499 Each shelved change has a name that makes it easier to find later.
6500 The name of a shelved change defaults to being based on the active
6500 The name of a shelved change defaults to being based on the active
6501 bookmark, or if there is no active bookmark, the current named
6501 bookmark, or if there is no active bookmark, the current named
6502 branch. To specify a different name, use ``--name``.
6502 branch. To specify a different name, use ``--name``.
6503
6503
6504 To see a list of existing shelved changes, use the ``--list``
6504 To see a list of existing shelved changes, use the ``--list``
6505 option. For each shelved change, this will print its name, age,
6505 option. For each shelved change, this will print its name, age,
6506 and description; use ``--patch`` or ``--stat`` for more details.
6506 and description; use ``--patch`` or ``--stat`` for more details.
6507
6507
6508 To delete specific shelved changes, use ``--delete``. To delete
6508 To delete specific shelved changes, use ``--delete``. To delete
6509 all shelved changes, use ``--cleanup``.
6509 all shelved changes, use ``--cleanup``.
6510 """
6510 """
6511 opts = pycompat.byteskwargs(opts)
6511 opts = pycompat.byteskwargs(opts)
6512 allowables = [
6512 allowables = [
6513 (b'addremove', {b'create'}), # 'create' is pseudo action
6513 (b'addremove', {b'create'}), # 'create' is pseudo action
6514 (b'unknown', {b'create'}),
6514 (b'unknown', {b'create'}),
6515 (b'cleanup', {b'cleanup'}),
6515 (b'cleanup', {b'cleanup'}),
6516 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
6516 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
6517 (b'delete', {b'delete'}),
6517 (b'delete', {b'delete'}),
6518 (b'edit', {b'create'}),
6518 (b'edit', {b'create'}),
6519 (b'keep', {b'create'}),
6519 (b'keep', {b'create'}),
6520 (b'list', {b'list'}),
6520 (b'list', {b'list'}),
6521 (b'message', {b'create'}),
6521 (b'message', {b'create'}),
6522 (b'name', {b'create'}),
6522 (b'name', {b'create'}),
6523 (b'patch', {b'patch', b'list'}),
6523 (b'patch', {b'patch', b'list'}),
6524 (b'stat', {b'stat', b'list'}),
6524 (b'stat', {b'stat', b'list'}),
6525 ]
6525 ]
6526
6526
6527 def checkopt(opt):
6527 def checkopt(opt):
6528 if opts.get(opt):
6528 if opts.get(opt):
6529 for i, allowable in allowables:
6529 for i, allowable in allowables:
6530 if opts[i] and opt not in allowable:
6530 if opts[i] and opt not in allowable:
6531 raise error.InputError(
6531 raise error.InputError(
6532 _(
6532 _(
6533 b"options '--%s' and '--%s' may not be "
6533 b"options '--%s' and '--%s' may not be "
6534 b"used together"
6534 b"used together"
6535 )
6535 )
6536 % (opt, i)
6536 % (opt, i)
6537 )
6537 )
6538 return True
6538 return True
6539
6539
6540 if checkopt(b'cleanup'):
6540 if checkopt(b'cleanup'):
6541 if pats:
6541 if pats:
6542 raise error.InputError(
6542 raise error.InputError(
6543 _(b"cannot specify names when using '--cleanup'")
6543 _(b"cannot specify names when using '--cleanup'")
6544 )
6544 )
6545 return shelvemod.cleanupcmd(ui, repo)
6545 return shelvemod.cleanupcmd(ui, repo)
6546 elif checkopt(b'delete'):
6546 elif checkopt(b'delete'):
6547 return shelvemod.deletecmd(ui, repo, pats)
6547 return shelvemod.deletecmd(ui, repo, pats)
6548 elif checkopt(b'list'):
6548 elif checkopt(b'list'):
6549 return shelvemod.listcmd(ui, repo, pats, opts)
6549 return shelvemod.listcmd(ui, repo, pats, opts)
6550 elif checkopt(b'patch') or checkopt(b'stat'):
6550 elif checkopt(b'patch') or checkopt(b'stat'):
6551 return shelvemod.patchcmds(ui, repo, pats, opts)
6551 return shelvemod.patchcmds(ui, repo, pats, opts)
6552 else:
6552 else:
6553 return shelvemod.createcmd(ui, repo, pats, opts)
6553 return shelvemod.createcmd(ui, repo, pats, opts)
6554
6554
6555
6555
6556 _NOTTERSE = b'nothing'
6556 _NOTTERSE = b'nothing'
6557
6557
6558
6558
6559 @command(
6559 @command(
6560 b'status|st',
6560 b'status|st',
6561 [
6561 [
6562 (b'A', b'all', None, _(b'show status of all files')),
6562 (b'A', b'all', None, _(b'show status of all files')),
6563 (b'm', b'modified', None, _(b'show only modified files')),
6563 (b'm', b'modified', None, _(b'show only modified files')),
6564 (b'a', b'added', None, _(b'show only added files')),
6564 (b'a', b'added', None, _(b'show only added files')),
6565 (b'r', b'removed', None, _(b'show only removed files')),
6565 (b'r', b'removed', None, _(b'show only removed files')),
6566 (b'd', b'deleted', None, _(b'show only missing files')),
6566 (b'd', b'deleted', None, _(b'show only missing files')),
6567 (b'c', b'clean', None, _(b'show only files without changes')),
6567 (b'c', b'clean', None, _(b'show only files without changes')),
6568 (b'u', b'unknown', None, _(b'show only unknown (not tracked) files')),
6568 (b'u', b'unknown', None, _(b'show only unknown (not tracked) files')),
6569 (b'i', b'ignored', None, _(b'show only ignored files')),
6569 (b'i', b'ignored', None, _(b'show only ignored files')),
6570 (b'n', b'no-status', None, _(b'hide status prefix')),
6570 (b'n', b'no-status', None, _(b'hide status prefix')),
6571 (b't', b'terse', _NOTTERSE, _(b'show the terse output (EXPERIMENTAL)')),
6571 (b't', b'terse', _NOTTERSE, _(b'show the terse output (EXPERIMENTAL)')),
6572 (
6572 (
6573 b'C',
6573 b'C',
6574 b'copies',
6574 b'copies',
6575 None,
6575 None,
6576 _(b'show source of copied files (DEFAULT: ui.statuscopies)'),
6576 _(b'show source of copied files (DEFAULT: ui.statuscopies)'),
6577 ),
6577 ),
6578 (
6578 (
6579 b'0',
6579 b'0',
6580 b'print0',
6580 b'print0',
6581 None,
6581 None,
6582 _(b'end filenames with NUL, for use with xargs'),
6582 _(b'end filenames with NUL, for use with xargs'),
6583 ),
6583 ),
6584 (b'', b'rev', [], _(b'show difference from revision'), _(b'REV')),
6584 (b'', b'rev', [], _(b'show difference from revision'), _(b'REV')),
6585 (
6585 (
6586 b'',
6586 b'',
6587 b'change',
6587 b'change',
6588 b'',
6588 b'',
6589 _(b'list the changed files of a revision'),
6589 _(b'list the changed files of a revision'),
6590 _(b'REV'),
6590 _(b'REV'),
6591 ),
6591 ),
6592 ]
6592 ]
6593 + walkopts
6593 + walkopts
6594 + subrepoopts
6594 + subrepoopts
6595 + formatteropts,
6595 + formatteropts,
6596 _(b'[OPTION]... [FILE]...'),
6596 _(b'[OPTION]... [FILE]...'),
6597 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6597 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6598 helpbasic=True,
6598 helpbasic=True,
6599 inferrepo=True,
6599 inferrepo=True,
6600 intents={INTENT_READONLY},
6600 intents={INTENT_READONLY},
6601 )
6601 )
6602 def status(ui, repo, *pats, **opts):
6602 def status(ui, repo, *pats, **opts):
6603 """show changed files in the working directory
6603 """show changed files in the working directory
6604
6604
6605 Show status of files in the repository. If names are given, only
6605 Show status of files in the repository. If names are given, only
6606 files that match are shown. Files that are clean or ignored or
6606 files that match are shown. Files that are clean or ignored or
6607 the source of a copy/move operation, are not listed unless
6607 the source of a copy/move operation, are not listed unless
6608 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6608 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6609 Unless options described with "show only ..." are given, the
6609 Unless options described with "show only ..." are given, the
6610 options -mardu are used.
6610 options -mardu are used.
6611
6611
6612 Option -q/--quiet hides untracked (unknown and ignored) files
6612 Option -q/--quiet hides untracked (unknown and ignored) files
6613 unless explicitly requested with -u/--unknown or -i/--ignored.
6613 unless explicitly requested with -u/--unknown or -i/--ignored.
6614
6614
6615 .. note::
6615 .. note::
6616
6616
6617 :hg:`status` may appear to disagree with diff if permissions have
6617 :hg:`status` may appear to disagree with diff if permissions have
6618 changed or a merge has occurred. The standard diff format does
6618 changed or a merge has occurred. The standard diff format does
6619 not report permission changes and diff only reports changes
6619 not report permission changes and diff only reports changes
6620 relative to one merge parent.
6620 relative to one merge parent.
6621
6621
6622 If one revision is given, it is used as the base revision.
6622 If one revision is given, it is used as the base revision.
6623 If two revisions are given, the differences between them are
6623 If two revisions are given, the differences between them are
6624 shown. The --change option can also be used as a shortcut to list
6624 shown. The --change option can also be used as a shortcut to list
6625 the changed files of a revision from its first parent.
6625 the changed files of a revision from its first parent.
6626
6626
6627 The codes used to show the status of files are::
6627 The codes used to show the status of files are::
6628
6628
6629 M = modified
6629 M = modified
6630 A = added
6630 A = added
6631 R = removed
6631 R = removed
6632 C = clean
6632 C = clean
6633 ! = missing (deleted by non-hg command, but still tracked)
6633 ! = missing (deleted by non-hg command, but still tracked)
6634 ? = not tracked
6634 ? = not tracked
6635 I = ignored
6635 I = ignored
6636 = origin of the previous file (with --copies)
6636 = origin of the previous file (with --copies)
6637
6637
6638 .. container:: verbose
6638 .. container:: verbose
6639
6639
6640 The -t/--terse option abbreviates the output by showing only the directory
6640 The -t/--terse option abbreviates the output by showing only the directory
6641 name if all the files in it share the same status. The option takes an
6641 name if all the files in it share the same status. The option takes an
6642 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
6642 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
6643 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
6643 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
6644 for 'ignored' and 'c' for clean.
6644 for 'ignored' and 'c' for clean.
6645
6645
6646 It abbreviates only those statuses which are passed. Note that clean and
6646 It abbreviates only those statuses which are passed. Note that clean and
6647 ignored files are not displayed with '--terse ic' unless the -c/--clean
6647 ignored files are not displayed with '--terse ic' unless the -c/--clean
6648 and -i/--ignored options are also used.
6648 and -i/--ignored options are also used.
6649
6649
6650 The -v/--verbose option shows information when the repository is in an
6650 The -v/--verbose option shows information when the repository is in an
6651 unfinished merge, shelve, rebase state etc. You can have this behavior
6651 unfinished merge, shelve, rebase state etc. You can have this behavior
6652 turned on by default by enabling the ``commands.status.verbose`` option.
6652 turned on by default by enabling the ``commands.status.verbose`` option.
6653
6653
6654 You can skip displaying some of these states by setting
6654 You can skip displaying some of these states by setting
6655 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
6655 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
6656 'histedit', 'merge', 'rebase', or 'unshelve'.
6656 'histedit', 'merge', 'rebase', or 'unshelve'.
6657
6657
6658 Template:
6658 Template:
6659
6659
6660 The following keywords are supported in addition to the common template
6660 The following keywords are supported in addition to the common template
6661 keywords and functions. See also :hg:`help templates`.
6661 keywords and functions. See also :hg:`help templates`.
6662
6662
6663 :path: String. Repository-absolute path of the file.
6663 :path: String. Repository-absolute path of the file.
6664 :source: String. Repository-absolute path of the file originated from.
6664 :source: String. Repository-absolute path of the file originated from.
6665 Available if ``--copies`` is specified.
6665 Available if ``--copies`` is specified.
6666 :status: String. Character denoting file's status.
6666 :status: String. Character denoting file's status.
6667
6667
6668 Examples:
6668 Examples:
6669
6669
6670 - show changes in the working directory relative to a
6670 - show changes in the working directory relative to a
6671 changeset::
6671 changeset::
6672
6672
6673 hg status --rev 9353
6673 hg status --rev 9353
6674
6674
6675 - show changes in the working directory relative to the
6675 - show changes in the working directory relative to the
6676 current directory (see :hg:`help patterns` for more information)::
6676 current directory (see :hg:`help patterns` for more information)::
6677
6677
6678 hg status re:
6678 hg status re:
6679
6679
6680 - show all changes including copies in an existing changeset::
6680 - show all changes including copies in an existing changeset::
6681
6681
6682 hg status --copies --change 9353
6682 hg status --copies --change 9353
6683
6683
6684 - get a NUL separated list of added files, suitable for xargs::
6684 - get a NUL separated list of added files, suitable for xargs::
6685
6685
6686 hg status -an0
6686 hg status -an0
6687
6687
6688 - show more information about the repository status, abbreviating
6688 - show more information about the repository status, abbreviating
6689 added, removed, modified, deleted, and untracked paths::
6689 added, removed, modified, deleted, and untracked paths::
6690
6690
6691 hg status -v -t mardu
6691 hg status -v -t mardu
6692
6692
6693 Returns 0 on success.
6693 Returns 0 on success.
6694
6694
6695 """
6695 """
6696
6696
6697 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
6697 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
6698 opts = pycompat.byteskwargs(opts)
6698 opts = pycompat.byteskwargs(opts)
6699 revs = opts.get(b'rev')
6699 revs = opts.get(b'rev')
6700 change = opts.get(b'change')
6700 change = opts.get(b'change')
6701 terse = opts.get(b'terse')
6701 terse = opts.get(b'terse')
6702 if terse is _NOTTERSE:
6702 if terse is _NOTTERSE:
6703 if revs:
6703 if revs:
6704 terse = b''
6704 terse = b''
6705 else:
6705 else:
6706 terse = ui.config(b'commands', b'status.terse')
6706 terse = ui.config(b'commands', b'status.terse')
6707
6707
6708 if revs and terse:
6708 if revs and terse:
6709 msg = _(b'cannot use --terse with --rev')
6709 msg = _(b'cannot use --terse with --rev')
6710 raise error.InputError(msg)
6710 raise error.InputError(msg)
6711 elif change:
6711 elif change:
6712 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
6712 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
6713 ctx2 = scmutil.revsingle(repo, change, None)
6713 ctx2 = scmutil.revsingle(repo, change, None)
6714 ctx1 = ctx2.p1()
6714 ctx1 = ctx2.p1()
6715 else:
6715 else:
6716 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
6716 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
6717 ctx1, ctx2 = scmutil.revpair(repo, revs)
6717 ctx1, ctx2 = scmutil.revpair(repo, revs)
6718
6718
6719 forcerelativevalue = None
6719 forcerelativevalue = None
6720 if ui.hasconfig(b'commands', b'status.relative'):
6720 if ui.hasconfig(b'commands', b'status.relative'):
6721 forcerelativevalue = ui.configbool(b'commands', b'status.relative')
6721 forcerelativevalue = ui.configbool(b'commands', b'status.relative')
6722 uipathfn = scmutil.getuipathfn(
6722 uipathfn = scmutil.getuipathfn(
6723 repo,
6723 repo,
6724 legacyrelativevalue=bool(pats),
6724 legacyrelativevalue=bool(pats),
6725 forcerelativevalue=forcerelativevalue,
6725 forcerelativevalue=forcerelativevalue,
6726 )
6726 )
6727
6727
6728 if opts.get(b'print0'):
6728 if opts.get(b'print0'):
6729 end = b'\0'
6729 end = b'\0'
6730 else:
6730 else:
6731 end = b'\n'
6731 end = b'\n'
6732 states = b'modified added removed deleted unknown ignored clean'.split()
6732 states = b'modified added removed deleted unknown ignored clean'.split()
6733 show = [k for k in states if opts.get(k)]
6733 show = [k for k in states if opts.get(k)]
6734 if opts.get(b'all'):
6734 if opts.get(b'all'):
6735 show += ui.quiet and (states[:4] + [b'clean']) or states
6735 show += ui.quiet and (states[:4] + [b'clean']) or states
6736
6736
6737 if not show:
6737 if not show:
6738 if ui.quiet:
6738 if ui.quiet:
6739 show = states[:4]
6739 show = states[:4]
6740 else:
6740 else:
6741 show = states[:5]
6741 show = states[:5]
6742
6742
6743 m = scmutil.match(ctx2, pats, opts)
6743 m = scmutil.match(ctx2, pats, opts)
6744 if terse:
6744 if terse:
6745 # we need to compute clean and unknown to terse
6745 # we need to compute clean and unknown to terse
6746 stat = repo.status(
6746 stat = repo.status(
6747 ctx1.node(),
6747 ctx1.node(),
6748 ctx2.node(),
6748 ctx2.node(),
6749 m,
6749 m,
6750 b'ignored' in show or b'i' in terse,
6750 b'ignored' in show or b'i' in terse,
6751 clean=True,
6751 clean=True,
6752 unknown=True,
6752 unknown=True,
6753 listsubrepos=opts.get(b'subrepos'),
6753 listsubrepos=opts.get(b'subrepos'),
6754 )
6754 )
6755
6755
6756 stat = cmdutil.tersedir(stat, terse)
6756 stat = cmdutil.tersedir(stat, terse)
6757 else:
6757 else:
6758 stat = repo.status(
6758 stat = repo.status(
6759 ctx1.node(),
6759 ctx1.node(),
6760 ctx2.node(),
6760 ctx2.node(),
6761 m,
6761 m,
6762 b'ignored' in show,
6762 b'ignored' in show,
6763 b'clean' in show,
6763 b'clean' in show,
6764 b'unknown' in show,
6764 b'unknown' in show,
6765 opts.get(b'subrepos'),
6765 opts.get(b'subrepos'),
6766 )
6766 )
6767
6767
6768 changestates = zip(
6768 changestates = zip(
6769 states,
6769 states,
6770 pycompat.iterbytestr(b'MAR!?IC'),
6770 pycompat.iterbytestr(b'MAR!?IC'),
6771 [getattr(stat, s.decode('utf8')) for s in states],
6771 [getattr(stat, s.decode('utf8')) for s in states],
6772 )
6772 )
6773
6773
6774 copy = {}
6774 copy = {}
6775 if (
6775 if (
6776 opts.get(b'all')
6776 opts.get(b'all')
6777 or opts.get(b'copies')
6777 or opts.get(b'copies')
6778 or ui.configbool(b'ui', b'statuscopies')
6778 or ui.configbool(b'ui', b'statuscopies')
6779 ) and not opts.get(b'no_status'):
6779 ) and not opts.get(b'no_status'):
6780 copy = copies.pathcopies(ctx1, ctx2, m)
6780 copy = copies.pathcopies(ctx1, ctx2, m)
6781
6781
6782 morestatus = None
6782 morestatus = None
6783 if (
6783 if (
6784 (ui.verbose or ui.configbool(b'commands', b'status.verbose'))
6784 (ui.verbose or ui.configbool(b'commands', b'status.verbose'))
6785 and not ui.plain()
6785 and not ui.plain()
6786 and not opts.get(b'print0')
6786 and not opts.get(b'print0')
6787 ):
6787 ):
6788 morestatus = cmdutil.readmorestatus(repo)
6788 morestatus = cmdutil.readmorestatus(repo)
6789
6789
6790 ui.pager(b'status')
6790 ui.pager(b'status')
6791 fm = ui.formatter(b'status', opts)
6791 fm = ui.formatter(b'status', opts)
6792 fmt = b'%s' + end
6792 fmt = b'%s' + end
6793 showchar = not opts.get(b'no_status')
6793 showchar = not opts.get(b'no_status')
6794
6794
6795 for state, char, files in changestates:
6795 for state, char, files in changestates:
6796 if state in show:
6796 if state in show:
6797 label = b'status.' + state
6797 label = b'status.' + state
6798 for f in files:
6798 for f in files:
6799 fm.startitem()
6799 fm.startitem()
6800 fm.context(ctx=ctx2)
6800 fm.context(ctx=ctx2)
6801 fm.data(itemtype=b'file', path=f)
6801 fm.data(itemtype=b'file', path=f)
6802 fm.condwrite(showchar, b'status', b'%s ', char, label=label)
6802 fm.condwrite(showchar, b'status', b'%s ', char, label=label)
6803 fm.plain(fmt % uipathfn(f), label=label)
6803 fm.plain(fmt % uipathfn(f), label=label)
6804 if f in copy:
6804 if f in copy:
6805 fm.data(source=copy[f])
6805 fm.data(source=copy[f])
6806 fm.plain(
6806 fm.plain(
6807 (b' %s' + end) % uipathfn(copy[f]),
6807 (b' %s' + end) % uipathfn(copy[f]),
6808 label=b'status.copied',
6808 label=b'status.copied',
6809 )
6809 )
6810 if morestatus:
6810 if morestatus:
6811 morestatus.formatfile(f, fm)
6811 morestatus.formatfile(f, fm)
6812
6812
6813 if morestatus:
6813 if morestatus:
6814 morestatus.formatfooter(fm)
6814 morestatus.formatfooter(fm)
6815 fm.end()
6815 fm.end()
6816
6816
6817
6817
6818 @command(
6818 @command(
6819 b'summary|sum',
6819 b'summary|sum',
6820 [(b'', b'remote', None, _(b'check for push and pull'))],
6820 [(b'', b'remote', None, _(b'check for push and pull'))],
6821 b'[--remote]',
6821 b'[--remote]',
6822 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6822 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6823 helpbasic=True,
6823 helpbasic=True,
6824 intents={INTENT_READONLY},
6824 intents={INTENT_READONLY},
6825 )
6825 )
6826 def summary(ui, repo, **opts):
6826 def summary(ui, repo, **opts):
6827 """summarize working directory state
6827 """summarize working directory state
6828
6828
6829 This generates a brief summary of the working directory state,
6829 This generates a brief summary of the working directory state,
6830 including parents, branch, commit status, phase and available updates.
6830 including parents, branch, commit status, phase and available updates.
6831
6831
6832 With the --remote option, this will check the default paths for
6832 With the --remote option, this will check the default paths for
6833 incoming and outgoing changes. This can be time-consuming.
6833 incoming and outgoing changes. This can be time-consuming.
6834
6834
6835 Returns 0 on success.
6835 Returns 0 on success.
6836 """
6836 """
6837
6837
6838 opts = pycompat.byteskwargs(opts)
6838 opts = pycompat.byteskwargs(opts)
6839 ui.pager(b'summary')
6839 ui.pager(b'summary')
6840 ctx = repo[None]
6840 ctx = repo[None]
6841 parents = ctx.parents()
6841 parents = ctx.parents()
6842 pnode = parents[0].node()
6842 pnode = parents[0].node()
6843 marks = []
6843 marks = []
6844
6844
6845 try:
6845 try:
6846 ms = mergestatemod.mergestate.read(repo)
6846 ms = mergestatemod.mergestate.read(repo)
6847 except error.UnsupportedMergeRecords as e:
6847 except error.UnsupportedMergeRecords as e:
6848 s = b' '.join(e.recordtypes)
6848 s = b' '.join(e.recordtypes)
6849 ui.warn(
6849 ui.warn(
6850 _(b'warning: merge state has unsupported record types: %s\n') % s
6850 _(b'warning: merge state has unsupported record types: %s\n') % s
6851 )
6851 )
6852 unresolved = []
6852 unresolved = []
6853 else:
6853 else:
6854 unresolved = list(ms.unresolved())
6854 unresolved = list(ms.unresolved())
6855
6855
6856 for p in parents:
6856 for p in parents:
6857 # label with log.changeset (instead of log.parent) since this
6857 # label with log.changeset (instead of log.parent) since this
6858 # shows a working directory parent *changeset*:
6858 # shows a working directory parent *changeset*:
6859 # i18n: column positioning for "hg summary"
6859 # i18n: column positioning for "hg summary"
6860 ui.write(
6860 ui.write(
6861 _(b'parent: %d:%s ') % (p.rev(), p),
6861 _(b'parent: %d:%s ') % (p.rev(), p),
6862 label=logcmdutil.changesetlabels(p),
6862 label=logcmdutil.changesetlabels(p),
6863 )
6863 )
6864 ui.write(b' '.join(p.tags()), label=b'log.tag')
6864 ui.write(b' '.join(p.tags()), label=b'log.tag')
6865 if p.bookmarks():
6865 if p.bookmarks():
6866 marks.extend(p.bookmarks())
6866 marks.extend(p.bookmarks())
6867 if p.rev() == -1:
6867 if p.rev() == -1:
6868 if not len(repo):
6868 if not len(repo):
6869 ui.write(_(b' (empty repository)'))
6869 ui.write(_(b' (empty repository)'))
6870 else:
6870 else:
6871 ui.write(_(b' (no revision checked out)'))
6871 ui.write(_(b' (no revision checked out)'))
6872 if p.obsolete():
6872 if p.obsolete():
6873 ui.write(_(b' (obsolete)'))
6873 ui.write(_(b' (obsolete)'))
6874 if p.isunstable():
6874 if p.isunstable():
6875 instabilities = (
6875 instabilities = (
6876 ui.label(instability, b'trouble.%s' % instability)
6876 ui.label(instability, b'trouble.%s' % instability)
6877 for instability in p.instabilities()
6877 for instability in p.instabilities()
6878 )
6878 )
6879 ui.write(b' (' + b', '.join(instabilities) + b')')
6879 ui.write(b' (' + b', '.join(instabilities) + b')')
6880 ui.write(b'\n')
6880 ui.write(b'\n')
6881 if p.description():
6881 if p.description():
6882 ui.status(
6882 ui.status(
6883 b' ' + p.description().splitlines()[0].strip() + b'\n',
6883 b' ' + p.description().splitlines()[0].strip() + b'\n',
6884 label=b'log.summary',
6884 label=b'log.summary',
6885 )
6885 )
6886
6886
6887 branch = ctx.branch()
6887 branch = ctx.branch()
6888 bheads = repo.branchheads(branch)
6888 bheads = repo.branchheads(branch)
6889 # i18n: column positioning for "hg summary"
6889 # i18n: column positioning for "hg summary"
6890 m = _(b'branch: %s\n') % branch
6890 m = _(b'branch: %s\n') % branch
6891 if branch != b'default':
6891 if branch != b'default':
6892 ui.write(m, label=b'log.branch')
6892 ui.write(m, label=b'log.branch')
6893 else:
6893 else:
6894 ui.status(m, label=b'log.branch')
6894 ui.status(m, label=b'log.branch')
6895
6895
6896 if marks:
6896 if marks:
6897 active = repo._activebookmark
6897 active = repo._activebookmark
6898 # i18n: column positioning for "hg summary"
6898 # i18n: column positioning for "hg summary"
6899 ui.write(_(b'bookmarks:'), label=b'log.bookmark')
6899 ui.write(_(b'bookmarks:'), label=b'log.bookmark')
6900 if active is not None:
6900 if active is not None:
6901 if active in marks:
6901 if active in marks:
6902 ui.write(b' *' + active, label=bookmarks.activebookmarklabel)
6902 ui.write(b' *' + active, label=bookmarks.activebookmarklabel)
6903 marks.remove(active)
6903 marks.remove(active)
6904 else:
6904 else:
6905 ui.write(b' [%s]' % active, label=bookmarks.activebookmarklabel)
6905 ui.write(b' [%s]' % active, label=bookmarks.activebookmarklabel)
6906 for m in marks:
6906 for m in marks:
6907 ui.write(b' ' + m, label=b'log.bookmark')
6907 ui.write(b' ' + m, label=b'log.bookmark')
6908 ui.write(b'\n', label=b'log.bookmark')
6908 ui.write(b'\n', label=b'log.bookmark')
6909
6909
6910 status = repo.status(unknown=True)
6910 status = repo.status(unknown=True)
6911
6911
6912 c = repo.dirstate.copies()
6912 c = repo.dirstate.copies()
6913 copied, renamed = [], []
6913 copied, renamed = [], []
6914 for d, s in pycompat.iteritems(c):
6914 for d, s in pycompat.iteritems(c):
6915 if s in status.removed:
6915 if s in status.removed:
6916 status.removed.remove(s)
6916 status.removed.remove(s)
6917 renamed.append(d)
6917 renamed.append(d)
6918 else:
6918 else:
6919 copied.append(d)
6919 copied.append(d)
6920 if d in status.added:
6920 if d in status.added:
6921 status.added.remove(d)
6921 status.added.remove(d)
6922
6922
6923 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6923 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6924
6924
6925 labels = [
6925 labels = [
6926 (ui.label(_(b'%d modified'), b'status.modified'), status.modified),
6926 (ui.label(_(b'%d modified'), b'status.modified'), status.modified),
6927 (ui.label(_(b'%d added'), b'status.added'), status.added),
6927 (ui.label(_(b'%d added'), b'status.added'), status.added),
6928 (ui.label(_(b'%d removed'), b'status.removed'), status.removed),
6928 (ui.label(_(b'%d removed'), b'status.removed'), status.removed),
6929 (ui.label(_(b'%d renamed'), b'status.copied'), renamed),
6929 (ui.label(_(b'%d renamed'), b'status.copied'), renamed),
6930 (ui.label(_(b'%d copied'), b'status.copied'), copied),
6930 (ui.label(_(b'%d copied'), b'status.copied'), copied),
6931 (ui.label(_(b'%d deleted'), b'status.deleted'), status.deleted),
6931 (ui.label(_(b'%d deleted'), b'status.deleted'), status.deleted),
6932 (ui.label(_(b'%d unknown'), b'status.unknown'), status.unknown),
6932 (ui.label(_(b'%d unknown'), b'status.unknown'), status.unknown),
6933 (ui.label(_(b'%d unresolved'), b'resolve.unresolved'), unresolved),
6933 (ui.label(_(b'%d unresolved'), b'resolve.unresolved'), unresolved),
6934 (ui.label(_(b'%d subrepos'), b'status.modified'), subs),
6934 (ui.label(_(b'%d subrepos'), b'status.modified'), subs),
6935 ]
6935 ]
6936 t = []
6936 t = []
6937 for l, s in labels:
6937 for l, s in labels:
6938 if s:
6938 if s:
6939 t.append(l % len(s))
6939 t.append(l % len(s))
6940
6940
6941 t = b', '.join(t)
6941 t = b', '.join(t)
6942 cleanworkdir = False
6942 cleanworkdir = False
6943
6943
6944 if repo.vfs.exists(b'graftstate'):
6944 if repo.vfs.exists(b'graftstate'):
6945 t += _(b' (graft in progress)')
6945 t += _(b' (graft in progress)')
6946 if repo.vfs.exists(b'updatestate'):
6946 if repo.vfs.exists(b'updatestate'):
6947 t += _(b' (interrupted update)')
6947 t += _(b' (interrupted update)')
6948 elif len(parents) > 1:
6948 elif len(parents) > 1:
6949 t += _(b' (merge)')
6949 t += _(b' (merge)')
6950 elif branch != parents[0].branch():
6950 elif branch != parents[0].branch():
6951 t += _(b' (new branch)')
6951 t += _(b' (new branch)')
6952 elif parents[0].closesbranch() and pnode in repo.branchheads(
6952 elif parents[0].closesbranch() and pnode in repo.branchheads(
6953 branch, closed=True
6953 branch, closed=True
6954 ):
6954 ):
6955 t += _(b' (head closed)')
6955 t += _(b' (head closed)')
6956 elif not (
6956 elif not (
6957 status.modified
6957 status.modified
6958 or status.added
6958 or status.added
6959 or status.removed
6959 or status.removed
6960 or renamed
6960 or renamed
6961 or copied
6961 or copied
6962 or subs
6962 or subs
6963 ):
6963 ):
6964 t += _(b' (clean)')
6964 t += _(b' (clean)')
6965 cleanworkdir = True
6965 cleanworkdir = True
6966 elif pnode not in bheads:
6966 elif pnode not in bheads:
6967 t += _(b' (new branch head)')
6967 t += _(b' (new branch head)')
6968
6968
6969 if parents:
6969 if parents:
6970 pendingphase = max(p.phase() for p in parents)
6970 pendingphase = max(p.phase() for p in parents)
6971 else:
6971 else:
6972 pendingphase = phases.public
6972 pendingphase = phases.public
6973
6973
6974 if pendingphase > phases.newcommitphase(ui):
6974 if pendingphase > phases.newcommitphase(ui):
6975 t += b' (%s)' % phases.phasenames[pendingphase]
6975 t += b' (%s)' % phases.phasenames[pendingphase]
6976
6976
6977 if cleanworkdir:
6977 if cleanworkdir:
6978 # i18n: column positioning for "hg summary"
6978 # i18n: column positioning for "hg summary"
6979 ui.status(_(b'commit: %s\n') % t.strip())
6979 ui.status(_(b'commit: %s\n') % t.strip())
6980 else:
6980 else:
6981 # i18n: column positioning for "hg summary"
6981 # i18n: column positioning for "hg summary"
6982 ui.write(_(b'commit: %s\n') % t.strip())
6982 ui.write(_(b'commit: %s\n') % t.strip())
6983
6983
6984 # all ancestors of branch heads - all ancestors of parent = new csets
6984 # all ancestors of branch heads - all ancestors of parent = new csets
6985 new = len(
6985 new = len(
6986 repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
6986 repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
6987 )
6987 )
6988
6988
6989 if new == 0:
6989 if new == 0:
6990 # i18n: column positioning for "hg summary"
6990 # i18n: column positioning for "hg summary"
6991 ui.status(_(b'update: (current)\n'))
6991 ui.status(_(b'update: (current)\n'))
6992 elif pnode not in bheads:
6992 elif pnode not in bheads:
6993 # i18n: column positioning for "hg summary"
6993 # i18n: column positioning for "hg summary"
6994 ui.write(_(b'update: %d new changesets (update)\n') % new)
6994 ui.write(_(b'update: %d new changesets (update)\n') % new)
6995 else:
6995 else:
6996 # i18n: column positioning for "hg summary"
6996 # i18n: column positioning for "hg summary"
6997 ui.write(
6997 ui.write(
6998 _(b'update: %d new changesets, %d branch heads (merge)\n')
6998 _(b'update: %d new changesets, %d branch heads (merge)\n')
6999 % (new, len(bheads))
6999 % (new, len(bheads))
7000 )
7000 )
7001
7001
7002 t = []
7002 t = []
7003 draft = len(repo.revs(b'draft()'))
7003 draft = len(repo.revs(b'draft()'))
7004 if draft:
7004 if draft:
7005 t.append(_(b'%d draft') % draft)
7005 t.append(_(b'%d draft') % draft)
7006 secret = len(repo.revs(b'secret()'))
7006 secret = len(repo.revs(b'secret()'))
7007 if secret:
7007 if secret:
7008 t.append(_(b'%d secret') % secret)
7008 t.append(_(b'%d secret') % secret)
7009
7009
7010 if draft or secret:
7010 if draft or secret:
7011 ui.status(_(b'phases: %s\n') % b', '.join(t))
7011 ui.status(_(b'phases: %s\n') % b', '.join(t))
7012
7012
7013 if obsolete.isenabled(repo, obsolete.createmarkersopt):
7013 if obsolete.isenabled(repo, obsolete.createmarkersopt):
7014 for trouble in (b"orphan", b"contentdivergent", b"phasedivergent"):
7014 for trouble in (b"orphan", b"contentdivergent", b"phasedivergent"):
7015 numtrouble = len(repo.revs(trouble + b"()"))
7015 numtrouble = len(repo.revs(trouble + b"()"))
7016 # We write all the possibilities to ease translation
7016 # We write all the possibilities to ease translation
7017 troublemsg = {
7017 troublemsg = {
7018 b"orphan": _(b"orphan: %d changesets"),
7018 b"orphan": _(b"orphan: %d changesets"),
7019 b"contentdivergent": _(b"content-divergent: %d changesets"),
7019 b"contentdivergent": _(b"content-divergent: %d changesets"),
7020 b"phasedivergent": _(b"phase-divergent: %d changesets"),
7020 b"phasedivergent": _(b"phase-divergent: %d changesets"),
7021 }
7021 }
7022 if numtrouble > 0:
7022 if numtrouble > 0:
7023 ui.status(troublemsg[trouble] % numtrouble + b"\n")
7023 ui.status(troublemsg[trouble] % numtrouble + b"\n")
7024
7024
7025 cmdutil.summaryhooks(ui, repo)
7025 cmdutil.summaryhooks(ui, repo)
7026
7026
7027 if opts.get(b'remote'):
7027 if opts.get(b'remote'):
7028 needsincoming, needsoutgoing = True, True
7028 needsincoming, needsoutgoing = True, True
7029 else:
7029 else:
7030 needsincoming, needsoutgoing = False, False
7030 needsincoming, needsoutgoing = False, False
7031 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
7031 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
7032 if i:
7032 if i:
7033 needsincoming = True
7033 needsincoming = True
7034 if o:
7034 if o:
7035 needsoutgoing = True
7035 needsoutgoing = True
7036 if not needsincoming and not needsoutgoing:
7036 if not needsincoming and not needsoutgoing:
7037 return
7037 return
7038
7038
7039 def getincoming():
7039 def getincoming():
7040 source, branches = hg.parseurl(ui.expandpath(b'default'))
7040 source, branches = hg.parseurl(ui.expandpath(b'default'))
7041 sbranch = branches[0]
7041 sbranch = branches[0]
7042 try:
7042 try:
7043 other = hg.peer(repo, {}, source)
7043 other = hg.peer(repo, {}, source)
7044 except error.RepoError:
7044 except error.RepoError:
7045 if opts.get(b'remote'):
7045 if opts.get(b'remote'):
7046 raise
7046 raise
7047 return source, sbranch, None, None, None
7047 return source, sbranch, None, None, None
7048 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
7048 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
7049 if revs:
7049 if revs:
7050 revs = [other.lookup(rev) for rev in revs]
7050 revs = [other.lookup(rev) for rev in revs]
7051 ui.debug(b'comparing with %s\n' % util.hidepassword(source))
7051 ui.debug(b'comparing with %s\n' % util.hidepassword(source))
7052 repo.ui.pushbuffer()
7052 repo.ui.pushbuffer()
7053 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
7053 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
7054 repo.ui.popbuffer()
7054 repo.ui.popbuffer()
7055 return source, sbranch, other, commoninc, commoninc[1]
7055 return source, sbranch, other, commoninc, commoninc[1]
7056
7056
7057 if needsincoming:
7057 if needsincoming:
7058 source, sbranch, sother, commoninc, incoming = getincoming()
7058 source, sbranch, sother, commoninc, incoming = getincoming()
7059 else:
7059 else:
7060 source = sbranch = sother = commoninc = incoming = None
7060 source = sbranch = sother = commoninc = incoming = None
7061
7061
7062 def getoutgoing():
7062 def getoutgoing():
7063 dest, branches = hg.parseurl(ui.expandpath(b'default-push', b'default'))
7063 dest, branches = hg.parseurl(ui.expandpath(b'default-push', b'default'))
7064 dbranch = branches[0]
7064 dbranch = branches[0]
7065 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
7065 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
7066 if source != dest:
7066 if source != dest:
7067 try:
7067 try:
7068 dother = hg.peer(repo, {}, dest)
7068 dother = hg.peer(repo, {}, dest)
7069 except error.RepoError:
7069 except error.RepoError:
7070 if opts.get(b'remote'):
7070 if opts.get(b'remote'):
7071 raise
7071 raise
7072 return dest, dbranch, None, None
7072 return dest, dbranch, None, None
7073 ui.debug(b'comparing with %s\n' % util.hidepassword(dest))
7073 ui.debug(b'comparing with %s\n' % util.hidepassword(dest))
7074 elif sother is None:
7074 elif sother is None:
7075 # there is no explicit destination peer, but source one is invalid
7075 # there is no explicit destination peer, but source one is invalid
7076 return dest, dbranch, None, None
7076 return dest, dbranch, None, None
7077 else:
7077 else:
7078 dother = sother
7078 dother = sother
7079 if source != dest or (sbranch is not None and sbranch != dbranch):
7079 if source != dest or (sbranch is not None and sbranch != dbranch):
7080 common = None
7080 common = None
7081 else:
7081 else:
7082 common = commoninc
7082 common = commoninc
7083 if revs:
7083 if revs:
7084 revs = [repo.lookup(rev) for rev in revs]
7084 revs = [repo.lookup(rev) for rev in revs]
7085 repo.ui.pushbuffer()
7085 repo.ui.pushbuffer()
7086 outgoing = discovery.findcommonoutgoing(
7086 outgoing = discovery.findcommonoutgoing(
7087 repo, dother, onlyheads=revs, commoninc=common
7087 repo, dother, onlyheads=revs, commoninc=common
7088 )
7088 )
7089 repo.ui.popbuffer()
7089 repo.ui.popbuffer()
7090 return dest, dbranch, dother, outgoing
7090 return dest, dbranch, dother, outgoing
7091
7091
7092 if needsoutgoing:
7092 if needsoutgoing:
7093 dest, dbranch, dother, outgoing = getoutgoing()
7093 dest, dbranch, dother, outgoing = getoutgoing()
7094 else:
7094 else:
7095 dest = dbranch = dother = outgoing = None
7095 dest = dbranch = dother = outgoing = None
7096
7096
7097 if opts.get(b'remote'):
7097 if opts.get(b'remote'):
7098 t = []
7098 t = []
7099 if incoming:
7099 if incoming:
7100 t.append(_(b'1 or more incoming'))
7100 t.append(_(b'1 or more incoming'))
7101 o = outgoing.missing
7101 o = outgoing.missing
7102 if o:
7102 if o:
7103 t.append(_(b'%d outgoing') % len(o))
7103 t.append(_(b'%d outgoing') % len(o))
7104 other = dother or sother
7104 other = dother or sother
7105 if b'bookmarks' in other.listkeys(b'namespaces'):
7105 if b'bookmarks' in other.listkeys(b'namespaces'):
7106 counts = bookmarks.summary(repo, other)
7106 counts = bookmarks.summary(repo, other)
7107 if counts[0] > 0:
7107 if counts[0] > 0:
7108 t.append(_(b'%d incoming bookmarks') % counts[0])
7108 t.append(_(b'%d incoming bookmarks') % counts[0])
7109 if counts[1] > 0:
7109 if counts[1] > 0:
7110 t.append(_(b'%d outgoing bookmarks') % counts[1])
7110 t.append(_(b'%d outgoing bookmarks') % counts[1])
7111
7111
7112 if t:
7112 if t:
7113 # i18n: column positioning for "hg summary"
7113 # i18n: column positioning for "hg summary"
7114 ui.write(_(b'remote: %s\n') % (b', '.join(t)))
7114 ui.write(_(b'remote: %s\n') % (b', '.join(t)))
7115 else:
7115 else:
7116 # i18n: column positioning for "hg summary"
7116 # i18n: column positioning for "hg summary"
7117 ui.status(_(b'remote: (synced)\n'))
7117 ui.status(_(b'remote: (synced)\n'))
7118
7118
7119 cmdutil.summaryremotehooks(
7119 cmdutil.summaryremotehooks(
7120 ui,
7120 ui,
7121 repo,
7121 repo,
7122 opts,
7122 opts,
7123 (
7123 (
7124 (source, sbranch, sother, commoninc),
7124 (source, sbranch, sother, commoninc),
7125 (dest, dbranch, dother, outgoing),
7125 (dest, dbranch, dother, outgoing),
7126 ),
7126 ),
7127 )
7127 )
7128
7128
7129
7129
7130 @command(
7130 @command(
7131 b'tag',
7131 b'tag',
7132 [
7132 [
7133 (b'f', b'force', None, _(b'force tag')),
7133 (b'f', b'force', None, _(b'force tag')),
7134 (b'l', b'local', None, _(b'make the tag local')),
7134 (b'l', b'local', None, _(b'make the tag local')),
7135 (b'r', b'rev', b'', _(b'revision to tag'), _(b'REV')),
7135 (b'r', b'rev', b'', _(b'revision to tag'), _(b'REV')),
7136 (b'', b'remove', None, _(b'remove a tag')),
7136 (b'', b'remove', None, _(b'remove a tag')),
7137 # -l/--local is already there, commitopts cannot be used
7137 # -l/--local is already there, commitopts cannot be used
7138 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
7138 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
7139 (b'm', b'message', b'', _(b'use text as commit message'), _(b'TEXT')),
7139 (b'm', b'message', b'', _(b'use text as commit message'), _(b'TEXT')),
7140 ]
7140 ]
7141 + commitopts2,
7141 + commitopts2,
7142 _(b'[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
7142 _(b'[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
7143 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7143 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7144 )
7144 )
7145 def tag(ui, repo, name1, *names, **opts):
7145 def tag(ui, repo, name1, *names, **opts):
7146 """add one or more tags for the current or given revision
7146 """add one or more tags for the current or given revision
7147
7147
7148 Name a particular revision using <name>.
7148 Name a particular revision using <name>.
7149
7149
7150 Tags are used to name particular revisions of the repository and are
7150 Tags are used to name particular revisions of the repository and are
7151 very useful to compare different revisions, to go back to significant
7151 very useful to compare different revisions, to go back to significant
7152 earlier versions or to mark branch points as releases, etc. Changing
7152 earlier versions or to mark branch points as releases, etc. Changing
7153 an existing tag is normally disallowed; use -f/--force to override.
7153 an existing tag is normally disallowed; use -f/--force to override.
7154
7154
7155 If no revision is given, the parent of the working directory is
7155 If no revision is given, the parent of the working directory is
7156 used.
7156 used.
7157
7157
7158 To facilitate version control, distribution, and merging of tags,
7158 To facilitate version control, distribution, and merging of tags,
7159 they are stored as a file named ".hgtags" which is managed similarly
7159 they are stored as a file named ".hgtags" which is managed similarly
7160 to other project files and can be hand-edited if necessary. This
7160 to other project files and can be hand-edited if necessary. This
7161 also means that tagging creates a new commit. The file
7161 also means that tagging creates a new commit. The file
7162 ".hg/localtags" is used for local tags (not shared among
7162 ".hg/localtags" is used for local tags (not shared among
7163 repositories).
7163 repositories).
7164
7164
7165 Tag commits are usually made at the head of a branch. If the parent
7165 Tag commits are usually made at the head of a branch. If the parent
7166 of the working directory is not a branch head, :hg:`tag` aborts; use
7166 of the working directory is not a branch head, :hg:`tag` aborts; use
7167 -f/--force to force the tag commit to be based on a non-head
7167 -f/--force to force the tag commit to be based on a non-head
7168 changeset.
7168 changeset.
7169
7169
7170 See :hg:`help dates` for a list of formats valid for -d/--date.
7170 See :hg:`help dates` for a list of formats valid for -d/--date.
7171
7171
7172 Since tag names have priority over branch names during revision
7172 Since tag names have priority over branch names during revision
7173 lookup, using an existing branch name as a tag name is discouraged.
7173 lookup, using an existing branch name as a tag name is discouraged.
7174
7174
7175 Returns 0 on success.
7175 Returns 0 on success.
7176 """
7176 """
7177 cmdutil.check_incompatible_arguments(opts, 'remove', ['rev'])
7177 cmdutil.check_incompatible_arguments(opts, 'remove', ['rev'])
7178 opts = pycompat.byteskwargs(opts)
7178 opts = pycompat.byteskwargs(opts)
7179 with repo.wlock(), repo.lock():
7179 with repo.wlock(), repo.lock():
7180 rev_ = b"."
7180 rev_ = b"."
7181 names = [t.strip() for t in (name1,) + names]
7181 names = [t.strip() for t in (name1,) + names]
7182 if len(names) != len(set(names)):
7182 if len(names) != len(set(names)):
7183 raise error.InputError(_(b'tag names must be unique'))
7183 raise error.InputError(_(b'tag names must be unique'))
7184 for n in names:
7184 for n in names:
7185 scmutil.checknewlabel(repo, n, b'tag')
7185 scmutil.checknewlabel(repo, n, b'tag')
7186 if not n:
7186 if not n:
7187 raise error.InputError(
7187 raise error.InputError(
7188 _(b'tag names cannot consist entirely of whitespace')
7188 _(b'tag names cannot consist entirely of whitespace')
7189 )
7189 )
7190 if opts.get(b'rev'):
7190 if opts.get(b'rev'):
7191 rev_ = opts[b'rev']
7191 rev_ = opts[b'rev']
7192 message = opts.get(b'message')
7192 message = opts.get(b'message')
7193 if opts.get(b'remove'):
7193 if opts.get(b'remove'):
7194 if opts.get(b'local'):
7194 if opts.get(b'local'):
7195 expectedtype = b'local'
7195 expectedtype = b'local'
7196 else:
7196 else:
7197 expectedtype = b'global'
7197 expectedtype = b'global'
7198
7198
7199 for n in names:
7199 for n in names:
7200 if repo.tagtype(n) == b'global':
7200 if repo.tagtype(n) == b'global':
7201 alltags = tagsmod.findglobaltags(ui, repo)
7201 alltags = tagsmod.findglobaltags(ui, repo)
7202 if alltags[n][0] == nullid:
7202 if alltags[n][0] == nullid:
7203 raise error.InputError(
7203 raise error.InputError(
7204 _(b"tag '%s' is already removed") % n
7204 _(b"tag '%s' is already removed") % n
7205 )
7205 )
7206 if not repo.tagtype(n):
7206 if not repo.tagtype(n):
7207 raise error.InputError(_(b"tag '%s' does not exist") % n)
7207 raise error.InputError(_(b"tag '%s' does not exist") % n)
7208 if repo.tagtype(n) != expectedtype:
7208 if repo.tagtype(n) != expectedtype:
7209 if expectedtype == b'global':
7209 if expectedtype == b'global':
7210 raise error.InputError(
7210 raise error.InputError(
7211 _(b"tag '%s' is not a global tag") % n
7211 _(b"tag '%s' is not a global tag") % n
7212 )
7212 )
7213 else:
7213 else:
7214 raise error.InputError(
7214 raise error.InputError(
7215 _(b"tag '%s' is not a local tag") % n
7215 _(b"tag '%s' is not a local tag") % n
7216 )
7216 )
7217 rev_ = b'null'
7217 rev_ = b'null'
7218 if not message:
7218 if not message:
7219 # we don't translate commit messages
7219 # we don't translate commit messages
7220 message = b'Removed tag %s' % b', '.join(names)
7220 message = b'Removed tag %s' % b', '.join(names)
7221 elif not opts.get(b'force'):
7221 elif not opts.get(b'force'):
7222 for n in names:
7222 for n in names:
7223 if n in repo.tags():
7223 if n in repo.tags():
7224 raise error.InputError(
7224 raise error.InputError(
7225 _(b"tag '%s' already exists (use -f to force)") % n
7225 _(b"tag '%s' already exists (use -f to force)") % n
7226 )
7226 )
7227 if not opts.get(b'local'):
7227 if not opts.get(b'local'):
7228 p1, p2 = repo.dirstate.parents()
7228 p1, p2 = repo.dirstate.parents()
7229 if p2 != nullid:
7229 if p2 != nullid:
7230 raise error.StateError(_(b'uncommitted merge'))
7230 raise error.StateError(_(b'uncommitted merge'))
7231 bheads = repo.branchheads()
7231 bheads = repo.branchheads()
7232 if not opts.get(b'force') and bheads and p1 not in bheads:
7232 if not opts.get(b'force') and bheads and p1 not in bheads:
7233 raise error.InputError(
7233 raise error.InputError(
7234 _(
7234 _(
7235 b'working directory is not at a branch head '
7235 b'working directory is not at a branch head '
7236 b'(use -f to force)'
7236 b'(use -f to force)'
7237 )
7237 )
7238 )
7238 )
7239 node = scmutil.revsingle(repo, rev_).node()
7239 node = scmutil.revsingle(repo, rev_).node()
7240
7240
7241 if not message:
7241 if not message:
7242 # we don't translate commit messages
7242 # we don't translate commit messages
7243 message = b'Added tag %s for changeset %s' % (
7243 message = b'Added tag %s for changeset %s' % (
7244 b', '.join(names),
7244 b', '.join(names),
7245 short(node),
7245 short(node),
7246 )
7246 )
7247
7247
7248 date = opts.get(b'date')
7248 date = opts.get(b'date')
7249 if date:
7249 if date:
7250 date = dateutil.parsedate(date)
7250 date = dateutil.parsedate(date)
7251
7251
7252 if opts.get(b'remove'):
7252 if opts.get(b'remove'):
7253 editform = b'tag.remove'
7253 editform = b'tag.remove'
7254 else:
7254 else:
7255 editform = b'tag.add'
7255 editform = b'tag.add'
7256 editor = cmdutil.getcommiteditor(
7256 editor = cmdutil.getcommiteditor(
7257 editform=editform, **pycompat.strkwargs(opts)
7257 editform=editform, **pycompat.strkwargs(opts)
7258 )
7258 )
7259
7259
7260 # don't allow tagging the null rev
7260 # don't allow tagging the null rev
7261 if (
7261 if (
7262 not opts.get(b'remove')
7262 not opts.get(b'remove')
7263 and scmutil.revsingle(repo, rev_).rev() == nullrev
7263 and scmutil.revsingle(repo, rev_).rev() == nullrev
7264 ):
7264 ):
7265 raise error.InputError(_(b"cannot tag null revision"))
7265 raise error.InputError(_(b"cannot tag null revision"))
7266
7266
7267 tagsmod.tag(
7267 tagsmod.tag(
7268 repo,
7268 repo,
7269 names,
7269 names,
7270 node,
7270 node,
7271 message,
7271 message,
7272 opts.get(b'local'),
7272 opts.get(b'local'),
7273 opts.get(b'user'),
7273 opts.get(b'user'),
7274 date,
7274 date,
7275 editor=editor,
7275 editor=editor,
7276 )
7276 )
7277
7277
7278
7278
7279 @command(
7279 @command(
7280 b'tags',
7280 b'tags',
7281 formatteropts,
7281 formatteropts,
7282 b'',
7282 b'',
7283 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7283 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7284 intents={INTENT_READONLY},
7284 intents={INTENT_READONLY},
7285 )
7285 )
7286 def tags(ui, repo, **opts):
7286 def tags(ui, repo, **opts):
7287 """list repository tags
7287 """list repository tags
7288
7288
7289 This lists both regular and local tags. When the -v/--verbose
7289 This lists both regular and local tags. When the -v/--verbose
7290 switch is used, a third column "local" is printed for local tags.
7290 switch is used, a third column "local" is printed for local tags.
7291 When the -q/--quiet switch is used, only the tag name is printed.
7291 When the -q/--quiet switch is used, only the tag name is printed.
7292
7292
7293 .. container:: verbose
7293 .. container:: verbose
7294
7294
7295 Template:
7295 Template:
7296
7296
7297 The following keywords are supported in addition to the common template
7297 The following keywords are supported in addition to the common template
7298 keywords and functions such as ``{tag}``. See also
7298 keywords and functions such as ``{tag}``. See also
7299 :hg:`help templates`.
7299 :hg:`help templates`.
7300
7300
7301 :type: String. ``local`` for local tags.
7301 :type: String. ``local`` for local tags.
7302
7302
7303 Returns 0 on success.
7303 Returns 0 on success.
7304 """
7304 """
7305
7305
7306 opts = pycompat.byteskwargs(opts)
7306 opts = pycompat.byteskwargs(opts)
7307 ui.pager(b'tags')
7307 ui.pager(b'tags')
7308 fm = ui.formatter(b'tags', opts)
7308 fm = ui.formatter(b'tags', opts)
7309 hexfunc = fm.hexfunc
7309 hexfunc = fm.hexfunc
7310
7310
7311 for t, n in reversed(repo.tagslist()):
7311 for t, n in reversed(repo.tagslist()):
7312 hn = hexfunc(n)
7312 hn = hexfunc(n)
7313 label = b'tags.normal'
7313 label = b'tags.normal'
7314 tagtype = b''
7314 tagtype = b''
7315 if repo.tagtype(t) == b'local':
7315 if repo.tagtype(t) == b'local':
7316 label = b'tags.local'
7316 label = b'tags.local'
7317 tagtype = b'local'
7317 tagtype = b'local'
7318
7318
7319 fm.startitem()
7319 fm.startitem()
7320 fm.context(repo=repo)
7320 fm.context(repo=repo)
7321 fm.write(b'tag', b'%s', t, label=label)
7321 fm.write(b'tag', b'%s', t, label=label)
7322 fmt = b" " * (30 - encoding.colwidth(t)) + b' %5d:%s'
7322 fmt = b" " * (30 - encoding.colwidth(t)) + b' %5d:%s'
7323 fm.condwrite(
7323 fm.condwrite(
7324 not ui.quiet,
7324 not ui.quiet,
7325 b'rev node',
7325 b'rev node',
7326 fmt,
7326 fmt,
7327 repo.changelog.rev(n),
7327 repo.changelog.rev(n),
7328 hn,
7328 hn,
7329 label=label,
7329 label=label,
7330 )
7330 )
7331 fm.condwrite(
7331 fm.condwrite(
7332 ui.verbose and tagtype, b'type', b' %s', tagtype, label=label
7332 ui.verbose and tagtype, b'type', b' %s', tagtype, label=label
7333 )
7333 )
7334 fm.plain(b'\n')
7334 fm.plain(b'\n')
7335 fm.end()
7335 fm.end()
7336
7336
7337
7337
7338 @command(
7338 @command(
7339 b'tip',
7339 b'tip',
7340 [
7340 [
7341 (b'p', b'patch', None, _(b'show patch')),
7341 (b'p', b'patch', None, _(b'show patch')),
7342 (b'g', b'git', None, _(b'use git extended diff format')),
7342 (b'g', b'git', None, _(b'use git extended diff format')),
7343 ]
7343 ]
7344 + templateopts,
7344 + templateopts,
7345 _(b'[-p] [-g]'),
7345 _(b'[-p] [-g]'),
7346 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
7346 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
7347 )
7347 )
7348 def tip(ui, repo, **opts):
7348 def tip(ui, repo, **opts):
7349 """show the tip revision (DEPRECATED)
7349 """show the tip revision (DEPRECATED)
7350
7350
7351 The tip revision (usually just called the tip) is the changeset
7351 The tip revision (usually just called the tip) is the changeset
7352 most recently added to the repository (and therefore the most
7352 most recently added to the repository (and therefore the most
7353 recently changed head).
7353 recently changed head).
7354
7354
7355 If you have just made a commit, that commit will be the tip. If
7355 If you have just made a commit, that commit will be the tip. If
7356 you have just pulled changes from another repository, the tip of
7356 you have just pulled changes from another repository, the tip of
7357 that repository becomes the current tip. The "tip" tag is special
7357 that repository becomes the current tip. The "tip" tag is special
7358 and cannot be renamed or assigned to a different changeset.
7358 and cannot be renamed or assigned to a different changeset.
7359
7359
7360 This command is deprecated, please use :hg:`heads` instead.
7360 This command is deprecated, please use :hg:`heads` instead.
7361
7361
7362 Returns 0 on success.
7362 Returns 0 on success.
7363 """
7363 """
7364 opts = pycompat.byteskwargs(opts)
7364 opts = pycompat.byteskwargs(opts)
7365 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
7365 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
7366 displayer.show(repo[b'tip'])
7366 displayer.show(repo[b'tip'])
7367 displayer.close()
7367 displayer.close()
7368
7368
7369
7369
7370 @command(
7370 @command(
7371 b'unbundle',
7371 b'unbundle',
7372 [
7372 [
7373 (
7373 (
7374 b'u',
7374 b'u',
7375 b'update',
7375 b'update',
7376 None,
7376 None,
7377 _(b'update to new branch head if changesets were unbundled'),
7377 _(b'update to new branch head if changesets were unbundled'),
7378 )
7378 )
7379 ],
7379 ],
7380 _(b'[-u] FILE...'),
7380 _(b'[-u] FILE...'),
7381 helpcategory=command.CATEGORY_IMPORT_EXPORT,
7381 helpcategory=command.CATEGORY_IMPORT_EXPORT,
7382 )
7382 )
7383 def unbundle(ui, repo, fname1, *fnames, **opts):
7383 def unbundle(ui, repo, fname1, *fnames, **opts):
7384 """apply one or more bundle files
7384 """apply one or more bundle files
7385
7385
7386 Apply one or more bundle files generated by :hg:`bundle`.
7386 Apply one or more bundle files generated by :hg:`bundle`.
7387
7387
7388 Returns 0 on success, 1 if an update has unresolved files.
7388 Returns 0 on success, 1 if an update has unresolved files.
7389 """
7389 """
7390 fnames = (fname1,) + fnames
7390 fnames = (fname1,) + fnames
7391
7391
7392 with repo.lock():
7392 with repo.lock():
7393 for fname in fnames:
7393 for fname in fnames:
7394 f = hg.openpath(ui, fname)
7394 f = hg.openpath(ui, fname)
7395 gen = exchange.readbundle(ui, f, fname)
7395 gen = exchange.readbundle(ui, f, fname)
7396 if isinstance(gen, streamclone.streamcloneapplier):
7396 if isinstance(gen, streamclone.streamcloneapplier):
7397 raise error.InputError(
7397 raise error.InputError(
7398 _(
7398 _(
7399 b'packed bundles cannot be applied with '
7399 b'packed bundles cannot be applied with '
7400 b'"hg unbundle"'
7400 b'"hg unbundle"'
7401 ),
7401 ),
7402 hint=_(b'use "hg debugapplystreamclonebundle"'),
7402 hint=_(b'use "hg debugapplystreamclonebundle"'),
7403 )
7403 )
7404 url = b'bundle:' + fname
7404 url = b'bundle:' + fname
7405 try:
7405 try:
7406 txnname = b'unbundle'
7406 txnname = b'unbundle'
7407 if not isinstance(gen, bundle2.unbundle20):
7407 if not isinstance(gen, bundle2.unbundle20):
7408 txnname = b'unbundle\n%s' % util.hidepassword(url)
7408 txnname = b'unbundle\n%s' % util.hidepassword(url)
7409 with repo.transaction(txnname) as tr:
7409 with repo.transaction(txnname) as tr:
7410 op = bundle2.applybundle(
7410 op = bundle2.applybundle(
7411 repo, gen, tr, source=b'unbundle', url=url
7411 repo, gen, tr, source=b'unbundle', url=url
7412 )
7412 )
7413 except error.BundleUnknownFeatureError as exc:
7413 except error.BundleUnknownFeatureError as exc:
7414 raise error.Abort(
7414 raise error.Abort(
7415 _(b'%s: unknown bundle feature, %s') % (fname, exc),
7415 _(b'%s: unknown bundle feature, %s') % (fname, exc),
7416 hint=_(
7416 hint=_(
7417 b"see https://mercurial-scm.org/"
7417 b"see https://mercurial-scm.org/"
7418 b"wiki/BundleFeature for more "
7418 b"wiki/BundleFeature for more "
7419 b"information"
7419 b"information"
7420 ),
7420 ),
7421 )
7421 )
7422 modheads = bundle2.combinechangegroupresults(op)
7422 modheads = bundle2.combinechangegroupresults(op)
7423
7423
7424 return postincoming(ui, repo, modheads, opts.get('update'), None, None)
7424 return postincoming(ui, repo, modheads, opts.get('update'), None, None)
7425
7425
7426
7426
7427 @command(
7427 @command(
7428 b'unshelve',
7428 b'unshelve',
7429 [
7429 [
7430 (b'a', b'abort', None, _(b'abort an incomplete unshelve operation')),
7430 (b'a', b'abort', None, _(b'abort an incomplete unshelve operation')),
7431 (
7431 (
7432 b'c',
7432 b'c',
7433 b'continue',
7433 b'continue',
7434 None,
7434 None,
7435 _(b'continue an incomplete unshelve operation'),
7435 _(b'continue an incomplete unshelve operation'),
7436 ),
7436 ),
7437 (b'i', b'interactive', None, _(b'use interactive mode (EXPERIMENTAL)')),
7437 (b'i', b'interactive', None, _(b'use interactive mode (EXPERIMENTAL)')),
7438 (b'k', b'keep', None, _(b'keep shelve after unshelving')),
7438 (b'k', b'keep', None, _(b'keep shelve after unshelving')),
7439 (
7439 (
7440 b'n',
7440 b'n',
7441 b'name',
7441 b'name',
7442 b'',
7442 b'',
7443 _(b'restore shelved change with given name'),
7443 _(b'restore shelved change with given name'),
7444 _(b'NAME'),
7444 _(b'NAME'),
7445 ),
7445 ),
7446 (b't', b'tool', b'', _(b'specify merge tool')),
7446 (b't', b'tool', b'', _(b'specify merge tool')),
7447 (
7447 (
7448 b'',
7448 b'',
7449 b'date',
7449 b'date',
7450 b'',
7450 b'',
7451 _(b'set date for temporary commits (DEPRECATED)'),
7451 _(b'set date for temporary commits (DEPRECATED)'),
7452 _(b'DATE'),
7452 _(b'DATE'),
7453 ),
7453 ),
7454 ],
7454 ],
7455 _(b'hg unshelve [OPTION]... [[-n] SHELVED]'),
7455 _(b'hg unshelve [OPTION]... [[-n] SHELVED]'),
7456 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7456 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7457 )
7457 )
7458 def unshelve(ui, repo, *shelved, **opts):
7458 def unshelve(ui, repo, *shelved, **opts):
7459 """restore a shelved change to the working directory
7459 """restore a shelved change to the working directory
7460
7460
7461 This command accepts an optional name of a shelved change to
7461 This command accepts an optional name of a shelved change to
7462 restore. If none is given, the most recent shelved change is used.
7462 restore. If none is given, the most recent shelved change is used.
7463
7463
7464 If a shelved change is applied successfully, the bundle that
7464 If a shelved change is applied successfully, the bundle that
7465 contains the shelved changes is moved to a backup location
7465 contains the shelved changes is moved to a backup location
7466 (.hg/shelve-backup).
7466 (.hg/shelve-backup).
7467
7467
7468 Since you can restore a shelved change on top of an arbitrary
7468 Since you can restore a shelved change on top of an arbitrary
7469 commit, it is possible that unshelving will result in a conflict
7469 commit, it is possible that unshelving will result in a conflict
7470 between your changes and the commits you are unshelving onto. If
7470 between your changes and the commits you are unshelving onto. If
7471 this occurs, you must resolve the conflict, then use
7471 this occurs, you must resolve the conflict, then use
7472 ``--continue`` to complete the unshelve operation. (The bundle
7472 ``--continue`` to complete the unshelve operation. (The bundle
7473 will not be moved until you successfully complete the unshelve.)
7473 will not be moved until you successfully complete the unshelve.)
7474
7474
7475 (Alternatively, you can use ``--abort`` to abandon an unshelve
7475 (Alternatively, you can use ``--abort`` to abandon an unshelve
7476 that causes a conflict. This reverts the unshelved changes, and
7476 that causes a conflict. This reverts the unshelved changes, and
7477 leaves the bundle in place.)
7477 leaves the bundle in place.)
7478
7478
7479 If bare shelved change (without interactive, include and exclude
7479 If bare shelved change (without interactive, include and exclude
7480 option) was done on newly created branch it would restore branch
7480 option) was done on newly created branch it would restore branch
7481 information to the working directory.
7481 information to the working directory.
7482
7482
7483 After a successful unshelve, the shelved changes are stored in a
7483 After a successful unshelve, the shelved changes are stored in a
7484 backup directory. Only the N most recent backups are kept. N
7484 backup directory. Only the N most recent backups are kept. N
7485 defaults to 10 but can be overridden using the ``shelve.maxbackups``
7485 defaults to 10 but can be overridden using the ``shelve.maxbackups``
7486 configuration option.
7486 configuration option.
7487
7487
7488 .. container:: verbose
7488 .. container:: verbose
7489
7489
7490 Timestamp in seconds is used to decide order of backups. More
7490 Timestamp in seconds is used to decide order of backups. More
7491 than ``maxbackups`` backups are kept, if same timestamp
7491 than ``maxbackups`` backups are kept, if same timestamp
7492 prevents from deciding exact order of them, for safety.
7492 prevents from deciding exact order of them, for safety.
7493
7493
7494 Selected changes can be unshelved with ``--interactive`` flag.
7494 Selected changes can be unshelved with ``--interactive`` flag.
7495 The working directory is updated with the selected changes, and
7495 The working directory is updated with the selected changes, and
7496 only the unselected changes remain shelved.
7496 only the unselected changes remain shelved.
7497 Note: The whole shelve is applied to working directory first before
7497 Note: The whole shelve is applied to working directory first before
7498 running interactively. So, this will bring up all the conflicts between
7498 running interactively. So, this will bring up all the conflicts between
7499 working directory and the shelve, irrespective of which changes will be
7499 working directory and the shelve, irrespective of which changes will be
7500 unshelved.
7500 unshelved.
7501 """
7501 """
7502 with repo.wlock():
7502 with repo.wlock():
7503 return shelvemod.unshelvecmd(ui, repo, *shelved, **opts)
7503 return shelvemod.unshelvecmd(ui, repo, *shelved, **opts)
7504
7504
7505
7505
7506 statemod.addunfinished(
7506 statemod.addunfinished(
7507 b'unshelve',
7507 b'unshelve',
7508 fname=b'shelvedstate',
7508 fname=b'shelvedstate',
7509 continueflag=True,
7509 continueflag=True,
7510 abortfunc=shelvemod.hgabortunshelve,
7510 abortfunc=shelvemod.hgabortunshelve,
7511 continuefunc=shelvemod.hgcontinueunshelve,
7511 continuefunc=shelvemod.hgcontinueunshelve,
7512 cmdmsg=_(b'unshelve already in progress'),
7512 cmdmsg=_(b'unshelve already in progress'),
7513 )
7513 )
7514
7514
7515
7515
7516 @command(
7516 @command(
7517 b'update|up|checkout|co',
7517 b'update|up|checkout|co',
7518 [
7518 [
7519 (b'C', b'clean', None, _(b'discard uncommitted changes (no backup)')),
7519 (b'C', b'clean', None, _(b'discard uncommitted changes (no backup)')),
7520 (b'c', b'check', None, _(b'require clean working directory')),
7520 (b'c', b'check', None, _(b'require clean working directory')),
7521 (b'm', b'merge', None, _(b'merge uncommitted changes')),
7521 (b'm', b'merge', None, _(b'merge uncommitted changes')),
7522 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
7522 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
7523 (b'r', b'rev', b'', _(b'revision'), _(b'REV')),
7523 (b'r', b'rev', b'', _(b'revision'), _(b'REV')),
7524 ]
7524 ]
7525 + mergetoolopts,
7525 + mergetoolopts,
7526 _(b'[-C|-c|-m] [-d DATE] [[-r] REV]'),
7526 _(b'[-C|-c|-m] [-d DATE] [[-r] REV]'),
7527 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7527 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7528 helpbasic=True,
7528 helpbasic=True,
7529 )
7529 )
7530 def update(ui, repo, node=None, **opts):
7530 def update(ui, repo, node=None, **opts):
7531 """update working directory (or switch revisions)
7531 """update working directory (or switch revisions)
7532
7532
7533 Update the repository's working directory to the specified
7533 Update the repository's working directory to the specified
7534 changeset. If no changeset is specified, update to the tip of the
7534 changeset. If no changeset is specified, update to the tip of the
7535 current named branch and move the active bookmark (see :hg:`help
7535 current named branch and move the active bookmark (see :hg:`help
7536 bookmarks`).
7536 bookmarks`).
7537
7537
7538 Update sets the working directory's parent revision to the specified
7538 Update sets the working directory's parent revision to the specified
7539 changeset (see :hg:`help parents`).
7539 changeset (see :hg:`help parents`).
7540
7540
7541 If the changeset is not a descendant or ancestor of the working
7541 If the changeset is not a descendant or ancestor of the working
7542 directory's parent and there are uncommitted changes, the update is
7542 directory's parent and there are uncommitted changes, the update is
7543 aborted. With the -c/--check option, the working directory is checked
7543 aborted. With the -c/--check option, the working directory is checked
7544 for uncommitted changes; if none are found, the working directory is
7544 for uncommitted changes; if none are found, the working directory is
7545 updated to the specified changeset.
7545 updated to the specified changeset.
7546
7546
7547 .. container:: verbose
7547 .. container:: verbose
7548
7548
7549 The -C/--clean, -c/--check, and -m/--merge options control what
7549 The -C/--clean, -c/--check, and -m/--merge options control what
7550 happens if the working directory contains uncommitted changes.
7550 happens if the working directory contains uncommitted changes.
7551 At most of one of them can be specified.
7551 At most of one of them can be specified.
7552
7552
7553 1. If no option is specified, and if
7553 1. If no option is specified, and if
7554 the requested changeset is an ancestor or descendant of
7554 the requested changeset is an ancestor or descendant of
7555 the working directory's parent, the uncommitted changes
7555 the working directory's parent, the uncommitted changes
7556 are merged into the requested changeset and the merged
7556 are merged into the requested changeset and the merged
7557 result is left uncommitted. If the requested changeset is
7557 result is left uncommitted. If the requested changeset is
7558 not an ancestor or descendant (that is, it is on another
7558 not an ancestor or descendant (that is, it is on another
7559 branch), the update is aborted and the uncommitted changes
7559 branch), the update is aborted and the uncommitted changes
7560 are preserved.
7560 are preserved.
7561
7561
7562 2. With the -m/--merge option, the update is allowed even if the
7562 2. With the -m/--merge option, the update is allowed even if the
7563 requested changeset is not an ancestor or descendant of
7563 requested changeset is not an ancestor or descendant of
7564 the working directory's parent.
7564 the working directory's parent.
7565
7565
7566 3. With the -c/--check option, the update is aborted and the
7566 3. With the -c/--check option, the update is aborted and the
7567 uncommitted changes are preserved.
7567 uncommitted changes are preserved.
7568
7568
7569 4. With the -C/--clean option, uncommitted changes are discarded and
7569 4. With the -C/--clean option, uncommitted changes are discarded and
7570 the working directory is updated to the requested changeset.
7570 the working directory is updated to the requested changeset.
7571
7571
7572 To cancel an uncommitted merge (and lose your changes), use
7572 To cancel an uncommitted merge (and lose your changes), use
7573 :hg:`merge --abort`.
7573 :hg:`merge --abort`.
7574
7574
7575 Use null as the changeset to remove the working directory (like
7575 Use null as the changeset to remove the working directory (like
7576 :hg:`clone -U`).
7576 :hg:`clone -U`).
7577
7577
7578 If you want to revert just one file to an older revision, use
7578 If you want to revert just one file to an older revision, use
7579 :hg:`revert [-r REV] NAME`.
7579 :hg:`revert [-r REV] NAME`.
7580
7580
7581 See :hg:`help dates` for a list of formats valid for -d/--date.
7581 See :hg:`help dates` for a list of formats valid for -d/--date.
7582
7582
7583 Returns 0 on success, 1 if there are unresolved files.
7583 Returns 0 on success, 1 if there are unresolved files.
7584 """
7584 """
7585 cmdutil.check_at_most_one_arg(opts, 'clean', 'check', 'merge')
7585 cmdutil.check_at_most_one_arg(opts, 'clean', 'check', 'merge')
7586 rev = opts.get('rev')
7586 rev = opts.get('rev')
7587 date = opts.get('date')
7587 date = opts.get('date')
7588 clean = opts.get('clean')
7588 clean = opts.get('clean')
7589 check = opts.get('check')
7589 check = opts.get('check')
7590 merge = opts.get('merge')
7590 merge = opts.get('merge')
7591 if rev and node:
7591 if rev and node:
7592 raise error.InputError(_(b"please specify just one revision"))
7592 raise error.InputError(_(b"please specify just one revision"))
7593
7593
7594 if ui.configbool(b'commands', b'update.requiredest'):
7594 if ui.configbool(b'commands', b'update.requiredest'):
7595 if not node and not rev and not date:
7595 if not node and not rev and not date:
7596 raise error.InputError(
7596 raise error.InputError(
7597 _(b'you must specify a destination'),
7597 _(b'you must specify a destination'),
7598 hint=_(b'for example: hg update ".::"'),
7598 hint=_(b'for example: hg update ".::"'),
7599 )
7599 )
7600
7600
7601 if rev is None or rev == b'':
7601 if rev is None or rev == b'':
7602 rev = node
7602 rev = node
7603
7603
7604 if date and rev is not None:
7604 if date and rev is not None:
7605 raise error.InputError(_(b"you can't specify a revision and a date"))
7605 raise error.InputError(_(b"you can't specify a revision and a date"))
7606
7606
7607 updatecheck = None
7607 updatecheck = None
7608 if check:
7608 if check:
7609 updatecheck = b'abort'
7609 updatecheck = b'abort'
7610 elif merge:
7610 elif merge:
7611 updatecheck = b'none'
7611 updatecheck = b'none'
7612
7612
7613 with repo.wlock():
7613 with repo.wlock():
7614 cmdutil.clearunfinished(repo)
7614 cmdutil.clearunfinished(repo)
7615 if date:
7615 if date:
7616 rev = cmdutil.finddate(ui, repo, date)
7616 rev = cmdutil.finddate(ui, repo, date)
7617
7617
7618 # if we defined a bookmark, we have to remember the original name
7618 # if we defined a bookmark, we have to remember the original name
7619 brev = rev
7619 brev = rev
7620 if rev:
7620 if rev:
7621 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
7621 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
7622 ctx = scmutil.revsingle(repo, rev, default=None)
7622 ctx = scmutil.revsingle(repo, rev, default=None)
7623 rev = ctx.rev()
7623 rev = ctx.rev()
7624 hidden = ctx.hidden()
7624 hidden = ctx.hidden()
7625 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
7625 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
7626 with ui.configoverride(overrides, b'update'):
7626 with ui.configoverride(overrides, b'update'):
7627 ret = hg.updatetotally(
7627 ret = hg.updatetotally(
7628 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
7628 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
7629 )
7629 )
7630 if hidden:
7630 if hidden:
7631 ctxstr = ctx.hex()[:12]
7631 ctxstr = ctx.hex()[:12]
7632 ui.warn(_(b"updated to hidden changeset %s\n") % ctxstr)
7632 ui.warn(_(b"updated to hidden changeset %s\n") % ctxstr)
7633
7633
7634 if ctx.obsolete():
7634 if ctx.obsolete():
7635 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
7635 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
7636 ui.warn(b"(%s)\n" % obsfatemsg)
7636 ui.warn(b"(%s)\n" % obsfatemsg)
7637 return ret
7637 return ret
7638
7638
7639
7639
7640 @command(
7640 @command(
7641 b'verify',
7641 b'verify',
7642 [(b'', b'full', False, b'perform more checks (EXPERIMENTAL)')],
7642 [(b'', b'full', False, b'perform more checks (EXPERIMENTAL)')],
7643 helpcategory=command.CATEGORY_MAINTENANCE,
7643 helpcategory=command.CATEGORY_MAINTENANCE,
7644 )
7644 )
7645 def verify(ui, repo, **opts):
7645 def verify(ui, repo, **opts):
7646 """verify the integrity of the repository
7646 """verify the integrity of the repository
7647
7647
7648 Verify the integrity of the current repository.
7648 Verify the integrity of the current repository.
7649
7649
7650 This will perform an extensive check of the repository's
7650 This will perform an extensive check of the repository's
7651 integrity, validating the hashes and checksums of each entry in
7651 integrity, validating the hashes and checksums of each entry in
7652 the changelog, manifest, and tracked files, as well as the
7652 the changelog, manifest, and tracked files, as well as the
7653 integrity of their crosslinks and indices.
7653 integrity of their crosslinks and indices.
7654
7654
7655 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
7655 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
7656 for more information about recovery from corruption of the
7656 for more information about recovery from corruption of the
7657 repository.
7657 repository.
7658
7658
7659 Returns 0 on success, 1 if errors are encountered.
7659 Returns 0 on success, 1 if errors are encountered.
7660 """
7660 """
7661 opts = pycompat.byteskwargs(opts)
7661 opts = pycompat.byteskwargs(opts)
7662
7662
7663 level = None
7663 level = None
7664 if opts[b'full']:
7664 if opts[b'full']:
7665 level = verifymod.VERIFY_FULL
7665 level = verifymod.VERIFY_FULL
7666 return hg.verify(repo, level)
7666 return hg.verify(repo, level)
7667
7667
7668
7668
7669 @command(
7669 @command(
7670 b'version',
7670 b'version',
7671 [] + formatteropts,
7671 [] + formatteropts,
7672 helpcategory=command.CATEGORY_HELP,
7672 helpcategory=command.CATEGORY_HELP,
7673 norepo=True,
7673 norepo=True,
7674 intents={INTENT_READONLY},
7674 intents={INTENT_READONLY},
7675 )
7675 )
7676 def version_(ui, **opts):
7676 def version_(ui, **opts):
7677 """output version and copyright information
7677 """output version and copyright information
7678
7678
7679 .. container:: verbose
7679 .. container:: verbose
7680
7680
7681 Template:
7681 Template:
7682
7682
7683 The following keywords are supported. See also :hg:`help templates`.
7683 The following keywords are supported. See also :hg:`help templates`.
7684
7684
7685 :extensions: List of extensions.
7685 :extensions: List of extensions.
7686 :ver: String. Version number.
7686 :ver: String. Version number.
7687
7687
7688 And each entry of ``{extensions}`` provides the following sub-keywords
7688 And each entry of ``{extensions}`` provides the following sub-keywords
7689 in addition to ``{ver}``.
7689 in addition to ``{ver}``.
7690
7690
7691 :bundled: Boolean. True if included in the release.
7691 :bundled: Boolean. True if included in the release.
7692 :name: String. Extension name.
7692 :name: String. Extension name.
7693 """
7693 """
7694 opts = pycompat.byteskwargs(opts)
7694 opts = pycompat.byteskwargs(opts)
7695 if ui.verbose:
7695 if ui.verbose:
7696 ui.pager(b'version')
7696 ui.pager(b'version')
7697 fm = ui.formatter(b"version", opts)
7697 fm = ui.formatter(b"version", opts)
7698 fm.startitem()
7698 fm.startitem()
7699 fm.write(
7699 fm.write(
7700 b"ver", _(b"Mercurial Distributed SCM (version %s)\n"), util.version()
7700 b"ver", _(b"Mercurial Distributed SCM (version %s)\n"), util.version()
7701 )
7701 )
7702 license = _(
7702 license = _(
7703 b"(see https://mercurial-scm.org for more information)\n"
7703 b"(see https://mercurial-scm.org for more information)\n"
7704 b"\nCopyright (C) 2005-2020 Matt Mackall and others\n"
7704 b"\nCopyright (C) 2005-2020 Matt Mackall and others\n"
7705 b"This is free software; see the source for copying conditions. "
7705 b"This is free software; see the source for copying conditions. "
7706 b"There is NO\nwarranty; "
7706 b"There is NO\nwarranty; "
7707 b"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
7707 b"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
7708 )
7708 )
7709 if not ui.quiet:
7709 if not ui.quiet:
7710 fm.plain(license)
7710 fm.plain(license)
7711
7711
7712 if ui.verbose:
7712 if ui.verbose:
7713 fm.plain(_(b"\nEnabled extensions:\n\n"))
7713 fm.plain(_(b"\nEnabled extensions:\n\n"))
7714 # format names and versions into columns
7714 # format names and versions into columns
7715 names = []
7715 names = []
7716 vers = []
7716 vers = []
7717 isinternals = []
7717 isinternals = []
7718 for name, module in sorted(extensions.extensions()):
7718 for name, module in sorted(extensions.extensions()):
7719 names.append(name)
7719 names.append(name)
7720 vers.append(extensions.moduleversion(module) or None)
7720 vers.append(extensions.moduleversion(module) or None)
7721 isinternals.append(extensions.ismoduleinternal(module))
7721 isinternals.append(extensions.ismoduleinternal(module))
7722 fn = fm.nested(b"extensions", tmpl=b'{name}\n')
7722 fn = fm.nested(b"extensions", tmpl=b'{name}\n')
7723 if names:
7723 if names:
7724 namefmt = b" %%-%ds " % max(len(n) for n in names)
7724 namefmt = b" %%-%ds " % max(len(n) for n in names)
7725 places = [_(b"external"), _(b"internal")]
7725 places = [_(b"external"), _(b"internal")]
7726 for n, v, p in zip(names, vers, isinternals):
7726 for n, v, p in zip(names, vers, isinternals):
7727 fn.startitem()
7727 fn.startitem()
7728 fn.condwrite(ui.verbose, b"name", namefmt, n)
7728 fn.condwrite(ui.verbose, b"name", namefmt, n)
7729 if ui.verbose:
7729 if ui.verbose:
7730 fn.plain(b"%s " % places[p])
7730 fn.plain(b"%s " % places[p])
7731 fn.data(bundled=p)
7731 fn.data(bundled=p)
7732 fn.condwrite(ui.verbose and v, b"ver", b"%s", v)
7732 fn.condwrite(ui.verbose and v, b"ver", b"%s", v)
7733 if ui.verbose:
7733 if ui.verbose:
7734 fn.plain(b"\n")
7734 fn.plain(b"\n")
7735 fn.end()
7735 fn.end()
7736 fm.end()
7736 fm.end()
7737
7737
7738
7738
7739 def loadcmdtable(ui, name, cmdtable):
7739 def loadcmdtable(ui, name, cmdtable):
7740 """Load command functions from specified cmdtable"""
7740 """Load command functions from specified cmdtable"""
7741 overrides = [cmd for cmd in cmdtable if cmd in table]
7741 overrides = [cmd for cmd in cmdtable if cmd in table]
7742 if overrides:
7742 if overrides:
7743 ui.warn(
7743 ui.warn(
7744 _(b"extension '%s' overrides commands: %s\n")
7744 _(b"extension '%s' overrides commands: %s\n")
7745 % (name, b" ".join(overrides))
7745 % (name, b" ".join(overrides))
7746 )
7746 )
7747 table.update(cmdtable)
7747 table.update(cmdtable)
@@ -1,48 +1,49 b''
1 == New Features ==
1 == New Features ==
2
2
3 * There is a new config section for templates used by hg commands. It
3 * There is a new config section for templates used by hg commands. It
4 is called `[command-templates]`. Some existing config options have
4 is called `[command-templates]`. Some existing config options have
5 been deprecated in favor of config options in the new
5 been deprecated in favor of config options in the new
6 section. These are: `ui.logtemplate` to `command-templates.log`,
6 section. These are: `ui.logtemplate` to `command-templates.log`,
7 `ui.graphnodetemplate` to `command-templates.graphnode`,
7 `ui.graphnodetemplate` to `command-templates.graphnode`,
8 `ui.mergemarkertemplate` to `command-templates.mergemarker`,
8 `ui.mergemarkertemplate` to `command-templates.mergemarker`,
9 `ui.pre-merge-tool-output-template` to
9 `ui.pre-merge-tool-output-template` to
10 `command-templates.pre-merge-tool-output`.
10 `command-templates.pre-merge-tool-output`.
11
11
12 * There is a new set of config options for the template used for the
12 * There is a new set of config options for the template used for the
13 one-line commit summary displayed by various commands, such as `hg
13 one-line commit summary displayed by various commands, such as `hg
14 rebase`. The main one is `command-templates.oneline-summary`. That
14 rebase`. The main one is `command-templates.oneline-summary`. That
15 can be overridden per command with
15 can be overridden per command with
16 `command-templates.oneline-summary.<command>`, where `<command>`
16 `command-templates.oneline-summary.<command>`, where `<command>`
17 can be e.g. `rebase`. As part of this effort, the default format
17 can be e.g. `rebase`. As part of this effort, the default format
18 from `hg rebase` was reorganized a bit.
18 from `hg rebase` was reorganized a bit.
19
19
20 * `hg strip`, from the strip extension, is now a core command, `hg
20 * `hg strip`, from the strip extension, is now a core command, `hg
21 debugstrip`. The extension remains for compatibility.
21 debugstrip`. The extension remains for compatibility.
22
22
23 * `hg diff` now supports `--from <rev>` and `--to <rev>` arguments as
23 * `hg diff` now supports `--from <rev>` and `--to <rev>` arguments as
24 clearer alternatives to `-r <revs>`.
24 clearer alternatives to `-r <revs>`. `-r <revs>` has been
25 deprecated.
25
26
26 * The memory footprint per changeset during pull/unbundle
27 * The memory footprint per changeset during pull/unbundle
27 operations has been further reduced.
28 operations has been further reduced.
28
29
29
30
30 == New Experimental Features ==
31 == New Experimental Features ==
31
32
32 * `experimental.single-head-per-branch:public-changes-only` can be used
33 * `experimental.single-head-per-branch:public-changes-only` can be used
33 restrict the single head check to public revision. This is useful for
34 restrict the single head check to public revision. This is useful for
34 overlay repository that have both a publishing and non-publishing view
35 overlay repository that have both a publishing and non-publishing view
35 of the same storage.
36 of the same storage.
36
37
37
38
38 == Bug Fixes ==
39 == Bug Fixes ==
39
40
40
41
41
42
42 == Backwards Compatibility Changes ==
43 == Backwards Compatibility Changes ==
43
44
44
45
45
46
46 == Internal API Changes ==
47 == Internal API Changes ==
47
48
48
49
@@ -1,3925 +1,3924 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 remove remove the specified files on the next commit
110 remove remove the specified files on the next commit
111 rename rename files; equivalent of copy + remove
111 rename rename files; equivalent of copy + remove
112 resolve redo merges or set/view the merge status of files
112 resolve redo merges or set/view the merge status of files
113 revert restore files to their checkout state
113 revert restore files to their checkout state
114 root print the root (top) of the current working directory
114 root print the root (top) of the current working directory
115 shelve save and set aside changes from the working directory
115 shelve save and set aside changes from the working directory
116 status show changed files in the working directory
116 status show changed files in the working directory
117 summary summarize working directory state
117 summary summarize working directory state
118 unshelve restore a shelved change to the working directory
118 unshelve restore a shelved change to the working directory
119 update update working directory (or switch revisions)
119 update update working directory (or switch revisions)
120
120
121 Change import/export:
121 Change import/export:
122
122
123 archive create an unversioned archive of a repository revision
123 archive create an unversioned archive of a repository revision
124 bundle create a bundle file
124 bundle create a bundle file
125 export dump the header and diffs for one or more changesets
125 export dump the header and diffs for one or more changesets
126 import import an ordered set of patches
126 import import an ordered set of patches
127 unbundle apply one or more bundle files
127 unbundle apply one or more bundle files
128
128
129 Repository maintenance:
129 Repository maintenance:
130
130
131 manifest output the current or given revision of the project manifest
131 manifest output the current or given revision of the project manifest
132 recover roll back an interrupted transaction
132 recover roll back an interrupted transaction
133 verify verify the integrity of the repository
133 verify verify the integrity of the repository
134
134
135 Help:
135 Help:
136
136
137 config show combined config settings from all hgrc files
137 config show combined config settings from all hgrc files
138 help show help for a given topic or a help overview
138 help show help for a given topic or a help overview
139 version output version and copyright information
139 version output version and copyright information
140
140
141 additional help topics:
141 additional help topics:
142
142
143 Mercurial identifiers:
143 Mercurial identifiers:
144
144
145 filesets Specifying File Sets
145 filesets Specifying File Sets
146 hgignore Syntax for Mercurial Ignore Files
146 hgignore Syntax for Mercurial Ignore Files
147 patterns File Name Patterns
147 patterns File Name Patterns
148 revisions Specifying Revisions
148 revisions Specifying Revisions
149 urls URL Paths
149 urls URL Paths
150
150
151 Mercurial output:
151 Mercurial output:
152
152
153 color Colorizing Outputs
153 color Colorizing Outputs
154 dates Date Formats
154 dates Date Formats
155 diffs Diff Formats
155 diffs Diff Formats
156 templating Template Usage
156 templating Template Usage
157
157
158 Mercurial configuration:
158 Mercurial configuration:
159
159
160 config Configuration Files
160 config Configuration Files
161 environment Environment Variables
161 environment Environment Variables
162 extensions Using Additional Features
162 extensions Using Additional Features
163 flags Command-line flags
163 flags Command-line flags
164 hgweb Configuring hgweb
164 hgweb Configuring hgweb
165 merge-tools Merge Tools
165 merge-tools Merge Tools
166 pager Pager Support
166 pager Pager Support
167
167
168 Concepts:
168 Concepts:
169
169
170 bundlespec Bundle File Formats
170 bundlespec Bundle File Formats
171 glossary Glossary
171 glossary Glossary
172 phases Working with Phases
172 phases Working with Phases
173 subrepos Subrepositories
173 subrepos Subrepositories
174
174
175 Miscellaneous:
175 Miscellaneous:
176
176
177 deprecated Deprecated Features
177 deprecated Deprecated Features
178 internals Technical implementation topics
178 internals Technical implementation topics
179 scripting Using Mercurial from scripts and automation
179 scripting Using Mercurial from scripts and automation
180
180
181 (use 'hg help -v' to show built-in aliases and global options)
181 (use 'hg help -v' to show built-in aliases and global options)
182
182
183 $ hg -q help
183 $ hg -q help
184 Repository creation:
184 Repository creation:
185
185
186 clone make a copy of an existing repository
186 clone make a copy of an existing repository
187 init create a new repository in the given directory
187 init create a new repository in the given directory
188
188
189 Remote repository management:
189 Remote repository management:
190
190
191 incoming show new changesets found in source
191 incoming show new changesets found in source
192 outgoing show changesets not found in the destination
192 outgoing show changesets not found in the destination
193 paths show aliases for remote repositories
193 paths show aliases for remote repositories
194 pull pull changes from the specified source
194 pull pull changes from the specified source
195 push push changes to the specified destination
195 push push changes to the specified destination
196 serve start stand-alone webserver
196 serve start stand-alone webserver
197
197
198 Change creation:
198 Change creation:
199
199
200 commit commit the specified files or all outstanding changes
200 commit commit the specified files or all outstanding changes
201
201
202 Change manipulation:
202 Change manipulation:
203
203
204 backout reverse effect of earlier changeset
204 backout reverse effect of earlier changeset
205 graft copy changes from other branches onto the current branch
205 graft copy changes from other branches onto the current branch
206 merge merge another revision into working directory
206 merge merge another revision into working directory
207
207
208 Change organization:
208 Change organization:
209
209
210 bookmarks create a new bookmark or list existing bookmarks
210 bookmarks create a new bookmark or list existing bookmarks
211 branch set or show the current branch name
211 branch set or show the current branch name
212 branches list repository named branches
212 branches list repository named branches
213 phase set or show the current phase name
213 phase set or show the current phase name
214 tag add one or more tags for the current or given revision
214 tag add one or more tags for the current or given revision
215 tags list repository tags
215 tags list repository tags
216
216
217 File content management:
217 File content management:
218
218
219 annotate show changeset information by line for each file
219 annotate show changeset information by line for each file
220 cat output the current or given revision of files
220 cat output the current or given revision of files
221 copy mark files as copied for the next commit
221 copy mark files as copied for the next commit
222 diff diff repository (or selected files)
222 diff diff repository (or selected files)
223 grep search for a pattern in specified files
223 grep search for a pattern in specified files
224
224
225 Change navigation:
225 Change navigation:
226
226
227 bisect subdivision search of changesets
227 bisect subdivision search of changesets
228 heads show branch heads
228 heads show branch heads
229 identify identify the working directory or specified revision
229 identify identify the working directory or specified revision
230 log show revision history of entire repository or files
230 log show revision history of entire repository or files
231
231
232 Working directory management:
232 Working directory management:
233
233
234 add add the specified files on the next commit
234 add add the specified files on the next commit
235 addremove add all new files, delete all missing files
235 addremove add all new files, delete all missing files
236 files list tracked files
236 files list tracked files
237 forget forget the specified files on the next commit
237 forget forget the specified files on the next commit
238 remove remove the specified files on the next commit
238 remove remove the specified files on the next commit
239 rename rename files; equivalent of copy + remove
239 rename rename files; equivalent of copy + remove
240 resolve redo merges or set/view the merge status of files
240 resolve redo merges or set/view the merge status of files
241 revert restore files to their checkout state
241 revert restore files to their checkout state
242 root print the root (top) of the current working directory
242 root print the root (top) of the current working directory
243 shelve save and set aside changes from the working directory
243 shelve save and set aside changes from the working directory
244 status show changed files in the working directory
244 status show changed files in the working directory
245 summary summarize working directory state
245 summary summarize working directory state
246 unshelve restore a shelved change to the working directory
246 unshelve restore a shelved change to the working directory
247 update update working directory (or switch revisions)
247 update update working directory (or switch revisions)
248
248
249 Change import/export:
249 Change import/export:
250
250
251 archive create an unversioned archive of a repository revision
251 archive create an unversioned archive of a repository revision
252 bundle create a bundle file
252 bundle create a bundle file
253 export dump the header and diffs for one or more changesets
253 export dump the header and diffs for one or more changesets
254 import import an ordered set of patches
254 import import an ordered set of patches
255 unbundle apply one or more bundle files
255 unbundle apply one or more bundle files
256
256
257 Repository maintenance:
257 Repository maintenance:
258
258
259 manifest output the current or given revision of the project manifest
259 manifest output the current or given revision of the project manifest
260 recover roll back an interrupted transaction
260 recover roll back an interrupted transaction
261 verify verify the integrity of the repository
261 verify verify the integrity of the repository
262
262
263 Help:
263 Help:
264
264
265 config show combined config settings from all hgrc files
265 config show combined config settings from all hgrc files
266 help show help for a given topic or a help overview
266 help show help for a given topic or a help overview
267 version output version and copyright information
267 version output version and copyright information
268
268
269 additional help topics:
269 additional help topics:
270
270
271 Mercurial identifiers:
271 Mercurial identifiers:
272
272
273 filesets Specifying File Sets
273 filesets Specifying File Sets
274 hgignore Syntax for Mercurial Ignore Files
274 hgignore Syntax for Mercurial Ignore Files
275 patterns File Name Patterns
275 patterns File Name Patterns
276 revisions Specifying Revisions
276 revisions Specifying Revisions
277 urls URL Paths
277 urls URL Paths
278
278
279 Mercurial output:
279 Mercurial output:
280
280
281 color Colorizing Outputs
281 color Colorizing Outputs
282 dates Date Formats
282 dates Date Formats
283 diffs Diff Formats
283 diffs Diff Formats
284 templating Template Usage
284 templating Template Usage
285
285
286 Mercurial configuration:
286 Mercurial configuration:
287
287
288 config Configuration Files
288 config Configuration Files
289 environment Environment Variables
289 environment Environment Variables
290 extensions Using Additional Features
290 extensions Using Additional Features
291 flags Command-line flags
291 flags Command-line flags
292 hgweb Configuring hgweb
292 hgweb Configuring hgweb
293 merge-tools Merge Tools
293 merge-tools Merge Tools
294 pager Pager Support
294 pager Pager Support
295
295
296 Concepts:
296 Concepts:
297
297
298 bundlespec Bundle File Formats
298 bundlespec Bundle File Formats
299 glossary Glossary
299 glossary Glossary
300 phases Working with Phases
300 phases Working with Phases
301 subrepos Subrepositories
301 subrepos Subrepositories
302
302
303 Miscellaneous:
303 Miscellaneous:
304
304
305 deprecated Deprecated Features
305 deprecated Deprecated Features
306 internals Technical implementation topics
306 internals Technical implementation topics
307 scripting Using Mercurial from scripts and automation
307 scripting Using Mercurial from scripts and automation
308
308
309 Test extension help:
309 Test extension help:
310 $ hg help extensions --config extensions.rebase= --config extensions.children=
310 $ hg help extensions --config extensions.rebase= --config extensions.children=
311 Using Additional Features
311 Using Additional Features
312 """""""""""""""""""""""""
312 """""""""""""""""""""""""
313
313
314 Mercurial has the ability to add new features through the use of
314 Mercurial has the ability to add new features through the use of
315 extensions. Extensions may add new commands, add options to existing
315 extensions. Extensions may add new commands, add options to existing
316 commands, change the default behavior of commands, or implement hooks.
316 commands, change the default behavior of commands, or implement hooks.
317
317
318 To enable the "foo" extension, either shipped with Mercurial or in the
318 To enable the "foo" extension, either shipped with Mercurial or in the
319 Python search path, create an entry for it in your configuration file,
319 Python search path, create an entry for it in your configuration file,
320 like this:
320 like this:
321
321
322 [extensions]
322 [extensions]
323 foo =
323 foo =
324
324
325 You may also specify the full path to an extension:
325 You may also specify the full path to an extension:
326
326
327 [extensions]
327 [extensions]
328 myfeature = ~/.hgext/myfeature.py
328 myfeature = ~/.hgext/myfeature.py
329
329
330 See 'hg help config' for more information on configuration files.
330 See 'hg help config' for more information on configuration files.
331
331
332 Extensions are not loaded by default for a variety of reasons: they can
332 Extensions are not loaded by default for a variety of reasons: they can
333 increase startup overhead; they may be meant for advanced usage only; they
333 increase startup overhead; they may be meant for advanced usage only; they
334 may provide potentially dangerous abilities (such as letting you destroy
334 may provide potentially dangerous abilities (such as letting you destroy
335 or modify history); they might not be ready for prime time; or they may
335 or modify history); they might not be ready for prime time; or they may
336 alter some usual behaviors of stock Mercurial. It is thus up to the user
336 alter some usual behaviors of stock Mercurial. It is thus up to the user
337 to activate extensions as needed.
337 to activate extensions as needed.
338
338
339 To explicitly disable an extension enabled in a configuration file of
339 To explicitly disable an extension enabled in a configuration file of
340 broader scope, prepend its path with !:
340 broader scope, prepend its path with !:
341
341
342 [extensions]
342 [extensions]
343 # disabling extension bar residing in /path/to/extension/bar.py
343 # disabling extension bar residing in /path/to/extension/bar.py
344 bar = !/path/to/extension/bar.py
344 bar = !/path/to/extension/bar.py
345 # ditto, but no path was supplied for extension baz
345 # ditto, but no path was supplied for extension baz
346 baz = !
346 baz = !
347
347
348 enabled extensions:
348 enabled extensions:
349
349
350 children command to display child changesets (DEPRECATED)
350 children command to display child changesets (DEPRECATED)
351 rebase command to move sets of revisions to a different ancestor
351 rebase command to move sets of revisions to a different ancestor
352
352
353 disabled extensions:
353 disabled extensions:
354
354
355 acl hooks for controlling repository access
355 acl hooks for controlling repository access
356 blackbox log repository events to a blackbox for debugging
356 blackbox log repository events to a blackbox for debugging
357 bugzilla hooks for integrating with the Bugzilla bug tracker
357 bugzilla hooks for integrating with the Bugzilla bug tracker
358 censor erase file content at a given revision
358 censor erase file content at a given revision
359 churn command to display statistics about repository history
359 churn command to display statistics about repository history
360 clonebundles advertise pre-generated bundles to seed clones
360 clonebundles advertise pre-generated bundles to seed clones
361 closehead close arbitrary heads without checking them out first
361 closehead close arbitrary heads without checking them out first
362 convert import revisions from foreign VCS repositories into
362 convert import revisions from foreign VCS repositories into
363 Mercurial
363 Mercurial
364 eol automatically manage newlines in repository files
364 eol automatically manage newlines in repository files
365 extdiff command to allow external programs to compare revisions
365 extdiff command to allow external programs to compare revisions
366 factotum http authentication with factotum
366 factotum http authentication with factotum
367 fastexport export repositories as git fast-import stream
367 fastexport export repositories as git fast-import stream
368 githelp try mapping git commands to Mercurial commands
368 githelp try mapping git commands to Mercurial commands
369 gpg commands to sign and verify changesets
369 gpg commands to sign and verify changesets
370 hgk browse the repository in a graphical way
370 hgk browse the repository in a graphical way
371 highlight syntax highlighting for hgweb (requires Pygments)
371 highlight syntax highlighting for hgweb (requires Pygments)
372 histedit interactive history editing
372 histedit interactive history editing
373 keyword expand keywords in tracked files
373 keyword expand keywords in tracked files
374 largefiles track large binary files
374 largefiles track large binary files
375 mq manage a stack of patches
375 mq manage a stack of patches
376 notify hooks for sending email push notifications
376 notify hooks for sending email push notifications
377 patchbomb command to send changesets as (a series of) patch emails
377 patchbomb command to send changesets as (a series of) patch emails
378 purge command to delete untracked files from the working
378 purge command to delete untracked files from the working
379 directory
379 directory
380 relink recreates hardlinks between repository clones
380 relink recreates hardlinks between repository clones
381 schemes extend schemes with shortcuts to repository swarms
381 schemes extend schemes with shortcuts to repository swarms
382 share share a common history between several working directories
382 share share a common history between several working directories
383 transplant command to transplant changesets from another branch
383 transplant command to transplant changesets from another branch
384 win32mbcs allow the use of MBCS paths with problematic encodings
384 win32mbcs allow the use of MBCS paths with problematic encodings
385 zeroconf discover and advertise repositories on the local network
385 zeroconf discover and advertise repositories on the local network
386
386
387 #endif
387 #endif
388
388
389 Verify that deprecated extensions are included if --verbose:
389 Verify that deprecated extensions are included if --verbose:
390
390
391 $ hg -v help extensions | grep children
391 $ hg -v help extensions | grep children
392 children command to display child changesets (DEPRECATED)
392 children command to display child changesets (DEPRECATED)
393
393
394 Verify that extension keywords appear in help templates
394 Verify that extension keywords appear in help templates
395
395
396 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
396 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
397
397
398 Test short command list with verbose option
398 Test short command list with verbose option
399
399
400 $ hg -v help shortlist
400 $ hg -v help shortlist
401 Mercurial Distributed SCM
401 Mercurial Distributed SCM
402
402
403 basic commands:
403 basic commands:
404
404
405 abort abort an unfinished operation (EXPERIMENTAL)
405 abort abort an unfinished operation (EXPERIMENTAL)
406 add add the specified files on the next commit
406 add add the specified files on the next commit
407 annotate, blame
407 annotate, blame
408 show changeset information by line for each file
408 show changeset information by line for each file
409 clone make a copy of an existing repository
409 clone make a copy of an existing repository
410 commit, ci commit the specified files or all outstanding changes
410 commit, ci commit the specified files or all outstanding changes
411 continue resumes an interrupted operation (EXPERIMENTAL)
411 continue resumes an interrupted operation (EXPERIMENTAL)
412 diff diff repository (or selected files)
412 diff diff repository (or selected files)
413 export dump the header and diffs for one or more changesets
413 export dump the header and diffs for one or more changesets
414 forget forget the specified files on the next commit
414 forget forget the specified files on the next commit
415 init create a new repository in the given directory
415 init create a new repository in the given directory
416 log, history show revision history of entire repository or files
416 log, history show revision history of entire repository or files
417 merge merge another revision into working directory
417 merge merge another revision into working directory
418 pull pull changes from the specified source
418 pull pull changes from the specified source
419 push push changes to the specified destination
419 push push changes to the specified destination
420 remove, rm remove the specified files on the next commit
420 remove, rm remove the specified files on the next commit
421 serve start stand-alone webserver
421 serve start stand-alone webserver
422 status, st show changed files in the working directory
422 status, st show changed files in the working directory
423 summary, sum summarize working directory state
423 summary, sum summarize working directory state
424 update, up, checkout, co
424 update, up, checkout, co
425 update working directory (or switch revisions)
425 update working directory (or switch revisions)
426
426
427 global options ([+] can be repeated):
427 global options ([+] can be repeated):
428
428
429 -R --repository REPO repository root directory or name of overlay bundle
429 -R --repository REPO repository root directory or name of overlay bundle
430 file
430 file
431 --cwd DIR change working directory
431 --cwd DIR change working directory
432 -y --noninteractive do not prompt, automatically pick the first choice for
432 -y --noninteractive do not prompt, automatically pick the first choice for
433 all prompts
433 all prompts
434 -q --quiet suppress output
434 -q --quiet suppress output
435 -v --verbose enable additional output
435 -v --verbose enable additional output
436 --color TYPE when to colorize (boolean, always, auto, never, or
436 --color TYPE when to colorize (boolean, always, auto, never, or
437 debug)
437 debug)
438 --config CONFIG [+] set/override config option (use 'section.name=value')
438 --config CONFIG [+] set/override config option (use 'section.name=value')
439 --debug enable debugging output
439 --debug enable debugging output
440 --debugger start debugger
440 --debugger start debugger
441 --encoding ENCODE set the charset encoding (default: ascii)
441 --encoding ENCODE set the charset encoding (default: ascii)
442 --encodingmode MODE set the charset encoding mode (default: strict)
442 --encodingmode MODE set the charset encoding mode (default: strict)
443 --traceback always print a traceback on exception
443 --traceback always print a traceback on exception
444 --time time how long the command takes
444 --time time how long the command takes
445 --profile print command execution profile
445 --profile print command execution profile
446 --version output version information and exit
446 --version output version information and exit
447 -h --help display help and exit
447 -h --help display help and exit
448 --hidden consider hidden changesets
448 --hidden consider hidden changesets
449 --pager TYPE when to paginate (boolean, always, auto, or never)
449 --pager TYPE when to paginate (boolean, always, auto, or never)
450 (default: auto)
450 (default: auto)
451
451
452 (use 'hg help' for the full list of commands)
452 (use 'hg help' for the full list of commands)
453
453
454 $ hg add -h
454 $ hg add -h
455 hg add [OPTION]... [FILE]...
455 hg add [OPTION]... [FILE]...
456
456
457 add the specified files on the next commit
457 add the specified files on the next commit
458
458
459 Schedule files to be version controlled and added to the repository.
459 Schedule files to be version controlled and added to the repository.
460
460
461 The files will be added to the repository at the next commit. To undo an
461 The files will be added to the repository at the next commit. To undo an
462 add before that, see 'hg forget'.
462 add before that, see 'hg forget'.
463
463
464 If no names are given, add all files to the repository (except files
464 If no names are given, add all files to the repository (except files
465 matching ".hgignore").
465 matching ".hgignore").
466
466
467 Returns 0 if all files are successfully added.
467 Returns 0 if all files are successfully added.
468
468
469 options ([+] can be repeated):
469 options ([+] can be repeated):
470
470
471 -I --include PATTERN [+] include names matching the given patterns
471 -I --include PATTERN [+] include names matching the given patterns
472 -X --exclude PATTERN [+] exclude names matching the given patterns
472 -X --exclude PATTERN [+] exclude names matching the given patterns
473 -S --subrepos recurse into subrepositories
473 -S --subrepos recurse into subrepositories
474 -n --dry-run do not perform actions, just print output
474 -n --dry-run do not perform actions, just print output
475
475
476 (some details hidden, use --verbose to show complete help)
476 (some details hidden, use --verbose to show complete help)
477
477
478 Verbose help for add
478 Verbose help for add
479
479
480 $ hg add -hv
480 $ hg add -hv
481 hg add [OPTION]... [FILE]...
481 hg add [OPTION]... [FILE]...
482
482
483 add the specified files on the next commit
483 add the specified files on the next commit
484
484
485 Schedule files to be version controlled and added to the repository.
485 Schedule files to be version controlled and added to the repository.
486
486
487 The files will be added to the repository at the next commit. To undo an
487 The files will be added to the repository at the next commit. To undo an
488 add before that, see 'hg forget'.
488 add before that, see 'hg forget'.
489
489
490 If no names are given, add all files to the repository (except files
490 If no names are given, add all files to the repository (except files
491 matching ".hgignore").
491 matching ".hgignore").
492
492
493 Examples:
493 Examples:
494
494
495 - New (unknown) files are added automatically by 'hg add':
495 - New (unknown) files are added automatically by 'hg add':
496
496
497 $ ls
497 $ ls
498 foo.c
498 foo.c
499 $ hg status
499 $ hg status
500 ? foo.c
500 ? foo.c
501 $ hg add
501 $ hg add
502 adding foo.c
502 adding foo.c
503 $ hg status
503 $ hg status
504 A foo.c
504 A foo.c
505
505
506 - Specific files to be added can be specified:
506 - Specific files to be added can be specified:
507
507
508 $ ls
508 $ ls
509 bar.c foo.c
509 bar.c foo.c
510 $ hg status
510 $ hg status
511 ? bar.c
511 ? bar.c
512 ? foo.c
512 ? foo.c
513 $ hg add bar.c
513 $ hg add bar.c
514 $ hg status
514 $ hg status
515 A bar.c
515 A bar.c
516 ? foo.c
516 ? foo.c
517
517
518 Returns 0 if all files are successfully added.
518 Returns 0 if all files are successfully added.
519
519
520 options ([+] can be repeated):
520 options ([+] can be repeated):
521
521
522 -I --include PATTERN [+] include names matching the given patterns
522 -I --include PATTERN [+] include names matching the given patterns
523 -X --exclude PATTERN [+] exclude names matching the given patterns
523 -X --exclude PATTERN [+] exclude names matching the given patterns
524 -S --subrepos recurse into subrepositories
524 -S --subrepos recurse into subrepositories
525 -n --dry-run do not perform actions, just print output
525 -n --dry-run do not perform actions, just print output
526
526
527 global options ([+] can be repeated):
527 global options ([+] can be repeated):
528
528
529 -R --repository REPO repository root directory or name of overlay bundle
529 -R --repository REPO repository root directory or name of overlay bundle
530 file
530 file
531 --cwd DIR change working directory
531 --cwd DIR change working directory
532 -y --noninteractive do not prompt, automatically pick the first choice for
532 -y --noninteractive do not prompt, automatically pick the first choice for
533 all prompts
533 all prompts
534 -q --quiet suppress output
534 -q --quiet suppress output
535 -v --verbose enable additional output
535 -v --verbose enable additional output
536 --color TYPE when to colorize (boolean, always, auto, never, or
536 --color TYPE when to colorize (boolean, always, auto, never, or
537 debug)
537 debug)
538 --config CONFIG [+] set/override config option (use 'section.name=value')
538 --config CONFIG [+] set/override config option (use 'section.name=value')
539 --debug enable debugging output
539 --debug enable debugging output
540 --debugger start debugger
540 --debugger start debugger
541 --encoding ENCODE set the charset encoding (default: ascii)
541 --encoding ENCODE set the charset encoding (default: ascii)
542 --encodingmode MODE set the charset encoding mode (default: strict)
542 --encodingmode MODE set the charset encoding mode (default: strict)
543 --traceback always print a traceback on exception
543 --traceback always print a traceback on exception
544 --time time how long the command takes
544 --time time how long the command takes
545 --profile print command execution profile
545 --profile print command execution profile
546 --version output version information and exit
546 --version output version information and exit
547 -h --help display help and exit
547 -h --help display help and exit
548 --hidden consider hidden changesets
548 --hidden consider hidden changesets
549 --pager TYPE when to paginate (boolean, always, auto, or never)
549 --pager TYPE when to paginate (boolean, always, auto, or never)
550 (default: auto)
550 (default: auto)
551
551
552 Test the textwidth config option
552 Test the textwidth config option
553
553
554 $ hg root -h --config ui.textwidth=50
554 $ hg root -h --config ui.textwidth=50
555 hg root
555 hg root
556
556
557 print the root (top) of the current working
557 print the root (top) of the current working
558 directory
558 directory
559
559
560 Print the root directory of the current
560 Print the root directory of the current
561 repository.
561 repository.
562
562
563 Returns 0 on success.
563 Returns 0 on success.
564
564
565 options:
565 options:
566
566
567 -T --template TEMPLATE display with template
567 -T --template TEMPLATE display with template
568
568
569 (some details hidden, use --verbose to show
569 (some details hidden, use --verbose to show
570 complete help)
570 complete help)
571
571
572 Test help option with version option
572 Test help option with version option
573
573
574 $ hg add -h --version
574 $ hg add -h --version
575 Mercurial Distributed SCM (version *) (glob)
575 Mercurial Distributed SCM (version *) (glob)
576 (see https://mercurial-scm.org for more information)
576 (see https://mercurial-scm.org for more information)
577
577
578 Copyright (C) 2005-* Matt Mackall and others (glob)
578 Copyright (C) 2005-* Matt Mackall and others (glob)
579 This is free software; see the source for copying conditions. There is NO
579 This is free software; see the source for copying conditions. There is NO
580 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
580 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
581
581
582 $ hg add --skjdfks
582 $ hg add --skjdfks
583 hg add: option --skjdfks not recognized
583 hg add: option --skjdfks not recognized
584 hg add [OPTION]... [FILE]...
584 hg add [OPTION]... [FILE]...
585
585
586 add the specified files on the next commit
586 add the specified files on the next commit
587
587
588 options ([+] can be repeated):
588 options ([+] can be repeated):
589
589
590 -I --include PATTERN [+] include names matching the given patterns
590 -I --include PATTERN [+] include names matching the given patterns
591 -X --exclude PATTERN [+] exclude names matching the given patterns
591 -X --exclude PATTERN [+] exclude names matching the given patterns
592 -S --subrepos recurse into subrepositories
592 -S --subrepos recurse into subrepositories
593 -n --dry-run do not perform actions, just print output
593 -n --dry-run do not perform actions, just print output
594
594
595 (use 'hg add -h' to show more help)
595 (use 'hg add -h' to show more help)
596 [255]
596 [255]
597
597
598 Test ambiguous command help
598 Test ambiguous command help
599
599
600 $ hg help ad
600 $ hg help ad
601 list of commands:
601 list of commands:
602
602
603 add add the specified files on the next commit
603 add add the specified files on the next commit
604 addremove add all new files, delete all missing files
604 addremove add all new files, delete all missing files
605
605
606 (use 'hg help -v ad' to show built-in aliases and global options)
606 (use 'hg help -v ad' to show built-in aliases and global options)
607
607
608 Test command without options
608 Test command without options
609
609
610 $ hg help verify
610 $ hg help verify
611 hg verify
611 hg verify
612
612
613 verify the integrity of the repository
613 verify the integrity of the repository
614
614
615 Verify the integrity of the current repository.
615 Verify the integrity of the current repository.
616
616
617 This will perform an extensive check of the repository's integrity,
617 This will perform an extensive check of the repository's integrity,
618 validating the hashes and checksums of each entry in the changelog,
618 validating the hashes and checksums of each entry in the changelog,
619 manifest, and tracked files, as well as the integrity of their crosslinks
619 manifest, and tracked files, as well as the integrity of their crosslinks
620 and indices.
620 and indices.
621
621
622 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
622 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
623 information about recovery from corruption of the repository.
623 information about recovery from corruption of the repository.
624
624
625 Returns 0 on success, 1 if errors are encountered.
625 Returns 0 on success, 1 if errors are encountered.
626
626
627 options:
627 options:
628
628
629 (some details hidden, use --verbose to show complete help)
629 (some details hidden, use --verbose to show complete help)
630
630
631 $ hg help diff
631 $ hg help diff
632 hg diff [OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...
632 hg diff [OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...
633
633
634 diff repository (or selected files)
634 diff repository (or selected files)
635
635
636 Show differences between revisions for the specified files.
636 Show differences between revisions for the specified files.
637
637
638 Differences between files are shown using the unified diff format.
638 Differences between files are shown using the unified diff format.
639
639
640 Note:
640 Note:
641 'hg diff' may generate unexpected results for merges, as it will
641 'hg diff' may generate unexpected results for merges, as it will
642 default to comparing against the working directory's first parent
642 default to comparing against the working directory's first parent
643 changeset if no revisions are specified.
643 changeset if no revisions are specified.
644
644
645 By default, the working directory files are compared to its first parent.
645 By default, the working directory files are compared to its first parent.
646 To see the differences from another revision, use --from. To see the
646 To see the differences from another revision, use --from. To see the
647 difference to another revision, use --to. For example, 'hg diff --from .^'
647 difference to another revision, use --to. For example, 'hg diff --from .^'
648 will show the differences from the working copy's grandparent to the
648 will show the differences from the working copy's grandparent to the
649 working copy, 'hg diff --to .' will show the diff from the working copy to
649 working copy, 'hg diff --to .' will show the diff from the working copy to
650 its parent (i.e. the reverse of the default), and 'hg diff --from 1.0 --to
650 its parent (i.e. the reverse of the default), and 'hg diff --from 1.0 --to
651 1.2' will show the diff between those two revisions.
651 1.2' will show the diff between those two revisions.
652
652
653 Alternatively you can specify -c/--change with a revision to see the
653 Alternatively you can specify -c/--change with a revision to see the
654 changes in that changeset relative to its first parent (i.e. 'hg diff -c
654 changes in that changeset relative to its first parent (i.e. 'hg diff -c
655 42' is equivalent to 'hg diff --from 42^ --to 42')
655 42' is equivalent to 'hg diff --from 42^ --to 42')
656
656
657 Without the -a/--text option, diff will avoid generating diffs of files it
657 Without the -a/--text option, diff will avoid generating diffs of files it
658 detects as binary. With -a, diff will generate a diff anyway, probably
658 detects as binary. With -a, diff will generate a diff anyway, probably
659 with undesirable results.
659 with undesirable results.
660
660
661 Use the -g/--git option to generate diffs in the git extended diff format.
661 Use the -g/--git option to generate diffs in the git extended diff format.
662 For more information, read 'hg help diffs'.
662 For more information, read 'hg help diffs'.
663
663
664 Returns 0 on success.
664 Returns 0 on success.
665
665
666 options ([+] can be repeated):
666 options ([+] can be repeated):
667
667
668 -r --rev REV [+] revision
669 --from REV1 revision to diff from
668 --from REV1 revision to diff from
670 --to REV2 revision to diff to
669 --to REV2 revision to diff to
671 -c --change REV change made by revision
670 -c --change REV change made by revision
672 -a --text treat all files as text
671 -a --text treat all files as text
673 -g --git use git extended diff format
672 -g --git use git extended diff format
674 --binary generate binary diffs in git mode (default)
673 --binary generate binary diffs in git mode (default)
675 --nodates omit dates from diff headers
674 --nodates omit dates from diff headers
676 --noprefix omit a/ and b/ prefixes from filenames
675 --noprefix omit a/ and b/ prefixes from filenames
677 -p --show-function show which function each change is in
676 -p --show-function show which function each change is in
678 --reverse produce a diff that undoes the changes
677 --reverse produce a diff that undoes the changes
679 -w --ignore-all-space ignore white space when comparing lines
678 -w --ignore-all-space ignore white space when comparing lines
680 -b --ignore-space-change ignore changes in the amount of white space
679 -b --ignore-space-change ignore changes in the amount of white space
681 -B --ignore-blank-lines ignore changes whose lines are all blank
680 -B --ignore-blank-lines ignore changes whose lines are all blank
682 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
681 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
683 -U --unified NUM number of lines of context to show
682 -U --unified NUM number of lines of context to show
684 --stat output diffstat-style summary of changes
683 --stat output diffstat-style summary of changes
685 --root DIR produce diffs relative to subdirectory
684 --root DIR produce diffs relative to subdirectory
686 -I --include PATTERN [+] include names matching the given patterns
685 -I --include PATTERN [+] include names matching the given patterns
687 -X --exclude PATTERN [+] exclude names matching the given patterns
686 -X --exclude PATTERN [+] exclude names matching the given patterns
688 -S --subrepos recurse into subrepositories
687 -S --subrepos recurse into subrepositories
689
688
690 (some details hidden, use --verbose to show complete help)
689 (some details hidden, use --verbose to show complete help)
691
690
692 $ hg help status
691 $ hg help status
693 hg status [OPTION]... [FILE]...
692 hg status [OPTION]... [FILE]...
694
693
695 aliases: st
694 aliases: st
696
695
697 show changed files in the working directory
696 show changed files in the working directory
698
697
699 Show status of files in the repository. If names are given, only files
698 Show status of files in the repository. If names are given, only files
700 that match are shown. Files that are clean or ignored or the source of a
699 that match are shown. Files that are clean or ignored or the source of a
701 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
700 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
702 -C/--copies or -A/--all are given. Unless options described with "show
701 -C/--copies or -A/--all are given. Unless options described with "show
703 only ..." are given, the options -mardu are used.
702 only ..." are given, the options -mardu are used.
704
703
705 Option -q/--quiet hides untracked (unknown and ignored) files unless
704 Option -q/--quiet hides untracked (unknown and ignored) files unless
706 explicitly requested with -u/--unknown or -i/--ignored.
705 explicitly requested with -u/--unknown or -i/--ignored.
707
706
708 Note:
707 Note:
709 'hg status' may appear to disagree with diff if permissions have
708 'hg status' may appear to disagree with diff if permissions have
710 changed or a merge has occurred. The standard diff format does not
709 changed or a merge has occurred. The standard diff format does not
711 report permission changes and diff only reports changes relative to one
710 report permission changes and diff only reports changes relative to one
712 merge parent.
711 merge parent.
713
712
714 If one revision is given, it is used as the base revision. If two
713 If one revision is given, it is used as the base revision. If two
715 revisions are given, the differences between them are shown. The --change
714 revisions are given, the differences between them are shown. The --change
716 option can also be used as a shortcut to list the changed files of a
715 option can also be used as a shortcut to list the changed files of a
717 revision from its first parent.
716 revision from its first parent.
718
717
719 The codes used to show the status of files are:
718 The codes used to show the status of files are:
720
719
721 M = modified
720 M = modified
722 A = added
721 A = added
723 R = removed
722 R = removed
724 C = clean
723 C = clean
725 ! = missing (deleted by non-hg command, but still tracked)
724 ! = missing (deleted by non-hg command, but still tracked)
726 ? = not tracked
725 ? = not tracked
727 I = ignored
726 I = ignored
728 = origin of the previous file (with --copies)
727 = origin of the previous file (with --copies)
729
728
730 Returns 0 on success.
729 Returns 0 on success.
731
730
732 options ([+] can be repeated):
731 options ([+] can be repeated):
733
732
734 -A --all show status of all files
733 -A --all show status of all files
735 -m --modified show only modified files
734 -m --modified show only modified files
736 -a --added show only added files
735 -a --added show only added files
737 -r --removed show only removed files
736 -r --removed show only removed files
738 -d --deleted show only missing files
737 -d --deleted show only missing files
739 -c --clean show only files without changes
738 -c --clean show only files without changes
740 -u --unknown show only unknown (not tracked) files
739 -u --unknown show only unknown (not tracked) files
741 -i --ignored show only ignored files
740 -i --ignored show only ignored files
742 -n --no-status hide status prefix
741 -n --no-status hide status prefix
743 -C --copies show source of copied files
742 -C --copies show source of copied files
744 -0 --print0 end filenames with NUL, for use with xargs
743 -0 --print0 end filenames with NUL, for use with xargs
745 --rev REV [+] show difference from revision
744 --rev REV [+] show difference from revision
746 --change REV list the changed files of a revision
745 --change REV list the changed files of a revision
747 -I --include PATTERN [+] include names matching the given patterns
746 -I --include PATTERN [+] include names matching the given patterns
748 -X --exclude PATTERN [+] exclude names matching the given patterns
747 -X --exclude PATTERN [+] exclude names matching the given patterns
749 -S --subrepos recurse into subrepositories
748 -S --subrepos recurse into subrepositories
750 -T --template TEMPLATE display with template
749 -T --template TEMPLATE display with template
751
750
752 (some details hidden, use --verbose to show complete help)
751 (some details hidden, use --verbose to show complete help)
753
752
754 $ hg -q help status
753 $ hg -q help status
755 hg status [OPTION]... [FILE]...
754 hg status [OPTION]... [FILE]...
756
755
757 show changed files in the working directory
756 show changed files in the working directory
758
757
759 $ hg help foo
758 $ hg help foo
760 abort: no such help topic: foo
759 abort: no such help topic: foo
761 (try 'hg help --keyword foo')
760 (try 'hg help --keyword foo')
762 [255]
761 [255]
763
762
764 $ hg skjdfks
763 $ hg skjdfks
765 hg: unknown command 'skjdfks'
764 hg: unknown command 'skjdfks'
766 (use 'hg help' for a list of commands)
765 (use 'hg help' for a list of commands)
767 [255]
766 [255]
768
767
769 Typoed command gives suggestion
768 Typoed command gives suggestion
770 $ hg puls
769 $ hg puls
771 hg: unknown command 'puls'
770 hg: unknown command 'puls'
772 (did you mean one of pull, push?)
771 (did you mean one of pull, push?)
773 [255]
772 [255]
774
773
775 Not enabled extension gets suggested
774 Not enabled extension gets suggested
776
775
777 $ hg rebase
776 $ hg rebase
778 hg: unknown command 'rebase'
777 hg: unknown command 'rebase'
779 'rebase' is provided by the following extension:
778 'rebase' is provided by the following extension:
780
779
781 rebase command to move sets of revisions to a different ancestor
780 rebase command to move sets of revisions to a different ancestor
782
781
783 (use 'hg help extensions' for information on enabling extensions)
782 (use 'hg help extensions' for information on enabling extensions)
784 [255]
783 [255]
785
784
786 Disabled extension gets suggested
785 Disabled extension gets suggested
787 $ hg --config extensions.rebase=! rebase
786 $ hg --config extensions.rebase=! rebase
788 hg: unknown command 'rebase'
787 hg: unknown command 'rebase'
789 'rebase' is provided by the following extension:
788 'rebase' is provided by the following extension:
790
789
791 rebase command to move sets of revisions to a different ancestor
790 rebase command to move sets of revisions to a different ancestor
792
791
793 (use 'hg help extensions' for information on enabling extensions)
792 (use 'hg help extensions' for information on enabling extensions)
794 [255]
793 [255]
795
794
796 Checking that help adapts based on the config:
795 Checking that help adapts based on the config:
797
796
798 $ hg help diff --config ui.tweakdefaults=true | egrep -e '^ *(-g|config)'
797 $ hg help diff --config ui.tweakdefaults=true | egrep -e '^ *(-g|config)'
799 -g --[no-]git use git extended diff format (default: on from
798 -g --[no-]git use git extended diff format (default: on from
800 config)
799 config)
801
800
802 Make sure that we don't run afoul of the help system thinking that
801 Make sure that we don't run afoul of the help system thinking that
803 this is a section and erroring out weirdly.
802 this is a section and erroring out weirdly.
804
803
805 $ hg .log
804 $ hg .log
806 hg: unknown command '.log'
805 hg: unknown command '.log'
807 (did you mean log?)
806 (did you mean log?)
808 [255]
807 [255]
809
808
810 $ hg log.
809 $ hg log.
811 hg: unknown command 'log.'
810 hg: unknown command 'log.'
812 (did you mean log?)
811 (did you mean log?)
813 [255]
812 [255]
814 $ hg pu.lh
813 $ hg pu.lh
815 hg: unknown command 'pu.lh'
814 hg: unknown command 'pu.lh'
816 (did you mean one of pull, push?)
815 (did you mean one of pull, push?)
817 [255]
816 [255]
818
817
819 $ cat > helpext.py <<EOF
818 $ cat > helpext.py <<EOF
820 > import os
819 > import os
821 > from mercurial import commands, fancyopts, registrar
820 > from mercurial import commands, fancyopts, registrar
822 >
821 >
823 > def func(arg):
822 > def func(arg):
824 > return '%sfoo' % arg
823 > return '%sfoo' % arg
825 > class customopt(fancyopts.customopt):
824 > class customopt(fancyopts.customopt):
826 > def newstate(self, oldstate, newparam, abort):
825 > def newstate(self, oldstate, newparam, abort):
827 > return '%sbar' % oldstate
826 > return '%sbar' % oldstate
828 > cmdtable = {}
827 > cmdtable = {}
829 > command = registrar.command(cmdtable)
828 > command = registrar.command(cmdtable)
830 >
829 >
831 > @command(b'nohelp',
830 > @command(b'nohelp',
832 > [(b'', b'longdesc', 3, b'x'*67),
831 > [(b'', b'longdesc', 3, b'x'*67),
833 > (b'n', b'', None, b'normal desc'),
832 > (b'n', b'', None, b'normal desc'),
834 > (b'', b'newline', b'', b'line1\nline2'),
833 > (b'', b'newline', b'', b'line1\nline2'),
835 > (b'', b'default-off', False, b'enable X'),
834 > (b'', b'default-off', False, b'enable X'),
836 > (b'', b'default-on', True, b'enable Y'),
835 > (b'', b'default-on', True, b'enable Y'),
837 > (b'', b'callableopt', func, b'adds foo'),
836 > (b'', b'callableopt', func, b'adds foo'),
838 > (b'', b'customopt', customopt(''), b'adds bar'),
837 > (b'', b'customopt', customopt(''), b'adds bar'),
839 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
838 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
840 > b'hg nohelp',
839 > b'hg nohelp',
841 > norepo=True)
840 > norepo=True)
842 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
841 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
843 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
842 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
844 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
843 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
845 > def nohelp(ui, *args, **kwargs):
844 > def nohelp(ui, *args, **kwargs):
846 > pass
845 > pass
847 >
846 >
848 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
847 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
849 > def hashelp(ui, *args, **kwargs):
848 > def hashelp(ui, *args, **kwargs):
850 > """Extension command's help"""
849 > """Extension command's help"""
851 >
850 >
852 > def uisetup(ui):
851 > def uisetup(ui):
853 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
852 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
854 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
853 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
855 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
854 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
856 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
855 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
857 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
856 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
858 >
857 >
859 > EOF
858 > EOF
860 $ echo '[extensions]' >> $HGRCPATH
859 $ echo '[extensions]' >> $HGRCPATH
861 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
860 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
862
861
863 Test for aliases
862 Test for aliases
864
863
865 $ hg help | grep hgalias
864 $ hg help | grep hgalias
866 hgalias My doc
865 hgalias My doc
867
866
868 $ hg help hgalias
867 $ hg help hgalias
869 hg hgalias [--remote]
868 hg hgalias [--remote]
870
869
871 alias for: hg summary
870 alias for: hg summary
872
871
873 My doc
872 My doc
874
873
875 defined by: helpext
874 defined by: helpext
876
875
877 options:
876 options:
878
877
879 --remote check for push and pull
878 --remote check for push and pull
880
879
881 (some details hidden, use --verbose to show complete help)
880 (some details hidden, use --verbose to show complete help)
882 $ hg help hgaliasnodoc
881 $ hg help hgaliasnodoc
883 hg hgaliasnodoc [--remote]
882 hg hgaliasnodoc [--remote]
884
883
885 alias for: hg summary
884 alias for: hg summary
886
885
887 summarize working directory state
886 summarize working directory state
888
887
889 This generates a brief summary of the working directory state, including
888 This generates a brief summary of the working directory state, including
890 parents, branch, commit status, phase and available updates.
889 parents, branch, commit status, phase and available updates.
891
890
892 With the --remote option, this will check the default paths for incoming
891 With the --remote option, this will check the default paths for incoming
893 and outgoing changes. This can be time-consuming.
892 and outgoing changes. This can be time-consuming.
894
893
895 Returns 0 on success.
894 Returns 0 on success.
896
895
897 defined by: helpext
896 defined by: helpext
898
897
899 options:
898 options:
900
899
901 --remote check for push and pull
900 --remote check for push and pull
902
901
903 (some details hidden, use --verbose to show complete help)
902 (some details hidden, use --verbose to show complete help)
904
903
905 $ hg help shellalias
904 $ hg help shellalias
906 hg shellalias
905 hg shellalias
907
906
908 shell alias for: echo hi
907 shell alias for: echo hi
909
908
910 (no help text available)
909 (no help text available)
911
910
912 defined by: helpext
911 defined by: helpext
913
912
914 (some details hidden, use --verbose to show complete help)
913 (some details hidden, use --verbose to show complete help)
915
914
916 Test command with no help text
915 Test command with no help text
917
916
918 $ hg help nohelp
917 $ hg help nohelp
919 hg nohelp
918 hg nohelp
920
919
921 (no help text available)
920 (no help text available)
922
921
923 options:
922 options:
924
923
925 --longdesc VALUE
924 --longdesc VALUE
926 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
925 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
927 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
926 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
928 -n -- normal desc
927 -n -- normal desc
929 --newline VALUE line1 line2
928 --newline VALUE line1 line2
930 --default-off enable X
929 --default-off enable X
931 --[no-]default-on enable Y (default: on)
930 --[no-]default-on enable Y (default: on)
932 --callableopt VALUE adds foo
931 --callableopt VALUE adds foo
933 --customopt VALUE adds bar
932 --customopt VALUE adds bar
934 --customopt-withdefault VALUE adds bar (default: foo)
933 --customopt-withdefault VALUE adds bar (default: foo)
935
934
936 (some details hidden, use --verbose to show complete help)
935 (some details hidden, use --verbose to show complete help)
937
936
938 Test that default list of commands includes extension commands that have help,
937 Test that default list of commands includes extension commands that have help,
939 but not those that don't, except in verbose mode, when a keyword is passed, or
938 but not those that don't, except in verbose mode, when a keyword is passed, or
940 when help about the extension is requested.
939 when help about the extension is requested.
941
940
942 #if no-extraextensions
941 #if no-extraextensions
943
942
944 $ hg help | grep hashelp
943 $ hg help | grep hashelp
945 hashelp Extension command's help
944 hashelp Extension command's help
946 $ hg help | grep nohelp
945 $ hg help | grep nohelp
947 [1]
946 [1]
948 $ hg help -v | grep nohelp
947 $ hg help -v | grep nohelp
949 nohelp (no help text available)
948 nohelp (no help text available)
950
949
951 $ hg help -k nohelp
950 $ hg help -k nohelp
952 Commands:
951 Commands:
953
952
954 nohelp hg nohelp
953 nohelp hg nohelp
955
954
956 Extension Commands:
955 Extension Commands:
957
956
958 nohelp (no help text available)
957 nohelp (no help text available)
959
958
960 $ hg help helpext
959 $ hg help helpext
961 helpext extension - no help text available
960 helpext extension - no help text available
962
961
963 list of commands:
962 list of commands:
964
963
965 hashelp Extension command's help
964 hashelp Extension command's help
966 nohelp (no help text available)
965 nohelp (no help text available)
967
966
968 (use 'hg help -v helpext' to show built-in aliases and global options)
967 (use 'hg help -v helpext' to show built-in aliases and global options)
969
968
970 #endif
969 #endif
971
970
972 Test list of internal help commands
971 Test list of internal help commands
973
972
974 $ hg help debug
973 $ hg help debug
975 debug commands (internal and unsupported):
974 debug commands (internal and unsupported):
976
975
977 debugancestor
976 debugancestor
978 find the ancestor revision of two revisions in a given index
977 find the ancestor revision of two revisions in a given index
979 debugantivirusrunning
978 debugantivirusrunning
980 attempt to trigger an antivirus scanner to see if one is active
979 attempt to trigger an antivirus scanner to see if one is active
981 debugapplystreamclonebundle
980 debugapplystreamclonebundle
982 apply a stream clone bundle file
981 apply a stream clone bundle file
983 debugbackupbundle
982 debugbackupbundle
984 lists the changesets available in backup bundles
983 lists the changesets available in backup bundles
985 debugbuilddag
984 debugbuilddag
986 builds a repo with a given DAG from scratch in the current
985 builds a repo with a given DAG from scratch in the current
987 empty repo
986 empty repo
988 debugbundle lists the contents of a bundle
987 debugbundle lists the contents of a bundle
989 debugcapabilities
988 debugcapabilities
990 lists the capabilities of a remote peer
989 lists the capabilities of a remote peer
991 debugchangedfiles
990 debugchangedfiles
992 list the stored files changes for a revision
991 list the stored files changes for a revision
993 debugcheckstate
992 debugcheckstate
994 validate the correctness of the current dirstate
993 validate the correctness of the current dirstate
995 debugcolor show available color, effects or style
994 debugcolor show available color, effects or style
996 debugcommands
995 debugcommands
997 list all available commands and options
996 list all available commands and options
998 debugcomplete
997 debugcomplete
999 returns the completion list associated with the given command
998 returns the completion list associated with the given command
1000 debugcreatestreamclonebundle
999 debugcreatestreamclonebundle
1001 create a stream clone bundle file
1000 create a stream clone bundle file
1002 debugdag format the changelog or an index DAG as a concise textual
1001 debugdag format the changelog or an index DAG as a concise textual
1003 description
1002 description
1004 debugdata dump the contents of a data file revision
1003 debugdata dump the contents of a data file revision
1005 debugdate parse and display a date
1004 debugdate parse and display a date
1006 debugdeltachain
1005 debugdeltachain
1007 dump information about delta chains in a revlog
1006 dump information about delta chains in a revlog
1008 debugdirstate
1007 debugdirstate
1009 show the contents of the current dirstate
1008 show the contents of the current dirstate
1010 debugdiscovery
1009 debugdiscovery
1011 runs the changeset discovery protocol in isolation
1010 runs the changeset discovery protocol in isolation
1012 debugdownload
1011 debugdownload
1013 download a resource using Mercurial logic and config
1012 download a resource using Mercurial logic and config
1014 debugextensions
1013 debugextensions
1015 show information about active extensions
1014 show information about active extensions
1016 debugfileset parse and apply a fileset specification
1015 debugfileset parse and apply a fileset specification
1017 debugformat display format information about the current repository
1016 debugformat display format information about the current repository
1018 debugfsinfo show information detected about current filesystem
1017 debugfsinfo show information detected about current filesystem
1019 debuggetbundle
1018 debuggetbundle
1020 retrieves a bundle from a repo
1019 retrieves a bundle from a repo
1021 debugignore display the combined ignore pattern and information about
1020 debugignore display the combined ignore pattern and information about
1022 ignored files
1021 ignored files
1023 debugindex dump index data for a storage primitive
1022 debugindex dump index data for a storage primitive
1024 debugindexdot
1023 debugindexdot
1025 dump an index DAG as a graphviz dot file
1024 dump an index DAG as a graphviz dot file
1026 debugindexstats
1025 debugindexstats
1027 show stats related to the changelog index
1026 show stats related to the changelog index
1028 debuginstall test Mercurial installation
1027 debuginstall test Mercurial installation
1029 debugknown test whether node ids are known to a repo
1028 debugknown test whether node ids are known to a repo
1030 debuglocks show or modify state of locks
1029 debuglocks show or modify state of locks
1031 debugmanifestfulltextcache
1030 debugmanifestfulltextcache
1032 show, clear or amend the contents of the manifest fulltext
1031 show, clear or amend the contents of the manifest fulltext
1033 cache
1032 cache
1034 debugmergestate
1033 debugmergestate
1035 print merge state
1034 print merge state
1036 debugnamecomplete
1035 debugnamecomplete
1037 complete "names" - tags, open branch names, bookmark names
1036 complete "names" - tags, open branch names, bookmark names
1038 debugnodemap write and inspect on disk nodemap
1037 debugnodemap write and inspect on disk nodemap
1039 debugobsolete
1038 debugobsolete
1040 create arbitrary obsolete marker
1039 create arbitrary obsolete marker
1041 debugoptADV (no help text available)
1040 debugoptADV (no help text available)
1042 debugoptDEP (no help text available)
1041 debugoptDEP (no help text available)
1043 debugoptEXP (no help text available)
1042 debugoptEXP (no help text available)
1044 debugp1copies
1043 debugp1copies
1045 dump copy information compared to p1
1044 dump copy information compared to p1
1046 debugp2copies
1045 debugp2copies
1047 dump copy information compared to p2
1046 dump copy information compared to p2
1048 debugpathcomplete
1047 debugpathcomplete
1049 complete part or all of a tracked path
1048 complete part or all of a tracked path
1050 debugpathcopies
1049 debugpathcopies
1051 show copies between two revisions
1050 show copies between two revisions
1052 debugpeer establish a connection to a peer repository
1051 debugpeer establish a connection to a peer repository
1053 debugpickmergetool
1052 debugpickmergetool
1054 examine which merge tool is chosen for specified file
1053 examine which merge tool is chosen for specified file
1055 debugpushkey access the pushkey key/value protocol
1054 debugpushkey access the pushkey key/value protocol
1056 debugpvec (no help text available)
1055 debugpvec (no help text available)
1057 debugrebuilddirstate
1056 debugrebuilddirstate
1058 rebuild the dirstate as it would look like for the given
1057 rebuild the dirstate as it would look like for the given
1059 revision
1058 revision
1060 debugrebuildfncache
1059 debugrebuildfncache
1061 rebuild the fncache file
1060 rebuild the fncache file
1062 debugrename dump rename information
1061 debugrename dump rename information
1063 debugrequires
1062 debugrequires
1064 print the current repo requirements
1063 print the current repo requirements
1065 debugrevlog show data and statistics about a revlog
1064 debugrevlog show data and statistics about a revlog
1066 debugrevlogindex
1065 debugrevlogindex
1067 dump the contents of a revlog index
1066 dump the contents of a revlog index
1068 debugrevspec parse and apply a revision specification
1067 debugrevspec parse and apply a revision specification
1069 debugserve run a server with advanced settings
1068 debugserve run a server with advanced settings
1070 debugsetparents
1069 debugsetparents
1071 manually set the parents of the current working directory
1070 manually set the parents of the current working directory
1072 debugsidedata
1071 debugsidedata
1073 dump the side data for a cl/manifest/file revision
1072 dump the side data for a cl/manifest/file revision
1074 debugssl test a secure connection to a server
1073 debugssl test a secure connection to a server
1075 debugstrip strip changesets and all their descendants from the repository
1074 debugstrip strip changesets and all their descendants from the repository
1076 debugsub (no help text available)
1075 debugsub (no help text available)
1077 debugsuccessorssets
1076 debugsuccessorssets
1078 show set of successors for revision
1077 show set of successors for revision
1079 debugtagscache
1078 debugtagscache
1080 display the contents of .hg/cache/hgtagsfnodes1
1079 display the contents of .hg/cache/hgtagsfnodes1
1081 debugtemplate
1080 debugtemplate
1082 parse and apply a template
1081 parse and apply a template
1083 debuguigetpass
1082 debuguigetpass
1084 show prompt to type password
1083 show prompt to type password
1085 debuguiprompt
1084 debuguiprompt
1086 show plain prompt
1085 show plain prompt
1087 debugupdatecaches
1086 debugupdatecaches
1088 warm all known caches in the repository
1087 warm all known caches in the repository
1089 debugupgraderepo
1088 debugupgraderepo
1090 upgrade a repository to use different features
1089 upgrade a repository to use different features
1091 debugwalk show how files match on given patterns
1090 debugwalk show how files match on given patterns
1092 debugwhyunstable
1091 debugwhyunstable
1093 explain instabilities of a changeset
1092 explain instabilities of a changeset
1094 debugwireargs
1093 debugwireargs
1095 (no help text available)
1094 (no help text available)
1096 debugwireproto
1095 debugwireproto
1097 send wire protocol commands to a server
1096 send wire protocol commands to a server
1098
1097
1099 (use 'hg help -v debug' to show built-in aliases and global options)
1098 (use 'hg help -v debug' to show built-in aliases and global options)
1100
1099
1101 internals topic renders index of available sub-topics
1100 internals topic renders index of available sub-topics
1102
1101
1103 $ hg help internals
1102 $ hg help internals
1104 Technical implementation topics
1103 Technical implementation topics
1105 """""""""""""""""""""""""""""""
1104 """""""""""""""""""""""""""""""
1106
1105
1107 To access a subtopic, use "hg help internals.{subtopic-name}"
1106 To access a subtopic, use "hg help internals.{subtopic-name}"
1108
1107
1109 bid-merge Bid Merge Algorithm
1108 bid-merge Bid Merge Algorithm
1110 bundle2 Bundle2
1109 bundle2 Bundle2
1111 bundles Bundles
1110 bundles Bundles
1112 cbor CBOR
1111 cbor CBOR
1113 censor Censor
1112 censor Censor
1114 changegroups Changegroups
1113 changegroups Changegroups
1115 config Config Registrar
1114 config Config Registrar
1116 extensions Extension API
1115 extensions Extension API
1117 mergestate Mergestate
1116 mergestate Mergestate
1118 requirements Repository Requirements
1117 requirements Repository Requirements
1119 revlogs Revision Logs
1118 revlogs Revision Logs
1120 wireprotocol Wire Protocol
1119 wireprotocol Wire Protocol
1121 wireprotocolrpc
1120 wireprotocolrpc
1122 Wire Protocol RPC
1121 Wire Protocol RPC
1123 wireprotocolv2
1122 wireprotocolv2
1124 Wire Protocol Version 2
1123 Wire Protocol Version 2
1125
1124
1126 sub-topics can be accessed
1125 sub-topics can be accessed
1127
1126
1128 $ hg help internals.changegroups
1127 $ hg help internals.changegroups
1129 Changegroups
1128 Changegroups
1130 """"""""""""
1129 """"""""""""
1131
1130
1132 Changegroups are representations of repository revlog data, specifically
1131 Changegroups are representations of repository revlog data, specifically
1133 the changelog data, root/flat manifest data, treemanifest data, and
1132 the changelog data, root/flat manifest data, treemanifest data, and
1134 filelogs.
1133 filelogs.
1135
1134
1136 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1135 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1137 level, versions "1" and "2" are almost exactly the same, with the only
1136 level, versions "1" and "2" are almost exactly the same, with the only
1138 difference being an additional item in the *delta header*. Version "3"
1137 difference being an additional item in the *delta header*. Version "3"
1139 adds support for storage flags in the *delta header* and optionally
1138 adds support for storage flags in the *delta header* and optionally
1140 exchanging treemanifests (enabled by setting an option on the
1139 exchanging treemanifests (enabled by setting an option on the
1141 "changegroup" part in the bundle2).
1140 "changegroup" part in the bundle2).
1142
1141
1143 Changegroups when not exchanging treemanifests consist of 3 logical
1142 Changegroups when not exchanging treemanifests consist of 3 logical
1144 segments:
1143 segments:
1145
1144
1146 +---------------------------------+
1145 +---------------------------------+
1147 | | | |
1146 | | | |
1148 | changeset | manifest | filelogs |
1147 | changeset | manifest | filelogs |
1149 | | | |
1148 | | | |
1150 | | | |
1149 | | | |
1151 +---------------------------------+
1150 +---------------------------------+
1152
1151
1153 When exchanging treemanifests, there are 4 logical segments:
1152 When exchanging treemanifests, there are 4 logical segments:
1154
1153
1155 +-------------------------------------------------+
1154 +-------------------------------------------------+
1156 | | | | |
1155 | | | | |
1157 | changeset | root | treemanifests | filelogs |
1156 | changeset | root | treemanifests | filelogs |
1158 | | manifest | | |
1157 | | manifest | | |
1159 | | | | |
1158 | | | | |
1160 +-------------------------------------------------+
1159 +-------------------------------------------------+
1161
1160
1162 The principle building block of each segment is a *chunk*. A *chunk* is a
1161 The principle building block of each segment is a *chunk*. A *chunk* is a
1163 framed piece of data:
1162 framed piece of data:
1164
1163
1165 +---------------------------------------+
1164 +---------------------------------------+
1166 | | |
1165 | | |
1167 | length | data |
1166 | length | data |
1168 | (4 bytes) | (<length - 4> bytes) |
1167 | (4 bytes) | (<length - 4> bytes) |
1169 | | |
1168 | | |
1170 +---------------------------------------+
1169 +---------------------------------------+
1171
1170
1172 All integers are big-endian signed integers. Each chunk starts with a
1171 All integers are big-endian signed integers. Each chunk starts with a
1173 32-bit integer indicating the length of the entire chunk (including the
1172 32-bit integer indicating the length of the entire chunk (including the
1174 length field itself).
1173 length field itself).
1175
1174
1176 There is a special case chunk that has a value of 0 for the length
1175 There is a special case chunk that has a value of 0 for the length
1177 ("0x00000000"). We call this an *empty chunk*.
1176 ("0x00000000"). We call this an *empty chunk*.
1178
1177
1179 Delta Groups
1178 Delta Groups
1180 ============
1179 ============
1181
1180
1182 A *delta group* expresses the content of a revlog as a series of deltas,
1181 A *delta group* expresses the content of a revlog as a series of deltas,
1183 or patches against previous revisions.
1182 or patches against previous revisions.
1184
1183
1185 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1184 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1186 to signal the end of the delta group:
1185 to signal the end of the delta group:
1187
1186
1188 +------------------------------------------------------------------------+
1187 +------------------------------------------------------------------------+
1189 | | | | | |
1188 | | | | | |
1190 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1189 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1191 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1190 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1192 | | | | | |
1191 | | | | | |
1193 +------------------------------------------------------------------------+
1192 +------------------------------------------------------------------------+
1194
1193
1195 Each *chunk*'s data consists of the following:
1194 Each *chunk*'s data consists of the following:
1196
1195
1197 +---------------------------------------+
1196 +---------------------------------------+
1198 | | |
1197 | | |
1199 | delta header | delta data |
1198 | delta header | delta data |
1200 | (various by version) | (various) |
1199 | (various by version) | (various) |
1201 | | |
1200 | | |
1202 +---------------------------------------+
1201 +---------------------------------------+
1203
1202
1204 The *delta data* is a series of *delta*s that describe a diff from an
1203 The *delta data* is a series of *delta*s that describe a diff from an
1205 existing entry (either that the recipient already has, or previously
1204 existing entry (either that the recipient already has, or previously
1206 specified in the bundle/changegroup).
1205 specified in the bundle/changegroup).
1207
1206
1208 The *delta header* is different between versions "1", "2", and "3" of the
1207 The *delta header* is different between versions "1", "2", and "3" of the
1209 changegroup format.
1208 changegroup format.
1210
1209
1211 Version 1 (headerlen=80):
1210 Version 1 (headerlen=80):
1212
1211
1213 +------------------------------------------------------+
1212 +------------------------------------------------------+
1214 | | | | |
1213 | | | | |
1215 | node | p1 node | p2 node | link node |
1214 | node | p1 node | p2 node | link node |
1216 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1215 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1217 | | | | |
1216 | | | | |
1218 +------------------------------------------------------+
1217 +------------------------------------------------------+
1219
1218
1220 Version 2 (headerlen=100):
1219 Version 2 (headerlen=100):
1221
1220
1222 +------------------------------------------------------------------+
1221 +------------------------------------------------------------------+
1223 | | | | | |
1222 | | | | | |
1224 | node | p1 node | p2 node | base node | link node |
1223 | node | p1 node | p2 node | base node | link node |
1225 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1224 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1226 | | | | | |
1225 | | | | | |
1227 +------------------------------------------------------------------+
1226 +------------------------------------------------------------------+
1228
1227
1229 Version 3 (headerlen=102):
1228 Version 3 (headerlen=102):
1230
1229
1231 +------------------------------------------------------------------------------+
1230 +------------------------------------------------------------------------------+
1232 | | | | | | |
1231 | | | | | | |
1233 | node | p1 node | p2 node | base node | link node | flags |
1232 | node | p1 node | p2 node | base node | link node | flags |
1234 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1233 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1235 | | | | | | |
1234 | | | | | | |
1236 +------------------------------------------------------------------------------+
1235 +------------------------------------------------------------------------------+
1237
1236
1238 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1237 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1239 contain a series of *delta*s, densely packed (no separators). These deltas
1238 contain a series of *delta*s, densely packed (no separators). These deltas
1240 describe a diff from an existing entry (either that the recipient already
1239 describe a diff from an existing entry (either that the recipient already
1241 has, or previously specified in the bundle/changegroup). The format is
1240 has, or previously specified in the bundle/changegroup). The format is
1242 described more fully in "hg help internals.bdiff", but briefly:
1241 described more fully in "hg help internals.bdiff", but briefly:
1243
1242
1244 +---------------------------------------------------------------+
1243 +---------------------------------------------------------------+
1245 | | | | |
1244 | | | | |
1246 | start offset | end offset | new length | content |
1245 | start offset | end offset | new length | content |
1247 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1246 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1248 | | | | |
1247 | | | | |
1249 +---------------------------------------------------------------+
1248 +---------------------------------------------------------------+
1250
1249
1251 Please note that the length field in the delta data does *not* include
1250 Please note that the length field in the delta data does *not* include
1252 itself.
1251 itself.
1253
1252
1254 In version 1, the delta is always applied against the previous node from
1253 In version 1, the delta is always applied against the previous node from
1255 the changegroup or the first parent if this is the first entry in the
1254 the changegroup or the first parent if this is the first entry in the
1256 changegroup.
1255 changegroup.
1257
1256
1258 In version 2 and up, the delta base node is encoded in the entry in the
1257 In version 2 and up, the delta base node is encoded in the entry in the
1259 changegroup. This allows the delta to be expressed against any parent,
1258 changegroup. This allows the delta to be expressed against any parent,
1260 which can result in smaller deltas and more efficient encoding of data.
1259 which can result in smaller deltas and more efficient encoding of data.
1261
1260
1262 The *flags* field holds bitwise flags affecting the processing of revision
1261 The *flags* field holds bitwise flags affecting the processing of revision
1263 data. The following flags are defined:
1262 data. The following flags are defined:
1264
1263
1265 32768
1264 32768
1266 Censored revision. The revision's fulltext has been replaced by censor
1265 Censored revision. The revision's fulltext has been replaced by censor
1267 metadata. May only occur on file revisions.
1266 metadata. May only occur on file revisions.
1268
1267
1269 16384
1268 16384
1270 Ellipsis revision. Revision hash does not match data (likely due to
1269 Ellipsis revision. Revision hash does not match data (likely due to
1271 rewritten parents).
1270 rewritten parents).
1272
1271
1273 8192
1272 8192
1274 Externally stored. The revision fulltext contains "key:value" "\n"
1273 Externally stored. The revision fulltext contains "key:value" "\n"
1275 delimited metadata defining an object stored elsewhere. Used by the LFS
1274 delimited metadata defining an object stored elsewhere. Used by the LFS
1276 extension.
1275 extension.
1277
1276
1278 For historical reasons, the integer values are identical to revlog version
1277 For historical reasons, the integer values are identical to revlog version
1279 1 per-revision storage flags and correspond to bits being set in this
1278 1 per-revision storage flags and correspond to bits being set in this
1280 2-byte field. Bits were allocated starting from the most-significant bit,
1279 2-byte field. Bits were allocated starting from the most-significant bit,
1281 hence the reverse ordering and allocation of these flags.
1280 hence the reverse ordering and allocation of these flags.
1282
1281
1283 Changeset Segment
1282 Changeset Segment
1284 =================
1283 =================
1285
1284
1286 The *changeset segment* consists of a single *delta group* holding
1285 The *changeset segment* consists of a single *delta group* holding
1287 changelog data. The *empty chunk* at the end of the *delta group* denotes
1286 changelog data. The *empty chunk* at the end of the *delta group* denotes
1288 the boundary to the *manifest segment*.
1287 the boundary to the *manifest segment*.
1289
1288
1290 Manifest Segment
1289 Manifest Segment
1291 ================
1290 ================
1292
1291
1293 The *manifest segment* consists of a single *delta group* holding manifest
1292 The *manifest segment* consists of a single *delta group* holding manifest
1294 data. If treemanifests are in use, it contains only the manifest for the
1293 data. If treemanifests are in use, it contains only the manifest for the
1295 root directory of the repository. Otherwise, it contains the entire
1294 root directory of the repository. Otherwise, it contains the entire
1296 manifest data. The *empty chunk* at the end of the *delta group* denotes
1295 manifest data. The *empty chunk* at the end of the *delta group* denotes
1297 the boundary to the next segment (either the *treemanifests segment* or
1296 the boundary to the next segment (either the *treemanifests segment* or
1298 the *filelogs segment*, depending on version and the request options).
1297 the *filelogs segment*, depending on version and the request options).
1299
1298
1300 Treemanifests Segment
1299 Treemanifests Segment
1301 ---------------------
1300 ---------------------
1302
1301
1303 The *treemanifests segment* only exists in changegroup version "3", and
1302 The *treemanifests segment* only exists in changegroup version "3", and
1304 only if the 'treemanifest' param is part of the bundle2 changegroup part
1303 only if the 'treemanifest' param is part of the bundle2 changegroup part
1305 (it is not possible to use changegroup version 3 outside of bundle2).
1304 (it is not possible to use changegroup version 3 outside of bundle2).
1306 Aside from the filenames in the *treemanifests segment* containing a
1305 Aside from the filenames in the *treemanifests segment* containing a
1307 trailing "/" character, it behaves identically to the *filelogs segment*
1306 trailing "/" character, it behaves identically to the *filelogs segment*
1308 (see below). The final sub-segment is followed by an *empty chunk*
1307 (see below). The final sub-segment is followed by an *empty chunk*
1309 (logically, a sub-segment with filename size 0). This denotes the boundary
1308 (logically, a sub-segment with filename size 0). This denotes the boundary
1310 to the *filelogs segment*.
1309 to the *filelogs segment*.
1311
1310
1312 Filelogs Segment
1311 Filelogs Segment
1313 ================
1312 ================
1314
1313
1315 The *filelogs segment* consists of multiple sub-segments, each
1314 The *filelogs segment* consists of multiple sub-segments, each
1316 corresponding to an individual file whose data is being described:
1315 corresponding to an individual file whose data is being described:
1317
1316
1318 +--------------------------------------------------+
1317 +--------------------------------------------------+
1319 | | | | | |
1318 | | | | | |
1320 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1319 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1321 | | | | | (4 bytes) |
1320 | | | | | (4 bytes) |
1322 | | | | | |
1321 | | | | | |
1323 +--------------------------------------------------+
1322 +--------------------------------------------------+
1324
1323
1325 The final filelog sub-segment is followed by an *empty chunk* (logically,
1324 The final filelog sub-segment is followed by an *empty chunk* (logically,
1326 a sub-segment with filename size 0). This denotes the end of the segment
1325 a sub-segment with filename size 0). This denotes the end of the segment
1327 and of the overall changegroup.
1326 and of the overall changegroup.
1328
1327
1329 Each filelog sub-segment consists of the following:
1328 Each filelog sub-segment consists of the following:
1330
1329
1331 +------------------------------------------------------+
1330 +------------------------------------------------------+
1332 | | | |
1331 | | | |
1333 | filename length | filename | delta group |
1332 | filename length | filename | delta group |
1334 | (4 bytes) | (<length - 4> bytes) | (various) |
1333 | (4 bytes) | (<length - 4> bytes) | (various) |
1335 | | | |
1334 | | | |
1336 +------------------------------------------------------+
1335 +------------------------------------------------------+
1337
1336
1338 That is, a *chunk* consisting of the filename (not terminated or padded)
1337 That is, a *chunk* consisting of the filename (not terminated or padded)
1339 followed by N chunks constituting the *delta group* for this file. The
1338 followed by N chunks constituting the *delta group* for this file. The
1340 *empty chunk* at the end of each *delta group* denotes the boundary to the
1339 *empty chunk* at the end of each *delta group* denotes the boundary to the
1341 next filelog sub-segment.
1340 next filelog sub-segment.
1342
1341
1343 non-existent subtopics print an error
1342 non-existent subtopics print an error
1344
1343
1345 $ hg help internals.foo
1344 $ hg help internals.foo
1346 abort: no such help topic: internals.foo
1345 abort: no such help topic: internals.foo
1347 (try 'hg help --keyword foo')
1346 (try 'hg help --keyword foo')
1348 [255]
1347 [255]
1349
1348
1350 test advanced, deprecated and experimental options are hidden in command help
1349 test advanced, deprecated and experimental options are hidden in command help
1351 $ hg help debugoptADV
1350 $ hg help debugoptADV
1352 hg debugoptADV
1351 hg debugoptADV
1353
1352
1354 (no help text available)
1353 (no help text available)
1355
1354
1356 options:
1355 options:
1357
1356
1358 (some details hidden, use --verbose to show complete help)
1357 (some details hidden, use --verbose to show complete help)
1359 $ hg help debugoptDEP
1358 $ hg help debugoptDEP
1360 hg debugoptDEP
1359 hg debugoptDEP
1361
1360
1362 (no help text available)
1361 (no help text available)
1363
1362
1364 options:
1363 options:
1365
1364
1366 (some details hidden, use --verbose to show complete help)
1365 (some details hidden, use --verbose to show complete help)
1367
1366
1368 $ hg help debugoptEXP
1367 $ hg help debugoptEXP
1369 hg debugoptEXP
1368 hg debugoptEXP
1370
1369
1371 (no help text available)
1370 (no help text available)
1372
1371
1373 options:
1372 options:
1374
1373
1375 (some details hidden, use --verbose to show complete help)
1374 (some details hidden, use --verbose to show complete help)
1376
1375
1377 test advanced, deprecated and experimental options are shown with -v
1376 test advanced, deprecated and experimental options are shown with -v
1378 $ hg help -v debugoptADV | grep aopt
1377 $ hg help -v debugoptADV | grep aopt
1379 --aopt option is (ADVANCED)
1378 --aopt option is (ADVANCED)
1380 $ hg help -v debugoptDEP | grep dopt
1379 $ hg help -v debugoptDEP | grep dopt
1381 --dopt option is (DEPRECATED)
1380 --dopt option is (DEPRECATED)
1382 $ hg help -v debugoptEXP | grep eopt
1381 $ hg help -v debugoptEXP | grep eopt
1383 --eopt option is (EXPERIMENTAL)
1382 --eopt option is (EXPERIMENTAL)
1384
1383
1385 #if gettext
1384 #if gettext
1386 test deprecated option is hidden with translation with untranslated description
1385 test deprecated option is hidden with translation with untranslated description
1387 (use many globy for not failing on changed transaction)
1386 (use many globy for not failing on changed transaction)
1388 $ LANGUAGE=sv hg help debugoptDEP
1387 $ LANGUAGE=sv hg help debugoptDEP
1389 hg debugoptDEP
1388 hg debugoptDEP
1390
1389
1391 (*) (glob)
1390 (*) (glob)
1392
1391
1393 options:
1392 options:
1394
1393
1395 (some details hidden, use --verbose to show complete help)
1394 (some details hidden, use --verbose to show complete help)
1396 #endif
1395 #endif
1397
1396
1398 Test commands that collide with topics (issue4240)
1397 Test commands that collide with topics (issue4240)
1399
1398
1400 $ hg config -hq
1399 $ hg config -hq
1401 hg config [-u] [NAME]...
1400 hg config [-u] [NAME]...
1402
1401
1403 show combined config settings from all hgrc files
1402 show combined config settings from all hgrc files
1404 $ hg showconfig -hq
1403 $ hg showconfig -hq
1405 hg config [-u] [NAME]...
1404 hg config [-u] [NAME]...
1406
1405
1407 show combined config settings from all hgrc files
1406 show combined config settings from all hgrc files
1408
1407
1409 Test a help topic
1408 Test a help topic
1410
1409
1411 $ hg help dates
1410 $ hg help dates
1412 Date Formats
1411 Date Formats
1413 """"""""""""
1412 """"""""""""
1414
1413
1415 Some commands allow the user to specify a date, e.g.:
1414 Some commands allow the user to specify a date, e.g.:
1416
1415
1417 - backout, commit, import, tag: Specify the commit date.
1416 - backout, commit, import, tag: Specify the commit date.
1418 - log, revert, update: Select revision(s) by date.
1417 - log, revert, update: Select revision(s) by date.
1419
1418
1420 Many date formats are valid. Here are some examples:
1419 Many date formats are valid. Here are some examples:
1421
1420
1422 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1421 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1423 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1422 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1424 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1423 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1425 - "Dec 6" (midnight)
1424 - "Dec 6" (midnight)
1426 - "13:18" (today assumed)
1425 - "13:18" (today assumed)
1427 - "3:39" (3:39AM assumed)
1426 - "3:39" (3:39AM assumed)
1428 - "3:39pm" (15:39)
1427 - "3:39pm" (15:39)
1429 - "2006-12-06 13:18:29" (ISO 8601 format)
1428 - "2006-12-06 13:18:29" (ISO 8601 format)
1430 - "2006-12-6 13:18"
1429 - "2006-12-6 13:18"
1431 - "2006-12-6"
1430 - "2006-12-6"
1432 - "12-6"
1431 - "12-6"
1433 - "12/6"
1432 - "12/6"
1434 - "12/6/6" (Dec 6 2006)
1433 - "12/6/6" (Dec 6 2006)
1435 - "today" (midnight)
1434 - "today" (midnight)
1436 - "yesterday" (midnight)
1435 - "yesterday" (midnight)
1437 - "now" - right now
1436 - "now" - right now
1438
1437
1439 Lastly, there is Mercurial's internal format:
1438 Lastly, there is Mercurial's internal format:
1440
1439
1441 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1440 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1442
1441
1443 This is the internal representation format for dates. The first number is
1442 This is the internal representation format for dates. The first number is
1444 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1443 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1445 is the offset of the local timezone, in seconds west of UTC (negative if
1444 is the offset of the local timezone, in seconds west of UTC (negative if
1446 the timezone is east of UTC).
1445 the timezone is east of UTC).
1447
1446
1448 The log command also accepts date ranges:
1447 The log command also accepts date ranges:
1449
1448
1450 - "<DATE" - at or before a given date/time
1449 - "<DATE" - at or before a given date/time
1451 - ">DATE" - on or after a given date/time
1450 - ">DATE" - on or after a given date/time
1452 - "DATE to DATE" - a date range, inclusive
1451 - "DATE to DATE" - a date range, inclusive
1453 - "-DAYS" - within a given number of days from today
1452 - "-DAYS" - within a given number of days from today
1454
1453
1455 Test repeated config section name
1454 Test repeated config section name
1456
1455
1457 $ hg help config.host
1456 $ hg help config.host
1458 "http_proxy.host"
1457 "http_proxy.host"
1459 Host name and (optional) port of the proxy server, for example
1458 Host name and (optional) port of the proxy server, for example
1460 "myproxy:8000".
1459 "myproxy:8000".
1461
1460
1462 "smtp.host"
1461 "smtp.host"
1463 Host name of mail server, e.g. "mail.example.com".
1462 Host name of mail server, e.g. "mail.example.com".
1464
1463
1465
1464
1466 Test section name with dot
1465 Test section name with dot
1467
1466
1468 $ hg help config.ui.username
1467 $ hg help config.ui.username
1469 "ui.username"
1468 "ui.username"
1470 The committer of a changeset created when running "commit". Typically
1469 The committer of a changeset created when running "commit". Typically
1471 a person's name and email address, e.g. "Fred Widget
1470 a person's name and email address, e.g. "Fred Widget
1472 <fred@example.com>". Environment variables in the username are
1471 <fred@example.com>". Environment variables in the username are
1473 expanded.
1472 expanded.
1474
1473
1475 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1474 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1476 empty, e.g. if the system admin set "username =" in the system hgrc,
1475 empty, e.g. if the system admin set "username =" in the system hgrc,
1477 it has to be specified manually or in a different hgrc file)
1476 it has to be specified manually or in a different hgrc file)
1478
1477
1479
1478
1480 $ hg help config.annotate.git
1479 $ hg help config.annotate.git
1481 abort: help section not found: config.annotate.git
1480 abort: help section not found: config.annotate.git
1482 [255]
1481 [255]
1483
1482
1484 $ hg help config.update.check
1483 $ hg help config.update.check
1485 "commands.update.check"
1484 "commands.update.check"
1486 Determines what level of checking 'hg update' will perform before
1485 Determines what level of checking 'hg update' will perform before
1487 moving to a destination revision. Valid values are "abort", "none",
1486 moving to a destination revision. Valid values are "abort", "none",
1488 "linear", and "noconflict". "abort" always fails if the working
1487 "linear", and "noconflict". "abort" always fails if the working
1489 directory has uncommitted changes. "none" performs no checking, and
1488 directory has uncommitted changes. "none" performs no checking, and
1490 may result in a merge with uncommitted changes. "linear" allows any
1489 may result in a merge with uncommitted changes. "linear" allows any
1491 update as long as it follows a straight line in the revision history,
1490 update as long as it follows a straight line in the revision history,
1492 and may trigger a merge with uncommitted changes. "noconflict" will
1491 and may trigger a merge with uncommitted changes. "noconflict" will
1493 allow any update which would not trigger a merge with uncommitted
1492 allow any update which would not trigger a merge with uncommitted
1494 changes, if any are present. (default: "linear")
1493 changes, if any are present. (default: "linear")
1495
1494
1496
1495
1497 $ hg help config.commands.update.check
1496 $ hg help config.commands.update.check
1498 "commands.update.check"
1497 "commands.update.check"
1499 Determines what level of checking 'hg update' will perform before
1498 Determines what level of checking 'hg update' will perform before
1500 moving to a destination revision. Valid values are "abort", "none",
1499 moving to a destination revision. Valid values are "abort", "none",
1501 "linear", and "noconflict". "abort" always fails if the working
1500 "linear", and "noconflict". "abort" always fails if the working
1502 directory has uncommitted changes. "none" performs no checking, and
1501 directory has uncommitted changes. "none" performs no checking, and
1503 may result in a merge with uncommitted changes. "linear" allows any
1502 may result in a merge with uncommitted changes. "linear" allows any
1504 update as long as it follows a straight line in the revision history,
1503 update as long as it follows a straight line in the revision history,
1505 and may trigger a merge with uncommitted changes. "noconflict" will
1504 and may trigger a merge with uncommitted changes. "noconflict" will
1506 allow any update which would not trigger a merge with uncommitted
1505 allow any update which would not trigger a merge with uncommitted
1507 changes, if any are present. (default: "linear")
1506 changes, if any are present. (default: "linear")
1508
1507
1509
1508
1510 $ hg help config.ommands.update.check
1509 $ hg help config.ommands.update.check
1511 abort: help section not found: config.ommands.update.check
1510 abort: help section not found: config.ommands.update.check
1512 [255]
1511 [255]
1513
1512
1514 Unrelated trailing paragraphs shouldn't be included
1513 Unrelated trailing paragraphs shouldn't be included
1515
1514
1516 $ hg help config.extramsg | grep '^$'
1515 $ hg help config.extramsg | grep '^$'
1517
1516
1518
1517
1519 Test capitalized section name
1518 Test capitalized section name
1520
1519
1521 $ hg help scripting.HGPLAIN > /dev/null
1520 $ hg help scripting.HGPLAIN > /dev/null
1522
1521
1523 Help subsection:
1522 Help subsection:
1524
1523
1525 $ hg help config.charsets |grep "Email example:" > /dev/null
1524 $ hg help config.charsets |grep "Email example:" > /dev/null
1526 [1]
1525 [1]
1527
1526
1528 Show nested definitions
1527 Show nested definitions
1529 ("profiling.type"[break]"ls"[break]"stat"[break])
1528 ("profiling.type"[break]"ls"[break]"stat"[break])
1530
1529
1531 $ hg help config.type | egrep '^$'|wc -l
1530 $ hg help config.type | egrep '^$'|wc -l
1532 \s*3 (re)
1531 \s*3 (re)
1533
1532
1534 $ hg help config.profiling.type.ls
1533 $ hg help config.profiling.type.ls
1535 "profiling.type.ls"
1534 "profiling.type.ls"
1536 Use Python's built-in instrumenting profiler. This profiler works on
1535 Use Python's built-in instrumenting profiler. This profiler works on
1537 all platforms, but each line number it reports is the first line of
1536 all platforms, but each line number it reports is the first line of
1538 a function. This restriction makes it difficult to identify the
1537 a function. This restriction makes it difficult to identify the
1539 expensive parts of a non-trivial function.
1538 expensive parts of a non-trivial function.
1540
1539
1541
1540
1542 Separate sections from subsections
1541 Separate sections from subsections
1543
1542
1544 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1543 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1545 "format"
1544 "format"
1546 --------
1545 --------
1547
1546
1548 "usegeneraldelta"
1547 "usegeneraldelta"
1549
1548
1550 "dotencode"
1549 "dotencode"
1551
1550
1552 "usefncache"
1551 "usefncache"
1553
1552
1554 "usestore"
1553 "usestore"
1555
1554
1556 "sparse-revlog"
1555 "sparse-revlog"
1557
1556
1558 "revlog-compression"
1557 "revlog-compression"
1559
1558
1560 "bookmarks-in-store"
1559 "bookmarks-in-store"
1561
1560
1562 "profiling"
1561 "profiling"
1563 -----------
1562 -----------
1564
1563
1565 "format"
1564 "format"
1566
1565
1567 "progress"
1566 "progress"
1568 ----------
1567 ----------
1569
1568
1570 "format"
1569 "format"
1571
1570
1572
1571
1573 Last item in help config.*:
1572 Last item in help config.*:
1574
1573
1575 $ hg help config.`hg help config|grep '^ "'| \
1574 $ hg help config.`hg help config|grep '^ "'| \
1576 > tail -1|sed 's![ "]*!!g'`| \
1575 > tail -1|sed 's![ "]*!!g'`| \
1577 > grep 'hg help -c config' > /dev/null
1576 > grep 'hg help -c config' > /dev/null
1578 [1]
1577 [1]
1579
1578
1580 note to use help -c for general hg help config:
1579 note to use help -c for general hg help config:
1581
1580
1582 $ hg help config |grep 'hg help -c config' > /dev/null
1581 $ hg help config |grep 'hg help -c config' > /dev/null
1583
1582
1584 Test templating help
1583 Test templating help
1585
1584
1586 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1585 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1587 desc String. The text of the changeset description.
1586 desc String. The text of the changeset description.
1588 diffstat String. Statistics of changes with the following format:
1587 diffstat String. Statistics of changes with the following format:
1589 firstline Any text. Returns the first line of text.
1588 firstline Any text. Returns the first line of text.
1590 nonempty Any text. Returns '(none)' if the string is empty.
1589 nonempty Any text. Returns '(none)' if the string is empty.
1591
1590
1592 Test deprecated items
1591 Test deprecated items
1593
1592
1594 $ hg help -v templating | grep currentbookmark
1593 $ hg help -v templating | grep currentbookmark
1595 currentbookmark
1594 currentbookmark
1596 $ hg help templating | (grep currentbookmark || true)
1595 $ hg help templating | (grep currentbookmark || true)
1597
1596
1598 Test help hooks
1597 Test help hooks
1599
1598
1600 $ cat > helphook1.py <<EOF
1599 $ cat > helphook1.py <<EOF
1601 > from mercurial import help
1600 > from mercurial import help
1602 >
1601 >
1603 > def rewrite(ui, topic, doc):
1602 > def rewrite(ui, topic, doc):
1604 > return doc + b'\nhelphook1\n'
1603 > return doc + b'\nhelphook1\n'
1605 >
1604 >
1606 > def extsetup(ui):
1605 > def extsetup(ui):
1607 > help.addtopichook(b'revisions', rewrite)
1606 > help.addtopichook(b'revisions', rewrite)
1608 > EOF
1607 > EOF
1609 $ cat > helphook2.py <<EOF
1608 $ cat > helphook2.py <<EOF
1610 > from mercurial import help
1609 > from mercurial import help
1611 >
1610 >
1612 > def rewrite(ui, topic, doc):
1611 > def rewrite(ui, topic, doc):
1613 > return doc + b'\nhelphook2\n'
1612 > return doc + b'\nhelphook2\n'
1614 >
1613 >
1615 > def extsetup(ui):
1614 > def extsetup(ui):
1616 > help.addtopichook(b'revisions', rewrite)
1615 > help.addtopichook(b'revisions', rewrite)
1617 > EOF
1616 > EOF
1618 $ echo '[extensions]' >> $HGRCPATH
1617 $ echo '[extensions]' >> $HGRCPATH
1619 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1618 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1620 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1619 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1621 $ hg help revsets | grep helphook
1620 $ hg help revsets | grep helphook
1622 helphook1
1621 helphook1
1623 helphook2
1622 helphook2
1624
1623
1625 help -c should only show debug --debug
1624 help -c should only show debug --debug
1626
1625
1627 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1626 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1628 [1]
1627 [1]
1629
1628
1630 help -c should only show deprecated for -v
1629 help -c should only show deprecated for -v
1631
1630
1632 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1631 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1633 [1]
1632 [1]
1634
1633
1635 Test -s / --system
1634 Test -s / --system
1636
1635
1637 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1636 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1638 > wc -l | sed -e 's/ //g'
1637 > wc -l | sed -e 's/ //g'
1639 0
1638 0
1640 $ hg help config.files --system unix | grep 'USER' | \
1639 $ hg help config.files --system unix | grep 'USER' | \
1641 > wc -l | sed -e 's/ //g'
1640 > wc -l | sed -e 's/ //g'
1642 0
1641 0
1643
1642
1644 Test -e / -c / -k combinations
1643 Test -e / -c / -k combinations
1645
1644
1646 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1645 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1647 Commands:
1646 Commands:
1648 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1647 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1649 Extensions:
1648 Extensions:
1650 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1649 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1651 Topics:
1650 Topics:
1652 Commands:
1651 Commands:
1653 Extensions:
1652 Extensions:
1654 Extension Commands:
1653 Extension Commands:
1655 $ hg help -c schemes
1654 $ hg help -c schemes
1656 abort: no such help topic: schemes
1655 abort: no such help topic: schemes
1657 (try 'hg help --keyword schemes')
1656 (try 'hg help --keyword schemes')
1658 [255]
1657 [255]
1659 $ hg help -e schemes |head -1
1658 $ hg help -e schemes |head -1
1660 schemes extension - extend schemes with shortcuts to repository swarms
1659 schemes extension - extend schemes with shortcuts to repository swarms
1661 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1660 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1662 Commands:
1661 Commands:
1663 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1662 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1664 Extensions:
1663 Extensions:
1665 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1664 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1666 Extensions:
1665 Extensions:
1667 Commands:
1666 Commands:
1668 $ hg help -c commit > /dev/null
1667 $ hg help -c commit > /dev/null
1669 $ hg help -e -c commit > /dev/null
1668 $ hg help -e -c commit > /dev/null
1670 $ hg help -e commit
1669 $ hg help -e commit
1671 abort: no such help topic: commit
1670 abort: no such help topic: commit
1672 (try 'hg help --keyword commit')
1671 (try 'hg help --keyword commit')
1673 [255]
1672 [255]
1674
1673
1675 Test keyword search help
1674 Test keyword search help
1676
1675
1677 $ cat > prefixedname.py <<EOF
1676 $ cat > prefixedname.py <<EOF
1678 > '''matched against word "clone"
1677 > '''matched against word "clone"
1679 > '''
1678 > '''
1680 > EOF
1679 > EOF
1681 $ echo '[extensions]' >> $HGRCPATH
1680 $ echo '[extensions]' >> $HGRCPATH
1682 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1681 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1683 $ hg help -k clone
1682 $ hg help -k clone
1684 Topics:
1683 Topics:
1685
1684
1686 config Configuration Files
1685 config Configuration Files
1687 extensions Using Additional Features
1686 extensions Using Additional Features
1688 glossary Glossary
1687 glossary Glossary
1689 phases Working with Phases
1688 phases Working with Phases
1690 subrepos Subrepositories
1689 subrepos Subrepositories
1691 urls URL Paths
1690 urls URL Paths
1692
1691
1693 Commands:
1692 Commands:
1694
1693
1695 bookmarks create a new bookmark or list existing bookmarks
1694 bookmarks create a new bookmark or list existing bookmarks
1696 clone make a copy of an existing repository
1695 clone make a copy of an existing repository
1697 paths show aliases for remote repositories
1696 paths show aliases for remote repositories
1698 pull pull changes from the specified source
1697 pull pull changes from the specified source
1699 update update working directory (or switch revisions)
1698 update update working directory (or switch revisions)
1700
1699
1701 Extensions:
1700 Extensions:
1702
1701
1703 clonebundles advertise pre-generated bundles to seed clones
1702 clonebundles advertise pre-generated bundles to seed clones
1704 narrow create clones which fetch history data for subset of files
1703 narrow create clones which fetch history data for subset of files
1705 (EXPERIMENTAL)
1704 (EXPERIMENTAL)
1706 prefixedname matched against word "clone"
1705 prefixedname matched against word "clone"
1707 relink recreates hardlinks between repository clones
1706 relink recreates hardlinks between repository clones
1708
1707
1709 Extension Commands:
1708 Extension Commands:
1710
1709
1711 qclone clone main and patch repository at same time
1710 qclone clone main and patch repository at same time
1712
1711
1713 Test unfound topic
1712 Test unfound topic
1714
1713
1715 $ hg help nonexistingtopicthatwillneverexisteverever
1714 $ hg help nonexistingtopicthatwillneverexisteverever
1716 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1715 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1717 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1716 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1718 [255]
1717 [255]
1719
1718
1720 Test unfound keyword
1719 Test unfound keyword
1721
1720
1722 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1721 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1723 abort: no matches
1722 abort: no matches
1724 (try 'hg help' for a list of topics)
1723 (try 'hg help' for a list of topics)
1725 [255]
1724 [255]
1726
1725
1727 Test omit indicating for help
1726 Test omit indicating for help
1728
1727
1729 $ cat > addverboseitems.py <<EOF
1728 $ cat > addverboseitems.py <<EOF
1730 > r'''extension to test omit indicating.
1729 > r'''extension to test omit indicating.
1731 >
1730 >
1732 > This paragraph is never omitted (for extension)
1731 > This paragraph is never omitted (for extension)
1733 >
1732 >
1734 > .. container:: verbose
1733 > .. container:: verbose
1735 >
1734 >
1736 > This paragraph is omitted,
1735 > This paragraph is omitted,
1737 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1736 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1738 >
1737 >
1739 > This paragraph is never omitted, too (for extension)
1738 > This paragraph is never omitted, too (for extension)
1740 > '''
1739 > '''
1741 > from __future__ import absolute_import
1740 > from __future__ import absolute_import
1742 > from mercurial import commands, help
1741 > from mercurial import commands, help
1743 > testtopic = br"""This paragraph is never omitted (for topic).
1742 > testtopic = br"""This paragraph is never omitted (for topic).
1744 >
1743 >
1745 > .. container:: verbose
1744 > .. container:: verbose
1746 >
1745 >
1747 > This paragraph is omitted,
1746 > This paragraph is omitted,
1748 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1747 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1749 >
1748 >
1750 > This paragraph is never omitted, too (for topic)
1749 > This paragraph is never omitted, too (for topic)
1751 > """
1750 > """
1752 > def extsetup(ui):
1751 > def extsetup(ui):
1753 > help.helptable.append(([b"topic-containing-verbose"],
1752 > help.helptable.append(([b"topic-containing-verbose"],
1754 > b"This is the topic to test omit indicating.",
1753 > b"This is the topic to test omit indicating.",
1755 > lambda ui: testtopic))
1754 > lambda ui: testtopic))
1756 > EOF
1755 > EOF
1757 $ echo '[extensions]' >> $HGRCPATH
1756 $ echo '[extensions]' >> $HGRCPATH
1758 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1757 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1759 $ hg help addverboseitems
1758 $ hg help addverboseitems
1760 addverboseitems extension - extension to test omit indicating.
1759 addverboseitems extension - extension to test omit indicating.
1761
1760
1762 This paragraph is never omitted (for extension)
1761 This paragraph is never omitted (for extension)
1763
1762
1764 This paragraph is never omitted, too (for extension)
1763 This paragraph is never omitted, too (for extension)
1765
1764
1766 (some details hidden, use --verbose to show complete help)
1765 (some details hidden, use --verbose to show complete help)
1767
1766
1768 no commands defined
1767 no commands defined
1769 $ hg help -v addverboseitems
1768 $ hg help -v addverboseitems
1770 addverboseitems extension - extension to test omit indicating.
1769 addverboseitems extension - extension to test omit indicating.
1771
1770
1772 This paragraph is never omitted (for extension)
1771 This paragraph is never omitted (for extension)
1773
1772
1774 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1773 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1775 extension)
1774 extension)
1776
1775
1777 This paragraph is never omitted, too (for extension)
1776 This paragraph is never omitted, too (for extension)
1778
1777
1779 no commands defined
1778 no commands defined
1780 $ hg help topic-containing-verbose
1779 $ hg help topic-containing-verbose
1781 This is the topic to test omit indicating.
1780 This is the topic to test omit indicating.
1782 """"""""""""""""""""""""""""""""""""""""""
1781 """"""""""""""""""""""""""""""""""""""""""
1783
1782
1784 This paragraph is never omitted (for topic).
1783 This paragraph is never omitted (for topic).
1785
1784
1786 This paragraph is never omitted, too (for topic)
1785 This paragraph is never omitted, too (for topic)
1787
1786
1788 (some details hidden, use --verbose to show complete help)
1787 (some details hidden, use --verbose to show complete help)
1789 $ hg help -v topic-containing-verbose
1788 $ hg help -v topic-containing-verbose
1790 This is the topic to test omit indicating.
1789 This is the topic to test omit indicating.
1791 """"""""""""""""""""""""""""""""""""""""""
1790 """"""""""""""""""""""""""""""""""""""""""
1792
1791
1793 This paragraph is never omitted (for topic).
1792 This paragraph is never omitted (for topic).
1794
1793
1795 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1794 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1796 topic)
1795 topic)
1797
1796
1798 This paragraph is never omitted, too (for topic)
1797 This paragraph is never omitted, too (for topic)
1799
1798
1800 Test section lookup
1799 Test section lookup
1801
1800
1802 $ hg help revset.merge
1801 $ hg help revset.merge
1803 "merge()"
1802 "merge()"
1804 Changeset is a merge changeset.
1803 Changeset is a merge changeset.
1805
1804
1806 $ hg help glossary.dag
1805 $ hg help glossary.dag
1807 DAG
1806 DAG
1808 The repository of changesets of a distributed version control system
1807 The repository of changesets of a distributed version control system
1809 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1808 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1810 of nodes and edges, where nodes correspond to changesets and edges
1809 of nodes and edges, where nodes correspond to changesets and edges
1811 imply a parent -> child relation. This graph can be visualized by
1810 imply a parent -> child relation. This graph can be visualized by
1812 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1811 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1813 limited by the requirement for children to have at most two parents.
1812 limited by the requirement for children to have at most two parents.
1814
1813
1815
1814
1816 $ hg help hgrc.paths
1815 $ hg help hgrc.paths
1817 "paths"
1816 "paths"
1818 -------
1817 -------
1819
1818
1820 Assigns symbolic names and behavior to repositories.
1819 Assigns symbolic names and behavior to repositories.
1821
1820
1822 Options are symbolic names defining the URL or directory that is the
1821 Options are symbolic names defining the URL or directory that is the
1823 location of the repository. Example:
1822 location of the repository. Example:
1824
1823
1825 [paths]
1824 [paths]
1826 my_server = https://example.com/my_repo
1825 my_server = https://example.com/my_repo
1827 local_path = /home/me/repo
1826 local_path = /home/me/repo
1828
1827
1829 These symbolic names can be used from the command line. To pull from
1828 These symbolic names can be used from the command line. To pull from
1830 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1829 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1831 local_path'.
1830 local_path'.
1832
1831
1833 Options containing colons (":") denote sub-options that can influence
1832 Options containing colons (":") denote sub-options that can influence
1834 behavior for that specific path. Example:
1833 behavior for that specific path. Example:
1835
1834
1836 [paths]
1835 [paths]
1837 my_server = https://example.com/my_path
1836 my_server = https://example.com/my_path
1838 my_server:pushurl = ssh://example.com/my_path
1837 my_server:pushurl = ssh://example.com/my_path
1839
1838
1840 The following sub-options can be defined:
1839 The following sub-options can be defined:
1841
1840
1842 "pushurl"
1841 "pushurl"
1843 The URL to use for push operations. If not defined, the location
1842 The URL to use for push operations. If not defined, the location
1844 defined by the path's main entry is used.
1843 defined by the path's main entry is used.
1845
1844
1846 "pushrev"
1845 "pushrev"
1847 A revset defining which revisions to push by default.
1846 A revset defining which revisions to push by default.
1848
1847
1849 When 'hg push' is executed without a "-r" argument, the revset defined
1848 When 'hg push' is executed without a "-r" argument, the revset defined
1850 by this sub-option is evaluated to determine what to push.
1849 by this sub-option is evaluated to determine what to push.
1851
1850
1852 For example, a value of "." will push the working directory's revision
1851 For example, a value of "." will push the working directory's revision
1853 by default.
1852 by default.
1854
1853
1855 Revsets specifying bookmarks will not result in the bookmark being
1854 Revsets specifying bookmarks will not result in the bookmark being
1856 pushed.
1855 pushed.
1857
1856
1858 The following special named paths exist:
1857 The following special named paths exist:
1859
1858
1860 "default"
1859 "default"
1861 The URL or directory to use when no source or remote is specified.
1860 The URL or directory to use when no source or remote is specified.
1862
1861
1863 'hg clone' will automatically define this path to the location the
1862 'hg clone' will automatically define this path to the location the
1864 repository was cloned from.
1863 repository was cloned from.
1865
1864
1866 "default-push"
1865 "default-push"
1867 (deprecated) The URL or directory for the default 'hg push' location.
1866 (deprecated) The URL or directory for the default 'hg push' location.
1868 "default:pushurl" should be used instead.
1867 "default:pushurl" should be used instead.
1869
1868
1870 $ hg help glossary.mcguffin
1869 $ hg help glossary.mcguffin
1871 abort: help section not found: glossary.mcguffin
1870 abort: help section not found: glossary.mcguffin
1872 [255]
1871 [255]
1873
1872
1874 $ hg help glossary.mc.guffin
1873 $ hg help glossary.mc.guffin
1875 abort: help section not found: glossary.mc.guffin
1874 abort: help section not found: glossary.mc.guffin
1876 [255]
1875 [255]
1877
1876
1878 $ hg help template.files
1877 $ hg help template.files
1879 files List of strings. All files modified, added, or removed by
1878 files List of strings. All files modified, added, or removed by
1880 this changeset.
1879 this changeset.
1881 files(pattern)
1880 files(pattern)
1882 All files of the current changeset matching the pattern. See
1881 All files of the current changeset matching the pattern. See
1883 'hg help patterns'.
1882 'hg help patterns'.
1884
1883
1885 Test section lookup by translated message
1884 Test section lookup by translated message
1886
1885
1887 str.lower() instead of encoding.lower(str) on translated message might
1886 str.lower() instead of encoding.lower(str) on translated message might
1888 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1887 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1889 as the second or later byte of multi-byte character.
1888 as the second or later byte of multi-byte character.
1890
1889
1891 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1890 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1892 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1891 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1893 replacement makes message meaningless.
1892 replacement makes message meaningless.
1894
1893
1895 This tests that section lookup by translated string isn't broken by
1894 This tests that section lookup by translated string isn't broken by
1896 such str.lower().
1895 such str.lower().
1897
1896
1898 $ "$PYTHON" <<EOF
1897 $ "$PYTHON" <<EOF
1899 > def escape(s):
1898 > def escape(s):
1900 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1899 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1901 > # translation of "record" in ja_JP.cp932
1900 > # translation of "record" in ja_JP.cp932
1902 > upper = b"\x8bL\x98^"
1901 > upper = b"\x8bL\x98^"
1903 > # str.lower()-ed section name should be treated as different one
1902 > # str.lower()-ed section name should be treated as different one
1904 > lower = b"\x8bl\x98^"
1903 > lower = b"\x8bl\x98^"
1905 > with open('ambiguous.py', 'wb') as fp:
1904 > with open('ambiguous.py', 'wb') as fp:
1906 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1905 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1907 > u'''summary of extension
1906 > u'''summary of extension
1908 >
1907 >
1909 > %s
1908 > %s
1910 > ----
1909 > ----
1911 >
1910 >
1912 > Upper name should show only this message
1911 > Upper name should show only this message
1913 >
1912 >
1914 > %s
1913 > %s
1915 > ----
1914 > ----
1916 >
1915 >
1917 > Lower name should show only this message
1916 > Lower name should show only this message
1918 >
1917 >
1919 > subsequent section
1918 > subsequent section
1920 > ------------------
1919 > ------------------
1921 >
1920 >
1922 > This should be hidden at 'hg help ambiguous' with section name.
1921 > This should be hidden at 'hg help ambiguous' with section name.
1923 > '''
1922 > '''
1924 > """ % (escape(upper), escape(lower)))
1923 > """ % (escape(upper), escape(lower)))
1925 > EOF
1924 > EOF
1926
1925
1927 $ cat >> $HGRCPATH <<EOF
1926 $ cat >> $HGRCPATH <<EOF
1928 > [extensions]
1927 > [extensions]
1929 > ambiguous = ./ambiguous.py
1928 > ambiguous = ./ambiguous.py
1930 > EOF
1929 > EOF
1931
1930
1932 $ "$PYTHON" <<EOF | sh
1931 $ "$PYTHON" <<EOF | sh
1933 > from mercurial.utils import procutil
1932 > from mercurial.utils import procutil
1934 > upper = b"\x8bL\x98^"
1933 > upper = b"\x8bL\x98^"
1935 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1934 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1936 > EOF
1935 > EOF
1937 \x8bL\x98^ (esc)
1936 \x8bL\x98^ (esc)
1938 ----
1937 ----
1939
1938
1940 Upper name should show only this message
1939 Upper name should show only this message
1941
1940
1942
1941
1943 $ "$PYTHON" <<EOF | sh
1942 $ "$PYTHON" <<EOF | sh
1944 > from mercurial.utils import procutil
1943 > from mercurial.utils import procutil
1945 > lower = b"\x8bl\x98^"
1944 > lower = b"\x8bl\x98^"
1946 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1945 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1947 > EOF
1946 > EOF
1948 \x8bl\x98^ (esc)
1947 \x8bl\x98^ (esc)
1949 ----
1948 ----
1950
1949
1951 Lower name should show only this message
1950 Lower name should show only this message
1952
1951
1953
1952
1954 $ cat >> $HGRCPATH <<EOF
1953 $ cat >> $HGRCPATH <<EOF
1955 > [extensions]
1954 > [extensions]
1956 > ambiguous = !
1955 > ambiguous = !
1957 > EOF
1956 > EOF
1958
1957
1959 Show help content of disabled extensions
1958 Show help content of disabled extensions
1960
1959
1961 $ cat >> $HGRCPATH <<EOF
1960 $ cat >> $HGRCPATH <<EOF
1962 > [extensions]
1961 > [extensions]
1963 > ambiguous = !./ambiguous.py
1962 > ambiguous = !./ambiguous.py
1964 > EOF
1963 > EOF
1965 $ hg help -e ambiguous
1964 $ hg help -e ambiguous
1966 ambiguous extension - (no help text available)
1965 ambiguous extension - (no help text available)
1967
1966
1968 (use 'hg help extensions' for information on enabling extensions)
1967 (use 'hg help extensions' for information on enabling extensions)
1969
1968
1970 Test dynamic list of merge tools only shows up once
1969 Test dynamic list of merge tools only shows up once
1971 $ hg help merge-tools
1970 $ hg help merge-tools
1972 Merge Tools
1971 Merge Tools
1973 """""""""""
1972 """""""""""
1974
1973
1975 To merge files Mercurial uses merge tools.
1974 To merge files Mercurial uses merge tools.
1976
1975
1977 A merge tool combines two different versions of a file into a merged file.
1976 A merge tool combines two different versions of a file into a merged file.
1978 Merge tools are given the two files and the greatest common ancestor of
1977 Merge tools are given the two files and the greatest common ancestor of
1979 the two file versions, so they can determine the changes made on both
1978 the two file versions, so they can determine the changes made on both
1980 branches.
1979 branches.
1981
1980
1982 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1981 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1983 backout' and in several extensions.
1982 backout' and in several extensions.
1984
1983
1985 Usually, the merge tool tries to automatically reconcile the files by
1984 Usually, the merge tool tries to automatically reconcile the files by
1986 combining all non-overlapping changes that occurred separately in the two
1985 combining all non-overlapping changes that occurred separately in the two
1987 different evolutions of the same initial base file. Furthermore, some
1986 different evolutions of the same initial base file. Furthermore, some
1988 interactive merge programs make it easier to manually resolve conflicting
1987 interactive merge programs make it easier to manually resolve conflicting
1989 merges, either in a graphical way, or by inserting some conflict markers.
1988 merges, either in a graphical way, or by inserting some conflict markers.
1990 Mercurial does not include any interactive merge programs but relies on
1989 Mercurial does not include any interactive merge programs but relies on
1991 external tools for that.
1990 external tools for that.
1992
1991
1993 Available merge tools
1992 Available merge tools
1994 =====================
1993 =====================
1995
1994
1996 External merge tools and their properties are configured in the merge-
1995 External merge tools and their properties are configured in the merge-
1997 tools configuration section - see hgrc(5) - but they can often just be
1996 tools configuration section - see hgrc(5) - but they can often just be
1998 named by their executable.
1997 named by their executable.
1999
1998
2000 A merge tool is generally usable if its executable can be found on the
1999 A merge tool is generally usable if its executable can be found on the
2001 system and if it can handle the merge. The executable is found if it is an
2000 system and if it can handle the merge. The executable is found if it is an
2002 absolute or relative executable path or the name of an application in the
2001 absolute or relative executable path or the name of an application in the
2003 executable search path. The tool is assumed to be able to handle the merge
2002 executable search path. The tool is assumed to be able to handle the merge
2004 if it can handle symlinks if the file is a symlink, if it can handle
2003 if it can handle symlinks if the file is a symlink, if it can handle
2005 binary files if the file is binary, and if a GUI is available if the tool
2004 binary files if the file is binary, and if a GUI is available if the tool
2006 requires a GUI.
2005 requires a GUI.
2007
2006
2008 There are some internal merge tools which can be used. The internal merge
2007 There are some internal merge tools which can be used. The internal merge
2009 tools are:
2008 tools are:
2010
2009
2011 ":dump"
2010 ":dump"
2012 Creates three versions of the files to merge, containing the contents of
2011 Creates three versions of the files to merge, containing the contents of
2013 local, other and base. These files can then be used to perform a merge
2012 local, other and base. These files can then be used to perform a merge
2014 manually. If the file to be merged is named "a.txt", these files will
2013 manually. If the file to be merged is named "a.txt", these files will
2015 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2014 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2016 they will be placed in the same directory as "a.txt".
2015 they will be placed in the same directory as "a.txt".
2017
2016
2018 This implies premerge. Therefore, files aren't dumped, if premerge runs
2017 This implies premerge. Therefore, files aren't dumped, if premerge runs
2019 successfully. Use :forcedump to forcibly write files out.
2018 successfully. Use :forcedump to forcibly write files out.
2020
2019
2021 (actual capabilities: binary, symlink)
2020 (actual capabilities: binary, symlink)
2022
2021
2023 ":fail"
2022 ":fail"
2024 Rather than attempting to merge files that were modified on both
2023 Rather than attempting to merge files that were modified on both
2025 branches, it marks them as unresolved. The resolve command must be used
2024 branches, it marks them as unresolved. The resolve command must be used
2026 to resolve these conflicts.
2025 to resolve these conflicts.
2027
2026
2028 (actual capabilities: binary, symlink)
2027 (actual capabilities: binary, symlink)
2029
2028
2030 ":forcedump"
2029 ":forcedump"
2031 Creates three versions of the files as same as :dump, but omits
2030 Creates three versions of the files as same as :dump, but omits
2032 premerge.
2031 premerge.
2033
2032
2034 (actual capabilities: binary, symlink)
2033 (actual capabilities: binary, symlink)
2035
2034
2036 ":local"
2035 ":local"
2037 Uses the local 'p1()' version of files as the merged version.
2036 Uses the local 'p1()' version of files as the merged version.
2038
2037
2039 (actual capabilities: binary, symlink)
2038 (actual capabilities: binary, symlink)
2040
2039
2041 ":merge"
2040 ":merge"
2042 Uses the internal non-interactive simple merge algorithm for merging
2041 Uses the internal non-interactive simple merge algorithm for merging
2043 files. It will fail if there are any conflicts and leave markers in the
2042 files. It will fail if there are any conflicts and leave markers in the
2044 partially merged file. Markers will have two sections, one for each side
2043 partially merged file. Markers will have two sections, one for each side
2045 of merge.
2044 of merge.
2046
2045
2047 ":merge-local"
2046 ":merge-local"
2048 Like :merge, but resolve all conflicts non-interactively in favor of the
2047 Like :merge, but resolve all conflicts non-interactively in favor of the
2049 local 'p1()' changes.
2048 local 'p1()' changes.
2050
2049
2051 ":merge-other"
2050 ":merge-other"
2052 Like :merge, but resolve all conflicts non-interactively in favor of the
2051 Like :merge, but resolve all conflicts non-interactively in favor of the
2053 other 'p2()' changes.
2052 other 'p2()' changes.
2054
2053
2055 ":merge3"
2054 ":merge3"
2056 Uses the internal non-interactive simple merge algorithm for merging
2055 Uses the internal non-interactive simple merge algorithm for merging
2057 files. It will fail if there are any conflicts and leave markers in the
2056 files. It will fail if there are any conflicts and leave markers in the
2058 partially merged file. Marker will have three sections, one from each
2057 partially merged file. Marker will have three sections, one from each
2059 side of the merge and one for the base content.
2058 side of the merge and one for the base content.
2060
2059
2061 ":other"
2060 ":other"
2062 Uses the other 'p2()' version of files as the merged version.
2061 Uses the other 'p2()' version of files as the merged version.
2063
2062
2064 (actual capabilities: binary, symlink)
2063 (actual capabilities: binary, symlink)
2065
2064
2066 ":prompt"
2065 ":prompt"
2067 Asks the user which of the local 'p1()' or the other 'p2()' version to
2066 Asks the user which of the local 'p1()' or the other 'p2()' version to
2068 keep as the merged version.
2067 keep as the merged version.
2069
2068
2070 (actual capabilities: binary, symlink)
2069 (actual capabilities: binary, symlink)
2071
2070
2072 ":tagmerge"
2071 ":tagmerge"
2073 Uses the internal tag merge algorithm (experimental).
2072 Uses the internal tag merge algorithm (experimental).
2074
2073
2075 ":union"
2074 ":union"
2076 Uses the internal non-interactive simple merge algorithm for merging
2075 Uses the internal non-interactive simple merge algorithm for merging
2077 files. It will use both left and right sides for conflict regions. No
2076 files. It will use both left and right sides for conflict regions. No
2078 markers are inserted.
2077 markers are inserted.
2079
2078
2080 Internal tools are always available and do not require a GUI but will by
2079 Internal tools are always available and do not require a GUI but will by
2081 default not handle symlinks or binary files. See next section for detail
2080 default not handle symlinks or binary files. See next section for detail
2082 about "actual capabilities" described above.
2081 about "actual capabilities" described above.
2083
2082
2084 Choosing a merge tool
2083 Choosing a merge tool
2085 =====================
2084 =====================
2086
2085
2087 Mercurial uses these rules when deciding which merge tool to use:
2086 Mercurial uses these rules when deciding which merge tool to use:
2088
2087
2089 1. If a tool has been specified with the --tool option to merge or
2088 1. If a tool has been specified with the --tool option to merge or
2090 resolve, it is used. If it is the name of a tool in the merge-tools
2089 resolve, it is used. If it is the name of a tool in the merge-tools
2091 configuration, its configuration is used. Otherwise the specified tool
2090 configuration, its configuration is used. Otherwise the specified tool
2092 must be executable by the shell.
2091 must be executable by the shell.
2093 2. If the "HGMERGE" environment variable is present, its value is used and
2092 2. If the "HGMERGE" environment variable is present, its value is used and
2094 must be executable by the shell.
2093 must be executable by the shell.
2095 3. If the filename of the file to be merged matches any of the patterns in
2094 3. If the filename of the file to be merged matches any of the patterns in
2096 the merge-patterns configuration section, the first usable merge tool
2095 the merge-patterns configuration section, the first usable merge tool
2097 corresponding to a matching pattern is used.
2096 corresponding to a matching pattern is used.
2098 4. If ui.merge is set it will be considered next. If the value is not the
2097 4. If ui.merge is set it will be considered next. If the value is not the
2099 name of a configured tool, the specified value is used and must be
2098 name of a configured tool, the specified value is used and must be
2100 executable by the shell. Otherwise the named tool is used if it is
2099 executable by the shell. Otherwise the named tool is used if it is
2101 usable.
2100 usable.
2102 5. If any usable merge tools are present in the merge-tools configuration
2101 5. If any usable merge tools are present in the merge-tools configuration
2103 section, the one with the highest priority is used.
2102 section, the one with the highest priority is used.
2104 6. If a program named "hgmerge" can be found on the system, it is used -
2103 6. If a program named "hgmerge" can be found on the system, it is used -
2105 but it will by default not be used for symlinks and binary files.
2104 but it will by default not be used for symlinks and binary files.
2106 7. If the file to be merged is not binary and is not a symlink, then
2105 7. If the file to be merged is not binary and is not a symlink, then
2107 internal ":merge" is used.
2106 internal ":merge" is used.
2108 8. Otherwise, ":prompt" is used.
2107 8. Otherwise, ":prompt" is used.
2109
2108
2110 For historical reason, Mercurial treats merge tools as below while
2109 For historical reason, Mercurial treats merge tools as below while
2111 examining rules above.
2110 examining rules above.
2112
2111
2113 step specified via binary symlink
2112 step specified via binary symlink
2114 ----------------------------------
2113 ----------------------------------
2115 1. --tool o/o o/o
2114 1. --tool o/o o/o
2116 2. HGMERGE o/o o/o
2115 2. HGMERGE o/o o/o
2117 3. merge-patterns o/o(*) x/?(*)
2116 3. merge-patterns o/o(*) x/?(*)
2118 4. ui.merge x/?(*) x/?(*)
2117 4. ui.merge x/?(*) x/?(*)
2119
2118
2120 Each capability column indicates Mercurial behavior for internal/external
2119 Each capability column indicates Mercurial behavior for internal/external
2121 merge tools at examining each rule.
2120 merge tools at examining each rule.
2122
2121
2123 - "o": "assume that a tool has capability"
2122 - "o": "assume that a tool has capability"
2124 - "x": "assume that a tool does not have capability"
2123 - "x": "assume that a tool does not have capability"
2125 - "?": "check actual capability of a tool"
2124 - "?": "check actual capability of a tool"
2126
2125
2127 If "merge.strict-capability-check" configuration is true, Mercurial checks
2126 If "merge.strict-capability-check" configuration is true, Mercurial checks
2128 capabilities of merge tools strictly in (*) cases above (= each capability
2127 capabilities of merge tools strictly in (*) cases above (= each capability
2129 column becomes "?/?"). It is false by default for backward compatibility.
2128 column becomes "?/?"). It is false by default for backward compatibility.
2130
2129
2131 Note:
2130 Note:
2132 After selecting a merge program, Mercurial will by default attempt to
2131 After selecting a merge program, Mercurial will by default attempt to
2133 merge the files using a simple merge algorithm first. Only if it
2132 merge the files using a simple merge algorithm first. Only if it
2134 doesn't succeed because of conflicting changes will Mercurial actually
2133 doesn't succeed because of conflicting changes will Mercurial actually
2135 execute the merge program. Whether to use the simple merge algorithm
2134 execute the merge program. Whether to use the simple merge algorithm
2136 first can be controlled by the premerge setting of the merge tool.
2135 first can be controlled by the premerge setting of the merge tool.
2137 Premerge is enabled by default unless the file is binary or a symlink.
2136 Premerge is enabled by default unless the file is binary or a symlink.
2138
2137
2139 See the merge-tools and ui sections of hgrc(5) for details on the
2138 See the merge-tools and ui sections of hgrc(5) for details on the
2140 configuration of merge tools.
2139 configuration of merge tools.
2141
2140
2142 Compression engines listed in `hg help bundlespec`
2141 Compression engines listed in `hg help bundlespec`
2143
2142
2144 $ hg help bundlespec | grep gzip
2143 $ hg help bundlespec | grep gzip
2145 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2144 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2146 An algorithm that produces smaller bundles than "gzip".
2145 An algorithm that produces smaller bundles than "gzip".
2147 This engine will likely produce smaller bundles than "gzip" but will be
2146 This engine will likely produce smaller bundles than "gzip" but will be
2148 "gzip"
2147 "gzip"
2149 better compression than "gzip". It also frequently yields better (?)
2148 better compression than "gzip". It also frequently yields better (?)
2150
2149
2151 Test usage of section marks in help documents
2150 Test usage of section marks in help documents
2152
2151
2153 $ cd "$TESTDIR"/../doc
2152 $ cd "$TESTDIR"/../doc
2154 $ "$PYTHON" check-seclevel.py
2153 $ "$PYTHON" check-seclevel.py
2155 $ cd $TESTTMP
2154 $ cd $TESTTMP
2156
2155
2157 #if serve
2156 #if serve
2158
2157
2159 Test the help pages in hgweb.
2158 Test the help pages in hgweb.
2160
2159
2161 Dish up an empty repo; serve it cold.
2160 Dish up an empty repo; serve it cold.
2162
2161
2163 $ hg init "$TESTTMP/test"
2162 $ hg init "$TESTTMP/test"
2164 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2163 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2165 $ cat hg.pid >> $DAEMON_PIDS
2164 $ cat hg.pid >> $DAEMON_PIDS
2166
2165
2167 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2166 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2168 200 Script output follows
2167 200 Script output follows
2169
2168
2170 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2169 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2171 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2170 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2172 <head>
2171 <head>
2173 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2172 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2174 <meta name="robots" content="index, nofollow" />
2173 <meta name="robots" content="index, nofollow" />
2175 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2174 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2176 <script type="text/javascript" src="/static/mercurial.js"></script>
2175 <script type="text/javascript" src="/static/mercurial.js"></script>
2177
2176
2178 <title>Help: Index</title>
2177 <title>Help: Index</title>
2179 </head>
2178 </head>
2180 <body>
2179 <body>
2181
2180
2182 <div class="container">
2181 <div class="container">
2183 <div class="menu">
2182 <div class="menu">
2184 <div class="logo">
2183 <div class="logo">
2185 <a href="https://mercurial-scm.org/">
2184 <a href="https://mercurial-scm.org/">
2186 <img src="/static/hglogo.png" alt="mercurial" /></a>
2185 <img src="/static/hglogo.png" alt="mercurial" /></a>
2187 </div>
2186 </div>
2188 <ul>
2187 <ul>
2189 <li><a href="/shortlog">log</a></li>
2188 <li><a href="/shortlog">log</a></li>
2190 <li><a href="/graph">graph</a></li>
2189 <li><a href="/graph">graph</a></li>
2191 <li><a href="/tags">tags</a></li>
2190 <li><a href="/tags">tags</a></li>
2192 <li><a href="/bookmarks">bookmarks</a></li>
2191 <li><a href="/bookmarks">bookmarks</a></li>
2193 <li><a href="/branches">branches</a></li>
2192 <li><a href="/branches">branches</a></li>
2194 </ul>
2193 </ul>
2195 <ul>
2194 <ul>
2196 <li class="active">help</li>
2195 <li class="active">help</li>
2197 </ul>
2196 </ul>
2198 </div>
2197 </div>
2199
2198
2200 <div class="main">
2199 <div class="main">
2201 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2200 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2202
2201
2203 <form class="search" action="/log">
2202 <form class="search" action="/log">
2204
2203
2205 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2204 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2206 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2205 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2207 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2206 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2208 </form>
2207 </form>
2209 <table class="bigtable">
2208 <table class="bigtable">
2210 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2209 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2211
2210
2212 <tr><td>
2211 <tr><td>
2213 <a href="/help/bundlespec">
2212 <a href="/help/bundlespec">
2214 bundlespec
2213 bundlespec
2215 </a>
2214 </a>
2216 </td><td>
2215 </td><td>
2217 Bundle File Formats
2216 Bundle File Formats
2218 </td></tr>
2217 </td></tr>
2219 <tr><td>
2218 <tr><td>
2220 <a href="/help/color">
2219 <a href="/help/color">
2221 color
2220 color
2222 </a>
2221 </a>
2223 </td><td>
2222 </td><td>
2224 Colorizing Outputs
2223 Colorizing Outputs
2225 </td></tr>
2224 </td></tr>
2226 <tr><td>
2225 <tr><td>
2227 <a href="/help/config">
2226 <a href="/help/config">
2228 config
2227 config
2229 </a>
2228 </a>
2230 </td><td>
2229 </td><td>
2231 Configuration Files
2230 Configuration Files
2232 </td></tr>
2231 </td></tr>
2233 <tr><td>
2232 <tr><td>
2234 <a href="/help/dates">
2233 <a href="/help/dates">
2235 dates
2234 dates
2236 </a>
2235 </a>
2237 </td><td>
2236 </td><td>
2238 Date Formats
2237 Date Formats
2239 </td></tr>
2238 </td></tr>
2240 <tr><td>
2239 <tr><td>
2241 <a href="/help/deprecated">
2240 <a href="/help/deprecated">
2242 deprecated
2241 deprecated
2243 </a>
2242 </a>
2244 </td><td>
2243 </td><td>
2245 Deprecated Features
2244 Deprecated Features
2246 </td></tr>
2245 </td></tr>
2247 <tr><td>
2246 <tr><td>
2248 <a href="/help/diffs">
2247 <a href="/help/diffs">
2249 diffs
2248 diffs
2250 </a>
2249 </a>
2251 </td><td>
2250 </td><td>
2252 Diff Formats
2251 Diff Formats
2253 </td></tr>
2252 </td></tr>
2254 <tr><td>
2253 <tr><td>
2255 <a href="/help/environment">
2254 <a href="/help/environment">
2256 environment
2255 environment
2257 </a>
2256 </a>
2258 </td><td>
2257 </td><td>
2259 Environment Variables
2258 Environment Variables
2260 </td></tr>
2259 </td></tr>
2261 <tr><td>
2260 <tr><td>
2262 <a href="/help/extensions">
2261 <a href="/help/extensions">
2263 extensions
2262 extensions
2264 </a>
2263 </a>
2265 </td><td>
2264 </td><td>
2266 Using Additional Features
2265 Using Additional Features
2267 </td></tr>
2266 </td></tr>
2268 <tr><td>
2267 <tr><td>
2269 <a href="/help/filesets">
2268 <a href="/help/filesets">
2270 filesets
2269 filesets
2271 </a>
2270 </a>
2272 </td><td>
2271 </td><td>
2273 Specifying File Sets
2272 Specifying File Sets
2274 </td></tr>
2273 </td></tr>
2275 <tr><td>
2274 <tr><td>
2276 <a href="/help/flags">
2275 <a href="/help/flags">
2277 flags
2276 flags
2278 </a>
2277 </a>
2279 </td><td>
2278 </td><td>
2280 Command-line flags
2279 Command-line flags
2281 </td></tr>
2280 </td></tr>
2282 <tr><td>
2281 <tr><td>
2283 <a href="/help/glossary">
2282 <a href="/help/glossary">
2284 glossary
2283 glossary
2285 </a>
2284 </a>
2286 </td><td>
2285 </td><td>
2287 Glossary
2286 Glossary
2288 </td></tr>
2287 </td></tr>
2289 <tr><td>
2288 <tr><td>
2290 <a href="/help/hgignore">
2289 <a href="/help/hgignore">
2291 hgignore
2290 hgignore
2292 </a>
2291 </a>
2293 </td><td>
2292 </td><td>
2294 Syntax for Mercurial Ignore Files
2293 Syntax for Mercurial Ignore Files
2295 </td></tr>
2294 </td></tr>
2296 <tr><td>
2295 <tr><td>
2297 <a href="/help/hgweb">
2296 <a href="/help/hgweb">
2298 hgweb
2297 hgweb
2299 </a>
2298 </a>
2300 </td><td>
2299 </td><td>
2301 Configuring hgweb
2300 Configuring hgweb
2302 </td></tr>
2301 </td></tr>
2303 <tr><td>
2302 <tr><td>
2304 <a href="/help/internals">
2303 <a href="/help/internals">
2305 internals
2304 internals
2306 </a>
2305 </a>
2307 </td><td>
2306 </td><td>
2308 Technical implementation topics
2307 Technical implementation topics
2309 </td></tr>
2308 </td></tr>
2310 <tr><td>
2309 <tr><td>
2311 <a href="/help/merge-tools">
2310 <a href="/help/merge-tools">
2312 merge-tools
2311 merge-tools
2313 </a>
2312 </a>
2314 </td><td>
2313 </td><td>
2315 Merge Tools
2314 Merge Tools
2316 </td></tr>
2315 </td></tr>
2317 <tr><td>
2316 <tr><td>
2318 <a href="/help/pager">
2317 <a href="/help/pager">
2319 pager
2318 pager
2320 </a>
2319 </a>
2321 </td><td>
2320 </td><td>
2322 Pager Support
2321 Pager Support
2323 </td></tr>
2322 </td></tr>
2324 <tr><td>
2323 <tr><td>
2325 <a href="/help/patterns">
2324 <a href="/help/patterns">
2326 patterns
2325 patterns
2327 </a>
2326 </a>
2328 </td><td>
2327 </td><td>
2329 File Name Patterns
2328 File Name Patterns
2330 </td></tr>
2329 </td></tr>
2331 <tr><td>
2330 <tr><td>
2332 <a href="/help/phases">
2331 <a href="/help/phases">
2333 phases
2332 phases
2334 </a>
2333 </a>
2335 </td><td>
2334 </td><td>
2336 Working with Phases
2335 Working with Phases
2337 </td></tr>
2336 </td></tr>
2338 <tr><td>
2337 <tr><td>
2339 <a href="/help/revisions">
2338 <a href="/help/revisions">
2340 revisions
2339 revisions
2341 </a>
2340 </a>
2342 </td><td>
2341 </td><td>
2343 Specifying Revisions
2342 Specifying Revisions
2344 </td></tr>
2343 </td></tr>
2345 <tr><td>
2344 <tr><td>
2346 <a href="/help/scripting">
2345 <a href="/help/scripting">
2347 scripting
2346 scripting
2348 </a>
2347 </a>
2349 </td><td>
2348 </td><td>
2350 Using Mercurial from scripts and automation
2349 Using Mercurial from scripts and automation
2351 </td></tr>
2350 </td></tr>
2352 <tr><td>
2351 <tr><td>
2353 <a href="/help/subrepos">
2352 <a href="/help/subrepos">
2354 subrepos
2353 subrepos
2355 </a>
2354 </a>
2356 </td><td>
2355 </td><td>
2357 Subrepositories
2356 Subrepositories
2358 </td></tr>
2357 </td></tr>
2359 <tr><td>
2358 <tr><td>
2360 <a href="/help/templating">
2359 <a href="/help/templating">
2361 templating
2360 templating
2362 </a>
2361 </a>
2363 </td><td>
2362 </td><td>
2364 Template Usage
2363 Template Usage
2365 </td></tr>
2364 </td></tr>
2366 <tr><td>
2365 <tr><td>
2367 <a href="/help/urls">
2366 <a href="/help/urls">
2368 urls
2367 urls
2369 </a>
2368 </a>
2370 </td><td>
2369 </td><td>
2371 URL Paths
2370 URL Paths
2372 </td></tr>
2371 </td></tr>
2373 <tr><td>
2372 <tr><td>
2374 <a href="/help/topic-containing-verbose">
2373 <a href="/help/topic-containing-verbose">
2375 topic-containing-verbose
2374 topic-containing-verbose
2376 </a>
2375 </a>
2377 </td><td>
2376 </td><td>
2378 This is the topic to test omit indicating.
2377 This is the topic to test omit indicating.
2379 </td></tr>
2378 </td></tr>
2380
2379
2381
2380
2382 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2381 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2383
2382
2384 <tr><td>
2383 <tr><td>
2385 <a href="/help/abort">
2384 <a href="/help/abort">
2386 abort
2385 abort
2387 </a>
2386 </a>
2388 </td><td>
2387 </td><td>
2389 abort an unfinished operation (EXPERIMENTAL)
2388 abort an unfinished operation (EXPERIMENTAL)
2390 </td></tr>
2389 </td></tr>
2391 <tr><td>
2390 <tr><td>
2392 <a href="/help/add">
2391 <a href="/help/add">
2393 add
2392 add
2394 </a>
2393 </a>
2395 </td><td>
2394 </td><td>
2396 add the specified files on the next commit
2395 add the specified files on the next commit
2397 </td></tr>
2396 </td></tr>
2398 <tr><td>
2397 <tr><td>
2399 <a href="/help/annotate">
2398 <a href="/help/annotate">
2400 annotate
2399 annotate
2401 </a>
2400 </a>
2402 </td><td>
2401 </td><td>
2403 show changeset information by line for each file
2402 show changeset information by line for each file
2404 </td></tr>
2403 </td></tr>
2405 <tr><td>
2404 <tr><td>
2406 <a href="/help/clone">
2405 <a href="/help/clone">
2407 clone
2406 clone
2408 </a>
2407 </a>
2409 </td><td>
2408 </td><td>
2410 make a copy of an existing repository
2409 make a copy of an existing repository
2411 </td></tr>
2410 </td></tr>
2412 <tr><td>
2411 <tr><td>
2413 <a href="/help/commit">
2412 <a href="/help/commit">
2414 commit
2413 commit
2415 </a>
2414 </a>
2416 </td><td>
2415 </td><td>
2417 commit the specified files or all outstanding changes
2416 commit the specified files or all outstanding changes
2418 </td></tr>
2417 </td></tr>
2419 <tr><td>
2418 <tr><td>
2420 <a href="/help/continue">
2419 <a href="/help/continue">
2421 continue
2420 continue
2422 </a>
2421 </a>
2423 </td><td>
2422 </td><td>
2424 resumes an interrupted operation (EXPERIMENTAL)
2423 resumes an interrupted operation (EXPERIMENTAL)
2425 </td></tr>
2424 </td></tr>
2426 <tr><td>
2425 <tr><td>
2427 <a href="/help/diff">
2426 <a href="/help/diff">
2428 diff
2427 diff
2429 </a>
2428 </a>
2430 </td><td>
2429 </td><td>
2431 diff repository (or selected files)
2430 diff repository (or selected files)
2432 </td></tr>
2431 </td></tr>
2433 <tr><td>
2432 <tr><td>
2434 <a href="/help/export">
2433 <a href="/help/export">
2435 export
2434 export
2436 </a>
2435 </a>
2437 </td><td>
2436 </td><td>
2438 dump the header and diffs for one or more changesets
2437 dump the header and diffs for one or more changesets
2439 </td></tr>
2438 </td></tr>
2440 <tr><td>
2439 <tr><td>
2441 <a href="/help/forget">
2440 <a href="/help/forget">
2442 forget
2441 forget
2443 </a>
2442 </a>
2444 </td><td>
2443 </td><td>
2445 forget the specified files on the next commit
2444 forget the specified files on the next commit
2446 </td></tr>
2445 </td></tr>
2447 <tr><td>
2446 <tr><td>
2448 <a href="/help/init">
2447 <a href="/help/init">
2449 init
2448 init
2450 </a>
2449 </a>
2451 </td><td>
2450 </td><td>
2452 create a new repository in the given directory
2451 create a new repository in the given directory
2453 </td></tr>
2452 </td></tr>
2454 <tr><td>
2453 <tr><td>
2455 <a href="/help/log">
2454 <a href="/help/log">
2456 log
2455 log
2457 </a>
2456 </a>
2458 </td><td>
2457 </td><td>
2459 show revision history of entire repository or files
2458 show revision history of entire repository or files
2460 </td></tr>
2459 </td></tr>
2461 <tr><td>
2460 <tr><td>
2462 <a href="/help/merge">
2461 <a href="/help/merge">
2463 merge
2462 merge
2464 </a>
2463 </a>
2465 </td><td>
2464 </td><td>
2466 merge another revision into working directory
2465 merge another revision into working directory
2467 </td></tr>
2466 </td></tr>
2468 <tr><td>
2467 <tr><td>
2469 <a href="/help/pull">
2468 <a href="/help/pull">
2470 pull
2469 pull
2471 </a>
2470 </a>
2472 </td><td>
2471 </td><td>
2473 pull changes from the specified source
2472 pull changes from the specified source
2474 </td></tr>
2473 </td></tr>
2475 <tr><td>
2474 <tr><td>
2476 <a href="/help/push">
2475 <a href="/help/push">
2477 push
2476 push
2478 </a>
2477 </a>
2479 </td><td>
2478 </td><td>
2480 push changes to the specified destination
2479 push changes to the specified destination
2481 </td></tr>
2480 </td></tr>
2482 <tr><td>
2481 <tr><td>
2483 <a href="/help/remove">
2482 <a href="/help/remove">
2484 remove
2483 remove
2485 </a>
2484 </a>
2486 </td><td>
2485 </td><td>
2487 remove the specified files on the next commit
2486 remove the specified files on the next commit
2488 </td></tr>
2487 </td></tr>
2489 <tr><td>
2488 <tr><td>
2490 <a href="/help/serve">
2489 <a href="/help/serve">
2491 serve
2490 serve
2492 </a>
2491 </a>
2493 </td><td>
2492 </td><td>
2494 start stand-alone webserver
2493 start stand-alone webserver
2495 </td></tr>
2494 </td></tr>
2496 <tr><td>
2495 <tr><td>
2497 <a href="/help/status">
2496 <a href="/help/status">
2498 status
2497 status
2499 </a>
2498 </a>
2500 </td><td>
2499 </td><td>
2501 show changed files in the working directory
2500 show changed files in the working directory
2502 </td></tr>
2501 </td></tr>
2503 <tr><td>
2502 <tr><td>
2504 <a href="/help/summary">
2503 <a href="/help/summary">
2505 summary
2504 summary
2506 </a>
2505 </a>
2507 </td><td>
2506 </td><td>
2508 summarize working directory state
2507 summarize working directory state
2509 </td></tr>
2508 </td></tr>
2510 <tr><td>
2509 <tr><td>
2511 <a href="/help/update">
2510 <a href="/help/update">
2512 update
2511 update
2513 </a>
2512 </a>
2514 </td><td>
2513 </td><td>
2515 update working directory (or switch revisions)
2514 update working directory (or switch revisions)
2516 </td></tr>
2515 </td></tr>
2517
2516
2518
2517
2519
2518
2520 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2519 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2521
2520
2522 <tr><td>
2521 <tr><td>
2523 <a href="/help/addremove">
2522 <a href="/help/addremove">
2524 addremove
2523 addremove
2525 </a>
2524 </a>
2526 </td><td>
2525 </td><td>
2527 add all new files, delete all missing files
2526 add all new files, delete all missing files
2528 </td></tr>
2527 </td></tr>
2529 <tr><td>
2528 <tr><td>
2530 <a href="/help/archive">
2529 <a href="/help/archive">
2531 archive
2530 archive
2532 </a>
2531 </a>
2533 </td><td>
2532 </td><td>
2534 create an unversioned archive of a repository revision
2533 create an unversioned archive of a repository revision
2535 </td></tr>
2534 </td></tr>
2536 <tr><td>
2535 <tr><td>
2537 <a href="/help/backout">
2536 <a href="/help/backout">
2538 backout
2537 backout
2539 </a>
2538 </a>
2540 </td><td>
2539 </td><td>
2541 reverse effect of earlier changeset
2540 reverse effect of earlier changeset
2542 </td></tr>
2541 </td></tr>
2543 <tr><td>
2542 <tr><td>
2544 <a href="/help/bisect">
2543 <a href="/help/bisect">
2545 bisect
2544 bisect
2546 </a>
2545 </a>
2547 </td><td>
2546 </td><td>
2548 subdivision search of changesets
2547 subdivision search of changesets
2549 </td></tr>
2548 </td></tr>
2550 <tr><td>
2549 <tr><td>
2551 <a href="/help/bookmarks">
2550 <a href="/help/bookmarks">
2552 bookmarks
2551 bookmarks
2553 </a>
2552 </a>
2554 </td><td>
2553 </td><td>
2555 create a new bookmark or list existing bookmarks
2554 create a new bookmark or list existing bookmarks
2556 </td></tr>
2555 </td></tr>
2557 <tr><td>
2556 <tr><td>
2558 <a href="/help/branch">
2557 <a href="/help/branch">
2559 branch
2558 branch
2560 </a>
2559 </a>
2561 </td><td>
2560 </td><td>
2562 set or show the current branch name
2561 set or show the current branch name
2563 </td></tr>
2562 </td></tr>
2564 <tr><td>
2563 <tr><td>
2565 <a href="/help/branches">
2564 <a href="/help/branches">
2566 branches
2565 branches
2567 </a>
2566 </a>
2568 </td><td>
2567 </td><td>
2569 list repository named branches
2568 list repository named branches
2570 </td></tr>
2569 </td></tr>
2571 <tr><td>
2570 <tr><td>
2572 <a href="/help/bundle">
2571 <a href="/help/bundle">
2573 bundle
2572 bundle
2574 </a>
2573 </a>
2575 </td><td>
2574 </td><td>
2576 create a bundle file
2575 create a bundle file
2577 </td></tr>
2576 </td></tr>
2578 <tr><td>
2577 <tr><td>
2579 <a href="/help/cat">
2578 <a href="/help/cat">
2580 cat
2579 cat
2581 </a>
2580 </a>
2582 </td><td>
2581 </td><td>
2583 output the current or given revision of files
2582 output the current or given revision of files
2584 </td></tr>
2583 </td></tr>
2585 <tr><td>
2584 <tr><td>
2586 <a href="/help/config">
2585 <a href="/help/config">
2587 config
2586 config
2588 </a>
2587 </a>
2589 </td><td>
2588 </td><td>
2590 show combined config settings from all hgrc files
2589 show combined config settings from all hgrc files
2591 </td></tr>
2590 </td></tr>
2592 <tr><td>
2591 <tr><td>
2593 <a href="/help/copy">
2592 <a href="/help/copy">
2594 copy
2593 copy
2595 </a>
2594 </a>
2596 </td><td>
2595 </td><td>
2597 mark files as copied for the next commit
2596 mark files as copied for the next commit
2598 </td></tr>
2597 </td></tr>
2599 <tr><td>
2598 <tr><td>
2600 <a href="/help/files">
2599 <a href="/help/files">
2601 files
2600 files
2602 </a>
2601 </a>
2603 </td><td>
2602 </td><td>
2604 list tracked files
2603 list tracked files
2605 </td></tr>
2604 </td></tr>
2606 <tr><td>
2605 <tr><td>
2607 <a href="/help/graft">
2606 <a href="/help/graft">
2608 graft
2607 graft
2609 </a>
2608 </a>
2610 </td><td>
2609 </td><td>
2611 copy changes from other branches onto the current branch
2610 copy changes from other branches onto the current branch
2612 </td></tr>
2611 </td></tr>
2613 <tr><td>
2612 <tr><td>
2614 <a href="/help/grep">
2613 <a href="/help/grep">
2615 grep
2614 grep
2616 </a>
2615 </a>
2617 </td><td>
2616 </td><td>
2618 search for a pattern in specified files
2617 search for a pattern in specified files
2619 </td></tr>
2618 </td></tr>
2620 <tr><td>
2619 <tr><td>
2621 <a href="/help/hashelp">
2620 <a href="/help/hashelp">
2622 hashelp
2621 hashelp
2623 </a>
2622 </a>
2624 </td><td>
2623 </td><td>
2625 Extension command's help
2624 Extension command's help
2626 </td></tr>
2625 </td></tr>
2627 <tr><td>
2626 <tr><td>
2628 <a href="/help/heads">
2627 <a href="/help/heads">
2629 heads
2628 heads
2630 </a>
2629 </a>
2631 </td><td>
2630 </td><td>
2632 show branch heads
2631 show branch heads
2633 </td></tr>
2632 </td></tr>
2634 <tr><td>
2633 <tr><td>
2635 <a href="/help/help">
2634 <a href="/help/help">
2636 help
2635 help
2637 </a>
2636 </a>
2638 </td><td>
2637 </td><td>
2639 show help for a given topic or a help overview
2638 show help for a given topic or a help overview
2640 </td></tr>
2639 </td></tr>
2641 <tr><td>
2640 <tr><td>
2642 <a href="/help/hgalias">
2641 <a href="/help/hgalias">
2643 hgalias
2642 hgalias
2644 </a>
2643 </a>
2645 </td><td>
2644 </td><td>
2646 My doc
2645 My doc
2647 </td></tr>
2646 </td></tr>
2648 <tr><td>
2647 <tr><td>
2649 <a href="/help/hgaliasnodoc">
2648 <a href="/help/hgaliasnodoc">
2650 hgaliasnodoc
2649 hgaliasnodoc
2651 </a>
2650 </a>
2652 </td><td>
2651 </td><td>
2653 summarize working directory state
2652 summarize working directory state
2654 </td></tr>
2653 </td></tr>
2655 <tr><td>
2654 <tr><td>
2656 <a href="/help/identify">
2655 <a href="/help/identify">
2657 identify
2656 identify
2658 </a>
2657 </a>
2659 </td><td>
2658 </td><td>
2660 identify the working directory or specified revision
2659 identify the working directory or specified revision
2661 </td></tr>
2660 </td></tr>
2662 <tr><td>
2661 <tr><td>
2663 <a href="/help/import">
2662 <a href="/help/import">
2664 import
2663 import
2665 </a>
2664 </a>
2666 </td><td>
2665 </td><td>
2667 import an ordered set of patches
2666 import an ordered set of patches
2668 </td></tr>
2667 </td></tr>
2669 <tr><td>
2668 <tr><td>
2670 <a href="/help/incoming">
2669 <a href="/help/incoming">
2671 incoming
2670 incoming
2672 </a>
2671 </a>
2673 </td><td>
2672 </td><td>
2674 show new changesets found in source
2673 show new changesets found in source
2675 </td></tr>
2674 </td></tr>
2676 <tr><td>
2675 <tr><td>
2677 <a href="/help/manifest">
2676 <a href="/help/manifest">
2678 manifest
2677 manifest
2679 </a>
2678 </a>
2680 </td><td>
2679 </td><td>
2681 output the current or given revision of the project manifest
2680 output the current or given revision of the project manifest
2682 </td></tr>
2681 </td></tr>
2683 <tr><td>
2682 <tr><td>
2684 <a href="/help/nohelp">
2683 <a href="/help/nohelp">
2685 nohelp
2684 nohelp
2686 </a>
2685 </a>
2687 </td><td>
2686 </td><td>
2688 (no help text available)
2687 (no help text available)
2689 </td></tr>
2688 </td></tr>
2690 <tr><td>
2689 <tr><td>
2691 <a href="/help/outgoing">
2690 <a href="/help/outgoing">
2692 outgoing
2691 outgoing
2693 </a>
2692 </a>
2694 </td><td>
2693 </td><td>
2695 show changesets not found in the destination
2694 show changesets not found in the destination
2696 </td></tr>
2695 </td></tr>
2697 <tr><td>
2696 <tr><td>
2698 <a href="/help/paths">
2697 <a href="/help/paths">
2699 paths
2698 paths
2700 </a>
2699 </a>
2701 </td><td>
2700 </td><td>
2702 show aliases for remote repositories
2701 show aliases for remote repositories
2703 </td></tr>
2702 </td></tr>
2704 <tr><td>
2703 <tr><td>
2705 <a href="/help/phase">
2704 <a href="/help/phase">
2706 phase
2705 phase
2707 </a>
2706 </a>
2708 </td><td>
2707 </td><td>
2709 set or show the current phase name
2708 set or show the current phase name
2710 </td></tr>
2709 </td></tr>
2711 <tr><td>
2710 <tr><td>
2712 <a href="/help/recover">
2711 <a href="/help/recover">
2713 recover
2712 recover
2714 </a>
2713 </a>
2715 </td><td>
2714 </td><td>
2716 roll back an interrupted transaction
2715 roll back an interrupted transaction
2717 </td></tr>
2716 </td></tr>
2718 <tr><td>
2717 <tr><td>
2719 <a href="/help/rename">
2718 <a href="/help/rename">
2720 rename
2719 rename
2721 </a>
2720 </a>
2722 </td><td>
2721 </td><td>
2723 rename files; equivalent of copy + remove
2722 rename files; equivalent of copy + remove
2724 </td></tr>
2723 </td></tr>
2725 <tr><td>
2724 <tr><td>
2726 <a href="/help/resolve">
2725 <a href="/help/resolve">
2727 resolve
2726 resolve
2728 </a>
2727 </a>
2729 </td><td>
2728 </td><td>
2730 redo merges or set/view the merge status of files
2729 redo merges or set/view the merge status of files
2731 </td></tr>
2730 </td></tr>
2732 <tr><td>
2731 <tr><td>
2733 <a href="/help/revert">
2732 <a href="/help/revert">
2734 revert
2733 revert
2735 </a>
2734 </a>
2736 </td><td>
2735 </td><td>
2737 restore files to their checkout state
2736 restore files to their checkout state
2738 </td></tr>
2737 </td></tr>
2739 <tr><td>
2738 <tr><td>
2740 <a href="/help/root">
2739 <a href="/help/root">
2741 root
2740 root
2742 </a>
2741 </a>
2743 </td><td>
2742 </td><td>
2744 print the root (top) of the current working directory
2743 print the root (top) of the current working directory
2745 </td></tr>
2744 </td></tr>
2746 <tr><td>
2745 <tr><td>
2747 <a href="/help/shellalias">
2746 <a href="/help/shellalias">
2748 shellalias
2747 shellalias
2749 </a>
2748 </a>
2750 </td><td>
2749 </td><td>
2751 (no help text available)
2750 (no help text available)
2752 </td></tr>
2751 </td></tr>
2753 <tr><td>
2752 <tr><td>
2754 <a href="/help/shelve">
2753 <a href="/help/shelve">
2755 shelve
2754 shelve
2756 </a>
2755 </a>
2757 </td><td>
2756 </td><td>
2758 save and set aside changes from the working directory
2757 save and set aside changes from the working directory
2759 </td></tr>
2758 </td></tr>
2760 <tr><td>
2759 <tr><td>
2761 <a href="/help/tag">
2760 <a href="/help/tag">
2762 tag
2761 tag
2763 </a>
2762 </a>
2764 </td><td>
2763 </td><td>
2765 add one or more tags for the current or given revision
2764 add one or more tags for the current or given revision
2766 </td></tr>
2765 </td></tr>
2767 <tr><td>
2766 <tr><td>
2768 <a href="/help/tags">
2767 <a href="/help/tags">
2769 tags
2768 tags
2770 </a>
2769 </a>
2771 </td><td>
2770 </td><td>
2772 list repository tags
2771 list repository tags
2773 </td></tr>
2772 </td></tr>
2774 <tr><td>
2773 <tr><td>
2775 <a href="/help/unbundle">
2774 <a href="/help/unbundle">
2776 unbundle
2775 unbundle
2777 </a>
2776 </a>
2778 </td><td>
2777 </td><td>
2779 apply one or more bundle files
2778 apply one or more bundle files
2780 </td></tr>
2779 </td></tr>
2781 <tr><td>
2780 <tr><td>
2782 <a href="/help/unshelve">
2781 <a href="/help/unshelve">
2783 unshelve
2782 unshelve
2784 </a>
2783 </a>
2785 </td><td>
2784 </td><td>
2786 restore a shelved change to the working directory
2785 restore a shelved change to the working directory
2787 </td></tr>
2786 </td></tr>
2788 <tr><td>
2787 <tr><td>
2789 <a href="/help/verify">
2788 <a href="/help/verify">
2790 verify
2789 verify
2791 </a>
2790 </a>
2792 </td><td>
2791 </td><td>
2793 verify the integrity of the repository
2792 verify the integrity of the repository
2794 </td></tr>
2793 </td></tr>
2795 <tr><td>
2794 <tr><td>
2796 <a href="/help/version">
2795 <a href="/help/version">
2797 version
2796 version
2798 </a>
2797 </a>
2799 </td><td>
2798 </td><td>
2800 output version and copyright information
2799 output version and copyright information
2801 </td></tr>
2800 </td></tr>
2802
2801
2803
2802
2804 </table>
2803 </table>
2805 </div>
2804 </div>
2806 </div>
2805 </div>
2807
2806
2808
2807
2809
2808
2810 </body>
2809 </body>
2811 </html>
2810 </html>
2812
2811
2813
2812
2814 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2813 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2815 200 Script output follows
2814 200 Script output follows
2816
2815
2817 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2816 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2818 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2817 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2819 <head>
2818 <head>
2820 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2819 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2821 <meta name="robots" content="index, nofollow" />
2820 <meta name="robots" content="index, nofollow" />
2822 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2821 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2823 <script type="text/javascript" src="/static/mercurial.js"></script>
2822 <script type="text/javascript" src="/static/mercurial.js"></script>
2824
2823
2825 <title>Help: add</title>
2824 <title>Help: add</title>
2826 </head>
2825 </head>
2827 <body>
2826 <body>
2828
2827
2829 <div class="container">
2828 <div class="container">
2830 <div class="menu">
2829 <div class="menu">
2831 <div class="logo">
2830 <div class="logo">
2832 <a href="https://mercurial-scm.org/">
2831 <a href="https://mercurial-scm.org/">
2833 <img src="/static/hglogo.png" alt="mercurial" /></a>
2832 <img src="/static/hglogo.png" alt="mercurial" /></a>
2834 </div>
2833 </div>
2835 <ul>
2834 <ul>
2836 <li><a href="/shortlog">log</a></li>
2835 <li><a href="/shortlog">log</a></li>
2837 <li><a href="/graph">graph</a></li>
2836 <li><a href="/graph">graph</a></li>
2838 <li><a href="/tags">tags</a></li>
2837 <li><a href="/tags">tags</a></li>
2839 <li><a href="/bookmarks">bookmarks</a></li>
2838 <li><a href="/bookmarks">bookmarks</a></li>
2840 <li><a href="/branches">branches</a></li>
2839 <li><a href="/branches">branches</a></li>
2841 </ul>
2840 </ul>
2842 <ul>
2841 <ul>
2843 <li class="active"><a href="/help">help</a></li>
2842 <li class="active"><a href="/help">help</a></li>
2844 </ul>
2843 </ul>
2845 </div>
2844 </div>
2846
2845
2847 <div class="main">
2846 <div class="main">
2848 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2847 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2849 <h3>Help: add</h3>
2848 <h3>Help: add</h3>
2850
2849
2851 <form class="search" action="/log">
2850 <form class="search" action="/log">
2852
2851
2853 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2852 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2854 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2853 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2855 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2854 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2856 </form>
2855 </form>
2857 <div id="doc">
2856 <div id="doc">
2858 <p>
2857 <p>
2859 hg add [OPTION]... [FILE]...
2858 hg add [OPTION]... [FILE]...
2860 </p>
2859 </p>
2861 <p>
2860 <p>
2862 add the specified files on the next commit
2861 add the specified files on the next commit
2863 </p>
2862 </p>
2864 <p>
2863 <p>
2865 Schedule files to be version controlled and added to the
2864 Schedule files to be version controlled and added to the
2866 repository.
2865 repository.
2867 </p>
2866 </p>
2868 <p>
2867 <p>
2869 The files will be added to the repository at the next commit. To
2868 The files will be added to the repository at the next commit. To
2870 undo an add before that, see 'hg forget'.
2869 undo an add before that, see 'hg forget'.
2871 </p>
2870 </p>
2872 <p>
2871 <p>
2873 If no names are given, add all files to the repository (except
2872 If no names are given, add all files to the repository (except
2874 files matching &quot;.hgignore&quot;).
2873 files matching &quot;.hgignore&quot;).
2875 </p>
2874 </p>
2876 <p>
2875 <p>
2877 Examples:
2876 Examples:
2878 </p>
2877 </p>
2879 <ul>
2878 <ul>
2880 <li> New (unknown) files are added automatically by 'hg add':
2879 <li> New (unknown) files are added automatically by 'hg add':
2881 <pre>
2880 <pre>
2882 \$ ls (re)
2881 \$ ls (re)
2883 foo.c
2882 foo.c
2884 \$ hg status (re)
2883 \$ hg status (re)
2885 ? foo.c
2884 ? foo.c
2886 \$ hg add (re)
2885 \$ hg add (re)
2887 adding foo.c
2886 adding foo.c
2888 \$ hg status (re)
2887 \$ hg status (re)
2889 A foo.c
2888 A foo.c
2890 </pre>
2889 </pre>
2891 <li> Specific files to be added can be specified:
2890 <li> Specific files to be added can be specified:
2892 <pre>
2891 <pre>
2893 \$ ls (re)
2892 \$ ls (re)
2894 bar.c foo.c
2893 bar.c foo.c
2895 \$ hg status (re)
2894 \$ hg status (re)
2896 ? bar.c
2895 ? bar.c
2897 ? foo.c
2896 ? foo.c
2898 \$ hg add bar.c (re)
2897 \$ hg add bar.c (re)
2899 \$ hg status (re)
2898 \$ hg status (re)
2900 A bar.c
2899 A bar.c
2901 ? foo.c
2900 ? foo.c
2902 </pre>
2901 </pre>
2903 </ul>
2902 </ul>
2904 <p>
2903 <p>
2905 Returns 0 if all files are successfully added.
2904 Returns 0 if all files are successfully added.
2906 </p>
2905 </p>
2907 <p>
2906 <p>
2908 options ([+] can be repeated):
2907 options ([+] can be repeated):
2909 </p>
2908 </p>
2910 <table>
2909 <table>
2911 <tr><td>-I</td>
2910 <tr><td>-I</td>
2912 <td>--include PATTERN [+]</td>
2911 <td>--include PATTERN [+]</td>
2913 <td>include names matching the given patterns</td></tr>
2912 <td>include names matching the given patterns</td></tr>
2914 <tr><td>-X</td>
2913 <tr><td>-X</td>
2915 <td>--exclude PATTERN [+]</td>
2914 <td>--exclude PATTERN [+]</td>
2916 <td>exclude names matching the given patterns</td></tr>
2915 <td>exclude names matching the given patterns</td></tr>
2917 <tr><td>-S</td>
2916 <tr><td>-S</td>
2918 <td>--subrepos</td>
2917 <td>--subrepos</td>
2919 <td>recurse into subrepositories</td></tr>
2918 <td>recurse into subrepositories</td></tr>
2920 <tr><td>-n</td>
2919 <tr><td>-n</td>
2921 <td>--dry-run</td>
2920 <td>--dry-run</td>
2922 <td>do not perform actions, just print output</td></tr>
2921 <td>do not perform actions, just print output</td></tr>
2923 </table>
2922 </table>
2924 <p>
2923 <p>
2925 global options ([+] can be repeated):
2924 global options ([+] can be repeated):
2926 </p>
2925 </p>
2927 <table>
2926 <table>
2928 <tr><td>-R</td>
2927 <tr><td>-R</td>
2929 <td>--repository REPO</td>
2928 <td>--repository REPO</td>
2930 <td>repository root directory or name of overlay bundle file</td></tr>
2929 <td>repository root directory or name of overlay bundle file</td></tr>
2931 <tr><td></td>
2930 <tr><td></td>
2932 <td>--cwd DIR</td>
2931 <td>--cwd DIR</td>
2933 <td>change working directory</td></tr>
2932 <td>change working directory</td></tr>
2934 <tr><td>-y</td>
2933 <tr><td>-y</td>
2935 <td>--noninteractive</td>
2934 <td>--noninteractive</td>
2936 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2935 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2937 <tr><td>-q</td>
2936 <tr><td>-q</td>
2938 <td>--quiet</td>
2937 <td>--quiet</td>
2939 <td>suppress output</td></tr>
2938 <td>suppress output</td></tr>
2940 <tr><td>-v</td>
2939 <tr><td>-v</td>
2941 <td>--verbose</td>
2940 <td>--verbose</td>
2942 <td>enable additional output</td></tr>
2941 <td>enable additional output</td></tr>
2943 <tr><td></td>
2942 <tr><td></td>
2944 <td>--color TYPE</td>
2943 <td>--color TYPE</td>
2945 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2944 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2946 <tr><td></td>
2945 <tr><td></td>
2947 <td>--config CONFIG [+]</td>
2946 <td>--config CONFIG [+]</td>
2948 <td>set/override config option (use 'section.name=value')</td></tr>
2947 <td>set/override config option (use 'section.name=value')</td></tr>
2949 <tr><td></td>
2948 <tr><td></td>
2950 <td>--debug</td>
2949 <td>--debug</td>
2951 <td>enable debugging output</td></tr>
2950 <td>enable debugging output</td></tr>
2952 <tr><td></td>
2951 <tr><td></td>
2953 <td>--debugger</td>
2952 <td>--debugger</td>
2954 <td>start debugger</td></tr>
2953 <td>start debugger</td></tr>
2955 <tr><td></td>
2954 <tr><td></td>
2956 <td>--encoding ENCODE</td>
2955 <td>--encoding ENCODE</td>
2957 <td>set the charset encoding (default: ascii)</td></tr>
2956 <td>set the charset encoding (default: ascii)</td></tr>
2958 <tr><td></td>
2957 <tr><td></td>
2959 <td>--encodingmode MODE</td>
2958 <td>--encodingmode MODE</td>
2960 <td>set the charset encoding mode (default: strict)</td></tr>
2959 <td>set the charset encoding mode (default: strict)</td></tr>
2961 <tr><td></td>
2960 <tr><td></td>
2962 <td>--traceback</td>
2961 <td>--traceback</td>
2963 <td>always print a traceback on exception</td></tr>
2962 <td>always print a traceback on exception</td></tr>
2964 <tr><td></td>
2963 <tr><td></td>
2965 <td>--time</td>
2964 <td>--time</td>
2966 <td>time how long the command takes</td></tr>
2965 <td>time how long the command takes</td></tr>
2967 <tr><td></td>
2966 <tr><td></td>
2968 <td>--profile</td>
2967 <td>--profile</td>
2969 <td>print command execution profile</td></tr>
2968 <td>print command execution profile</td></tr>
2970 <tr><td></td>
2969 <tr><td></td>
2971 <td>--version</td>
2970 <td>--version</td>
2972 <td>output version information and exit</td></tr>
2971 <td>output version information and exit</td></tr>
2973 <tr><td>-h</td>
2972 <tr><td>-h</td>
2974 <td>--help</td>
2973 <td>--help</td>
2975 <td>display help and exit</td></tr>
2974 <td>display help and exit</td></tr>
2976 <tr><td></td>
2975 <tr><td></td>
2977 <td>--hidden</td>
2976 <td>--hidden</td>
2978 <td>consider hidden changesets</td></tr>
2977 <td>consider hidden changesets</td></tr>
2979 <tr><td></td>
2978 <tr><td></td>
2980 <td>--pager TYPE</td>
2979 <td>--pager TYPE</td>
2981 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2980 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2982 </table>
2981 </table>
2983
2982
2984 </div>
2983 </div>
2985 </div>
2984 </div>
2986 </div>
2985 </div>
2987
2986
2988
2987
2989
2988
2990 </body>
2989 </body>
2991 </html>
2990 </html>
2992
2991
2993
2992
2994 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2993 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2995 200 Script output follows
2994 200 Script output follows
2996
2995
2997 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2996 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2998 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2997 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2999 <head>
2998 <head>
3000 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2999 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3001 <meta name="robots" content="index, nofollow" />
3000 <meta name="robots" content="index, nofollow" />
3002 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3001 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3003 <script type="text/javascript" src="/static/mercurial.js"></script>
3002 <script type="text/javascript" src="/static/mercurial.js"></script>
3004
3003
3005 <title>Help: remove</title>
3004 <title>Help: remove</title>
3006 </head>
3005 </head>
3007 <body>
3006 <body>
3008
3007
3009 <div class="container">
3008 <div class="container">
3010 <div class="menu">
3009 <div class="menu">
3011 <div class="logo">
3010 <div class="logo">
3012 <a href="https://mercurial-scm.org/">
3011 <a href="https://mercurial-scm.org/">
3013 <img src="/static/hglogo.png" alt="mercurial" /></a>
3012 <img src="/static/hglogo.png" alt="mercurial" /></a>
3014 </div>
3013 </div>
3015 <ul>
3014 <ul>
3016 <li><a href="/shortlog">log</a></li>
3015 <li><a href="/shortlog">log</a></li>
3017 <li><a href="/graph">graph</a></li>
3016 <li><a href="/graph">graph</a></li>
3018 <li><a href="/tags">tags</a></li>
3017 <li><a href="/tags">tags</a></li>
3019 <li><a href="/bookmarks">bookmarks</a></li>
3018 <li><a href="/bookmarks">bookmarks</a></li>
3020 <li><a href="/branches">branches</a></li>
3019 <li><a href="/branches">branches</a></li>
3021 </ul>
3020 </ul>
3022 <ul>
3021 <ul>
3023 <li class="active"><a href="/help">help</a></li>
3022 <li class="active"><a href="/help">help</a></li>
3024 </ul>
3023 </ul>
3025 </div>
3024 </div>
3026
3025
3027 <div class="main">
3026 <div class="main">
3028 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3027 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3029 <h3>Help: remove</h3>
3028 <h3>Help: remove</h3>
3030
3029
3031 <form class="search" action="/log">
3030 <form class="search" action="/log">
3032
3031
3033 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3032 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3034 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3033 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3035 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3034 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3036 </form>
3035 </form>
3037 <div id="doc">
3036 <div id="doc">
3038 <p>
3037 <p>
3039 hg remove [OPTION]... FILE...
3038 hg remove [OPTION]... FILE...
3040 </p>
3039 </p>
3041 <p>
3040 <p>
3042 aliases: rm
3041 aliases: rm
3043 </p>
3042 </p>
3044 <p>
3043 <p>
3045 remove the specified files on the next commit
3044 remove the specified files on the next commit
3046 </p>
3045 </p>
3047 <p>
3046 <p>
3048 Schedule the indicated files for removal from the current branch.
3047 Schedule the indicated files for removal from the current branch.
3049 </p>
3048 </p>
3050 <p>
3049 <p>
3051 This command schedules the files to be removed at the next commit.
3050 This command schedules the files to be removed at the next commit.
3052 To undo a remove before that, see 'hg revert'. To undo added
3051 To undo a remove before that, see 'hg revert'. To undo added
3053 files, see 'hg forget'.
3052 files, see 'hg forget'.
3054 </p>
3053 </p>
3055 <p>
3054 <p>
3056 -A/--after can be used to remove only files that have already
3055 -A/--after can be used to remove only files that have already
3057 been deleted, -f/--force can be used to force deletion, and -Af
3056 been deleted, -f/--force can be used to force deletion, and -Af
3058 can be used to remove files from the next revision without
3057 can be used to remove files from the next revision without
3059 deleting them from the working directory.
3058 deleting them from the working directory.
3060 </p>
3059 </p>
3061 <p>
3060 <p>
3062 The following table details the behavior of remove for different
3061 The following table details the behavior of remove for different
3063 file states (columns) and option combinations (rows). The file
3062 file states (columns) and option combinations (rows). The file
3064 states are Added [A], Clean [C], Modified [M] and Missing [!]
3063 states are Added [A], Clean [C], Modified [M] and Missing [!]
3065 (as reported by 'hg status'). The actions are Warn, Remove
3064 (as reported by 'hg status'). The actions are Warn, Remove
3066 (from branch) and Delete (from disk):
3065 (from branch) and Delete (from disk):
3067 </p>
3066 </p>
3068 <table>
3067 <table>
3069 <tr><td>opt/state</td>
3068 <tr><td>opt/state</td>
3070 <td>A</td>
3069 <td>A</td>
3071 <td>C</td>
3070 <td>C</td>
3072 <td>M</td>
3071 <td>M</td>
3073 <td>!</td></tr>
3072 <td>!</td></tr>
3074 <tr><td>none</td>
3073 <tr><td>none</td>
3075 <td>W</td>
3074 <td>W</td>
3076 <td>RD</td>
3075 <td>RD</td>
3077 <td>W</td>
3076 <td>W</td>
3078 <td>R</td></tr>
3077 <td>R</td></tr>
3079 <tr><td>-f</td>
3078 <tr><td>-f</td>
3080 <td>R</td>
3079 <td>R</td>
3081 <td>RD</td>
3080 <td>RD</td>
3082 <td>RD</td>
3081 <td>RD</td>
3083 <td>R</td></tr>
3082 <td>R</td></tr>
3084 <tr><td>-A</td>
3083 <tr><td>-A</td>
3085 <td>W</td>
3084 <td>W</td>
3086 <td>W</td>
3085 <td>W</td>
3087 <td>W</td>
3086 <td>W</td>
3088 <td>R</td></tr>
3087 <td>R</td></tr>
3089 <tr><td>-Af</td>
3088 <tr><td>-Af</td>
3090 <td>R</td>
3089 <td>R</td>
3091 <td>R</td>
3090 <td>R</td>
3092 <td>R</td>
3091 <td>R</td>
3093 <td>R</td></tr>
3092 <td>R</td></tr>
3094 </table>
3093 </table>
3095 <p>
3094 <p>
3096 <b>Note:</b>
3095 <b>Note:</b>
3097 </p>
3096 </p>
3098 <p>
3097 <p>
3099 'hg remove' never deletes files in Added [A] state from the
3098 'hg remove' never deletes files in Added [A] state from the
3100 working directory, not even if &quot;--force&quot; is specified.
3099 working directory, not even if &quot;--force&quot; is specified.
3101 </p>
3100 </p>
3102 <p>
3101 <p>
3103 Returns 0 on success, 1 if any warnings encountered.
3102 Returns 0 on success, 1 if any warnings encountered.
3104 </p>
3103 </p>
3105 <p>
3104 <p>
3106 options ([+] can be repeated):
3105 options ([+] can be repeated):
3107 </p>
3106 </p>
3108 <table>
3107 <table>
3109 <tr><td>-A</td>
3108 <tr><td>-A</td>
3110 <td>--after</td>
3109 <td>--after</td>
3111 <td>record delete for missing files</td></tr>
3110 <td>record delete for missing files</td></tr>
3112 <tr><td>-f</td>
3111 <tr><td>-f</td>
3113 <td>--force</td>
3112 <td>--force</td>
3114 <td>forget added files, delete modified files</td></tr>
3113 <td>forget added files, delete modified files</td></tr>
3115 <tr><td>-S</td>
3114 <tr><td>-S</td>
3116 <td>--subrepos</td>
3115 <td>--subrepos</td>
3117 <td>recurse into subrepositories</td></tr>
3116 <td>recurse into subrepositories</td></tr>
3118 <tr><td>-I</td>
3117 <tr><td>-I</td>
3119 <td>--include PATTERN [+]</td>
3118 <td>--include PATTERN [+]</td>
3120 <td>include names matching the given patterns</td></tr>
3119 <td>include names matching the given patterns</td></tr>
3121 <tr><td>-X</td>
3120 <tr><td>-X</td>
3122 <td>--exclude PATTERN [+]</td>
3121 <td>--exclude PATTERN [+]</td>
3123 <td>exclude names matching the given patterns</td></tr>
3122 <td>exclude names matching the given patterns</td></tr>
3124 <tr><td>-n</td>
3123 <tr><td>-n</td>
3125 <td>--dry-run</td>
3124 <td>--dry-run</td>
3126 <td>do not perform actions, just print output</td></tr>
3125 <td>do not perform actions, just print output</td></tr>
3127 </table>
3126 </table>
3128 <p>
3127 <p>
3129 global options ([+] can be repeated):
3128 global options ([+] can be repeated):
3130 </p>
3129 </p>
3131 <table>
3130 <table>
3132 <tr><td>-R</td>
3131 <tr><td>-R</td>
3133 <td>--repository REPO</td>
3132 <td>--repository REPO</td>
3134 <td>repository root directory or name of overlay bundle file</td></tr>
3133 <td>repository root directory or name of overlay bundle file</td></tr>
3135 <tr><td></td>
3134 <tr><td></td>
3136 <td>--cwd DIR</td>
3135 <td>--cwd DIR</td>
3137 <td>change working directory</td></tr>
3136 <td>change working directory</td></tr>
3138 <tr><td>-y</td>
3137 <tr><td>-y</td>
3139 <td>--noninteractive</td>
3138 <td>--noninteractive</td>
3140 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3139 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3141 <tr><td>-q</td>
3140 <tr><td>-q</td>
3142 <td>--quiet</td>
3141 <td>--quiet</td>
3143 <td>suppress output</td></tr>
3142 <td>suppress output</td></tr>
3144 <tr><td>-v</td>
3143 <tr><td>-v</td>
3145 <td>--verbose</td>
3144 <td>--verbose</td>
3146 <td>enable additional output</td></tr>
3145 <td>enable additional output</td></tr>
3147 <tr><td></td>
3146 <tr><td></td>
3148 <td>--color TYPE</td>
3147 <td>--color TYPE</td>
3149 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3148 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3150 <tr><td></td>
3149 <tr><td></td>
3151 <td>--config CONFIG [+]</td>
3150 <td>--config CONFIG [+]</td>
3152 <td>set/override config option (use 'section.name=value')</td></tr>
3151 <td>set/override config option (use 'section.name=value')</td></tr>
3153 <tr><td></td>
3152 <tr><td></td>
3154 <td>--debug</td>
3153 <td>--debug</td>
3155 <td>enable debugging output</td></tr>
3154 <td>enable debugging output</td></tr>
3156 <tr><td></td>
3155 <tr><td></td>
3157 <td>--debugger</td>
3156 <td>--debugger</td>
3158 <td>start debugger</td></tr>
3157 <td>start debugger</td></tr>
3159 <tr><td></td>
3158 <tr><td></td>
3160 <td>--encoding ENCODE</td>
3159 <td>--encoding ENCODE</td>
3161 <td>set the charset encoding (default: ascii)</td></tr>
3160 <td>set the charset encoding (default: ascii)</td></tr>
3162 <tr><td></td>
3161 <tr><td></td>
3163 <td>--encodingmode MODE</td>
3162 <td>--encodingmode MODE</td>
3164 <td>set the charset encoding mode (default: strict)</td></tr>
3163 <td>set the charset encoding mode (default: strict)</td></tr>
3165 <tr><td></td>
3164 <tr><td></td>
3166 <td>--traceback</td>
3165 <td>--traceback</td>
3167 <td>always print a traceback on exception</td></tr>
3166 <td>always print a traceback on exception</td></tr>
3168 <tr><td></td>
3167 <tr><td></td>
3169 <td>--time</td>
3168 <td>--time</td>
3170 <td>time how long the command takes</td></tr>
3169 <td>time how long the command takes</td></tr>
3171 <tr><td></td>
3170 <tr><td></td>
3172 <td>--profile</td>
3171 <td>--profile</td>
3173 <td>print command execution profile</td></tr>
3172 <td>print command execution profile</td></tr>
3174 <tr><td></td>
3173 <tr><td></td>
3175 <td>--version</td>
3174 <td>--version</td>
3176 <td>output version information and exit</td></tr>
3175 <td>output version information and exit</td></tr>
3177 <tr><td>-h</td>
3176 <tr><td>-h</td>
3178 <td>--help</td>
3177 <td>--help</td>
3179 <td>display help and exit</td></tr>
3178 <td>display help and exit</td></tr>
3180 <tr><td></td>
3179 <tr><td></td>
3181 <td>--hidden</td>
3180 <td>--hidden</td>
3182 <td>consider hidden changesets</td></tr>
3181 <td>consider hidden changesets</td></tr>
3183 <tr><td></td>
3182 <tr><td></td>
3184 <td>--pager TYPE</td>
3183 <td>--pager TYPE</td>
3185 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3184 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3186 </table>
3185 </table>
3187
3186
3188 </div>
3187 </div>
3189 </div>
3188 </div>
3190 </div>
3189 </div>
3191
3190
3192
3191
3193
3192
3194 </body>
3193 </body>
3195 </html>
3194 </html>
3196
3195
3197
3196
3198 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3197 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3199 200 Script output follows
3198 200 Script output follows
3200
3199
3201 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3200 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3202 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3201 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3203 <head>
3202 <head>
3204 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3203 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3205 <meta name="robots" content="index, nofollow" />
3204 <meta name="robots" content="index, nofollow" />
3206 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3205 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3207 <script type="text/javascript" src="/static/mercurial.js"></script>
3206 <script type="text/javascript" src="/static/mercurial.js"></script>
3208
3207
3209 <title>Help: dates</title>
3208 <title>Help: dates</title>
3210 </head>
3209 </head>
3211 <body>
3210 <body>
3212
3211
3213 <div class="container">
3212 <div class="container">
3214 <div class="menu">
3213 <div class="menu">
3215 <div class="logo">
3214 <div class="logo">
3216 <a href="https://mercurial-scm.org/">
3215 <a href="https://mercurial-scm.org/">
3217 <img src="/static/hglogo.png" alt="mercurial" /></a>
3216 <img src="/static/hglogo.png" alt="mercurial" /></a>
3218 </div>
3217 </div>
3219 <ul>
3218 <ul>
3220 <li><a href="/shortlog">log</a></li>
3219 <li><a href="/shortlog">log</a></li>
3221 <li><a href="/graph">graph</a></li>
3220 <li><a href="/graph">graph</a></li>
3222 <li><a href="/tags">tags</a></li>
3221 <li><a href="/tags">tags</a></li>
3223 <li><a href="/bookmarks">bookmarks</a></li>
3222 <li><a href="/bookmarks">bookmarks</a></li>
3224 <li><a href="/branches">branches</a></li>
3223 <li><a href="/branches">branches</a></li>
3225 </ul>
3224 </ul>
3226 <ul>
3225 <ul>
3227 <li class="active"><a href="/help">help</a></li>
3226 <li class="active"><a href="/help">help</a></li>
3228 </ul>
3227 </ul>
3229 </div>
3228 </div>
3230
3229
3231 <div class="main">
3230 <div class="main">
3232 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3231 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3233 <h3>Help: dates</h3>
3232 <h3>Help: dates</h3>
3234
3233
3235 <form class="search" action="/log">
3234 <form class="search" action="/log">
3236
3235
3237 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3236 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3238 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3237 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3239 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3238 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3240 </form>
3239 </form>
3241 <div id="doc">
3240 <div id="doc">
3242 <h1>Date Formats</h1>
3241 <h1>Date Formats</h1>
3243 <p>
3242 <p>
3244 Some commands allow the user to specify a date, e.g.:
3243 Some commands allow the user to specify a date, e.g.:
3245 </p>
3244 </p>
3246 <ul>
3245 <ul>
3247 <li> backout, commit, import, tag: Specify the commit date.
3246 <li> backout, commit, import, tag: Specify the commit date.
3248 <li> log, revert, update: Select revision(s) by date.
3247 <li> log, revert, update: Select revision(s) by date.
3249 </ul>
3248 </ul>
3250 <p>
3249 <p>
3251 Many date formats are valid. Here are some examples:
3250 Many date formats are valid. Here are some examples:
3252 </p>
3251 </p>
3253 <ul>
3252 <ul>
3254 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3253 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3255 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3254 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3256 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3255 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3257 <li> &quot;Dec 6&quot; (midnight)
3256 <li> &quot;Dec 6&quot; (midnight)
3258 <li> &quot;13:18&quot; (today assumed)
3257 <li> &quot;13:18&quot; (today assumed)
3259 <li> &quot;3:39&quot; (3:39AM assumed)
3258 <li> &quot;3:39&quot; (3:39AM assumed)
3260 <li> &quot;3:39pm&quot; (15:39)
3259 <li> &quot;3:39pm&quot; (15:39)
3261 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3260 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3262 <li> &quot;2006-12-6 13:18&quot;
3261 <li> &quot;2006-12-6 13:18&quot;
3263 <li> &quot;2006-12-6&quot;
3262 <li> &quot;2006-12-6&quot;
3264 <li> &quot;12-6&quot;
3263 <li> &quot;12-6&quot;
3265 <li> &quot;12/6&quot;
3264 <li> &quot;12/6&quot;
3266 <li> &quot;12/6/6&quot; (Dec 6 2006)
3265 <li> &quot;12/6/6&quot; (Dec 6 2006)
3267 <li> &quot;today&quot; (midnight)
3266 <li> &quot;today&quot; (midnight)
3268 <li> &quot;yesterday&quot; (midnight)
3267 <li> &quot;yesterday&quot; (midnight)
3269 <li> &quot;now&quot; - right now
3268 <li> &quot;now&quot; - right now
3270 </ul>
3269 </ul>
3271 <p>
3270 <p>
3272 Lastly, there is Mercurial's internal format:
3271 Lastly, there is Mercurial's internal format:
3273 </p>
3272 </p>
3274 <ul>
3273 <ul>
3275 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3274 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3276 </ul>
3275 </ul>
3277 <p>
3276 <p>
3278 This is the internal representation format for dates. The first number
3277 This is the internal representation format for dates. The first number
3279 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3278 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3280 second is the offset of the local timezone, in seconds west of UTC
3279 second is the offset of the local timezone, in seconds west of UTC
3281 (negative if the timezone is east of UTC).
3280 (negative if the timezone is east of UTC).
3282 </p>
3281 </p>
3283 <p>
3282 <p>
3284 The log command also accepts date ranges:
3283 The log command also accepts date ranges:
3285 </p>
3284 </p>
3286 <ul>
3285 <ul>
3287 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3286 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3288 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3287 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3289 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3288 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3290 <li> &quot;-DAYS&quot; - within a given number of days from today
3289 <li> &quot;-DAYS&quot; - within a given number of days from today
3291 </ul>
3290 </ul>
3292
3291
3293 </div>
3292 </div>
3294 </div>
3293 </div>
3295 </div>
3294 </div>
3296
3295
3297
3296
3298
3297
3299 </body>
3298 </body>
3300 </html>
3299 </html>
3301
3300
3302
3301
3303 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3302 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3304 200 Script output follows
3303 200 Script output follows
3305
3304
3306 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3305 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3307 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3306 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3308 <head>
3307 <head>
3309 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3308 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3310 <meta name="robots" content="index, nofollow" />
3309 <meta name="robots" content="index, nofollow" />
3311 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3310 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3312 <script type="text/javascript" src="/static/mercurial.js"></script>
3311 <script type="text/javascript" src="/static/mercurial.js"></script>
3313
3312
3314 <title>Help: pager</title>
3313 <title>Help: pager</title>
3315 </head>
3314 </head>
3316 <body>
3315 <body>
3317
3316
3318 <div class="container">
3317 <div class="container">
3319 <div class="menu">
3318 <div class="menu">
3320 <div class="logo">
3319 <div class="logo">
3321 <a href="https://mercurial-scm.org/">
3320 <a href="https://mercurial-scm.org/">
3322 <img src="/static/hglogo.png" alt="mercurial" /></a>
3321 <img src="/static/hglogo.png" alt="mercurial" /></a>
3323 </div>
3322 </div>
3324 <ul>
3323 <ul>
3325 <li><a href="/shortlog">log</a></li>
3324 <li><a href="/shortlog">log</a></li>
3326 <li><a href="/graph">graph</a></li>
3325 <li><a href="/graph">graph</a></li>
3327 <li><a href="/tags">tags</a></li>
3326 <li><a href="/tags">tags</a></li>
3328 <li><a href="/bookmarks">bookmarks</a></li>
3327 <li><a href="/bookmarks">bookmarks</a></li>
3329 <li><a href="/branches">branches</a></li>
3328 <li><a href="/branches">branches</a></li>
3330 </ul>
3329 </ul>
3331 <ul>
3330 <ul>
3332 <li class="active"><a href="/help">help</a></li>
3331 <li class="active"><a href="/help">help</a></li>
3333 </ul>
3332 </ul>
3334 </div>
3333 </div>
3335
3334
3336 <div class="main">
3335 <div class="main">
3337 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3336 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3338 <h3>Help: pager</h3>
3337 <h3>Help: pager</h3>
3339
3338
3340 <form class="search" action="/log">
3339 <form class="search" action="/log">
3341
3340
3342 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3341 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3343 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3342 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3344 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3343 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3345 </form>
3344 </form>
3346 <div id="doc">
3345 <div id="doc">
3347 <h1>Pager Support</h1>
3346 <h1>Pager Support</h1>
3348 <p>
3347 <p>
3349 Some Mercurial commands can produce a lot of output, and Mercurial will
3348 Some Mercurial commands can produce a lot of output, and Mercurial will
3350 attempt to use a pager to make those commands more pleasant.
3349 attempt to use a pager to make those commands more pleasant.
3351 </p>
3350 </p>
3352 <p>
3351 <p>
3353 To set the pager that should be used, set the application variable:
3352 To set the pager that should be used, set the application variable:
3354 </p>
3353 </p>
3355 <pre>
3354 <pre>
3356 [pager]
3355 [pager]
3357 pager = less -FRX
3356 pager = less -FRX
3358 </pre>
3357 </pre>
3359 <p>
3358 <p>
3360 If no pager is set in the user or repository configuration, Mercurial uses the
3359 If no pager is set in the user or repository configuration, Mercurial uses the
3361 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3360 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3362 or system configuration is used. If none of these are set, a default pager will
3361 or system configuration is used. If none of these are set, a default pager will
3363 be used, typically 'less' on Unix and 'more' on Windows.
3362 be used, typically 'less' on Unix and 'more' on Windows.
3364 </p>
3363 </p>
3365 <p>
3364 <p>
3366 You can disable the pager for certain commands by adding them to the
3365 You can disable the pager for certain commands by adding them to the
3367 pager.ignore list:
3366 pager.ignore list:
3368 </p>
3367 </p>
3369 <pre>
3368 <pre>
3370 [pager]
3369 [pager]
3371 ignore = version, help, update
3370 ignore = version, help, update
3372 </pre>
3371 </pre>
3373 <p>
3372 <p>
3374 To ignore global commands like 'hg version' or 'hg help', you have
3373 To ignore global commands like 'hg version' or 'hg help', you have
3375 to specify them in your user configuration file.
3374 to specify them in your user configuration file.
3376 </p>
3375 </p>
3377 <p>
3376 <p>
3378 To control whether the pager is used at all for an individual command,
3377 To control whether the pager is used at all for an individual command,
3379 you can use --pager=&lt;value&gt;:
3378 you can use --pager=&lt;value&gt;:
3380 </p>
3379 </p>
3381 <ul>
3380 <ul>
3382 <li> use as needed: 'auto'.
3381 <li> use as needed: 'auto'.
3383 <li> require the pager: 'yes' or 'on'.
3382 <li> require the pager: 'yes' or 'on'.
3384 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3383 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3385 </ul>
3384 </ul>
3386 <p>
3385 <p>
3387 To globally turn off all attempts to use a pager, set:
3386 To globally turn off all attempts to use a pager, set:
3388 </p>
3387 </p>
3389 <pre>
3388 <pre>
3390 [ui]
3389 [ui]
3391 paginate = never
3390 paginate = never
3392 </pre>
3391 </pre>
3393 <p>
3392 <p>
3394 which will prevent the pager from running.
3393 which will prevent the pager from running.
3395 </p>
3394 </p>
3396
3395
3397 </div>
3396 </div>
3398 </div>
3397 </div>
3399 </div>
3398 </div>
3400
3399
3401
3400
3402
3401
3403 </body>
3402 </body>
3404 </html>
3403 </html>
3405
3404
3406
3405
3407 Sub-topic indexes rendered properly
3406 Sub-topic indexes rendered properly
3408
3407
3409 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3408 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3410 200 Script output follows
3409 200 Script output follows
3411
3410
3412 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3411 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3413 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3412 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3414 <head>
3413 <head>
3415 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3414 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3416 <meta name="robots" content="index, nofollow" />
3415 <meta name="robots" content="index, nofollow" />
3417 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3416 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3418 <script type="text/javascript" src="/static/mercurial.js"></script>
3417 <script type="text/javascript" src="/static/mercurial.js"></script>
3419
3418
3420 <title>Help: internals</title>
3419 <title>Help: internals</title>
3421 </head>
3420 </head>
3422 <body>
3421 <body>
3423
3422
3424 <div class="container">
3423 <div class="container">
3425 <div class="menu">
3424 <div class="menu">
3426 <div class="logo">
3425 <div class="logo">
3427 <a href="https://mercurial-scm.org/">
3426 <a href="https://mercurial-scm.org/">
3428 <img src="/static/hglogo.png" alt="mercurial" /></a>
3427 <img src="/static/hglogo.png" alt="mercurial" /></a>
3429 </div>
3428 </div>
3430 <ul>
3429 <ul>
3431 <li><a href="/shortlog">log</a></li>
3430 <li><a href="/shortlog">log</a></li>
3432 <li><a href="/graph">graph</a></li>
3431 <li><a href="/graph">graph</a></li>
3433 <li><a href="/tags">tags</a></li>
3432 <li><a href="/tags">tags</a></li>
3434 <li><a href="/bookmarks">bookmarks</a></li>
3433 <li><a href="/bookmarks">bookmarks</a></li>
3435 <li><a href="/branches">branches</a></li>
3434 <li><a href="/branches">branches</a></li>
3436 </ul>
3435 </ul>
3437 <ul>
3436 <ul>
3438 <li><a href="/help">help</a></li>
3437 <li><a href="/help">help</a></li>
3439 </ul>
3438 </ul>
3440 </div>
3439 </div>
3441
3440
3442 <div class="main">
3441 <div class="main">
3443 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3442 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3444
3443
3445 <form class="search" action="/log">
3444 <form class="search" action="/log">
3446
3445
3447 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3446 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3448 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3447 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3449 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3448 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3450 </form>
3449 </form>
3451 <table class="bigtable">
3450 <table class="bigtable">
3452 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3451 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3453
3452
3454 <tr><td>
3453 <tr><td>
3455 <a href="/help/internals.bid-merge">
3454 <a href="/help/internals.bid-merge">
3456 bid-merge
3455 bid-merge
3457 </a>
3456 </a>
3458 </td><td>
3457 </td><td>
3459 Bid Merge Algorithm
3458 Bid Merge Algorithm
3460 </td></tr>
3459 </td></tr>
3461 <tr><td>
3460 <tr><td>
3462 <a href="/help/internals.bundle2">
3461 <a href="/help/internals.bundle2">
3463 bundle2
3462 bundle2
3464 </a>
3463 </a>
3465 </td><td>
3464 </td><td>
3466 Bundle2
3465 Bundle2
3467 </td></tr>
3466 </td></tr>
3468 <tr><td>
3467 <tr><td>
3469 <a href="/help/internals.bundles">
3468 <a href="/help/internals.bundles">
3470 bundles
3469 bundles
3471 </a>
3470 </a>
3472 </td><td>
3471 </td><td>
3473 Bundles
3472 Bundles
3474 </td></tr>
3473 </td></tr>
3475 <tr><td>
3474 <tr><td>
3476 <a href="/help/internals.cbor">
3475 <a href="/help/internals.cbor">
3477 cbor
3476 cbor
3478 </a>
3477 </a>
3479 </td><td>
3478 </td><td>
3480 CBOR
3479 CBOR
3481 </td></tr>
3480 </td></tr>
3482 <tr><td>
3481 <tr><td>
3483 <a href="/help/internals.censor">
3482 <a href="/help/internals.censor">
3484 censor
3483 censor
3485 </a>
3484 </a>
3486 </td><td>
3485 </td><td>
3487 Censor
3486 Censor
3488 </td></tr>
3487 </td></tr>
3489 <tr><td>
3488 <tr><td>
3490 <a href="/help/internals.changegroups">
3489 <a href="/help/internals.changegroups">
3491 changegroups
3490 changegroups
3492 </a>
3491 </a>
3493 </td><td>
3492 </td><td>
3494 Changegroups
3493 Changegroups
3495 </td></tr>
3494 </td></tr>
3496 <tr><td>
3495 <tr><td>
3497 <a href="/help/internals.config">
3496 <a href="/help/internals.config">
3498 config
3497 config
3499 </a>
3498 </a>
3500 </td><td>
3499 </td><td>
3501 Config Registrar
3500 Config Registrar
3502 </td></tr>
3501 </td></tr>
3503 <tr><td>
3502 <tr><td>
3504 <a href="/help/internals.extensions">
3503 <a href="/help/internals.extensions">
3505 extensions
3504 extensions
3506 </a>
3505 </a>
3507 </td><td>
3506 </td><td>
3508 Extension API
3507 Extension API
3509 </td></tr>
3508 </td></tr>
3510 <tr><td>
3509 <tr><td>
3511 <a href="/help/internals.mergestate">
3510 <a href="/help/internals.mergestate">
3512 mergestate
3511 mergestate
3513 </a>
3512 </a>
3514 </td><td>
3513 </td><td>
3515 Mergestate
3514 Mergestate
3516 </td></tr>
3515 </td></tr>
3517 <tr><td>
3516 <tr><td>
3518 <a href="/help/internals.requirements">
3517 <a href="/help/internals.requirements">
3519 requirements
3518 requirements
3520 </a>
3519 </a>
3521 </td><td>
3520 </td><td>
3522 Repository Requirements
3521 Repository Requirements
3523 </td></tr>
3522 </td></tr>
3524 <tr><td>
3523 <tr><td>
3525 <a href="/help/internals.revlogs">
3524 <a href="/help/internals.revlogs">
3526 revlogs
3525 revlogs
3527 </a>
3526 </a>
3528 </td><td>
3527 </td><td>
3529 Revision Logs
3528 Revision Logs
3530 </td></tr>
3529 </td></tr>
3531 <tr><td>
3530 <tr><td>
3532 <a href="/help/internals.wireprotocol">
3531 <a href="/help/internals.wireprotocol">
3533 wireprotocol
3532 wireprotocol
3534 </a>
3533 </a>
3535 </td><td>
3534 </td><td>
3536 Wire Protocol
3535 Wire Protocol
3537 </td></tr>
3536 </td></tr>
3538 <tr><td>
3537 <tr><td>
3539 <a href="/help/internals.wireprotocolrpc">
3538 <a href="/help/internals.wireprotocolrpc">
3540 wireprotocolrpc
3539 wireprotocolrpc
3541 </a>
3540 </a>
3542 </td><td>
3541 </td><td>
3543 Wire Protocol RPC
3542 Wire Protocol RPC
3544 </td></tr>
3543 </td></tr>
3545 <tr><td>
3544 <tr><td>
3546 <a href="/help/internals.wireprotocolv2">
3545 <a href="/help/internals.wireprotocolv2">
3547 wireprotocolv2
3546 wireprotocolv2
3548 </a>
3547 </a>
3549 </td><td>
3548 </td><td>
3550 Wire Protocol Version 2
3549 Wire Protocol Version 2
3551 </td></tr>
3550 </td></tr>
3552
3551
3553
3552
3554
3553
3555
3554
3556
3555
3557 </table>
3556 </table>
3558 </div>
3557 </div>
3559 </div>
3558 </div>
3560
3559
3561
3560
3562
3561
3563 </body>
3562 </body>
3564 </html>
3563 </html>
3565
3564
3566
3565
3567 Sub-topic topics rendered properly
3566 Sub-topic topics rendered properly
3568
3567
3569 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3568 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3570 200 Script output follows
3569 200 Script output follows
3571
3570
3572 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3571 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3573 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3572 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3574 <head>
3573 <head>
3575 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3574 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3576 <meta name="robots" content="index, nofollow" />
3575 <meta name="robots" content="index, nofollow" />
3577 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3576 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3578 <script type="text/javascript" src="/static/mercurial.js"></script>
3577 <script type="text/javascript" src="/static/mercurial.js"></script>
3579
3578
3580 <title>Help: internals.changegroups</title>
3579 <title>Help: internals.changegroups</title>
3581 </head>
3580 </head>
3582 <body>
3581 <body>
3583
3582
3584 <div class="container">
3583 <div class="container">
3585 <div class="menu">
3584 <div class="menu">
3586 <div class="logo">
3585 <div class="logo">
3587 <a href="https://mercurial-scm.org/">
3586 <a href="https://mercurial-scm.org/">
3588 <img src="/static/hglogo.png" alt="mercurial" /></a>
3587 <img src="/static/hglogo.png" alt="mercurial" /></a>
3589 </div>
3588 </div>
3590 <ul>
3589 <ul>
3591 <li><a href="/shortlog">log</a></li>
3590 <li><a href="/shortlog">log</a></li>
3592 <li><a href="/graph">graph</a></li>
3591 <li><a href="/graph">graph</a></li>
3593 <li><a href="/tags">tags</a></li>
3592 <li><a href="/tags">tags</a></li>
3594 <li><a href="/bookmarks">bookmarks</a></li>
3593 <li><a href="/bookmarks">bookmarks</a></li>
3595 <li><a href="/branches">branches</a></li>
3594 <li><a href="/branches">branches</a></li>
3596 </ul>
3595 </ul>
3597 <ul>
3596 <ul>
3598 <li class="active"><a href="/help">help</a></li>
3597 <li class="active"><a href="/help">help</a></li>
3599 </ul>
3598 </ul>
3600 </div>
3599 </div>
3601
3600
3602 <div class="main">
3601 <div class="main">
3603 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3602 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3604 <h3>Help: internals.changegroups</h3>
3603 <h3>Help: internals.changegroups</h3>
3605
3604
3606 <form class="search" action="/log">
3605 <form class="search" action="/log">
3607
3606
3608 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3607 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3609 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3608 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3610 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3609 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3611 </form>
3610 </form>
3612 <div id="doc">
3611 <div id="doc">
3613 <h1>Changegroups</h1>
3612 <h1>Changegroups</h1>
3614 <p>
3613 <p>
3615 Changegroups are representations of repository revlog data, specifically
3614 Changegroups are representations of repository revlog data, specifically
3616 the changelog data, root/flat manifest data, treemanifest data, and
3615 the changelog data, root/flat manifest data, treemanifest data, and
3617 filelogs.
3616 filelogs.
3618 </p>
3617 </p>
3619 <p>
3618 <p>
3620 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3619 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3621 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3620 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3622 only difference being an additional item in the *delta header*. Version
3621 only difference being an additional item in the *delta header*. Version
3623 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3622 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3624 exchanging treemanifests (enabled by setting an option on the
3623 exchanging treemanifests (enabled by setting an option on the
3625 &quot;changegroup&quot; part in the bundle2).
3624 &quot;changegroup&quot; part in the bundle2).
3626 </p>
3625 </p>
3627 <p>
3626 <p>
3628 Changegroups when not exchanging treemanifests consist of 3 logical
3627 Changegroups when not exchanging treemanifests consist of 3 logical
3629 segments:
3628 segments:
3630 </p>
3629 </p>
3631 <pre>
3630 <pre>
3632 +---------------------------------+
3631 +---------------------------------+
3633 | | | |
3632 | | | |
3634 | changeset | manifest | filelogs |
3633 | changeset | manifest | filelogs |
3635 | | | |
3634 | | | |
3636 | | | |
3635 | | | |
3637 +---------------------------------+
3636 +---------------------------------+
3638 </pre>
3637 </pre>
3639 <p>
3638 <p>
3640 When exchanging treemanifests, there are 4 logical segments:
3639 When exchanging treemanifests, there are 4 logical segments:
3641 </p>
3640 </p>
3642 <pre>
3641 <pre>
3643 +-------------------------------------------------+
3642 +-------------------------------------------------+
3644 | | | | |
3643 | | | | |
3645 | changeset | root | treemanifests | filelogs |
3644 | changeset | root | treemanifests | filelogs |
3646 | | manifest | | |
3645 | | manifest | | |
3647 | | | | |
3646 | | | | |
3648 +-------------------------------------------------+
3647 +-------------------------------------------------+
3649 </pre>
3648 </pre>
3650 <p>
3649 <p>
3651 The principle building block of each segment is a *chunk*. A *chunk*
3650 The principle building block of each segment is a *chunk*. A *chunk*
3652 is a framed piece of data:
3651 is a framed piece of data:
3653 </p>
3652 </p>
3654 <pre>
3653 <pre>
3655 +---------------------------------------+
3654 +---------------------------------------+
3656 | | |
3655 | | |
3657 | length | data |
3656 | length | data |
3658 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3657 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3659 | | |
3658 | | |
3660 +---------------------------------------+
3659 +---------------------------------------+
3661 </pre>
3660 </pre>
3662 <p>
3661 <p>
3663 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3662 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3664 integer indicating the length of the entire chunk (including the length field
3663 integer indicating the length of the entire chunk (including the length field
3665 itself).
3664 itself).
3666 </p>
3665 </p>
3667 <p>
3666 <p>
3668 There is a special case chunk that has a value of 0 for the length
3667 There is a special case chunk that has a value of 0 for the length
3669 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3668 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3670 </p>
3669 </p>
3671 <h2>Delta Groups</h2>
3670 <h2>Delta Groups</h2>
3672 <p>
3671 <p>
3673 A *delta group* expresses the content of a revlog as a series of deltas,
3672 A *delta group* expresses the content of a revlog as a series of deltas,
3674 or patches against previous revisions.
3673 or patches against previous revisions.
3675 </p>
3674 </p>
3676 <p>
3675 <p>
3677 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3676 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3678 to signal the end of the delta group:
3677 to signal the end of the delta group:
3679 </p>
3678 </p>
3680 <pre>
3679 <pre>
3681 +------------------------------------------------------------------------+
3680 +------------------------------------------------------------------------+
3682 | | | | | |
3681 | | | | | |
3683 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3682 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3684 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3683 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3685 | | | | | |
3684 | | | | | |
3686 +------------------------------------------------------------------------+
3685 +------------------------------------------------------------------------+
3687 </pre>
3686 </pre>
3688 <p>
3687 <p>
3689 Each *chunk*'s data consists of the following:
3688 Each *chunk*'s data consists of the following:
3690 </p>
3689 </p>
3691 <pre>
3690 <pre>
3692 +---------------------------------------+
3691 +---------------------------------------+
3693 | | |
3692 | | |
3694 | delta header | delta data |
3693 | delta header | delta data |
3695 | (various by version) | (various) |
3694 | (various by version) | (various) |
3696 | | |
3695 | | |
3697 +---------------------------------------+
3696 +---------------------------------------+
3698 </pre>
3697 </pre>
3699 <p>
3698 <p>
3700 The *delta data* is a series of *delta*s that describe a diff from an existing
3699 The *delta data* is a series of *delta*s that describe a diff from an existing
3701 entry (either that the recipient already has, or previously specified in the
3700 entry (either that the recipient already has, or previously specified in the
3702 bundle/changegroup).
3701 bundle/changegroup).
3703 </p>
3702 </p>
3704 <p>
3703 <p>
3705 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3704 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3706 &quot;3&quot; of the changegroup format.
3705 &quot;3&quot; of the changegroup format.
3707 </p>
3706 </p>
3708 <p>
3707 <p>
3709 Version 1 (headerlen=80):
3708 Version 1 (headerlen=80):
3710 </p>
3709 </p>
3711 <pre>
3710 <pre>
3712 +------------------------------------------------------+
3711 +------------------------------------------------------+
3713 | | | | |
3712 | | | | |
3714 | node | p1 node | p2 node | link node |
3713 | node | p1 node | p2 node | link node |
3715 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3714 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3716 | | | | |
3715 | | | | |
3717 +------------------------------------------------------+
3716 +------------------------------------------------------+
3718 </pre>
3717 </pre>
3719 <p>
3718 <p>
3720 Version 2 (headerlen=100):
3719 Version 2 (headerlen=100):
3721 </p>
3720 </p>
3722 <pre>
3721 <pre>
3723 +------------------------------------------------------------------+
3722 +------------------------------------------------------------------+
3724 | | | | | |
3723 | | | | | |
3725 | node | p1 node | p2 node | base node | link node |
3724 | node | p1 node | p2 node | base node | link node |
3726 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3725 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3727 | | | | | |
3726 | | | | | |
3728 +------------------------------------------------------------------+
3727 +------------------------------------------------------------------+
3729 </pre>
3728 </pre>
3730 <p>
3729 <p>
3731 Version 3 (headerlen=102):
3730 Version 3 (headerlen=102):
3732 </p>
3731 </p>
3733 <pre>
3732 <pre>
3734 +------------------------------------------------------------------------------+
3733 +------------------------------------------------------------------------------+
3735 | | | | | | |
3734 | | | | | | |
3736 | node | p1 node | p2 node | base node | link node | flags |
3735 | node | p1 node | p2 node | base node | link node | flags |
3737 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3736 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3738 | | | | | | |
3737 | | | | | | |
3739 +------------------------------------------------------------------------------+
3738 +------------------------------------------------------------------------------+
3740 </pre>
3739 </pre>
3741 <p>
3740 <p>
3742 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3741 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3743 series of *delta*s, densely packed (no separators). These deltas describe a diff
3742 series of *delta*s, densely packed (no separators). These deltas describe a diff
3744 from an existing entry (either that the recipient already has, or previously
3743 from an existing entry (either that the recipient already has, or previously
3745 specified in the bundle/changegroup). The format is described more fully in
3744 specified in the bundle/changegroup). The format is described more fully in
3746 &quot;hg help internals.bdiff&quot;, but briefly:
3745 &quot;hg help internals.bdiff&quot;, but briefly:
3747 </p>
3746 </p>
3748 <pre>
3747 <pre>
3749 +---------------------------------------------------------------+
3748 +---------------------------------------------------------------+
3750 | | | | |
3749 | | | | |
3751 | start offset | end offset | new length | content |
3750 | start offset | end offset | new length | content |
3752 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3751 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3753 | | | | |
3752 | | | | |
3754 +---------------------------------------------------------------+
3753 +---------------------------------------------------------------+
3755 </pre>
3754 </pre>
3756 <p>
3755 <p>
3757 Please note that the length field in the delta data does *not* include itself.
3756 Please note that the length field in the delta data does *not* include itself.
3758 </p>
3757 </p>
3759 <p>
3758 <p>
3760 In version 1, the delta is always applied against the previous node from
3759 In version 1, the delta is always applied against the previous node from
3761 the changegroup or the first parent if this is the first entry in the
3760 the changegroup or the first parent if this is the first entry in the
3762 changegroup.
3761 changegroup.
3763 </p>
3762 </p>
3764 <p>
3763 <p>
3765 In version 2 and up, the delta base node is encoded in the entry in the
3764 In version 2 and up, the delta base node is encoded in the entry in the
3766 changegroup. This allows the delta to be expressed against any parent,
3765 changegroup. This allows the delta to be expressed against any parent,
3767 which can result in smaller deltas and more efficient encoding of data.
3766 which can result in smaller deltas and more efficient encoding of data.
3768 </p>
3767 </p>
3769 <p>
3768 <p>
3770 The *flags* field holds bitwise flags affecting the processing of revision
3769 The *flags* field holds bitwise flags affecting the processing of revision
3771 data. The following flags are defined:
3770 data. The following flags are defined:
3772 </p>
3771 </p>
3773 <dl>
3772 <dl>
3774 <dt>32768
3773 <dt>32768
3775 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3774 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3776 <dt>16384
3775 <dt>16384
3777 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3776 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3778 <dt>8192
3777 <dt>8192
3779 <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.
3778 <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.
3780 </dl>
3779 </dl>
3781 <p>
3780 <p>
3782 For historical reasons, the integer values are identical to revlog version 1
3781 For historical reasons, the integer values are identical to revlog version 1
3783 per-revision storage flags and correspond to bits being set in this 2-byte
3782 per-revision storage flags and correspond to bits being set in this 2-byte
3784 field. Bits were allocated starting from the most-significant bit, hence the
3783 field. Bits were allocated starting from the most-significant bit, hence the
3785 reverse ordering and allocation of these flags.
3784 reverse ordering and allocation of these flags.
3786 </p>
3785 </p>
3787 <h2>Changeset Segment</h2>
3786 <h2>Changeset Segment</h2>
3788 <p>
3787 <p>
3789 The *changeset segment* consists of a single *delta group* holding
3788 The *changeset segment* consists of a single *delta group* holding
3790 changelog data. The *empty chunk* at the end of the *delta group* denotes
3789 changelog data. The *empty chunk* at the end of the *delta group* denotes
3791 the boundary to the *manifest segment*.
3790 the boundary to the *manifest segment*.
3792 </p>
3791 </p>
3793 <h2>Manifest Segment</h2>
3792 <h2>Manifest Segment</h2>
3794 <p>
3793 <p>
3795 The *manifest segment* consists of a single *delta group* holding manifest
3794 The *manifest segment* consists of a single *delta group* holding manifest
3796 data. If treemanifests are in use, it contains only the manifest for the
3795 data. If treemanifests are in use, it contains only the manifest for the
3797 root directory of the repository. Otherwise, it contains the entire
3796 root directory of the repository. Otherwise, it contains the entire
3798 manifest data. The *empty chunk* at the end of the *delta group* denotes
3797 manifest data. The *empty chunk* at the end of the *delta group* denotes
3799 the boundary to the next segment (either the *treemanifests segment* or the
3798 the boundary to the next segment (either the *treemanifests segment* or the
3800 *filelogs segment*, depending on version and the request options).
3799 *filelogs segment*, depending on version and the request options).
3801 </p>
3800 </p>
3802 <h3>Treemanifests Segment</h3>
3801 <h3>Treemanifests Segment</h3>
3803 <p>
3802 <p>
3804 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3803 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3805 only if the 'treemanifest' param is part of the bundle2 changegroup part
3804 only if the 'treemanifest' param is part of the bundle2 changegroup part
3806 (it is not possible to use changegroup version 3 outside of bundle2).
3805 (it is not possible to use changegroup version 3 outside of bundle2).
3807 Aside from the filenames in the *treemanifests segment* containing a
3806 Aside from the filenames in the *treemanifests segment* containing a
3808 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3807 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3809 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3808 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3810 a sub-segment with filename size 0). This denotes the boundary to the
3809 a sub-segment with filename size 0). This denotes the boundary to the
3811 *filelogs segment*.
3810 *filelogs segment*.
3812 </p>
3811 </p>
3813 <h2>Filelogs Segment</h2>
3812 <h2>Filelogs Segment</h2>
3814 <p>
3813 <p>
3815 The *filelogs segment* consists of multiple sub-segments, each
3814 The *filelogs segment* consists of multiple sub-segments, each
3816 corresponding to an individual file whose data is being described:
3815 corresponding to an individual file whose data is being described:
3817 </p>
3816 </p>
3818 <pre>
3817 <pre>
3819 +--------------------------------------------------+
3818 +--------------------------------------------------+
3820 | | | | | |
3819 | | | | | |
3821 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3820 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3822 | | | | | (4 bytes) |
3821 | | | | | (4 bytes) |
3823 | | | | | |
3822 | | | | | |
3824 +--------------------------------------------------+
3823 +--------------------------------------------------+
3825 </pre>
3824 </pre>
3826 <p>
3825 <p>
3827 The final filelog sub-segment is followed by an *empty chunk* (logically,
3826 The final filelog sub-segment is followed by an *empty chunk* (logically,
3828 a sub-segment with filename size 0). This denotes the end of the segment
3827 a sub-segment with filename size 0). This denotes the end of the segment
3829 and of the overall changegroup.
3828 and of the overall changegroup.
3830 </p>
3829 </p>
3831 <p>
3830 <p>
3832 Each filelog sub-segment consists of the following:
3831 Each filelog sub-segment consists of the following:
3833 </p>
3832 </p>
3834 <pre>
3833 <pre>
3835 +------------------------------------------------------+
3834 +------------------------------------------------------+
3836 | | | |
3835 | | | |
3837 | filename length | filename | delta group |
3836 | filename length | filename | delta group |
3838 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3837 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3839 | | | |
3838 | | | |
3840 +------------------------------------------------------+
3839 +------------------------------------------------------+
3841 </pre>
3840 </pre>
3842 <p>
3841 <p>
3843 That is, a *chunk* consisting of the filename (not terminated or padded)
3842 That is, a *chunk* consisting of the filename (not terminated or padded)
3844 followed by N chunks constituting the *delta group* for this file. The
3843 followed by N chunks constituting the *delta group* for this file. The
3845 *empty chunk* at the end of each *delta group* denotes the boundary to the
3844 *empty chunk* at the end of each *delta group* denotes the boundary to the
3846 next filelog sub-segment.
3845 next filelog sub-segment.
3847 </p>
3846 </p>
3848
3847
3849 </div>
3848 </div>
3850 </div>
3849 </div>
3851 </div>
3850 </div>
3852
3851
3853
3852
3854
3853
3855 </body>
3854 </body>
3856 </html>
3855 </html>
3857
3856
3858
3857
3859 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3858 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3860 404 Not Found
3859 404 Not Found
3861
3860
3862 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3861 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3863 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3862 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3864 <head>
3863 <head>
3865 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3864 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3866 <meta name="robots" content="index, nofollow" />
3865 <meta name="robots" content="index, nofollow" />
3867 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3866 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3868 <script type="text/javascript" src="/static/mercurial.js"></script>
3867 <script type="text/javascript" src="/static/mercurial.js"></script>
3869
3868
3870 <title>test: error</title>
3869 <title>test: error</title>
3871 </head>
3870 </head>
3872 <body>
3871 <body>
3873
3872
3874 <div class="container">
3873 <div class="container">
3875 <div class="menu">
3874 <div class="menu">
3876 <div class="logo">
3875 <div class="logo">
3877 <a href="https://mercurial-scm.org/">
3876 <a href="https://mercurial-scm.org/">
3878 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3877 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3879 </div>
3878 </div>
3880 <ul>
3879 <ul>
3881 <li><a href="/shortlog">log</a></li>
3880 <li><a href="/shortlog">log</a></li>
3882 <li><a href="/graph">graph</a></li>
3881 <li><a href="/graph">graph</a></li>
3883 <li><a href="/tags">tags</a></li>
3882 <li><a href="/tags">tags</a></li>
3884 <li><a href="/bookmarks">bookmarks</a></li>
3883 <li><a href="/bookmarks">bookmarks</a></li>
3885 <li><a href="/branches">branches</a></li>
3884 <li><a href="/branches">branches</a></li>
3886 </ul>
3885 </ul>
3887 <ul>
3886 <ul>
3888 <li><a href="/help">help</a></li>
3887 <li><a href="/help">help</a></li>
3889 </ul>
3888 </ul>
3890 </div>
3889 </div>
3891
3890
3892 <div class="main">
3891 <div class="main">
3893
3892
3894 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3893 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3895 <h3>error</h3>
3894 <h3>error</h3>
3896
3895
3897
3896
3898 <form class="search" action="/log">
3897 <form class="search" action="/log">
3899
3898
3900 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3899 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3901 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3900 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3902 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3901 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3903 </form>
3902 </form>
3904
3903
3905 <div class="description">
3904 <div class="description">
3906 <p>
3905 <p>
3907 An error occurred while processing your request:
3906 An error occurred while processing your request:
3908 </p>
3907 </p>
3909 <p>
3908 <p>
3910 Not Found
3909 Not Found
3911 </p>
3910 </p>
3912 </div>
3911 </div>
3913 </div>
3912 </div>
3914 </div>
3913 </div>
3915
3914
3916
3915
3917
3916
3918 </body>
3917 </body>
3919 </html>
3918 </html>
3920
3919
3921 [1]
3920 [1]
3922
3921
3923 $ killdaemons.py
3922 $ killdaemons.py
3924
3923
3925 #endif
3924 #endif
General Comments 0
You need to be logged in to leave comments. Login now