##// END OF EJS Templates
grep: update docs to reflect new --all-files default...
Jordi Gutiérrez Hermoso -
r43599:d782cce1 default
parent child Browse files
Show More
@@ -1,7803 +1,7808 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 difflib
10 import difflib
11 import errno
11 import errno
12 import os
12 import os
13 import re
13 import re
14 import sys
14 import sys
15
15
16 from .i18n import _
16 from .i18n import _
17 from .node import (
17 from .node import (
18 hex,
18 hex,
19 nullid,
19 nullid,
20 nullrev,
20 nullrev,
21 short,
21 short,
22 wdirhex,
22 wdirhex,
23 wdirrev,
23 wdirrev,
24 )
24 )
25 from .pycompat import open
25 from .pycompat import open
26 from . import (
26 from . import (
27 archival,
27 archival,
28 bookmarks,
28 bookmarks,
29 bundle2,
29 bundle2,
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 hbisect,
44 hbisect,
45 help,
45 help,
46 hg,
46 hg,
47 logcmdutil,
47 logcmdutil,
48 merge as mergemod,
48 merge as mergemod,
49 narrowspec,
49 narrowspec,
50 obsolete,
50 obsolete,
51 obsutil,
51 obsutil,
52 patch,
52 patch,
53 phases,
53 phases,
54 pycompat,
54 pycompat,
55 rcutil,
55 rcutil,
56 registrar,
56 registrar,
57 revsetlang,
57 revsetlang,
58 rewriteutil,
58 rewriteutil,
59 scmutil,
59 scmutil,
60 server,
60 server,
61 shelve as shelvemod,
61 shelve as shelvemod,
62 state as statemod,
62 state as statemod,
63 streamclone,
63 streamclone,
64 tags as tagsmod,
64 tags as tagsmod,
65 ui as uimod,
65 ui as uimod,
66 util,
66 util,
67 verify as verifymod,
67 verify as verifymod,
68 wireprotoserver,
68 wireprotoserver,
69 )
69 )
70 from .utils import (
70 from .utils import (
71 dateutil,
71 dateutil,
72 stringutil,
72 stringutil,
73 )
73 )
74
74
75 table = {}
75 table = {}
76 table.update(debugcommandsmod.command._table)
76 table.update(debugcommandsmod.command._table)
77
77
78 command = registrar.command(table)
78 command = registrar.command(table)
79 INTENT_READONLY = registrar.INTENT_READONLY
79 INTENT_READONLY = registrar.INTENT_READONLY
80
80
81 # common command options
81 # common command options
82
82
83 globalopts = [
83 globalopts = [
84 (
84 (
85 b'R',
85 b'R',
86 b'repository',
86 b'repository',
87 b'',
87 b'',
88 _(b'repository root directory or name of overlay bundle file'),
88 _(b'repository root directory or name of overlay bundle file'),
89 _(b'REPO'),
89 _(b'REPO'),
90 ),
90 ),
91 (b'', b'cwd', b'', _(b'change working directory'), _(b'DIR')),
91 (b'', b'cwd', b'', _(b'change working directory'), _(b'DIR')),
92 (
92 (
93 b'y',
93 b'y',
94 b'noninteractive',
94 b'noninteractive',
95 None,
95 None,
96 _(
96 _(
97 b'do not prompt, automatically pick the first choice for all prompts'
97 b'do not prompt, automatically pick the first choice for all prompts'
98 ),
98 ),
99 ),
99 ),
100 (b'q', b'quiet', None, _(b'suppress output')),
100 (b'q', b'quiet', None, _(b'suppress output')),
101 (b'v', b'verbose', None, _(b'enable additional output')),
101 (b'v', b'verbose', None, _(b'enable additional output')),
102 (
102 (
103 b'',
103 b'',
104 b'color',
104 b'color',
105 b'',
105 b'',
106 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
106 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
107 # and should not be translated
107 # and should not be translated
108 _(b"when to colorize (boolean, always, auto, never, or debug)"),
108 _(b"when to colorize (boolean, always, auto, never, or debug)"),
109 _(b'TYPE'),
109 _(b'TYPE'),
110 ),
110 ),
111 (
111 (
112 b'',
112 b'',
113 b'config',
113 b'config',
114 [],
114 [],
115 _(b'set/override config option (use \'section.name=value\')'),
115 _(b'set/override config option (use \'section.name=value\')'),
116 _(b'CONFIG'),
116 _(b'CONFIG'),
117 ),
117 ),
118 (b'', b'debug', None, _(b'enable debugging output')),
118 (b'', b'debug', None, _(b'enable debugging output')),
119 (b'', b'debugger', None, _(b'start debugger')),
119 (b'', b'debugger', None, _(b'start debugger')),
120 (
120 (
121 b'',
121 b'',
122 b'encoding',
122 b'encoding',
123 encoding.encoding,
123 encoding.encoding,
124 _(b'set the charset encoding'),
124 _(b'set the charset encoding'),
125 _(b'ENCODE'),
125 _(b'ENCODE'),
126 ),
126 ),
127 (
127 (
128 b'',
128 b'',
129 b'encodingmode',
129 b'encodingmode',
130 encoding.encodingmode,
130 encoding.encodingmode,
131 _(b'set the charset encoding mode'),
131 _(b'set the charset encoding mode'),
132 _(b'MODE'),
132 _(b'MODE'),
133 ),
133 ),
134 (b'', b'traceback', None, _(b'always print a traceback on exception')),
134 (b'', b'traceback', None, _(b'always print a traceback on exception')),
135 (b'', b'time', None, _(b'time how long the command takes')),
135 (b'', b'time', None, _(b'time how long the command takes')),
136 (b'', b'profile', None, _(b'print command execution profile')),
136 (b'', b'profile', None, _(b'print command execution profile')),
137 (b'', b'version', None, _(b'output version information and exit')),
137 (b'', b'version', None, _(b'output version information and exit')),
138 (b'h', b'help', None, _(b'display help and exit')),
138 (b'h', b'help', None, _(b'display help and exit')),
139 (b'', b'hidden', False, _(b'consider hidden changesets')),
139 (b'', b'hidden', False, _(b'consider hidden changesets')),
140 (
140 (
141 b'',
141 b'',
142 b'pager',
142 b'pager',
143 b'auto',
143 b'auto',
144 _(b"when to paginate (boolean, always, auto, or never)"),
144 _(b"when to paginate (boolean, always, auto, or never)"),
145 _(b'TYPE'),
145 _(b'TYPE'),
146 ),
146 ),
147 ]
147 ]
148
148
149 dryrunopts = cmdutil.dryrunopts
149 dryrunopts = cmdutil.dryrunopts
150 remoteopts = cmdutil.remoteopts
150 remoteopts = cmdutil.remoteopts
151 walkopts = cmdutil.walkopts
151 walkopts = cmdutil.walkopts
152 commitopts = cmdutil.commitopts
152 commitopts = cmdutil.commitopts
153 commitopts2 = cmdutil.commitopts2
153 commitopts2 = cmdutil.commitopts2
154 commitopts3 = cmdutil.commitopts3
154 commitopts3 = cmdutil.commitopts3
155 formatteropts = cmdutil.formatteropts
155 formatteropts = cmdutil.formatteropts
156 templateopts = cmdutil.templateopts
156 templateopts = cmdutil.templateopts
157 logopts = cmdutil.logopts
157 logopts = cmdutil.logopts
158 diffopts = cmdutil.diffopts
158 diffopts = cmdutil.diffopts
159 diffwsopts = cmdutil.diffwsopts
159 diffwsopts = cmdutil.diffwsopts
160 diffopts2 = cmdutil.diffopts2
160 diffopts2 = cmdutil.diffopts2
161 mergetoolopts = cmdutil.mergetoolopts
161 mergetoolopts = cmdutil.mergetoolopts
162 similarityopts = cmdutil.similarityopts
162 similarityopts = cmdutil.similarityopts
163 subrepoopts = cmdutil.subrepoopts
163 subrepoopts = cmdutil.subrepoopts
164 debugrevlogopts = cmdutil.debugrevlogopts
164 debugrevlogopts = cmdutil.debugrevlogopts
165
165
166 # Commands start here, listed alphabetically
166 # Commands start here, listed alphabetically
167
167
168
168
169 @command(
169 @command(
170 b'abort',
170 b'abort',
171 dryrunopts,
171 dryrunopts,
172 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
172 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
173 helpbasic=True,
173 helpbasic=True,
174 )
174 )
175 def abort(ui, repo, **opts):
175 def abort(ui, repo, **opts):
176 """abort an unfinished operation (EXPERIMENTAL)
176 """abort an unfinished operation (EXPERIMENTAL)
177
177
178 Aborts a multistep operation like graft, histedit, rebase, merge,
178 Aborts a multistep operation like graft, histedit, rebase, merge,
179 and unshelve if they are in an unfinished state.
179 and unshelve if they are in an unfinished state.
180
180
181 use --dry-run/-n to dry run the command.
181 use --dry-run/-n to dry run the command.
182 """
182 """
183 dryrun = opts.get(r'dry_run')
183 dryrun = opts.get(r'dry_run')
184 abortstate = cmdutil.getunfinishedstate(repo)
184 abortstate = cmdutil.getunfinishedstate(repo)
185 if not abortstate:
185 if not abortstate:
186 raise error.Abort(_(b'no operation in progress'))
186 raise error.Abort(_(b'no operation in progress'))
187 if not abortstate.abortfunc:
187 if not abortstate.abortfunc:
188 raise error.Abort(
188 raise error.Abort(
189 (
189 (
190 _(b"%s in progress but does not support 'hg abort'")
190 _(b"%s in progress but does not support 'hg abort'")
191 % (abortstate._opname)
191 % (abortstate._opname)
192 ),
192 ),
193 hint=abortstate.hint(),
193 hint=abortstate.hint(),
194 )
194 )
195 if dryrun:
195 if dryrun:
196 ui.status(
196 ui.status(
197 _(b'%s in progress, will be aborted\n') % (abortstate._opname)
197 _(b'%s in progress, will be aborted\n') % (abortstate._opname)
198 )
198 )
199 return
199 return
200 return abortstate.abortfunc(ui, repo)
200 return abortstate.abortfunc(ui, repo)
201
201
202
202
203 @command(
203 @command(
204 b'add',
204 b'add',
205 walkopts + subrepoopts + dryrunopts,
205 walkopts + subrepoopts + dryrunopts,
206 _(b'[OPTION]... [FILE]...'),
206 _(b'[OPTION]... [FILE]...'),
207 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
207 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
208 helpbasic=True,
208 helpbasic=True,
209 inferrepo=True,
209 inferrepo=True,
210 )
210 )
211 def add(ui, repo, *pats, **opts):
211 def add(ui, repo, *pats, **opts):
212 """add the specified files on the next commit
212 """add the specified files on the next commit
213
213
214 Schedule files to be version controlled and added to the
214 Schedule files to be version controlled and added to the
215 repository.
215 repository.
216
216
217 The files will be added to the repository at the next commit. To
217 The files will be added to the repository at the next commit. To
218 undo an add before that, see :hg:`forget`.
218 undo an add before that, see :hg:`forget`.
219
219
220 If no names are given, add all files to the repository (except
220 If no names are given, add all files to the repository (except
221 files matching ``.hgignore``).
221 files matching ``.hgignore``).
222
222
223 .. container:: verbose
223 .. container:: verbose
224
224
225 Examples:
225 Examples:
226
226
227 - New (unknown) files are added
227 - New (unknown) files are added
228 automatically by :hg:`add`::
228 automatically by :hg:`add`::
229
229
230 $ ls
230 $ ls
231 foo.c
231 foo.c
232 $ hg status
232 $ hg status
233 ? foo.c
233 ? foo.c
234 $ hg add
234 $ hg add
235 adding foo.c
235 adding foo.c
236 $ hg status
236 $ hg status
237 A foo.c
237 A foo.c
238
238
239 - Specific files to be added can be specified::
239 - Specific files to be added can be specified::
240
240
241 $ ls
241 $ ls
242 bar.c foo.c
242 bar.c foo.c
243 $ hg status
243 $ hg status
244 ? bar.c
244 ? bar.c
245 ? foo.c
245 ? foo.c
246 $ hg add bar.c
246 $ hg add bar.c
247 $ hg status
247 $ hg status
248 A bar.c
248 A bar.c
249 ? foo.c
249 ? foo.c
250
250
251 Returns 0 if all files are successfully added.
251 Returns 0 if all files are successfully added.
252 """
252 """
253
253
254 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
254 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
255 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
255 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
256 rejected = cmdutil.add(ui, repo, m, b"", uipathfn, False, **opts)
256 rejected = cmdutil.add(ui, repo, m, b"", uipathfn, False, **opts)
257 return rejected and 1 or 0
257 return rejected and 1 or 0
258
258
259
259
260 @command(
260 @command(
261 b'addremove',
261 b'addremove',
262 similarityopts + subrepoopts + walkopts + dryrunopts,
262 similarityopts + subrepoopts + walkopts + dryrunopts,
263 _(b'[OPTION]... [FILE]...'),
263 _(b'[OPTION]... [FILE]...'),
264 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
264 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
265 inferrepo=True,
265 inferrepo=True,
266 )
266 )
267 def addremove(ui, repo, *pats, **opts):
267 def addremove(ui, repo, *pats, **opts):
268 """add all new files, delete all missing files
268 """add all new files, delete all missing files
269
269
270 Add all new files and remove all missing files from the
270 Add all new files and remove all missing files from the
271 repository.
271 repository.
272
272
273 Unless names are given, new files are ignored if they match any of
273 Unless names are given, new files are ignored if they match any of
274 the patterns in ``.hgignore``. As with add, these changes take
274 the patterns in ``.hgignore``. As with add, these changes take
275 effect at the next commit.
275 effect at the next commit.
276
276
277 Use the -s/--similarity option to detect renamed files. This
277 Use the -s/--similarity option to detect renamed files. This
278 option takes a percentage between 0 (disabled) and 100 (files must
278 option takes a percentage between 0 (disabled) and 100 (files must
279 be identical) as its parameter. With a parameter greater than 0,
279 be identical) as its parameter. With a parameter greater than 0,
280 this compares every removed file with every added file and records
280 this compares every removed file with every added file and records
281 those similar enough as renames. Detecting renamed files this way
281 those similar enough as renames. Detecting renamed files this way
282 can be expensive. After using this option, :hg:`status -C` can be
282 can be expensive. After using this option, :hg:`status -C` can be
283 used to check which files were identified as moved or renamed. If
283 used to check which files were identified as moved or renamed. If
284 not specified, -s/--similarity defaults to 100 and only renames of
284 not specified, -s/--similarity defaults to 100 and only renames of
285 identical files are detected.
285 identical files are detected.
286
286
287 .. container:: verbose
287 .. container:: verbose
288
288
289 Examples:
289 Examples:
290
290
291 - A number of files (bar.c and foo.c) are new,
291 - A number of files (bar.c and foo.c) are new,
292 while foobar.c has been removed (without using :hg:`remove`)
292 while foobar.c has been removed (without using :hg:`remove`)
293 from the repository::
293 from the repository::
294
294
295 $ ls
295 $ ls
296 bar.c foo.c
296 bar.c foo.c
297 $ hg status
297 $ hg status
298 ! foobar.c
298 ! foobar.c
299 ? bar.c
299 ? bar.c
300 ? foo.c
300 ? foo.c
301 $ hg addremove
301 $ hg addremove
302 adding bar.c
302 adding bar.c
303 adding foo.c
303 adding foo.c
304 removing foobar.c
304 removing foobar.c
305 $ hg status
305 $ hg status
306 A bar.c
306 A bar.c
307 A foo.c
307 A foo.c
308 R foobar.c
308 R foobar.c
309
309
310 - A file foobar.c was moved to foo.c without using :hg:`rename`.
310 - A file foobar.c was moved to foo.c without using :hg:`rename`.
311 Afterwards, it was edited slightly::
311 Afterwards, it was edited slightly::
312
312
313 $ ls
313 $ ls
314 foo.c
314 foo.c
315 $ hg status
315 $ hg status
316 ! foobar.c
316 ! foobar.c
317 ? foo.c
317 ? foo.c
318 $ hg addremove --similarity 90
318 $ hg addremove --similarity 90
319 removing foobar.c
319 removing foobar.c
320 adding foo.c
320 adding foo.c
321 recording removal of foobar.c as rename to foo.c (94% similar)
321 recording removal of foobar.c as rename to foo.c (94% similar)
322 $ hg status -C
322 $ hg status -C
323 A foo.c
323 A foo.c
324 foobar.c
324 foobar.c
325 R foobar.c
325 R foobar.c
326
326
327 Returns 0 if all files are successfully added.
327 Returns 0 if all files are successfully added.
328 """
328 """
329 opts = pycompat.byteskwargs(opts)
329 opts = pycompat.byteskwargs(opts)
330 if not opts.get(b'similarity'):
330 if not opts.get(b'similarity'):
331 opts[b'similarity'] = b'100'
331 opts[b'similarity'] = b'100'
332 matcher = scmutil.match(repo[None], pats, opts)
332 matcher = scmutil.match(repo[None], pats, opts)
333 relative = scmutil.anypats(pats, opts)
333 relative = scmutil.anypats(pats, opts)
334 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
334 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
335 return scmutil.addremove(repo, matcher, b"", uipathfn, opts)
335 return scmutil.addremove(repo, matcher, b"", uipathfn, opts)
336
336
337
337
338 @command(
338 @command(
339 b'annotate|blame',
339 b'annotate|blame',
340 [
340 [
341 (b'r', b'rev', b'', _(b'annotate the specified revision'), _(b'REV')),
341 (b'r', b'rev', b'', _(b'annotate the specified revision'), _(b'REV')),
342 (
342 (
343 b'',
343 b'',
344 b'follow',
344 b'follow',
345 None,
345 None,
346 _(b'follow copies/renames and list the filename (DEPRECATED)'),
346 _(b'follow copies/renames and list the filename (DEPRECATED)'),
347 ),
347 ),
348 (b'', b'no-follow', None, _(b"don't follow copies and renames")),
348 (b'', b'no-follow', None, _(b"don't follow copies and renames")),
349 (b'a', b'text', None, _(b'treat all files as text')),
349 (b'a', b'text', None, _(b'treat all files as text')),
350 (b'u', b'user', None, _(b'list the author (long with -v)')),
350 (b'u', b'user', None, _(b'list the author (long with -v)')),
351 (b'f', b'file', None, _(b'list the filename')),
351 (b'f', b'file', None, _(b'list the filename')),
352 (b'd', b'date', None, _(b'list the date (short with -q)')),
352 (b'd', b'date', None, _(b'list the date (short with -q)')),
353 (b'n', b'number', None, _(b'list the revision number (default)')),
353 (b'n', b'number', None, _(b'list the revision number (default)')),
354 (b'c', b'changeset', None, _(b'list the changeset')),
354 (b'c', b'changeset', None, _(b'list the changeset')),
355 (
355 (
356 b'l',
356 b'l',
357 b'line-number',
357 b'line-number',
358 None,
358 None,
359 _(b'show line number at the first appearance'),
359 _(b'show line number at the first appearance'),
360 ),
360 ),
361 (
361 (
362 b'',
362 b'',
363 b'skip',
363 b'skip',
364 [],
364 [],
365 _(b'revision to not display (EXPERIMENTAL)'),
365 _(b'revision to not display (EXPERIMENTAL)'),
366 _(b'REV'),
366 _(b'REV'),
367 ),
367 ),
368 ]
368 ]
369 + diffwsopts
369 + diffwsopts
370 + walkopts
370 + walkopts
371 + formatteropts,
371 + formatteropts,
372 _(b'[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
372 _(b'[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
373 helpcategory=command.CATEGORY_FILE_CONTENTS,
373 helpcategory=command.CATEGORY_FILE_CONTENTS,
374 helpbasic=True,
374 helpbasic=True,
375 inferrepo=True,
375 inferrepo=True,
376 )
376 )
377 def annotate(ui, repo, *pats, **opts):
377 def annotate(ui, repo, *pats, **opts):
378 """show changeset information by line for each file
378 """show changeset information by line for each file
379
379
380 List changes in files, showing the revision id responsible for
380 List changes in files, showing the revision id responsible for
381 each line.
381 each line.
382
382
383 This command is useful for discovering when a change was made and
383 This command is useful for discovering when a change was made and
384 by whom.
384 by whom.
385
385
386 If you include --file, --user, or --date, the revision number is
386 If you include --file, --user, or --date, the revision number is
387 suppressed unless you also include --number.
387 suppressed unless you also include --number.
388
388
389 Without the -a/--text option, annotate will avoid processing files
389 Without the -a/--text option, annotate will avoid processing files
390 it detects as binary. With -a, annotate will annotate the file
390 it detects as binary. With -a, annotate will annotate the file
391 anyway, although the results will probably be neither useful
391 anyway, although the results will probably be neither useful
392 nor desirable.
392 nor desirable.
393
393
394 .. container:: verbose
394 .. container:: verbose
395
395
396 Template:
396 Template:
397
397
398 The following keywords are supported in addition to the common template
398 The following keywords are supported in addition to the common template
399 keywords and functions. See also :hg:`help templates`.
399 keywords and functions. See also :hg:`help templates`.
400
400
401 :lines: List of lines with annotation data.
401 :lines: List of lines with annotation data.
402 :path: String. Repository-absolute path of the specified file.
402 :path: String. Repository-absolute path of the specified file.
403
403
404 And each entry of ``{lines}`` provides the following sub-keywords in
404 And each entry of ``{lines}`` provides the following sub-keywords in
405 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
405 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
406
406
407 :line: String. Line content.
407 :line: String. Line content.
408 :lineno: Integer. Line number at that revision.
408 :lineno: Integer. Line number at that revision.
409 :path: String. Repository-absolute path of the file at that revision.
409 :path: String. Repository-absolute path of the file at that revision.
410
410
411 See :hg:`help templates.operators` for the list expansion syntax.
411 See :hg:`help templates.operators` for the list expansion syntax.
412
412
413 Returns 0 on success.
413 Returns 0 on success.
414 """
414 """
415 opts = pycompat.byteskwargs(opts)
415 opts = pycompat.byteskwargs(opts)
416 if not pats:
416 if not pats:
417 raise error.Abort(_(b'at least one filename or pattern is required'))
417 raise error.Abort(_(b'at least one filename or pattern is required'))
418
418
419 if opts.get(b'follow'):
419 if opts.get(b'follow'):
420 # --follow is deprecated and now just an alias for -f/--file
420 # --follow is deprecated and now just an alias for -f/--file
421 # to mimic the behavior of Mercurial before version 1.5
421 # to mimic the behavior of Mercurial before version 1.5
422 opts[b'file'] = True
422 opts[b'file'] = True
423
423
424 if (
424 if (
425 not opts.get(b'user')
425 not opts.get(b'user')
426 and not opts.get(b'changeset')
426 and not opts.get(b'changeset')
427 and not opts.get(b'date')
427 and not opts.get(b'date')
428 and not opts.get(b'file')
428 and not opts.get(b'file')
429 ):
429 ):
430 opts[b'number'] = True
430 opts[b'number'] = True
431
431
432 linenumber = opts.get(b'line_number') is not None
432 linenumber = opts.get(b'line_number') is not None
433 if (
433 if (
434 linenumber
434 linenumber
435 and (not opts.get(b'changeset'))
435 and (not opts.get(b'changeset'))
436 and (not opts.get(b'number'))
436 and (not opts.get(b'number'))
437 ):
437 ):
438 raise error.Abort(_(b'at least one of -n/-c is required for -l'))
438 raise error.Abort(_(b'at least one of -n/-c is required for -l'))
439
439
440 rev = opts.get(b'rev')
440 rev = opts.get(b'rev')
441 if rev:
441 if rev:
442 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
442 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
443 ctx = scmutil.revsingle(repo, rev)
443 ctx = scmutil.revsingle(repo, rev)
444
444
445 ui.pager(b'annotate')
445 ui.pager(b'annotate')
446 rootfm = ui.formatter(b'annotate', opts)
446 rootfm = ui.formatter(b'annotate', opts)
447 if ui.debugflag:
447 if ui.debugflag:
448 shorthex = pycompat.identity
448 shorthex = pycompat.identity
449 else:
449 else:
450
450
451 def shorthex(h):
451 def shorthex(h):
452 return h[:12]
452 return h[:12]
453
453
454 if ui.quiet:
454 if ui.quiet:
455 datefunc = dateutil.shortdate
455 datefunc = dateutil.shortdate
456 else:
456 else:
457 datefunc = dateutil.datestr
457 datefunc = dateutil.datestr
458 if ctx.rev() is None:
458 if ctx.rev() is None:
459 if opts.get(b'changeset'):
459 if opts.get(b'changeset'):
460 # omit "+" suffix which is appended to node hex
460 # omit "+" suffix which is appended to node hex
461 def formatrev(rev):
461 def formatrev(rev):
462 if rev == wdirrev:
462 if rev == wdirrev:
463 return b'%d' % ctx.p1().rev()
463 return b'%d' % ctx.p1().rev()
464 else:
464 else:
465 return b'%d' % rev
465 return b'%d' % rev
466
466
467 else:
467 else:
468
468
469 def formatrev(rev):
469 def formatrev(rev):
470 if rev == wdirrev:
470 if rev == wdirrev:
471 return b'%d+' % ctx.p1().rev()
471 return b'%d+' % ctx.p1().rev()
472 else:
472 else:
473 return b'%d ' % rev
473 return b'%d ' % rev
474
474
475 def formathex(h):
475 def formathex(h):
476 if h == wdirhex:
476 if h == wdirhex:
477 return b'%s+' % shorthex(hex(ctx.p1().node()))
477 return b'%s+' % shorthex(hex(ctx.p1().node()))
478 else:
478 else:
479 return b'%s ' % shorthex(h)
479 return b'%s ' % shorthex(h)
480
480
481 else:
481 else:
482 formatrev = b'%d'.__mod__
482 formatrev = b'%d'.__mod__
483 formathex = shorthex
483 formathex = shorthex
484
484
485 opmap = [
485 opmap = [
486 (b'user', b' ', lambda x: x.fctx.user(), ui.shortuser),
486 (b'user', b' ', lambda x: x.fctx.user(), ui.shortuser),
487 (b'rev', b' ', lambda x: scmutil.intrev(x.fctx), formatrev),
487 (b'rev', b' ', lambda x: scmutil.intrev(x.fctx), formatrev),
488 (b'node', b' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
488 (b'node', b' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
489 (b'date', b' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
489 (b'date', b' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
490 (b'path', b' ', lambda x: x.fctx.path(), pycompat.bytestr),
490 (b'path', b' ', lambda x: x.fctx.path(), pycompat.bytestr),
491 (b'lineno', b':', lambda x: x.lineno, pycompat.bytestr),
491 (b'lineno', b':', lambda x: x.lineno, pycompat.bytestr),
492 ]
492 ]
493 opnamemap = {
493 opnamemap = {
494 b'rev': b'number',
494 b'rev': b'number',
495 b'node': b'changeset',
495 b'node': b'changeset',
496 b'path': b'file',
496 b'path': b'file',
497 b'lineno': b'line_number',
497 b'lineno': b'line_number',
498 }
498 }
499
499
500 if rootfm.isplain():
500 if rootfm.isplain():
501
501
502 def makefunc(get, fmt):
502 def makefunc(get, fmt):
503 return lambda x: fmt(get(x))
503 return lambda x: fmt(get(x))
504
504
505 else:
505 else:
506
506
507 def makefunc(get, fmt):
507 def makefunc(get, fmt):
508 return get
508 return get
509
509
510 datahint = rootfm.datahint()
510 datahint = rootfm.datahint()
511 funcmap = [
511 funcmap = [
512 (makefunc(get, fmt), sep)
512 (makefunc(get, fmt), sep)
513 for fn, sep, get, fmt in opmap
513 for fn, sep, get, fmt in opmap
514 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
514 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
515 ]
515 ]
516 funcmap[0] = (funcmap[0][0], b'') # no separator in front of first column
516 funcmap[0] = (funcmap[0][0], b'') # no separator in front of first column
517 fields = b' '.join(
517 fields = b' '.join(
518 fn
518 fn
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
522
523 def bad(x, y):
523 def bad(x, y):
524 raise error.Abort(b"%s: %s" % (x, y))
524 raise error.Abort(b"%s: %s" % (x, y))
525
525
526 m = scmutil.match(ctx, pats, opts, badfn=bad)
526 m = scmutil.match(ctx, pats, opts, badfn=bad)
527
527
528 follow = not opts.get(b'no_follow')
528 follow = not opts.get(b'no_follow')
529 diffopts = patch.difffeatureopts(
529 diffopts = patch.difffeatureopts(
530 ui, opts, section=b'annotate', whitespace=True
530 ui, opts, section=b'annotate', whitespace=True
531 )
531 )
532 skiprevs = opts.get(b'skip')
532 skiprevs = opts.get(b'skip')
533 if skiprevs:
533 if skiprevs:
534 skiprevs = scmutil.revrange(repo, skiprevs)
534 skiprevs = scmutil.revrange(repo, skiprevs)
535
535
536 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
536 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
537 for abs in ctx.walk(m):
537 for abs in ctx.walk(m):
538 fctx = ctx[abs]
538 fctx = ctx[abs]
539 rootfm.startitem()
539 rootfm.startitem()
540 rootfm.data(path=abs)
540 rootfm.data(path=abs)
541 if not opts.get(b'text') and fctx.isbinary():
541 if not opts.get(b'text') and fctx.isbinary():
542 rootfm.plain(_(b"%s: binary file\n") % uipathfn(abs))
542 rootfm.plain(_(b"%s: binary file\n") % uipathfn(abs))
543 continue
543 continue
544
544
545 fm = rootfm.nested(b'lines', tmpl=b'{rev}: {line}')
545 fm = rootfm.nested(b'lines', tmpl=b'{rev}: {line}')
546 lines = fctx.annotate(
546 lines = fctx.annotate(
547 follow=follow, skiprevs=skiprevs, diffopts=diffopts
547 follow=follow, skiprevs=skiprevs, diffopts=diffopts
548 )
548 )
549 if not lines:
549 if not lines:
550 fm.end()
550 fm.end()
551 continue
551 continue
552 formats = []
552 formats = []
553 pieces = []
553 pieces = []
554
554
555 for f, sep in funcmap:
555 for f, sep in funcmap:
556 l = [f(n) for n in lines]
556 l = [f(n) for n in lines]
557 if fm.isplain():
557 if fm.isplain():
558 sizes = [encoding.colwidth(x) for x in l]
558 sizes = [encoding.colwidth(x) for x in l]
559 ml = max(sizes)
559 ml = max(sizes)
560 formats.append([sep + b' ' * (ml - w) + b'%s' for w in sizes])
560 formats.append([sep + b' ' * (ml - w) + b'%s' for w in sizes])
561 else:
561 else:
562 formats.append([b'%s' for x in l])
562 formats.append([b'%s' for x in l])
563 pieces.append(l)
563 pieces.append(l)
564
564
565 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
565 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
566 fm.startitem()
566 fm.startitem()
567 fm.context(fctx=n.fctx)
567 fm.context(fctx=n.fctx)
568 fm.write(fields, b"".join(f), *p)
568 fm.write(fields, b"".join(f), *p)
569 if n.skip:
569 if n.skip:
570 fmt = b"* %s"
570 fmt = b"* %s"
571 else:
571 else:
572 fmt = b": %s"
572 fmt = b": %s"
573 fm.write(b'line', fmt, n.text)
573 fm.write(b'line', fmt, n.text)
574
574
575 if not lines[-1].text.endswith(b'\n'):
575 if not lines[-1].text.endswith(b'\n'):
576 fm.plain(b'\n')
576 fm.plain(b'\n')
577 fm.end()
577 fm.end()
578
578
579 rootfm.end()
579 rootfm.end()
580
580
581
581
582 @command(
582 @command(
583 b'archive',
583 b'archive',
584 [
584 [
585 (b'', b'no-decode', None, _(b'do not pass files through decoders')),
585 (b'', b'no-decode', None, _(b'do not pass files through decoders')),
586 (
586 (
587 b'p',
587 b'p',
588 b'prefix',
588 b'prefix',
589 b'',
589 b'',
590 _(b'directory prefix for files in archive'),
590 _(b'directory prefix for files in archive'),
591 _(b'PREFIX'),
591 _(b'PREFIX'),
592 ),
592 ),
593 (b'r', b'rev', b'', _(b'revision to distribute'), _(b'REV')),
593 (b'r', b'rev', b'', _(b'revision to distribute'), _(b'REV')),
594 (b't', b'type', b'', _(b'type of distribution to create'), _(b'TYPE')),
594 (b't', b'type', b'', _(b'type of distribution to create'), _(b'TYPE')),
595 ]
595 ]
596 + subrepoopts
596 + subrepoopts
597 + walkopts,
597 + walkopts,
598 _(b'[OPTION]... DEST'),
598 _(b'[OPTION]... DEST'),
599 helpcategory=command.CATEGORY_IMPORT_EXPORT,
599 helpcategory=command.CATEGORY_IMPORT_EXPORT,
600 )
600 )
601 def archive(ui, repo, dest, **opts):
601 def archive(ui, repo, dest, **opts):
602 '''create an unversioned archive of a repository revision
602 '''create an unversioned archive of a repository revision
603
603
604 By default, the revision used is the parent of the working
604 By default, the revision used is the parent of the working
605 directory; use -r/--rev to specify a different revision.
605 directory; use -r/--rev to specify a different revision.
606
606
607 The archive type is automatically detected based on file
607 The archive type is automatically detected based on file
608 extension (to override, use -t/--type).
608 extension (to override, use -t/--type).
609
609
610 .. container:: verbose
610 .. container:: verbose
611
611
612 Examples:
612 Examples:
613
613
614 - create a zip file containing the 1.0 release::
614 - create a zip file containing the 1.0 release::
615
615
616 hg archive -r 1.0 project-1.0.zip
616 hg archive -r 1.0 project-1.0.zip
617
617
618 - create a tarball excluding .hg files::
618 - create a tarball excluding .hg files::
619
619
620 hg archive project.tar.gz -X ".hg*"
620 hg archive project.tar.gz -X ".hg*"
621
621
622 Valid types are:
622 Valid types are:
623
623
624 :``files``: a directory full of files (default)
624 :``files``: a directory full of files (default)
625 :``tar``: tar archive, uncompressed
625 :``tar``: tar archive, uncompressed
626 :``tbz2``: tar archive, compressed using bzip2
626 :``tbz2``: tar archive, compressed using bzip2
627 :``tgz``: tar archive, compressed using gzip
627 :``tgz``: tar archive, compressed using gzip
628 :``txz``: tar archive, compressed using lzma (only in Python 3)
628 :``txz``: tar archive, compressed using lzma (only in Python 3)
629 :``uzip``: zip archive, uncompressed
629 :``uzip``: zip archive, uncompressed
630 :``zip``: zip archive, compressed using deflate
630 :``zip``: zip archive, compressed using deflate
631
631
632 The exact name of the destination archive or directory is given
632 The exact name of the destination archive or directory is given
633 using a format string; see :hg:`help export` for details.
633 using a format string; see :hg:`help export` for details.
634
634
635 Each member added to an archive file has a directory prefix
635 Each member added to an archive file has a directory prefix
636 prepended. Use -p/--prefix to specify a format string for the
636 prepended. Use -p/--prefix to specify a format string for the
637 prefix. The default is the basename of the archive, with suffixes
637 prefix. The default is the basename of the archive, with suffixes
638 removed.
638 removed.
639
639
640 Returns 0 on success.
640 Returns 0 on success.
641 '''
641 '''
642
642
643 opts = pycompat.byteskwargs(opts)
643 opts = pycompat.byteskwargs(opts)
644 rev = opts.get(b'rev')
644 rev = opts.get(b'rev')
645 if rev:
645 if rev:
646 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
646 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
647 ctx = scmutil.revsingle(repo, rev)
647 ctx = scmutil.revsingle(repo, rev)
648 if not ctx:
648 if not ctx:
649 raise error.Abort(_(b'no working directory: please specify a revision'))
649 raise error.Abort(_(b'no working directory: please specify a revision'))
650 node = ctx.node()
650 node = ctx.node()
651 dest = cmdutil.makefilename(ctx, dest)
651 dest = cmdutil.makefilename(ctx, dest)
652 if os.path.realpath(dest) == repo.root:
652 if os.path.realpath(dest) == repo.root:
653 raise error.Abort(_(b'repository root cannot be destination'))
653 raise error.Abort(_(b'repository root cannot be destination'))
654
654
655 kind = opts.get(b'type') or archival.guesskind(dest) or b'files'
655 kind = opts.get(b'type') or archival.guesskind(dest) or b'files'
656 prefix = opts.get(b'prefix')
656 prefix = opts.get(b'prefix')
657
657
658 if dest == b'-':
658 if dest == b'-':
659 if kind == b'files':
659 if kind == b'files':
660 raise error.Abort(_(b'cannot archive plain files to stdout'))
660 raise error.Abort(_(b'cannot archive plain files to stdout'))
661 dest = cmdutil.makefileobj(ctx, dest)
661 dest = cmdutil.makefileobj(ctx, dest)
662 if not prefix:
662 if not prefix:
663 prefix = os.path.basename(repo.root) + b'-%h'
663 prefix = os.path.basename(repo.root) + b'-%h'
664
664
665 prefix = cmdutil.makefilename(ctx, prefix)
665 prefix = cmdutil.makefilename(ctx, prefix)
666 match = scmutil.match(ctx, [], opts)
666 match = scmutil.match(ctx, [], opts)
667 archival.archive(
667 archival.archive(
668 repo,
668 repo,
669 dest,
669 dest,
670 node,
670 node,
671 kind,
671 kind,
672 not opts.get(b'no_decode'),
672 not opts.get(b'no_decode'),
673 match,
673 match,
674 prefix,
674 prefix,
675 subrepos=opts.get(b'subrepos'),
675 subrepos=opts.get(b'subrepos'),
676 )
676 )
677
677
678
678
679 @command(
679 @command(
680 b'backout',
680 b'backout',
681 [
681 [
682 (
682 (
683 b'',
683 b'',
684 b'merge',
684 b'merge',
685 None,
685 None,
686 _(b'merge with old dirstate parent after backout'),
686 _(b'merge with old dirstate parent after backout'),
687 ),
687 ),
688 (
688 (
689 b'',
689 b'',
690 b'commit',
690 b'commit',
691 None,
691 None,
692 _(b'commit if no conflicts were encountered (DEPRECATED)'),
692 _(b'commit if no conflicts were encountered (DEPRECATED)'),
693 ),
693 ),
694 (b'', b'no-commit', None, _(b'do not commit')),
694 (b'', b'no-commit', None, _(b'do not commit')),
695 (
695 (
696 b'',
696 b'',
697 b'parent',
697 b'parent',
698 b'',
698 b'',
699 _(b'parent to choose when backing out merge (DEPRECATED)'),
699 _(b'parent to choose when backing out merge (DEPRECATED)'),
700 _(b'REV'),
700 _(b'REV'),
701 ),
701 ),
702 (b'r', b'rev', b'', _(b'revision to backout'), _(b'REV')),
702 (b'r', b'rev', b'', _(b'revision to backout'), _(b'REV')),
703 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
703 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
704 ]
704 ]
705 + mergetoolopts
705 + mergetoolopts
706 + walkopts
706 + walkopts
707 + commitopts
707 + commitopts
708 + commitopts2,
708 + commitopts2,
709 _(b'[OPTION]... [-r] REV'),
709 _(b'[OPTION]... [-r] REV'),
710 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
710 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
711 )
711 )
712 def backout(ui, repo, node=None, rev=None, **opts):
712 def backout(ui, repo, node=None, rev=None, **opts):
713 '''reverse effect of earlier changeset
713 '''reverse effect of earlier changeset
714
714
715 Prepare a new changeset with the effect of REV undone in the
715 Prepare a new changeset with the effect of REV undone in the
716 current working directory. If no conflicts were encountered,
716 current working directory. If no conflicts were encountered,
717 it will be committed immediately.
717 it will be committed immediately.
718
718
719 If REV is the parent of the working directory, then this new changeset
719 If REV is the parent of the working directory, then this new changeset
720 is committed automatically (unless --no-commit is specified).
720 is committed automatically (unless --no-commit is specified).
721
721
722 .. note::
722 .. note::
723
723
724 :hg:`backout` cannot be used to fix either an unwanted or
724 :hg:`backout` cannot be used to fix either an unwanted or
725 incorrect merge.
725 incorrect merge.
726
726
727 .. container:: verbose
727 .. container:: verbose
728
728
729 Examples:
729 Examples:
730
730
731 - Reverse the effect of the parent of the working directory.
731 - Reverse the effect of the parent of the working directory.
732 This backout will be committed immediately::
732 This backout will be committed immediately::
733
733
734 hg backout -r .
734 hg backout -r .
735
735
736 - Reverse the effect of previous bad revision 23::
736 - Reverse the effect of previous bad revision 23::
737
737
738 hg backout -r 23
738 hg backout -r 23
739
739
740 - Reverse the effect of previous bad revision 23 and
740 - Reverse the effect of previous bad revision 23 and
741 leave changes uncommitted::
741 leave changes uncommitted::
742
742
743 hg backout -r 23 --no-commit
743 hg backout -r 23 --no-commit
744 hg commit -m "Backout revision 23"
744 hg commit -m "Backout revision 23"
745
745
746 By default, the pending changeset will have one parent,
746 By default, the pending changeset will have one parent,
747 maintaining a linear history. With --merge, the pending
747 maintaining a linear history. With --merge, the pending
748 changeset will instead have two parents: the old parent of the
748 changeset will instead have two parents: the old parent of the
749 working directory and a new child of REV that simply undoes REV.
749 working directory and a new child of REV that simply undoes REV.
750
750
751 Before version 1.7, the behavior without --merge was equivalent
751 Before version 1.7, the behavior without --merge was equivalent
752 to specifying --merge followed by :hg:`update --clean .` to
752 to specifying --merge followed by :hg:`update --clean .` to
753 cancel the merge and leave the child of REV as a head to be
753 cancel the merge and leave the child of REV as a head to be
754 merged separately.
754 merged separately.
755
755
756 See :hg:`help dates` for a list of formats valid for -d/--date.
756 See :hg:`help dates` for a list of formats valid for -d/--date.
757
757
758 See :hg:`help revert` for a way to restore files to the state
758 See :hg:`help revert` for a way to restore files to the state
759 of another revision.
759 of another revision.
760
760
761 Returns 0 on success, 1 if nothing to backout or there are unresolved
761 Returns 0 on success, 1 if nothing to backout or there are unresolved
762 files.
762 files.
763 '''
763 '''
764 with repo.wlock(), repo.lock():
764 with repo.wlock(), repo.lock():
765 return _dobackout(ui, repo, node, rev, **opts)
765 return _dobackout(ui, repo, node, rev, **opts)
766
766
767
767
768 def _dobackout(ui, repo, node=None, rev=None, **opts):
768 def _dobackout(ui, repo, node=None, rev=None, **opts):
769 opts = pycompat.byteskwargs(opts)
769 opts = pycompat.byteskwargs(opts)
770 if opts.get(b'commit') and opts.get(b'no_commit'):
770 if opts.get(b'commit') and opts.get(b'no_commit'):
771 raise error.Abort(_(b"cannot use --commit with --no-commit"))
771 raise error.Abort(_(b"cannot use --commit with --no-commit"))
772 if opts.get(b'merge') and opts.get(b'no_commit'):
772 if opts.get(b'merge') and opts.get(b'no_commit'):
773 raise error.Abort(_(b"cannot use --merge with --no-commit"))
773 raise error.Abort(_(b"cannot use --merge with --no-commit"))
774
774
775 if rev and node:
775 if rev and node:
776 raise error.Abort(_(b"please specify just one revision"))
776 raise error.Abort(_(b"please specify just one revision"))
777
777
778 if not rev:
778 if not rev:
779 rev = node
779 rev = node
780
780
781 if not rev:
781 if not rev:
782 raise error.Abort(_(b"please specify a revision to backout"))
782 raise error.Abort(_(b"please specify a revision to backout"))
783
783
784 date = opts.get(b'date')
784 date = opts.get(b'date')
785 if date:
785 if date:
786 opts[b'date'] = dateutil.parsedate(date)
786 opts[b'date'] = dateutil.parsedate(date)
787
787
788 cmdutil.checkunfinished(repo)
788 cmdutil.checkunfinished(repo)
789 cmdutil.bailifchanged(repo)
789 cmdutil.bailifchanged(repo)
790 node = scmutil.revsingle(repo, rev).node()
790 node = scmutil.revsingle(repo, rev).node()
791
791
792 op1, op2 = repo.dirstate.parents()
792 op1, op2 = repo.dirstate.parents()
793 if not repo.changelog.isancestor(node, op1):
793 if not repo.changelog.isancestor(node, op1):
794 raise error.Abort(_(b'cannot backout change that is not an ancestor'))
794 raise error.Abort(_(b'cannot backout change that is not an ancestor'))
795
795
796 p1, p2 = repo.changelog.parents(node)
796 p1, p2 = repo.changelog.parents(node)
797 if p1 == nullid:
797 if p1 == nullid:
798 raise error.Abort(_(b'cannot backout a change with no parents'))
798 raise error.Abort(_(b'cannot backout a change with no parents'))
799 if p2 != nullid:
799 if p2 != nullid:
800 if not opts.get(b'parent'):
800 if not opts.get(b'parent'):
801 raise error.Abort(_(b'cannot backout a merge changeset'))
801 raise error.Abort(_(b'cannot backout a merge changeset'))
802 p = repo.lookup(opts[b'parent'])
802 p = repo.lookup(opts[b'parent'])
803 if p not in (p1, p2):
803 if p not in (p1, p2):
804 raise error.Abort(
804 raise error.Abort(
805 _(b'%s is not a parent of %s') % (short(p), short(node))
805 _(b'%s is not a parent of %s') % (short(p), short(node))
806 )
806 )
807 parent = p
807 parent = p
808 else:
808 else:
809 if opts.get(b'parent'):
809 if opts.get(b'parent'):
810 raise error.Abort(_(b'cannot use --parent on non-merge changeset'))
810 raise error.Abort(_(b'cannot use --parent on non-merge changeset'))
811 parent = p1
811 parent = p1
812
812
813 # the backout should appear on the same branch
813 # the backout should appear on the same branch
814 branch = repo.dirstate.branch()
814 branch = repo.dirstate.branch()
815 bheads = repo.branchheads(branch)
815 bheads = repo.branchheads(branch)
816 rctx = scmutil.revsingle(repo, hex(parent))
816 rctx = scmutil.revsingle(repo, hex(parent))
817 if not opts.get(b'merge') and op1 != node:
817 if not opts.get(b'merge') and op1 != node:
818 with dirstateguard.dirstateguard(repo, b'backout'):
818 with dirstateguard.dirstateguard(repo, b'backout'):
819 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
819 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
820 with ui.configoverride(overrides, b'backout'):
820 with ui.configoverride(overrides, b'backout'):
821 stats = mergemod.update(
821 stats = mergemod.update(
822 repo,
822 repo,
823 parent,
823 parent,
824 branchmerge=True,
824 branchmerge=True,
825 force=True,
825 force=True,
826 ancestor=node,
826 ancestor=node,
827 mergeancestor=False,
827 mergeancestor=False,
828 )
828 )
829 repo.setparents(op1, op2)
829 repo.setparents(op1, op2)
830 hg._showstats(repo, stats)
830 hg._showstats(repo, stats)
831 if stats.unresolvedcount:
831 if stats.unresolvedcount:
832 repo.ui.status(
832 repo.ui.status(
833 _(b"use 'hg resolve' to retry unresolved file merges\n")
833 _(b"use 'hg resolve' to retry unresolved file merges\n")
834 )
834 )
835 return 1
835 return 1
836 else:
836 else:
837 hg.clean(repo, node, show_stats=False)
837 hg.clean(repo, node, show_stats=False)
838 repo.dirstate.setbranch(branch)
838 repo.dirstate.setbranch(branch)
839 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
839 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
840
840
841 if opts.get(b'no_commit'):
841 if opts.get(b'no_commit'):
842 msg = _(b"changeset %s backed out, don't forget to commit.\n")
842 msg = _(b"changeset %s backed out, don't forget to commit.\n")
843 ui.status(msg % short(node))
843 ui.status(msg % short(node))
844 return 0
844 return 0
845
845
846 def commitfunc(ui, repo, message, match, opts):
846 def commitfunc(ui, repo, message, match, opts):
847 editform = b'backout'
847 editform = b'backout'
848 e = cmdutil.getcommiteditor(
848 e = cmdutil.getcommiteditor(
849 editform=editform, **pycompat.strkwargs(opts)
849 editform=editform, **pycompat.strkwargs(opts)
850 )
850 )
851 if not message:
851 if not message:
852 # we don't translate commit messages
852 # we don't translate commit messages
853 message = b"Backed out changeset %s" % short(node)
853 message = b"Backed out changeset %s" % short(node)
854 e = cmdutil.getcommiteditor(edit=True, editform=editform)
854 e = cmdutil.getcommiteditor(edit=True, editform=editform)
855 return repo.commit(
855 return repo.commit(
856 message, opts.get(b'user'), opts.get(b'date'), match, editor=e
856 message, opts.get(b'user'), opts.get(b'date'), match, editor=e
857 )
857 )
858
858
859 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
859 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
860 if not newnode:
860 if not newnode:
861 ui.status(_(b"nothing changed\n"))
861 ui.status(_(b"nothing changed\n"))
862 return 1
862 return 1
863 cmdutil.commitstatus(repo, newnode, branch, bheads)
863 cmdutil.commitstatus(repo, newnode, branch, bheads)
864
864
865 def nice(node):
865 def nice(node):
866 return b'%d:%s' % (repo.changelog.rev(node), short(node))
866 return b'%d:%s' % (repo.changelog.rev(node), short(node))
867
867
868 ui.status(
868 ui.status(
869 _(b'changeset %s backs out changeset %s\n')
869 _(b'changeset %s backs out changeset %s\n')
870 % (nice(repo.changelog.tip()), nice(node))
870 % (nice(repo.changelog.tip()), nice(node))
871 )
871 )
872 if opts.get(b'merge') and op1 != node:
872 if opts.get(b'merge') and op1 != node:
873 hg.clean(repo, op1, show_stats=False)
873 hg.clean(repo, op1, show_stats=False)
874 ui.status(
874 ui.status(
875 _(b'merging with changeset %s\n') % nice(repo.changelog.tip())
875 _(b'merging with changeset %s\n') % nice(repo.changelog.tip())
876 )
876 )
877 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
877 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
878 with ui.configoverride(overrides, b'backout'):
878 with ui.configoverride(overrides, b'backout'):
879 return hg.merge(repo, hex(repo.changelog.tip()))
879 return hg.merge(repo, hex(repo.changelog.tip()))
880 return 0
880 return 0
881
881
882
882
883 @command(
883 @command(
884 b'bisect',
884 b'bisect',
885 [
885 [
886 (b'r', b'reset', False, _(b'reset bisect state')),
886 (b'r', b'reset', False, _(b'reset bisect state')),
887 (b'g', b'good', False, _(b'mark changeset good')),
887 (b'g', b'good', False, _(b'mark changeset good')),
888 (b'b', b'bad', False, _(b'mark changeset bad')),
888 (b'b', b'bad', False, _(b'mark changeset bad')),
889 (b's', b'skip', False, _(b'skip testing changeset')),
889 (b's', b'skip', False, _(b'skip testing changeset')),
890 (b'e', b'extend', False, _(b'extend the bisect range')),
890 (b'e', b'extend', False, _(b'extend the bisect range')),
891 (
891 (
892 b'c',
892 b'c',
893 b'command',
893 b'command',
894 b'',
894 b'',
895 _(b'use command to check changeset state'),
895 _(b'use command to check changeset state'),
896 _(b'CMD'),
896 _(b'CMD'),
897 ),
897 ),
898 (b'U', b'noupdate', False, _(b'do not update to target')),
898 (b'U', b'noupdate', False, _(b'do not update to target')),
899 ],
899 ],
900 _(b"[-gbsr] [-U] [-c CMD] [REV]"),
900 _(b"[-gbsr] [-U] [-c CMD] [REV]"),
901 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
901 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
902 )
902 )
903 def bisect(
903 def bisect(
904 ui,
904 ui,
905 repo,
905 repo,
906 rev=None,
906 rev=None,
907 extra=None,
907 extra=None,
908 command=None,
908 command=None,
909 reset=None,
909 reset=None,
910 good=None,
910 good=None,
911 bad=None,
911 bad=None,
912 skip=None,
912 skip=None,
913 extend=None,
913 extend=None,
914 noupdate=None,
914 noupdate=None,
915 ):
915 ):
916 """subdivision search of changesets
916 """subdivision search of changesets
917
917
918 This command helps to find changesets which introduce problems. To
918 This command helps to find changesets which introduce problems. To
919 use, mark the earliest changeset you know exhibits the problem as
919 use, mark the earliest changeset you know exhibits the problem as
920 bad, then mark the latest changeset which is free from the problem
920 bad, then mark the latest changeset which is free from the problem
921 as good. Bisect will update your working directory to a revision
921 as good. Bisect will update your working directory to a revision
922 for testing (unless the -U/--noupdate option is specified). Once
922 for testing (unless the -U/--noupdate option is specified). Once
923 you have performed tests, mark the working directory as good or
923 you have performed tests, mark the working directory as good or
924 bad, and bisect will either update to another candidate changeset
924 bad, and bisect will either update to another candidate changeset
925 or announce that it has found the bad revision.
925 or announce that it has found the bad revision.
926
926
927 As a shortcut, you can also use the revision argument to mark a
927 As a shortcut, you can also use the revision argument to mark a
928 revision as good or bad without checking it out first.
928 revision as good or bad without checking it out first.
929
929
930 If you supply a command, it will be used for automatic bisection.
930 If you supply a command, it will be used for automatic bisection.
931 The environment variable HG_NODE will contain the ID of the
931 The environment variable HG_NODE will contain the ID of the
932 changeset being tested. The exit status of the command will be
932 changeset being tested. The exit status of the command will be
933 used to mark revisions as good or bad: status 0 means good, 125
933 used to mark revisions as good or bad: status 0 means good, 125
934 means to skip the revision, 127 (command not found) will abort the
934 means to skip the revision, 127 (command not found) will abort the
935 bisection, and any other non-zero exit status means the revision
935 bisection, and any other non-zero exit status means the revision
936 is bad.
936 is bad.
937
937
938 .. container:: verbose
938 .. container:: verbose
939
939
940 Some examples:
940 Some examples:
941
941
942 - start a bisection with known bad revision 34, and good revision 12::
942 - start a bisection with known bad revision 34, and good revision 12::
943
943
944 hg bisect --bad 34
944 hg bisect --bad 34
945 hg bisect --good 12
945 hg bisect --good 12
946
946
947 - advance the current bisection by marking current revision as good or
947 - advance the current bisection by marking current revision as good or
948 bad::
948 bad::
949
949
950 hg bisect --good
950 hg bisect --good
951 hg bisect --bad
951 hg bisect --bad
952
952
953 - mark the current revision, or a known revision, to be skipped (e.g. if
953 - mark the current revision, or a known revision, to be skipped (e.g. if
954 that revision is not usable because of another issue)::
954 that revision is not usable because of another issue)::
955
955
956 hg bisect --skip
956 hg bisect --skip
957 hg bisect --skip 23
957 hg bisect --skip 23
958
958
959 - skip all revisions that do not touch directories ``foo`` or ``bar``::
959 - skip all revisions that do not touch directories ``foo`` or ``bar``::
960
960
961 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
961 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
962
962
963 - forget the current bisection::
963 - forget the current bisection::
964
964
965 hg bisect --reset
965 hg bisect --reset
966
966
967 - use 'make && make tests' to automatically find the first broken
967 - use 'make && make tests' to automatically find the first broken
968 revision::
968 revision::
969
969
970 hg bisect --reset
970 hg bisect --reset
971 hg bisect --bad 34
971 hg bisect --bad 34
972 hg bisect --good 12
972 hg bisect --good 12
973 hg bisect --command "make && make tests"
973 hg bisect --command "make && make tests"
974
974
975 - see all changesets whose states are already known in the current
975 - see all changesets whose states are already known in the current
976 bisection::
976 bisection::
977
977
978 hg log -r "bisect(pruned)"
978 hg log -r "bisect(pruned)"
979
979
980 - see the changeset currently being bisected (especially useful
980 - see the changeset currently being bisected (especially useful
981 if running with -U/--noupdate)::
981 if running with -U/--noupdate)::
982
982
983 hg log -r "bisect(current)"
983 hg log -r "bisect(current)"
984
984
985 - see all changesets that took part in the current bisection::
985 - see all changesets that took part in the current bisection::
986
986
987 hg log -r "bisect(range)"
987 hg log -r "bisect(range)"
988
988
989 - you can even get a nice graph::
989 - you can even get a nice graph::
990
990
991 hg log --graph -r "bisect(range)"
991 hg log --graph -r "bisect(range)"
992
992
993 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
993 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
994
994
995 Returns 0 on success.
995 Returns 0 on success.
996 """
996 """
997 # backward compatibility
997 # backward compatibility
998 if rev in b"good bad reset init".split():
998 if rev in b"good bad reset init".split():
999 ui.warn(_(b"(use of 'hg bisect <cmd>' is deprecated)\n"))
999 ui.warn(_(b"(use of 'hg bisect <cmd>' is deprecated)\n"))
1000 cmd, rev, extra = rev, extra, None
1000 cmd, rev, extra = rev, extra, None
1001 if cmd == b"good":
1001 if cmd == b"good":
1002 good = True
1002 good = True
1003 elif cmd == b"bad":
1003 elif cmd == b"bad":
1004 bad = True
1004 bad = True
1005 else:
1005 else:
1006 reset = True
1006 reset = True
1007 elif extra:
1007 elif extra:
1008 raise error.Abort(_(b'incompatible arguments'))
1008 raise error.Abort(_(b'incompatible arguments'))
1009
1009
1010 incompatibles = {
1010 incompatibles = {
1011 b'--bad': bad,
1011 b'--bad': bad,
1012 b'--command': bool(command),
1012 b'--command': bool(command),
1013 b'--extend': extend,
1013 b'--extend': extend,
1014 b'--good': good,
1014 b'--good': good,
1015 b'--reset': reset,
1015 b'--reset': reset,
1016 b'--skip': skip,
1016 b'--skip': skip,
1017 }
1017 }
1018
1018
1019 enabled = [x for x in incompatibles if incompatibles[x]]
1019 enabled = [x for x in incompatibles if incompatibles[x]]
1020
1020
1021 if len(enabled) > 1:
1021 if len(enabled) > 1:
1022 raise error.Abort(
1022 raise error.Abort(
1023 _(b'%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
1023 _(b'%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
1024 )
1024 )
1025
1025
1026 if reset:
1026 if reset:
1027 hbisect.resetstate(repo)
1027 hbisect.resetstate(repo)
1028 return
1028 return
1029
1029
1030 state = hbisect.load_state(repo)
1030 state = hbisect.load_state(repo)
1031
1031
1032 # update state
1032 # update state
1033 if good or bad or skip:
1033 if good or bad or skip:
1034 if rev:
1034 if rev:
1035 nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
1035 nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
1036 else:
1036 else:
1037 nodes = [repo.lookup(b'.')]
1037 nodes = [repo.lookup(b'.')]
1038 if good:
1038 if good:
1039 state[b'good'] += nodes
1039 state[b'good'] += nodes
1040 elif bad:
1040 elif bad:
1041 state[b'bad'] += nodes
1041 state[b'bad'] += nodes
1042 elif skip:
1042 elif skip:
1043 state[b'skip'] += nodes
1043 state[b'skip'] += nodes
1044 hbisect.save_state(repo, state)
1044 hbisect.save_state(repo, state)
1045 if not (state[b'good'] and state[b'bad']):
1045 if not (state[b'good'] and state[b'bad']):
1046 return
1046 return
1047
1047
1048 def mayupdate(repo, node, show_stats=True):
1048 def mayupdate(repo, node, show_stats=True):
1049 """common used update sequence"""
1049 """common used update sequence"""
1050 if noupdate:
1050 if noupdate:
1051 return
1051 return
1052 cmdutil.checkunfinished(repo)
1052 cmdutil.checkunfinished(repo)
1053 cmdutil.bailifchanged(repo)
1053 cmdutil.bailifchanged(repo)
1054 return hg.clean(repo, node, show_stats=show_stats)
1054 return hg.clean(repo, node, show_stats=show_stats)
1055
1055
1056 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
1056 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
1057
1057
1058 if command:
1058 if command:
1059 changesets = 1
1059 changesets = 1
1060 if noupdate:
1060 if noupdate:
1061 try:
1061 try:
1062 node = state[b'current'][0]
1062 node = state[b'current'][0]
1063 except LookupError:
1063 except LookupError:
1064 raise error.Abort(
1064 raise error.Abort(
1065 _(
1065 _(
1066 b'current bisect revision is unknown - '
1066 b'current bisect revision is unknown - '
1067 b'start a new bisect to fix'
1067 b'start a new bisect to fix'
1068 )
1068 )
1069 )
1069 )
1070 else:
1070 else:
1071 node, p2 = repo.dirstate.parents()
1071 node, p2 = repo.dirstate.parents()
1072 if p2 != nullid:
1072 if p2 != nullid:
1073 raise error.Abort(_(b'current bisect revision is a merge'))
1073 raise error.Abort(_(b'current bisect revision is a merge'))
1074 if rev:
1074 if rev:
1075 node = repo[scmutil.revsingle(repo, rev, node)].node()
1075 node = repo[scmutil.revsingle(repo, rev, node)].node()
1076 try:
1076 try:
1077 while changesets:
1077 while changesets:
1078 # update state
1078 # update state
1079 state[b'current'] = [node]
1079 state[b'current'] = [node]
1080 hbisect.save_state(repo, state)
1080 hbisect.save_state(repo, state)
1081 status = ui.system(
1081 status = ui.system(
1082 command,
1082 command,
1083 environ={b'HG_NODE': hex(node)},
1083 environ={b'HG_NODE': hex(node)},
1084 blockedtag=b'bisect_check',
1084 blockedtag=b'bisect_check',
1085 )
1085 )
1086 if status == 125:
1086 if status == 125:
1087 transition = b"skip"
1087 transition = b"skip"
1088 elif status == 0:
1088 elif status == 0:
1089 transition = b"good"
1089 transition = b"good"
1090 # status < 0 means process was killed
1090 # status < 0 means process was killed
1091 elif status == 127:
1091 elif status == 127:
1092 raise error.Abort(_(b"failed to execute %s") % command)
1092 raise error.Abort(_(b"failed to execute %s") % command)
1093 elif status < 0:
1093 elif status < 0:
1094 raise error.Abort(_(b"%s killed") % command)
1094 raise error.Abort(_(b"%s killed") % command)
1095 else:
1095 else:
1096 transition = b"bad"
1096 transition = b"bad"
1097 state[transition].append(node)
1097 state[transition].append(node)
1098 ctx = repo[node]
1098 ctx = repo[node]
1099 ui.status(
1099 ui.status(
1100 _(b'changeset %d:%s: %s\n') % (ctx.rev(), ctx, transition)
1100 _(b'changeset %d:%s: %s\n') % (ctx.rev(), ctx, transition)
1101 )
1101 )
1102 hbisect.checkstate(state)
1102 hbisect.checkstate(state)
1103 # bisect
1103 # bisect
1104 nodes, changesets, bgood = hbisect.bisect(repo, state)
1104 nodes, changesets, bgood = hbisect.bisect(repo, state)
1105 # update to next check
1105 # update to next check
1106 node = nodes[0]
1106 node = nodes[0]
1107 mayupdate(repo, node, show_stats=False)
1107 mayupdate(repo, node, show_stats=False)
1108 finally:
1108 finally:
1109 state[b'current'] = [node]
1109 state[b'current'] = [node]
1110 hbisect.save_state(repo, state)
1110 hbisect.save_state(repo, state)
1111 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
1111 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
1112 return
1112 return
1113
1113
1114 hbisect.checkstate(state)
1114 hbisect.checkstate(state)
1115
1115
1116 # actually bisect
1116 # actually bisect
1117 nodes, changesets, good = hbisect.bisect(repo, state)
1117 nodes, changesets, good = hbisect.bisect(repo, state)
1118 if extend:
1118 if extend:
1119 if not changesets:
1119 if not changesets:
1120 extendnode = hbisect.extendrange(repo, state, nodes, good)
1120 extendnode = hbisect.extendrange(repo, state, nodes, good)
1121 if extendnode is not None:
1121 if extendnode is not None:
1122 ui.write(
1122 ui.write(
1123 _(b"Extending search to changeset %d:%s\n")
1123 _(b"Extending search to changeset %d:%s\n")
1124 % (extendnode.rev(), extendnode)
1124 % (extendnode.rev(), extendnode)
1125 )
1125 )
1126 state[b'current'] = [extendnode.node()]
1126 state[b'current'] = [extendnode.node()]
1127 hbisect.save_state(repo, state)
1127 hbisect.save_state(repo, state)
1128 return mayupdate(repo, extendnode.node())
1128 return mayupdate(repo, extendnode.node())
1129 raise error.Abort(_(b"nothing to extend"))
1129 raise error.Abort(_(b"nothing to extend"))
1130
1130
1131 if changesets == 0:
1131 if changesets == 0:
1132 hbisect.printresult(ui, repo, state, displayer, nodes, good)
1132 hbisect.printresult(ui, repo, state, displayer, nodes, good)
1133 else:
1133 else:
1134 assert len(nodes) == 1 # only a single node can be tested next
1134 assert len(nodes) == 1 # only a single node can be tested next
1135 node = nodes[0]
1135 node = nodes[0]
1136 # compute the approximate number of remaining tests
1136 # compute the approximate number of remaining tests
1137 tests, size = 0, 2
1137 tests, size = 0, 2
1138 while size <= changesets:
1138 while size <= changesets:
1139 tests, size = tests + 1, size * 2
1139 tests, size = tests + 1, size * 2
1140 rev = repo.changelog.rev(node)
1140 rev = repo.changelog.rev(node)
1141 ui.write(
1141 ui.write(
1142 _(
1142 _(
1143 b"Testing changeset %d:%s "
1143 b"Testing changeset %d:%s "
1144 b"(%d changesets remaining, ~%d tests)\n"
1144 b"(%d changesets remaining, ~%d tests)\n"
1145 )
1145 )
1146 % (rev, short(node), changesets, tests)
1146 % (rev, short(node), changesets, tests)
1147 )
1147 )
1148 state[b'current'] = [node]
1148 state[b'current'] = [node]
1149 hbisect.save_state(repo, state)
1149 hbisect.save_state(repo, state)
1150 return mayupdate(repo, node)
1150 return mayupdate(repo, node)
1151
1151
1152
1152
1153 @command(
1153 @command(
1154 b'bookmarks|bookmark',
1154 b'bookmarks|bookmark',
1155 [
1155 [
1156 (b'f', b'force', False, _(b'force')),
1156 (b'f', b'force', False, _(b'force')),
1157 (b'r', b'rev', b'', _(b'revision for bookmark action'), _(b'REV')),
1157 (b'r', b'rev', b'', _(b'revision for bookmark action'), _(b'REV')),
1158 (b'd', b'delete', False, _(b'delete a given bookmark')),
1158 (b'd', b'delete', False, _(b'delete a given bookmark')),
1159 (b'm', b'rename', b'', _(b'rename a given bookmark'), _(b'OLD')),
1159 (b'm', b'rename', b'', _(b'rename a given bookmark'), _(b'OLD')),
1160 (b'i', b'inactive', False, _(b'mark a bookmark inactive')),
1160 (b'i', b'inactive', False, _(b'mark a bookmark inactive')),
1161 (b'l', b'list', False, _(b'list existing bookmarks')),
1161 (b'l', b'list', False, _(b'list existing bookmarks')),
1162 ]
1162 ]
1163 + formatteropts,
1163 + formatteropts,
1164 _(b'hg bookmarks [OPTIONS]... [NAME]...'),
1164 _(b'hg bookmarks [OPTIONS]... [NAME]...'),
1165 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1165 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1166 )
1166 )
1167 def bookmark(ui, repo, *names, **opts):
1167 def bookmark(ui, repo, *names, **opts):
1168 '''create a new bookmark or list existing bookmarks
1168 '''create a new bookmark or list existing bookmarks
1169
1169
1170 Bookmarks are labels on changesets to help track lines of development.
1170 Bookmarks are labels on changesets to help track lines of development.
1171 Bookmarks are unversioned and can be moved, renamed and deleted.
1171 Bookmarks are unversioned and can be moved, renamed and deleted.
1172 Deleting or moving a bookmark has no effect on the associated changesets.
1172 Deleting or moving a bookmark has no effect on the associated changesets.
1173
1173
1174 Creating or updating to a bookmark causes it to be marked as 'active'.
1174 Creating or updating to a bookmark causes it to be marked as 'active'.
1175 The active bookmark is indicated with a '*'.
1175 The active bookmark is indicated with a '*'.
1176 When a commit is made, the active bookmark will advance to the new commit.
1176 When a commit is made, the active bookmark will advance to the new commit.
1177 A plain :hg:`update` will also advance an active bookmark, if possible.
1177 A plain :hg:`update` will also advance an active bookmark, if possible.
1178 Updating away from a bookmark will cause it to be deactivated.
1178 Updating away from a bookmark will cause it to be deactivated.
1179
1179
1180 Bookmarks can be pushed and pulled between repositories (see
1180 Bookmarks can be pushed and pulled between repositories (see
1181 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
1181 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
1182 diverged, a new 'divergent bookmark' of the form 'name@path' will
1182 diverged, a new 'divergent bookmark' of the form 'name@path' will
1183 be created. Using :hg:`merge` will resolve the divergence.
1183 be created. Using :hg:`merge` will resolve the divergence.
1184
1184
1185 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
1185 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
1186 the active bookmark's name.
1186 the active bookmark's name.
1187
1187
1188 A bookmark named '@' has the special property that :hg:`clone` will
1188 A bookmark named '@' has the special property that :hg:`clone` will
1189 check it out by default if it exists.
1189 check it out by default if it exists.
1190
1190
1191 .. container:: verbose
1191 .. container:: verbose
1192
1192
1193 Template:
1193 Template:
1194
1194
1195 The following keywords are supported in addition to the common template
1195 The following keywords are supported in addition to the common template
1196 keywords and functions such as ``{bookmark}``. See also
1196 keywords and functions such as ``{bookmark}``. See also
1197 :hg:`help templates`.
1197 :hg:`help templates`.
1198
1198
1199 :active: Boolean. True if the bookmark is active.
1199 :active: Boolean. True if the bookmark is active.
1200
1200
1201 Examples:
1201 Examples:
1202
1202
1203 - create an active bookmark for a new line of development::
1203 - create an active bookmark for a new line of development::
1204
1204
1205 hg book new-feature
1205 hg book new-feature
1206
1206
1207 - create an inactive bookmark as a place marker::
1207 - create an inactive bookmark as a place marker::
1208
1208
1209 hg book -i reviewed
1209 hg book -i reviewed
1210
1210
1211 - create an inactive bookmark on another changeset::
1211 - create an inactive bookmark on another changeset::
1212
1212
1213 hg book -r .^ tested
1213 hg book -r .^ tested
1214
1214
1215 - rename bookmark turkey to dinner::
1215 - rename bookmark turkey to dinner::
1216
1216
1217 hg book -m turkey dinner
1217 hg book -m turkey dinner
1218
1218
1219 - move the '@' bookmark from another branch::
1219 - move the '@' bookmark from another branch::
1220
1220
1221 hg book -f @
1221 hg book -f @
1222
1222
1223 - print only the active bookmark name::
1223 - print only the active bookmark name::
1224
1224
1225 hg book -ql .
1225 hg book -ql .
1226 '''
1226 '''
1227 opts = pycompat.byteskwargs(opts)
1227 opts = pycompat.byteskwargs(opts)
1228 force = opts.get(b'force')
1228 force = opts.get(b'force')
1229 rev = opts.get(b'rev')
1229 rev = opts.get(b'rev')
1230 inactive = opts.get(b'inactive') # meaning add/rename to inactive bookmark
1230 inactive = opts.get(b'inactive') # meaning add/rename to inactive bookmark
1231
1231
1232 selactions = [k for k in [b'delete', b'rename', b'list'] if opts.get(k)]
1232 selactions = [k for k in [b'delete', b'rename', b'list'] if opts.get(k)]
1233 if len(selactions) > 1:
1233 if len(selactions) > 1:
1234 raise error.Abort(
1234 raise error.Abort(
1235 _(b'--%s and --%s are incompatible') % tuple(selactions[:2])
1235 _(b'--%s and --%s are incompatible') % tuple(selactions[:2])
1236 )
1236 )
1237 if selactions:
1237 if selactions:
1238 action = selactions[0]
1238 action = selactions[0]
1239 elif names or rev:
1239 elif names or rev:
1240 action = b'add'
1240 action = b'add'
1241 elif inactive:
1241 elif inactive:
1242 action = b'inactive' # meaning deactivate
1242 action = b'inactive' # meaning deactivate
1243 else:
1243 else:
1244 action = b'list'
1244 action = b'list'
1245
1245
1246 if rev and action in {b'delete', b'rename', b'list'}:
1246 if rev and action in {b'delete', b'rename', b'list'}:
1247 raise error.Abort(_(b"--rev is incompatible with --%s") % action)
1247 raise error.Abort(_(b"--rev is incompatible with --%s") % action)
1248 if inactive and action in {b'delete', b'list'}:
1248 if inactive and action in {b'delete', b'list'}:
1249 raise error.Abort(_(b"--inactive is incompatible with --%s") % action)
1249 raise error.Abort(_(b"--inactive is incompatible with --%s") % action)
1250 if not names and action in {b'add', b'delete'}:
1250 if not names and action in {b'add', b'delete'}:
1251 raise error.Abort(_(b"bookmark name required"))
1251 raise error.Abort(_(b"bookmark name required"))
1252
1252
1253 if action in {b'add', b'delete', b'rename', b'inactive'}:
1253 if action in {b'add', b'delete', b'rename', b'inactive'}:
1254 with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
1254 with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
1255 if action == b'delete':
1255 if action == b'delete':
1256 names = pycompat.maplist(repo._bookmarks.expandname, names)
1256 names = pycompat.maplist(repo._bookmarks.expandname, names)
1257 bookmarks.delete(repo, tr, names)
1257 bookmarks.delete(repo, tr, names)
1258 elif action == b'rename':
1258 elif action == b'rename':
1259 if not names:
1259 if not names:
1260 raise error.Abort(_(b"new bookmark name required"))
1260 raise error.Abort(_(b"new bookmark name required"))
1261 elif len(names) > 1:
1261 elif len(names) > 1:
1262 raise error.Abort(_(b"only one new bookmark name allowed"))
1262 raise error.Abort(_(b"only one new bookmark name allowed"))
1263 oldname = repo._bookmarks.expandname(opts[b'rename'])
1263 oldname = repo._bookmarks.expandname(opts[b'rename'])
1264 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1264 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1265 elif action == b'add':
1265 elif action == b'add':
1266 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1266 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1267 elif action == b'inactive':
1267 elif action == b'inactive':
1268 if len(repo._bookmarks) == 0:
1268 if len(repo._bookmarks) == 0:
1269 ui.status(_(b"no bookmarks set\n"))
1269 ui.status(_(b"no bookmarks set\n"))
1270 elif not repo._activebookmark:
1270 elif not repo._activebookmark:
1271 ui.status(_(b"no active bookmark\n"))
1271 ui.status(_(b"no active bookmark\n"))
1272 else:
1272 else:
1273 bookmarks.deactivate(repo)
1273 bookmarks.deactivate(repo)
1274 elif action == b'list':
1274 elif action == b'list':
1275 names = pycompat.maplist(repo._bookmarks.expandname, names)
1275 names = pycompat.maplist(repo._bookmarks.expandname, names)
1276 with ui.formatter(b'bookmarks', opts) as fm:
1276 with ui.formatter(b'bookmarks', opts) as fm:
1277 bookmarks.printbookmarks(ui, repo, fm, names)
1277 bookmarks.printbookmarks(ui, repo, fm, names)
1278 else:
1278 else:
1279 raise error.ProgrammingError(b'invalid action: %s' % action)
1279 raise error.ProgrammingError(b'invalid action: %s' % action)
1280
1280
1281
1281
1282 @command(
1282 @command(
1283 b'branch',
1283 b'branch',
1284 [
1284 [
1285 (
1285 (
1286 b'f',
1286 b'f',
1287 b'force',
1287 b'force',
1288 None,
1288 None,
1289 _(b'set branch name even if it shadows an existing branch'),
1289 _(b'set branch name even if it shadows an existing branch'),
1290 ),
1290 ),
1291 (b'C', b'clean', None, _(b'reset branch name to parent branch name')),
1291 (b'C', b'clean', None, _(b'reset branch name to parent branch name')),
1292 (
1292 (
1293 b'r',
1293 b'r',
1294 b'rev',
1294 b'rev',
1295 [],
1295 [],
1296 _(b'change branches of the given revs (EXPERIMENTAL)'),
1296 _(b'change branches of the given revs (EXPERIMENTAL)'),
1297 ),
1297 ),
1298 ],
1298 ],
1299 _(b'[-fC] [NAME]'),
1299 _(b'[-fC] [NAME]'),
1300 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1300 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1301 )
1301 )
1302 def branch(ui, repo, label=None, **opts):
1302 def branch(ui, repo, label=None, **opts):
1303 """set or show the current branch name
1303 """set or show the current branch name
1304
1304
1305 .. note::
1305 .. note::
1306
1306
1307 Branch names are permanent and global. Use :hg:`bookmark` to create a
1307 Branch names are permanent and global. Use :hg:`bookmark` to create a
1308 light-weight bookmark instead. See :hg:`help glossary` for more
1308 light-weight bookmark instead. See :hg:`help glossary` for more
1309 information about named branches and bookmarks.
1309 information about named branches and bookmarks.
1310
1310
1311 With no argument, show the current branch name. With one argument,
1311 With no argument, show the current branch name. With one argument,
1312 set the working directory branch name (the branch will not exist
1312 set the working directory branch name (the branch will not exist
1313 in the repository until the next commit). Standard practice
1313 in the repository until the next commit). Standard practice
1314 recommends that primary development take place on the 'default'
1314 recommends that primary development take place on the 'default'
1315 branch.
1315 branch.
1316
1316
1317 Unless -f/--force is specified, branch will not let you set a
1317 Unless -f/--force is specified, branch will not let you set a
1318 branch name that already exists.
1318 branch name that already exists.
1319
1319
1320 Use -C/--clean to reset the working directory branch to that of
1320 Use -C/--clean to reset the working directory branch to that of
1321 the parent of the working directory, negating a previous branch
1321 the parent of the working directory, negating a previous branch
1322 change.
1322 change.
1323
1323
1324 Use the command :hg:`update` to switch to an existing branch. Use
1324 Use the command :hg:`update` to switch to an existing branch. Use
1325 :hg:`commit --close-branch` to mark this branch head as closed.
1325 :hg:`commit --close-branch` to mark this branch head as closed.
1326 When all heads of a branch are closed, the branch will be
1326 When all heads of a branch are closed, the branch will be
1327 considered closed.
1327 considered closed.
1328
1328
1329 Returns 0 on success.
1329 Returns 0 on success.
1330 """
1330 """
1331 opts = pycompat.byteskwargs(opts)
1331 opts = pycompat.byteskwargs(opts)
1332 revs = opts.get(b'rev')
1332 revs = opts.get(b'rev')
1333 if label:
1333 if label:
1334 label = label.strip()
1334 label = label.strip()
1335
1335
1336 if not opts.get(b'clean') and not label:
1336 if not opts.get(b'clean') and not label:
1337 if revs:
1337 if revs:
1338 raise error.Abort(_(b"no branch name specified for the revisions"))
1338 raise error.Abort(_(b"no branch name specified for the revisions"))
1339 ui.write(b"%s\n" % repo.dirstate.branch())
1339 ui.write(b"%s\n" % repo.dirstate.branch())
1340 return
1340 return
1341
1341
1342 with repo.wlock():
1342 with repo.wlock():
1343 if opts.get(b'clean'):
1343 if opts.get(b'clean'):
1344 label = repo[b'.'].branch()
1344 label = repo[b'.'].branch()
1345 repo.dirstate.setbranch(label)
1345 repo.dirstate.setbranch(label)
1346 ui.status(_(b'reset working directory to branch %s\n') % label)
1346 ui.status(_(b'reset working directory to branch %s\n') % label)
1347 elif label:
1347 elif label:
1348
1348
1349 scmutil.checknewlabel(repo, label, b'branch')
1349 scmutil.checknewlabel(repo, label, b'branch')
1350 if revs:
1350 if revs:
1351 return cmdutil.changebranch(ui, repo, revs, label)
1351 return cmdutil.changebranch(ui, repo, revs, label)
1352
1352
1353 if not opts.get(b'force') and label in repo.branchmap():
1353 if not opts.get(b'force') and label in repo.branchmap():
1354 if label not in [p.branch() for p in repo[None].parents()]:
1354 if label not in [p.branch() for p in repo[None].parents()]:
1355 raise error.Abort(
1355 raise error.Abort(
1356 _(b'a branch of the same name already exists'),
1356 _(b'a branch of the same name already exists'),
1357 # i18n: "it" refers to an existing branch
1357 # i18n: "it" refers to an existing branch
1358 hint=_(b"use 'hg update' to switch to it"),
1358 hint=_(b"use 'hg update' to switch to it"),
1359 )
1359 )
1360
1360
1361 repo.dirstate.setbranch(label)
1361 repo.dirstate.setbranch(label)
1362 ui.status(_(b'marked working directory as branch %s\n') % label)
1362 ui.status(_(b'marked working directory as branch %s\n') % label)
1363
1363
1364 # find any open named branches aside from default
1364 # find any open named branches aside from default
1365 for n, h, t, c in repo.branchmap().iterbranches():
1365 for n, h, t, c in repo.branchmap().iterbranches():
1366 if n != b"default" and not c:
1366 if n != b"default" and not c:
1367 return 0
1367 return 0
1368 ui.status(
1368 ui.status(
1369 _(
1369 _(
1370 b'(branches are permanent and global, '
1370 b'(branches are permanent and global, '
1371 b'did you want a bookmark?)\n'
1371 b'did you want a bookmark?)\n'
1372 )
1372 )
1373 )
1373 )
1374
1374
1375
1375
1376 @command(
1376 @command(
1377 b'branches',
1377 b'branches',
1378 [
1378 [
1379 (
1379 (
1380 b'a',
1380 b'a',
1381 b'active',
1381 b'active',
1382 False,
1382 False,
1383 _(b'show only branches that have unmerged heads (DEPRECATED)'),
1383 _(b'show only branches that have unmerged heads (DEPRECATED)'),
1384 ),
1384 ),
1385 (b'c', b'closed', False, _(b'show normal and closed branches')),
1385 (b'c', b'closed', False, _(b'show normal and closed branches')),
1386 (b'r', b'rev', [], _(b'show branch name(s) of the given rev')),
1386 (b'r', b'rev', [], _(b'show branch name(s) of the given rev')),
1387 ]
1387 ]
1388 + formatteropts,
1388 + formatteropts,
1389 _(b'[-c]'),
1389 _(b'[-c]'),
1390 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1390 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1391 intents={INTENT_READONLY},
1391 intents={INTENT_READONLY},
1392 )
1392 )
1393 def branches(ui, repo, active=False, closed=False, **opts):
1393 def branches(ui, repo, active=False, closed=False, **opts):
1394 """list repository named branches
1394 """list repository named branches
1395
1395
1396 List the repository's named branches, indicating which ones are
1396 List the repository's named branches, indicating which ones are
1397 inactive. If -c/--closed is specified, also list branches which have
1397 inactive. If -c/--closed is specified, also list branches which have
1398 been marked closed (see :hg:`commit --close-branch`).
1398 been marked closed (see :hg:`commit --close-branch`).
1399
1399
1400 Use the command :hg:`update` to switch to an existing branch.
1400 Use the command :hg:`update` to switch to an existing branch.
1401
1401
1402 .. container:: verbose
1402 .. container:: verbose
1403
1403
1404 Template:
1404 Template:
1405
1405
1406 The following keywords are supported in addition to the common template
1406 The following keywords are supported in addition to the common template
1407 keywords and functions such as ``{branch}``. See also
1407 keywords and functions such as ``{branch}``. See also
1408 :hg:`help templates`.
1408 :hg:`help templates`.
1409
1409
1410 :active: Boolean. True if the branch is active.
1410 :active: Boolean. True if the branch is active.
1411 :closed: Boolean. True if the branch is closed.
1411 :closed: Boolean. True if the branch is closed.
1412 :current: Boolean. True if it is the current branch.
1412 :current: Boolean. True if it is the current branch.
1413
1413
1414 Returns 0.
1414 Returns 0.
1415 """
1415 """
1416
1416
1417 opts = pycompat.byteskwargs(opts)
1417 opts = pycompat.byteskwargs(opts)
1418 revs = opts.get(b'rev')
1418 revs = opts.get(b'rev')
1419 selectedbranches = None
1419 selectedbranches = None
1420 if revs:
1420 if revs:
1421 revs = scmutil.revrange(repo, revs)
1421 revs = scmutil.revrange(repo, revs)
1422 getbi = repo.revbranchcache().branchinfo
1422 getbi = repo.revbranchcache().branchinfo
1423 selectedbranches = {getbi(r)[0] for r in revs}
1423 selectedbranches = {getbi(r)[0] for r in revs}
1424
1424
1425 ui.pager(b'branches')
1425 ui.pager(b'branches')
1426 fm = ui.formatter(b'branches', opts)
1426 fm = ui.formatter(b'branches', opts)
1427 hexfunc = fm.hexfunc
1427 hexfunc = fm.hexfunc
1428
1428
1429 allheads = set(repo.heads())
1429 allheads = set(repo.heads())
1430 branches = []
1430 branches = []
1431 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1431 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1432 if selectedbranches is not None and tag not in selectedbranches:
1432 if selectedbranches is not None and tag not in selectedbranches:
1433 continue
1433 continue
1434 isactive = False
1434 isactive = False
1435 if not isclosed:
1435 if not isclosed:
1436 openheads = set(repo.branchmap().iteropen(heads))
1436 openheads = set(repo.branchmap().iteropen(heads))
1437 isactive = bool(openheads & allheads)
1437 isactive = bool(openheads & allheads)
1438 branches.append((tag, repo[tip], isactive, not isclosed))
1438 branches.append((tag, repo[tip], isactive, not isclosed))
1439 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]), reverse=True)
1439 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]), reverse=True)
1440
1440
1441 for tag, ctx, isactive, isopen in branches:
1441 for tag, ctx, isactive, isopen in branches:
1442 if active and not isactive:
1442 if active and not isactive:
1443 continue
1443 continue
1444 if isactive:
1444 if isactive:
1445 label = b'branches.active'
1445 label = b'branches.active'
1446 notice = b''
1446 notice = b''
1447 elif not isopen:
1447 elif not isopen:
1448 if not closed:
1448 if not closed:
1449 continue
1449 continue
1450 label = b'branches.closed'
1450 label = b'branches.closed'
1451 notice = _(b' (closed)')
1451 notice = _(b' (closed)')
1452 else:
1452 else:
1453 label = b'branches.inactive'
1453 label = b'branches.inactive'
1454 notice = _(b' (inactive)')
1454 notice = _(b' (inactive)')
1455 current = tag == repo.dirstate.branch()
1455 current = tag == repo.dirstate.branch()
1456 if current:
1456 if current:
1457 label = b'branches.current'
1457 label = b'branches.current'
1458
1458
1459 fm.startitem()
1459 fm.startitem()
1460 fm.write(b'branch', b'%s', tag, label=label)
1460 fm.write(b'branch', b'%s', tag, label=label)
1461 rev = ctx.rev()
1461 rev = ctx.rev()
1462 padsize = max(31 - len(b"%d" % rev) - encoding.colwidth(tag), 0)
1462 padsize = max(31 - len(b"%d" % rev) - encoding.colwidth(tag), 0)
1463 fmt = b' ' * padsize + b' %d:%s'
1463 fmt = b' ' * padsize + b' %d:%s'
1464 fm.condwrite(
1464 fm.condwrite(
1465 not ui.quiet,
1465 not ui.quiet,
1466 b'rev node',
1466 b'rev node',
1467 fmt,
1467 fmt,
1468 rev,
1468 rev,
1469 hexfunc(ctx.node()),
1469 hexfunc(ctx.node()),
1470 label=b'log.changeset changeset.%s' % ctx.phasestr(),
1470 label=b'log.changeset changeset.%s' % ctx.phasestr(),
1471 )
1471 )
1472 fm.context(ctx=ctx)
1472 fm.context(ctx=ctx)
1473 fm.data(active=isactive, closed=not isopen, current=current)
1473 fm.data(active=isactive, closed=not isopen, current=current)
1474 if not ui.quiet:
1474 if not ui.quiet:
1475 fm.plain(notice)
1475 fm.plain(notice)
1476 fm.plain(b'\n')
1476 fm.plain(b'\n')
1477 fm.end()
1477 fm.end()
1478
1478
1479
1479
1480 @command(
1480 @command(
1481 b'bundle',
1481 b'bundle',
1482 [
1482 [
1483 (
1483 (
1484 b'f',
1484 b'f',
1485 b'force',
1485 b'force',
1486 None,
1486 None,
1487 _(b'run even when the destination is unrelated'),
1487 _(b'run even when the destination is unrelated'),
1488 ),
1488 ),
1489 (
1489 (
1490 b'r',
1490 b'r',
1491 b'rev',
1491 b'rev',
1492 [],
1492 [],
1493 _(b'a changeset intended to be added to the destination'),
1493 _(b'a changeset intended to be added to the destination'),
1494 _(b'REV'),
1494 _(b'REV'),
1495 ),
1495 ),
1496 (
1496 (
1497 b'b',
1497 b'b',
1498 b'branch',
1498 b'branch',
1499 [],
1499 [],
1500 _(b'a specific branch you would like to bundle'),
1500 _(b'a specific branch you would like to bundle'),
1501 _(b'BRANCH'),
1501 _(b'BRANCH'),
1502 ),
1502 ),
1503 (
1503 (
1504 b'',
1504 b'',
1505 b'base',
1505 b'base',
1506 [],
1506 [],
1507 _(b'a base changeset assumed to be available at the destination'),
1507 _(b'a base changeset assumed to be available at the destination'),
1508 _(b'REV'),
1508 _(b'REV'),
1509 ),
1509 ),
1510 (b'a', b'all', None, _(b'bundle all changesets in the repository')),
1510 (b'a', b'all', None, _(b'bundle all changesets in the repository')),
1511 (
1511 (
1512 b't',
1512 b't',
1513 b'type',
1513 b'type',
1514 b'bzip2',
1514 b'bzip2',
1515 _(b'bundle compression type to use'),
1515 _(b'bundle compression type to use'),
1516 _(b'TYPE'),
1516 _(b'TYPE'),
1517 ),
1517 ),
1518 ]
1518 ]
1519 + remoteopts,
1519 + remoteopts,
1520 _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1520 _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1521 helpcategory=command.CATEGORY_IMPORT_EXPORT,
1521 helpcategory=command.CATEGORY_IMPORT_EXPORT,
1522 )
1522 )
1523 def bundle(ui, repo, fname, dest=None, **opts):
1523 def bundle(ui, repo, fname, dest=None, **opts):
1524 """create a bundle file
1524 """create a bundle file
1525
1525
1526 Generate a bundle file containing data to be transferred to another
1526 Generate a bundle file containing data to be transferred to another
1527 repository.
1527 repository.
1528
1528
1529 To create a bundle containing all changesets, use -a/--all
1529 To create a bundle containing all changesets, use -a/--all
1530 (or --base null). Otherwise, hg assumes the destination will have
1530 (or --base null). Otherwise, hg assumes the destination will have
1531 all the nodes you specify with --base parameters. Otherwise, hg
1531 all the nodes you specify with --base parameters. Otherwise, hg
1532 will assume the repository has all the nodes in destination, or
1532 will assume the repository has all the nodes in destination, or
1533 default-push/default if no destination is specified, where destination
1533 default-push/default if no destination is specified, where destination
1534 is the repository you provide through DEST option.
1534 is the repository you provide through DEST option.
1535
1535
1536 You can change bundle format with the -t/--type option. See
1536 You can change bundle format with the -t/--type option. See
1537 :hg:`help bundlespec` for documentation on this format. By default,
1537 :hg:`help bundlespec` for documentation on this format. By default,
1538 the most appropriate format is used and compression defaults to
1538 the most appropriate format is used and compression defaults to
1539 bzip2.
1539 bzip2.
1540
1540
1541 The bundle file can then be transferred using conventional means
1541 The bundle file can then be transferred using conventional means
1542 and applied to another repository with the unbundle or pull
1542 and applied to another repository with the unbundle or pull
1543 command. This is useful when direct push and pull are not
1543 command. This is useful when direct push and pull are not
1544 available or when exporting an entire repository is undesirable.
1544 available or when exporting an entire repository is undesirable.
1545
1545
1546 Applying bundles preserves all changeset contents including
1546 Applying bundles preserves all changeset contents including
1547 permissions, copy/rename information, and revision history.
1547 permissions, copy/rename information, and revision history.
1548
1548
1549 Returns 0 on success, 1 if no changes found.
1549 Returns 0 on success, 1 if no changes found.
1550 """
1550 """
1551 opts = pycompat.byteskwargs(opts)
1551 opts = pycompat.byteskwargs(opts)
1552 revs = None
1552 revs = None
1553 if b'rev' in opts:
1553 if b'rev' in opts:
1554 revstrings = opts[b'rev']
1554 revstrings = opts[b'rev']
1555 revs = scmutil.revrange(repo, revstrings)
1555 revs = scmutil.revrange(repo, revstrings)
1556 if revstrings and not revs:
1556 if revstrings and not revs:
1557 raise error.Abort(_(b'no commits to bundle'))
1557 raise error.Abort(_(b'no commits to bundle'))
1558
1558
1559 bundletype = opts.get(b'type', b'bzip2').lower()
1559 bundletype = opts.get(b'type', b'bzip2').lower()
1560 try:
1560 try:
1561 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
1561 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
1562 except error.UnsupportedBundleSpecification as e:
1562 except error.UnsupportedBundleSpecification as e:
1563 raise error.Abort(
1563 raise error.Abort(
1564 pycompat.bytestr(e),
1564 pycompat.bytestr(e),
1565 hint=_(b"see 'hg help bundlespec' for supported values for --type"),
1565 hint=_(b"see 'hg help bundlespec' for supported values for --type"),
1566 )
1566 )
1567 cgversion = bundlespec.contentopts[b"cg.version"]
1567 cgversion = bundlespec.contentopts[b"cg.version"]
1568
1568
1569 # Packed bundles are a pseudo bundle format for now.
1569 # Packed bundles are a pseudo bundle format for now.
1570 if cgversion == b's1':
1570 if cgversion == b's1':
1571 raise error.Abort(
1571 raise error.Abort(
1572 _(b'packed bundles cannot be produced by "hg bundle"'),
1572 _(b'packed bundles cannot be produced by "hg bundle"'),
1573 hint=_(b"use 'hg debugcreatestreamclonebundle'"),
1573 hint=_(b"use 'hg debugcreatestreamclonebundle'"),
1574 )
1574 )
1575
1575
1576 if opts.get(b'all'):
1576 if opts.get(b'all'):
1577 if dest:
1577 if dest:
1578 raise error.Abort(
1578 raise error.Abort(
1579 _(b"--all is incompatible with specifying a destination")
1579 _(b"--all is incompatible with specifying a destination")
1580 )
1580 )
1581 if opts.get(b'base'):
1581 if opts.get(b'base'):
1582 ui.warn(_(b"ignoring --base because --all was specified\n"))
1582 ui.warn(_(b"ignoring --base because --all was specified\n"))
1583 base = [nullrev]
1583 base = [nullrev]
1584 else:
1584 else:
1585 base = scmutil.revrange(repo, opts.get(b'base'))
1585 base = scmutil.revrange(repo, opts.get(b'base'))
1586 if cgversion not in changegroup.supportedoutgoingversions(repo):
1586 if cgversion not in changegroup.supportedoutgoingversions(repo):
1587 raise error.Abort(
1587 raise error.Abort(
1588 _(b"repository does not support bundle version %s") % cgversion
1588 _(b"repository does not support bundle version %s") % cgversion
1589 )
1589 )
1590
1590
1591 if base:
1591 if base:
1592 if dest:
1592 if dest:
1593 raise error.Abort(
1593 raise error.Abort(
1594 _(b"--base is incompatible with specifying a destination")
1594 _(b"--base is incompatible with specifying a destination")
1595 )
1595 )
1596 common = [repo[rev].node() for rev in base]
1596 common = [repo[rev].node() for rev in base]
1597 heads = [repo[r].node() for r in revs] if revs else None
1597 heads = [repo[r].node() for r in revs] if revs else None
1598 outgoing = discovery.outgoing(repo, common, heads)
1598 outgoing = discovery.outgoing(repo, common, heads)
1599 else:
1599 else:
1600 dest = ui.expandpath(dest or b'default-push', dest or b'default')
1600 dest = ui.expandpath(dest or b'default-push', dest or b'default')
1601 dest, branches = hg.parseurl(dest, opts.get(b'branch'))
1601 dest, branches = hg.parseurl(dest, opts.get(b'branch'))
1602 other = hg.peer(repo, opts, dest)
1602 other = hg.peer(repo, opts, dest)
1603 revs = [repo[r].hex() for r in revs]
1603 revs = [repo[r].hex() for r in revs]
1604 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1604 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1605 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1605 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1606 outgoing = discovery.findcommonoutgoing(
1606 outgoing = discovery.findcommonoutgoing(
1607 repo,
1607 repo,
1608 other,
1608 other,
1609 onlyheads=heads,
1609 onlyheads=heads,
1610 force=opts.get(b'force'),
1610 force=opts.get(b'force'),
1611 portable=True,
1611 portable=True,
1612 )
1612 )
1613
1613
1614 if not outgoing.missing:
1614 if not outgoing.missing:
1615 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1615 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1616 return 1
1616 return 1
1617
1617
1618 if cgversion == b'01': # bundle1
1618 if cgversion == b'01': # bundle1
1619 bversion = b'HG10' + bundlespec.wirecompression
1619 bversion = b'HG10' + bundlespec.wirecompression
1620 bcompression = None
1620 bcompression = None
1621 elif cgversion in (b'02', b'03'):
1621 elif cgversion in (b'02', b'03'):
1622 bversion = b'HG20'
1622 bversion = b'HG20'
1623 bcompression = bundlespec.wirecompression
1623 bcompression = bundlespec.wirecompression
1624 else:
1624 else:
1625 raise error.ProgrammingError(
1625 raise error.ProgrammingError(
1626 b'bundle: unexpected changegroup version %s' % cgversion
1626 b'bundle: unexpected changegroup version %s' % cgversion
1627 )
1627 )
1628
1628
1629 # TODO compression options should be derived from bundlespec parsing.
1629 # TODO compression options should be derived from bundlespec parsing.
1630 # This is a temporary hack to allow adjusting bundle compression
1630 # This is a temporary hack to allow adjusting bundle compression
1631 # level without a) formalizing the bundlespec changes to declare it
1631 # level without a) formalizing the bundlespec changes to declare it
1632 # b) introducing a command flag.
1632 # b) introducing a command flag.
1633 compopts = {}
1633 compopts = {}
1634 complevel = ui.configint(
1634 complevel = ui.configint(
1635 b'experimental', b'bundlecomplevel.' + bundlespec.compression
1635 b'experimental', b'bundlecomplevel.' + bundlespec.compression
1636 )
1636 )
1637 if complevel is None:
1637 if complevel is None:
1638 complevel = ui.configint(b'experimental', b'bundlecomplevel')
1638 complevel = ui.configint(b'experimental', b'bundlecomplevel')
1639 if complevel is not None:
1639 if complevel is not None:
1640 compopts[b'level'] = complevel
1640 compopts[b'level'] = complevel
1641
1641
1642 # Allow overriding the bundling of obsmarker in phases through
1642 # Allow overriding the bundling of obsmarker in phases through
1643 # configuration while we don't have a bundle version that include them
1643 # configuration while we don't have a bundle version that include them
1644 if repo.ui.configbool(b'experimental', b'evolution.bundle-obsmarker'):
1644 if repo.ui.configbool(b'experimental', b'evolution.bundle-obsmarker'):
1645 bundlespec.contentopts[b'obsolescence'] = True
1645 bundlespec.contentopts[b'obsolescence'] = True
1646 if repo.ui.configbool(b'experimental', b'bundle-phases'):
1646 if repo.ui.configbool(b'experimental', b'bundle-phases'):
1647 bundlespec.contentopts[b'phases'] = True
1647 bundlespec.contentopts[b'phases'] = True
1648
1648
1649 bundle2.writenewbundle(
1649 bundle2.writenewbundle(
1650 ui,
1650 ui,
1651 repo,
1651 repo,
1652 b'bundle',
1652 b'bundle',
1653 fname,
1653 fname,
1654 bversion,
1654 bversion,
1655 outgoing,
1655 outgoing,
1656 bundlespec.contentopts,
1656 bundlespec.contentopts,
1657 compression=bcompression,
1657 compression=bcompression,
1658 compopts=compopts,
1658 compopts=compopts,
1659 )
1659 )
1660
1660
1661
1661
1662 @command(
1662 @command(
1663 b'cat',
1663 b'cat',
1664 [
1664 [
1665 (
1665 (
1666 b'o',
1666 b'o',
1667 b'output',
1667 b'output',
1668 b'',
1668 b'',
1669 _(b'print output to file with formatted name'),
1669 _(b'print output to file with formatted name'),
1670 _(b'FORMAT'),
1670 _(b'FORMAT'),
1671 ),
1671 ),
1672 (b'r', b'rev', b'', _(b'print the given revision'), _(b'REV')),
1672 (b'r', b'rev', b'', _(b'print the given revision'), _(b'REV')),
1673 (b'', b'decode', None, _(b'apply any matching decode filter')),
1673 (b'', b'decode', None, _(b'apply any matching decode filter')),
1674 ]
1674 ]
1675 + walkopts
1675 + walkopts
1676 + formatteropts,
1676 + formatteropts,
1677 _(b'[OPTION]... FILE...'),
1677 _(b'[OPTION]... FILE...'),
1678 helpcategory=command.CATEGORY_FILE_CONTENTS,
1678 helpcategory=command.CATEGORY_FILE_CONTENTS,
1679 inferrepo=True,
1679 inferrepo=True,
1680 intents={INTENT_READONLY},
1680 intents={INTENT_READONLY},
1681 )
1681 )
1682 def cat(ui, repo, file1, *pats, **opts):
1682 def cat(ui, repo, file1, *pats, **opts):
1683 """output the current or given revision of files
1683 """output the current or given revision of files
1684
1684
1685 Print the specified files as they were at the given revision. If
1685 Print the specified files as they were at the given revision. If
1686 no revision is given, the parent of the working directory is used.
1686 no revision is given, the parent of the working directory is used.
1687
1687
1688 Output may be to a file, in which case the name of the file is
1688 Output may be to a file, in which case the name of the file is
1689 given using a template string. See :hg:`help templates`. In addition
1689 given using a template string. See :hg:`help templates`. In addition
1690 to the common template keywords, the following formatting rules are
1690 to the common template keywords, the following formatting rules are
1691 supported:
1691 supported:
1692
1692
1693 :``%%``: literal "%" character
1693 :``%%``: literal "%" character
1694 :``%s``: basename of file being printed
1694 :``%s``: basename of file being printed
1695 :``%d``: dirname of file being printed, or '.' if in repository root
1695 :``%d``: dirname of file being printed, or '.' if in repository root
1696 :``%p``: root-relative path name of file being printed
1696 :``%p``: root-relative path name of file being printed
1697 :``%H``: changeset hash (40 hexadecimal digits)
1697 :``%H``: changeset hash (40 hexadecimal digits)
1698 :``%R``: changeset revision number
1698 :``%R``: changeset revision number
1699 :``%h``: short-form changeset hash (12 hexadecimal digits)
1699 :``%h``: short-form changeset hash (12 hexadecimal digits)
1700 :``%r``: zero-padded changeset revision number
1700 :``%r``: zero-padded changeset revision number
1701 :``%b``: basename of the exporting repository
1701 :``%b``: basename of the exporting repository
1702 :``\\``: literal "\\" character
1702 :``\\``: literal "\\" character
1703
1703
1704 .. container:: verbose
1704 .. container:: verbose
1705
1705
1706 Template:
1706 Template:
1707
1707
1708 The following keywords are supported in addition to the common template
1708 The following keywords are supported in addition to the common template
1709 keywords and functions. See also :hg:`help templates`.
1709 keywords and functions. See also :hg:`help templates`.
1710
1710
1711 :data: String. File content.
1711 :data: String. File content.
1712 :path: String. Repository-absolute path of the file.
1712 :path: String. Repository-absolute path of the file.
1713
1713
1714 Returns 0 on success.
1714 Returns 0 on success.
1715 """
1715 """
1716 opts = pycompat.byteskwargs(opts)
1716 opts = pycompat.byteskwargs(opts)
1717 rev = opts.get(b'rev')
1717 rev = opts.get(b'rev')
1718 if rev:
1718 if rev:
1719 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
1719 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
1720 ctx = scmutil.revsingle(repo, rev)
1720 ctx = scmutil.revsingle(repo, rev)
1721 m = scmutil.match(ctx, (file1,) + pats, opts)
1721 m = scmutil.match(ctx, (file1,) + pats, opts)
1722 fntemplate = opts.pop(b'output', b'')
1722 fntemplate = opts.pop(b'output', b'')
1723 if cmdutil.isstdiofilename(fntemplate):
1723 if cmdutil.isstdiofilename(fntemplate):
1724 fntemplate = b''
1724 fntemplate = b''
1725
1725
1726 if fntemplate:
1726 if fntemplate:
1727 fm = formatter.nullformatter(ui, b'cat', opts)
1727 fm = formatter.nullformatter(ui, b'cat', opts)
1728 else:
1728 else:
1729 ui.pager(b'cat')
1729 ui.pager(b'cat')
1730 fm = ui.formatter(b'cat', opts)
1730 fm = ui.formatter(b'cat', opts)
1731 with fm:
1731 with fm:
1732 return cmdutil.cat(
1732 return cmdutil.cat(
1733 ui, repo, ctx, m, fm, fntemplate, b'', **pycompat.strkwargs(opts)
1733 ui, repo, ctx, m, fm, fntemplate, b'', **pycompat.strkwargs(opts)
1734 )
1734 )
1735
1735
1736
1736
1737 @command(
1737 @command(
1738 b'clone',
1738 b'clone',
1739 [
1739 [
1740 (
1740 (
1741 b'U',
1741 b'U',
1742 b'noupdate',
1742 b'noupdate',
1743 None,
1743 None,
1744 _(
1744 _(
1745 b'the clone will include an empty working '
1745 b'the clone will include an empty working '
1746 b'directory (only a repository)'
1746 b'directory (only a repository)'
1747 ),
1747 ),
1748 ),
1748 ),
1749 (
1749 (
1750 b'u',
1750 b'u',
1751 b'updaterev',
1751 b'updaterev',
1752 b'',
1752 b'',
1753 _(b'revision, tag, or branch to check out'),
1753 _(b'revision, tag, or branch to check out'),
1754 _(b'REV'),
1754 _(b'REV'),
1755 ),
1755 ),
1756 (
1756 (
1757 b'r',
1757 b'r',
1758 b'rev',
1758 b'rev',
1759 [],
1759 [],
1760 _(
1760 _(
1761 b'do not clone everything, but include this changeset'
1761 b'do not clone everything, but include this changeset'
1762 b' and its ancestors'
1762 b' and its ancestors'
1763 ),
1763 ),
1764 _(b'REV'),
1764 _(b'REV'),
1765 ),
1765 ),
1766 (
1766 (
1767 b'b',
1767 b'b',
1768 b'branch',
1768 b'branch',
1769 [],
1769 [],
1770 _(
1770 _(
1771 b'do not clone everything, but include this branch\'s'
1771 b'do not clone everything, but include this branch\'s'
1772 b' changesets and their ancestors'
1772 b' changesets and their ancestors'
1773 ),
1773 ),
1774 _(b'BRANCH'),
1774 _(b'BRANCH'),
1775 ),
1775 ),
1776 (b'', b'pull', None, _(b'use pull protocol to copy metadata')),
1776 (b'', b'pull', None, _(b'use pull protocol to copy metadata')),
1777 (b'', b'uncompressed', None, _(b'an alias to --stream (DEPRECATED)')),
1777 (b'', b'uncompressed', None, _(b'an alias to --stream (DEPRECATED)')),
1778 (b'', b'stream', None, _(b'clone with minimal data processing')),
1778 (b'', b'stream', None, _(b'clone with minimal data processing')),
1779 ]
1779 ]
1780 + remoteopts,
1780 + remoteopts,
1781 _(b'[OPTION]... SOURCE [DEST]'),
1781 _(b'[OPTION]... SOURCE [DEST]'),
1782 helpcategory=command.CATEGORY_REPO_CREATION,
1782 helpcategory=command.CATEGORY_REPO_CREATION,
1783 helpbasic=True,
1783 helpbasic=True,
1784 norepo=True,
1784 norepo=True,
1785 )
1785 )
1786 def clone(ui, source, dest=None, **opts):
1786 def clone(ui, source, dest=None, **opts):
1787 """make a copy of an existing repository
1787 """make a copy of an existing repository
1788
1788
1789 Create a copy of an existing repository in a new directory.
1789 Create a copy of an existing repository in a new directory.
1790
1790
1791 If no destination directory name is specified, it defaults to the
1791 If no destination directory name is specified, it defaults to the
1792 basename of the source.
1792 basename of the source.
1793
1793
1794 The location of the source is added to the new repository's
1794 The location of the source is added to the new repository's
1795 ``.hg/hgrc`` file, as the default to be used for future pulls.
1795 ``.hg/hgrc`` file, as the default to be used for future pulls.
1796
1796
1797 Only local paths and ``ssh://`` URLs are supported as
1797 Only local paths and ``ssh://`` URLs are supported as
1798 destinations. For ``ssh://`` destinations, no working directory or
1798 destinations. For ``ssh://`` destinations, no working directory or
1799 ``.hg/hgrc`` will be created on the remote side.
1799 ``.hg/hgrc`` will be created on the remote side.
1800
1800
1801 If the source repository has a bookmark called '@' set, that
1801 If the source repository has a bookmark called '@' set, that
1802 revision will be checked out in the new repository by default.
1802 revision will be checked out in the new repository by default.
1803
1803
1804 To check out a particular version, use -u/--update, or
1804 To check out a particular version, use -u/--update, or
1805 -U/--noupdate to create a clone with no working directory.
1805 -U/--noupdate to create a clone with no working directory.
1806
1806
1807 To pull only a subset of changesets, specify one or more revisions
1807 To pull only a subset of changesets, specify one or more revisions
1808 identifiers with -r/--rev or branches with -b/--branch. The
1808 identifiers with -r/--rev or branches with -b/--branch. The
1809 resulting clone will contain only the specified changesets and
1809 resulting clone will contain only the specified changesets and
1810 their ancestors. These options (or 'clone src#rev dest') imply
1810 their ancestors. These options (or 'clone src#rev dest') imply
1811 --pull, even for local source repositories.
1811 --pull, even for local source repositories.
1812
1812
1813 In normal clone mode, the remote normalizes repository data into a common
1813 In normal clone mode, the remote normalizes repository data into a common
1814 exchange format and the receiving end translates this data into its local
1814 exchange format and the receiving end translates this data into its local
1815 storage format. --stream activates a different clone mode that essentially
1815 storage format. --stream activates a different clone mode that essentially
1816 copies repository files from the remote with minimal data processing. This
1816 copies repository files from the remote with minimal data processing. This
1817 significantly reduces the CPU cost of a clone both remotely and locally.
1817 significantly reduces the CPU cost of a clone both remotely and locally.
1818 However, it often increases the transferred data size by 30-40%. This can
1818 However, it often increases the transferred data size by 30-40%. This can
1819 result in substantially faster clones where I/O throughput is plentiful,
1819 result in substantially faster clones where I/O throughput is plentiful,
1820 especially for larger repositories. A side-effect of --stream clones is
1820 especially for larger repositories. A side-effect of --stream clones is
1821 that storage settings and requirements on the remote are applied locally:
1821 that storage settings and requirements on the remote are applied locally:
1822 a modern client may inherit legacy or inefficient storage used by the
1822 a modern client may inherit legacy or inefficient storage used by the
1823 remote or a legacy Mercurial client may not be able to clone from a
1823 remote or a legacy Mercurial client may not be able to clone from a
1824 modern Mercurial remote.
1824 modern Mercurial remote.
1825
1825
1826 .. note::
1826 .. note::
1827
1827
1828 Specifying a tag will include the tagged changeset but not the
1828 Specifying a tag will include the tagged changeset but not the
1829 changeset containing the tag.
1829 changeset containing the tag.
1830
1830
1831 .. container:: verbose
1831 .. container:: verbose
1832
1832
1833 For efficiency, hardlinks are used for cloning whenever the
1833 For efficiency, hardlinks are used for cloning whenever the
1834 source and destination are on the same filesystem (note this
1834 source and destination are on the same filesystem (note this
1835 applies only to the repository data, not to the working
1835 applies only to the repository data, not to the working
1836 directory). Some filesystems, such as AFS, implement hardlinking
1836 directory). Some filesystems, such as AFS, implement hardlinking
1837 incorrectly, but do not report errors. In these cases, use the
1837 incorrectly, but do not report errors. In these cases, use the
1838 --pull option to avoid hardlinking.
1838 --pull option to avoid hardlinking.
1839
1839
1840 Mercurial will update the working directory to the first applicable
1840 Mercurial will update the working directory to the first applicable
1841 revision from this list:
1841 revision from this list:
1842
1842
1843 a) null if -U or the source repository has no changesets
1843 a) null if -U or the source repository has no changesets
1844 b) if -u . and the source repository is local, the first parent of
1844 b) if -u . and the source repository is local, the first parent of
1845 the source repository's working directory
1845 the source repository's working directory
1846 c) the changeset specified with -u (if a branch name, this means the
1846 c) the changeset specified with -u (if a branch name, this means the
1847 latest head of that branch)
1847 latest head of that branch)
1848 d) the changeset specified with -r
1848 d) the changeset specified with -r
1849 e) the tipmost head specified with -b
1849 e) the tipmost head specified with -b
1850 f) the tipmost head specified with the url#branch source syntax
1850 f) the tipmost head specified with the url#branch source syntax
1851 g) the revision marked with the '@' bookmark, if present
1851 g) the revision marked with the '@' bookmark, if present
1852 h) the tipmost head of the default branch
1852 h) the tipmost head of the default branch
1853 i) tip
1853 i) tip
1854
1854
1855 When cloning from servers that support it, Mercurial may fetch
1855 When cloning from servers that support it, Mercurial may fetch
1856 pre-generated data from a server-advertised URL or inline from the
1856 pre-generated data from a server-advertised URL or inline from the
1857 same stream. When this is done, hooks operating on incoming changesets
1857 same stream. When this is done, hooks operating on incoming changesets
1858 and changegroups may fire more than once, once for each pre-generated
1858 and changegroups may fire more than once, once for each pre-generated
1859 bundle and as well as for any additional remaining data. In addition,
1859 bundle and as well as for any additional remaining data. In addition,
1860 if an error occurs, the repository may be rolled back to a partial
1860 if an error occurs, the repository may be rolled back to a partial
1861 clone. This behavior may change in future releases.
1861 clone. This behavior may change in future releases.
1862 See :hg:`help -e clonebundles` for more.
1862 See :hg:`help -e clonebundles` for more.
1863
1863
1864 Examples:
1864 Examples:
1865
1865
1866 - clone a remote repository to a new directory named hg/::
1866 - clone a remote repository to a new directory named hg/::
1867
1867
1868 hg clone https://www.mercurial-scm.org/repo/hg/
1868 hg clone https://www.mercurial-scm.org/repo/hg/
1869
1869
1870 - create a lightweight local clone::
1870 - create a lightweight local clone::
1871
1871
1872 hg clone project/ project-feature/
1872 hg clone project/ project-feature/
1873
1873
1874 - clone from an absolute path on an ssh server (note double-slash)::
1874 - clone from an absolute path on an ssh server (note double-slash)::
1875
1875
1876 hg clone ssh://user@server//home/projects/alpha/
1876 hg clone ssh://user@server//home/projects/alpha/
1877
1877
1878 - do a streaming clone while checking out a specified version::
1878 - do a streaming clone while checking out a specified version::
1879
1879
1880 hg clone --stream http://server/repo -u 1.5
1880 hg clone --stream http://server/repo -u 1.5
1881
1881
1882 - create a repository without changesets after a particular revision::
1882 - create a repository without changesets after a particular revision::
1883
1883
1884 hg clone -r 04e544 experimental/ good/
1884 hg clone -r 04e544 experimental/ good/
1885
1885
1886 - clone (and track) a particular named branch::
1886 - clone (and track) a particular named branch::
1887
1887
1888 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1888 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1889
1889
1890 See :hg:`help urls` for details on specifying URLs.
1890 See :hg:`help urls` for details on specifying URLs.
1891
1891
1892 Returns 0 on success.
1892 Returns 0 on success.
1893 """
1893 """
1894 opts = pycompat.byteskwargs(opts)
1894 opts = pycompat.byteskwargs(opts)
1895 if opts.get(b'noupdate') and opts.get(b'updaterev'):
1895 if opts.get(b'noupdate') and opts.get(b'updaterev'):
1896 raise error.Abort(_(b"cannot specify both --noupdate and --updaterev"))
1896 raise error.Abort(_(b"cannot specify both --noupdate and --updaterev"))
1897
1897
1898 # --include/--exclude can come from narrow or sparse.
1898 # --include/--exclude can come from narrow or sparse.
1899 includepats, excludepats = None, None
1899 includepats, excludepats = None, None
1900
1900
1901 # hg.clone() differentiates between None and an empty set. So make sure
1901 # hg.clone() differentiates between None and an empty set. So make sure
1902 # patterns are sets if narrow is requested without patterns.
1902 # patterns are sets if narrow is requested without patterns.
1903 if opts.get(b'narrow'):
1903 if opts.get(b'narrow'):
1904 includepats = set()
1904 includepats = set()
1905 excludepats = set()
1905 excludepats = set()
1906
1906
1907 if opts.get(b'include'):
1907 if opts.get(b'include'):
1908 includepats = narrowspec.parsepatterns(opts.get(b'include'))
1908 includepats = narrowspec.parsepatterns(opts.get(b'include'))
1909 if opts.get(b'exclude'):
1909 if opts.get(b'exclude'):
1910 excludepats = narrowspec.parsepatterns(opts.get(b'exclude'))
1910 excludepats = narrowspec.parsepatterns(opts.get(b'exclude'))
1911
1911
1912 r = hg.clone(
1912 r = hg.clone(
1913 ui,
1913 ui,
1914 opts,
1914 opts,
1915 source,
1915 source,
1916 dest,
1916 dest,
1917 pull=opts.get(b'pull'),
1917 pull=opts.get(b'pull'),
1918 stream=opts.get(b'stream') or opts.get(b'uncompressed'),
1918 stream=opts.get(b'stream') or opts.get(b'uncompressed'),
1919 revs=opts.get(b'rev'),
1919 revs=opts.get(b'rev'),
1920 update=opts.get(b'updaterev') or not opts.get(b'noupdate'),
1920 update=opts.get(b'updaterev') or not opts.get(b'noupdate'),
1921 branch=opts.get(b'branch'),
1921 branch=opts.get(b'branch'),
1922 shareopts=opts.get(b'shareopts'),
1922 shareopts=opts.get(b'shareopts'),
1923 storeincludepats=includepats,
1923 storeincludepats=includepats,
1924 storeexcludepats=excludepats,
1924 storeexcludepats=excludepats,
1925 depth=opts.get(b'depth') or None,
1925 depth=opts.get(b'depth') or None,
1926 )
1926 )
1927
1927
1928 return r is None
1928 return r is None
1929
1929
1930
1930
1931 @command(
1931 @command(
1932 b'commit|ci',
1932 b'commit|ci',
1933 [
1933 [
1934 (
1934 (
1935 b'A',
1935 b'A',
1936 b'addremove',
1936 b'addremove',
1937 None,
1937 None,
1938 _(b'mark new/missing files as added/removed before committing'),
1938 _(b'mark new/missing files as added/removed before committing'),
1939 ),
1939 ),
1940 (b'', b'close-branch', None, _(b'mark a branch head as closed')),
1940 (b'', b'close-branch', None, _(b'mark a branch head as closed')),
1941 (b'', b'amend', None, _(b'amend the parent of the working directory')),
1941 (b'', b'amend', None, _(b'amend the parent of the working directory')),
1942 (b's', b'secret', None, _(b'use the secret phase for committing')),
1942 (b's', b'secret', None, _(b'use the secret phase for committing')),
1943 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
1943 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
1944 (
1944 (
1945 b'',
1945 b'',
1946 b'force-close-branch',
1946 b'force-close-branch',
1947 None,
1947 None,
1948 _(b'forcibly close branch from a non-head changeset (ADVANCED)'),
1948 _(b'forcibly close branch from a non-head changeset (ADVANCED)'),
1949 ),
1949 ),
1950 (b'i', b'interactive', None, _(b'use interactive mode')),
1950 (b'i', b'interactive', None, _(b'use interactive mode')),
1951 ]
1951 ]
1952 + walkopts
1952 + walkopts
1953 + commitopts
1953 + commitopts
1954 + commitopts2
1954 + commitopts2
1955 + subrepoopts,
1955 + subrepoopts,
1956 _(b'[OPTION]... [FILE]...'),
1956 _(b'[OPTION]... [FILE]...'),
1957 helpcategory=command.CATEGORY_COMMITTING,
1957 helpcategory=command.CATEGORY_COMMITTING,
1958 helpbasic=True,
1958 helpbasic=True,
1959 inferrepo=True,
1959 inferrepo=True,
1960 )
1960 )
1961 def commit(ui, repo, *pats, **opts):
1961 def commit(ui, repo, *pats, **opts):
1962 """commit the specified files or all outstanding changes
1962 """commit the specified files or all outstanding changes
1963
1963
1964 Commit changes to the given files into the repository. Unlike a
1964 Commit changes to the given files into the repository. Unlike a
1965 centralized SCM, this operation is a local operation. See
1965 centralized SCM, this operation is a local operation. See
1966 :hg:`push` for a way to actively distribute your changes.
1966 :hg:`push` for a way to actively distribute your changes.
1967
1967
1968 If a list of files is omitted, all changes reported by :hg:`status`
1968 If a list of files is omitted, all changes reported by :hg:`status`
1969 will be committed.
1969 will be committed.
1970
1970
1971 If you are committing the result of a merge, do not provide any
1971 If you are committing the result of a merge, do not provide any
1972 filenames or -I/-X filters.
1972 filenames or -I/-X filters.
1973
1973
1974 If no commit message is specified, Mercurial starts your
1974 If no commit message is specified, Mercurial starts your
1975 configured editor where you can enter a message. In case your
1975 configured editor where you can enter a message. In case your
1976 commit fails, you will find a backup of your message in
1976 commit fails, you will find a backup of your message in
1977 ``.hg/last-message.txt``.
1977 ``.hg/last-message.txt``.
1978
1978
1979 The --close-branch flag can be used to mark the current branch
1979 The --close-branch flag can be used to mark the current branch
1980 head closed. When all heads of a branch are closed, the branch
1980 head closed. When all heads of a branch are closed, the branch
1981 will be considered closed and no longer listed.
1981 will be considered closed and no longer listed.
1982
1982
1983 The --amend flag can be used to amend the parent of the
1983 The --amend flag can be used to amend the parent of the
1984 working directory with a new commit that contains the changes
1984 working directory with a new commit that contains the changes
1985 in the parent in addition to those currently reported by :hg:`status`,
1985 in the parent in addition to those currently reported by :hg:`status`,
1986 if there are any. The old commit is stored in a backup bundle in
1986 if there are any. The old commit is stored in a backup bundle in
1987 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1987 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1988 on how to restore it).
1988 on how to restore it).
1989
1989
1990 Message, user and date are taken from the amended commit unless
1990 Message, user and date are taken from the amended commit unless
1991 specified. When a message isn't specified on the command line,
1991 specified. When a message isn't specified on the command line,
1992 the editor will open with the message of the amended commit.
1992 the editor will open with the message of the amended commit.
1993
1993
1994 It is not possible to amend public changesets (see :hg:`help phases`)
1994 It is not possible to amend public changesets (see :hg:`help phases`)
1995 or changesets that have children.
1995 or changesets that have children.
1996
1996
1997 See :hg:`help dates` for a list of formats valid for -d/--date.
1997 See :hg:`help dates` for a list of formats valid for -d/--date.
1998
1998
1999 Returns 0 on success, 1 if nothing changed.
1999 Returns 0 on success, 1 if nothing changed.
2000
2000
2001 .. container:: verbose
2001 .. container:: verbose
2002
2002
2003 Examples:
2003 Examples:
2004
2004
2005 - commit all files ending in .py::
2005 - commit all files ending in .py::
2006
2006
2007 hg commit --include "set:**.py"
2007 hg commit --include "set:**.py"
2008
2008
2009 - commit all non-binary files::
2009 - commit all non-binary files::
2010
2010
2011 hg commit --exclude "set:binary()"
2011 hg commit --exclude "set:binary()"
2012
2012
2013 - amend the current commit and set the date to now::
2013 - amend the current commit and set the date to now::
2014
2014
2015 hg commit --amend --date now
2015 hg commit --amend --date now
2016 """
2016 """
2017 with repo.wlock(), repo.lock():
2017 with repo.wlock(), repo.lock():
2018 return _docommit(ui, repo, *pats, **opts)
2018 return _docommit(ui, repo, *pats, **opts)
2019
2019
2020
2020
2021 def _docommit(ui, repo, *pats, **opts):
2021 def _docommit(ui, repo, *pats, **opts):
2022 if opts.get(r'interactive'):
2022 if opts.get(r'interactive'):
2023 opts.pop(r'interactive')
2023 opts.pop(r'interactive')
2024 ret = cmdutil.dorecord(
2024 ret = cmdutil.dorecord(
2025 ui, repo, commit, None, False, cmdutil.recordfilter, *pats, **opts
2025 ui, repo, commit, None, False, cmdutil.recordfilter, *pats, **opts
2026 )
2026 )
2027 # ret can be 0 (no changes to record) or the value returned by
2027 # ret can be 0 (no changes to record) or the value returned by
2028 # commit(), 1 if nothing changed or None on success.
2028 # commit(), 1 if nothing changed or None on success.
2029 return 1 if ret == 0 else ret
2029 return 1 if ret == 0 else ret
2030
2030
2031 opts = pycompat.byteskwargs(opts)
2031 opts = pycompat.byteskwargs(opts)
2032 if opts.get(b'subrepos'):
2032 if opts.get(b'subrepos'):
2033 if opts.get(b'amend'):
2033 if opts.get(b'amend'):
2034 raise error.Abort(_(b'cannot amend with --subrepos'))
2034 raise error.Abort(_(b'cannot amend with --subrepos'))
2035 # Let --subrepos on the command line override config setting.
2035 # Let --subrepos on the command line override config setting.
2036 ui.setconfig(b'ui', b'commitsubrepos', True, b'commit')
2036 ui.setconfig(b'ui', b'commitsubrepos', True, b'commit')
2037
2037
2038 cmdutil.checkunfinished(repo, commit=True)
2038 cmdutil.checkunfinished(repo, commit=True)
2039
2039
2040 branch = repo[None].branch()
2040 branch = repo[None].branch()
2041 bheads = repo.branchheads(branch)
2041 bheads = repo.branchheads(branch)
2042
2042
2043 extra = {}
2043 extra = {}
2044 if opts.get(b'close_branch') or opts.get(b'force_close_branch'):
2044 if opts.get(b'close_branch') or opts.get(b'force_close_branch'):
2045 extra[b'close'] = b'1'
2045 extra[b'close'] = b'1'
2046
2046
2047 if repo[b'.'].closesbranch():
2047 if repo[b'.'].closesbranch():
2048 raise error.Abort(
2048 raise error.Abort(
2049 _(b'current revision is already a branch closing head')
2049 _(b'current revision is already a branch closing head')
2050 )
2050 )
2051 elif not bheads:
2051 elif not bheads:
2052 raise error.Abort(_(b'branch "%s" has no heads to close') % branch)
2052 raise error.Abort(_(b'branch "%s" has no heads to close') % branch)
2053 elif (
2053 elif (
2054 branch == repo[b'.'].branch()
2054 branch == repo[b'.'].branch()
2055 and repo[b'.'].node() not in bheads
2055 and repo[b'.'].node() not in bheads
2056 and not opts.get(b'force_close_branch')
2056 and not opts.get(b'force_close_branch')
2057 ):
2057 ):
2058 hint = _(
2058 hint = _(
2059 b'use --force-close-branch to close branch from a non-head'
2059 b'use --force-close-branch to close branch from a non-head'
2060 b' changeset'
2060 b' changeset'
2061 )
2061 )
2062 raise error.Abort(_(b'can only close branch heads'), hint=hint)
2062 raise error.Abort(_(b'can only close branch heads'), hint=hint)
2063 elif opts.get(b'amend'):
2063 elif opts.get(b'amend'):
2064 if (
2064 if (
2065 repo[b'.'].p1().branch() != branch
2065 repo[b'.'].p1().branch() != branch
2066 and repo[b'.'].p2().branch() != branch
2066 and repo[b'.'].p2().branch() != branch
2067 ):
2067 ):
2068 raise error.Abort(_(b'can only close branch heads'))
2068 raise error.Abort(_(b'can only close branch heads'))
2069
2069
2070 if opts.get(b'amend'):
2070 if opts.get(b'amend'):
2071 if ui.configbool(b'ui', b'commitsubrepos'):
2071 if ui.configbool(b'ui', b'commitsubrepos'):
2072 raise error.Abort(_(b'cannot amend with ui.commitsubrepos enabled'))
2072 raise error.Abort(_(b'cannot amend with ui.commitsubrepos enabled'))
2073
2073
2074 old = repo[b'.']
2074 old = repo[b'.']
2075 rewriteutil.precheck(repo, [old.rev()], b'amend')
2075 rewriteutil.precheck(repo, [old.rev()], b'amend')
2076
2076
2077 # Currently histedit gets confused if an amend happens while histedit
2077 # Currently histedit gets confused if an amend happens while histedit
2078 # is in progress. Since we have a checkunfinished command, we are
2078 # is in progress. Since we have a checkunfinished command, we are
2079 # temporarily honoring it.
2079 # temporarily honoring it.
2080 #
2080 #
2081 # Note: eventually this guard will be removed. Please do not expect
2081 # Note: eventually this guard will be removed. Please do not expect
2082 # this behavior to remain.
2082 # this behavior to remain.
2083 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
2083 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
2084 cmdutil.checkunfinished(repo)
2084 cmdutil.checkunfinished(repo)
2085
2085
2086 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
2086 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
2087 if node == old.node():
2087 if node == old.node():
2088 ui.status(_(b"nothing changed\n"))
2088 ui.status(_(b"nothing changed\n"))
2089 return 1
2089 return 1
2090 else:
2090 else:
2091
2091
2092 def commitfunc(ui, repo, message, match, opts):
2092 def commitfunc(ui, repo, message, match, opts):
2093 overrides = {}
2093 overrides = {}
2094 if opts.get(b'secret'):
2094 if opts.get(b'secret'):
2095 overrides[(b'phases', b'new-commit')] = b'secret'
2095 overrides[(b'phases', b'new-commit')] = b'secret'
2096
2096
2097 baseui = repo.baseui
2097 baseui = repo.baseui
2098 with baseui.configoverride(overrides, b'commit'):
2098 with baseui.configoverride(overrides, b'commit'):
2099 with ui.configoverride(overrides, b'commit'):
2099 with ui.configoverride(overrides, b'commit'):
2100 editform = cmdutil.mergeeditform(
2100 editform = cmdutil.mergeeditform(
2101 repo[None], b'commit.normal'
2101 repo[None], b'commit.normal'
2102 )
2102 )
2103 editor = cmdutil.getcommiteditor(
2103 editor = cmdutil.getcommiteditor(
2104 editform=editform, **pycompat.strkwargs(opts)
2104 editform=editform, **pycompat.strkwargs(opts)
2105 )
2105 )
2106 return repo.commit(
2106 return repo.commit(
2107 message,
2107 message,
2108 opts.get(b'user'),
2108 opts.get(b'user'),
2109 opts.get(b'date'),
2109 opts.get(b'date'),
2110 match,
2110 match,
2111 editor=editor,
2111 editor=editor,
2112 extra=extra,
2112 extra=extra,
2113 )
2113 )
2114
2114
2115 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
2115 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
2116
2116
2117 if not node:
2117 if not node:
2118 stat = cmdutil.postcommitstatus(repo, pats, opts)
2118 stat = cmdutil.postcommitstatus(repo, pats, opts)
2119 if stat[3]:
2119 if stat[3]:
2120 ui.status(
2120 ui.status(
2121 _(
2121 _(
2122 b"nothing changed (%d missing files, see "
2122 b"nothing changed (%d missing files, see "
2123 b"'hg status')\n"
2123 b"'hg status')\n"
2124 )
2124 )
2125 % len(stat[3])
2125 % len(stat[3])
2126 )
2126 )
2127 else:
2127 else:
2128 ui.status(_(b"nothing changed\n"))
2128 ui.status(_(b"nothing changed\n"))
2129 return 1
2129 return 1
2130
2130
2131 cmdutil.commitstatus(repo, node, branch, bheads, opts)
2131 cmdutil.commitstatus(repo, node, branch, bheads, opts)
2132
2132
2133 if not ui.quiet and ui.configbool(b'commands', b'commit.post-status'):
2133 if not ui.quiet and ui.configbool(b'commands', b'commit.post-status'):
2134 status(
2134 status(
2135 ui,
2135 ui,
2136 repo,
2136 repo,
2137 modified=True,
2137 modified=True,
2138 added=True,
2138 added=True,
2139 removed=True,
2139 removed=True,
2140 deleted=True,
2140 deleted=True,
2141 unknown=True,
2141 unknown=True,
2142 subrepos=opts.get(b'subrepos'),
2142 subrepos=opts.get(b'subrepos'),
2143 )
2143 )
2144
2144
2145
2145
2146 @command(
2146 @command(
2147 b'config|showconfig|debugconfig',
2147 b'config|showconfig|debugconfig',
2148 [
2148 [
2149 (b'u', b'untrusted', None, _(b'show untrusted configuration options')),
2149 (b'u', b'untrusted', None, _(b'show untrusted configuration options')),
2150 (b'e', b'edit', None, _(b'edit user config')),
2150 (b'e', b'edit', None, _(b'edit user config')),
2151 (b'l', b'local', None, _(b'edit repository config')),
2151 (b'l', b'local', None, _(b'edit repository config')),
2152 (b'g', b'global', None, _(b'edit global config')),
2152 (b'g', b'global', None, _(b'edit global config')),
2153 ]
2153 ]
2154 + formatteropts,
2154 + formatteropts,
2155 _(b'[-u] [NAME]...'),
2155 _(b'[-u] [NAME]...'),
2156 helpcategory=command.CATEGORY_HELP,
2156 helpcategory=command.CATEGORY_HELP,
2157 optionalrepo=True,
2157 optionalrepo=True,
2158 intents={INTENT_READONLY},
2158 intents={INTENT_READONLY},
2159 )
2159 )
2160 def config(ui, repo, *values, **opts):
2160 def config(ui, repo, *values, **opts):
2161 """show combined config settings from all hgrc files
2161 """show combined config settings from all hgrc files
2162
2162
2163 With no arguments, print names and values of all config items.
2163 With no arguments, print names and values of all config items.
2164
2164
2165 With one argument of the form section.name, print just the value
2165 With one argument of the form section.name, print just the value
2166 of that config item.
2166 of that config item.
2167
2167
2168 With multiple arguments, print names and values of all config
2168 With multiple arguments, print names and values of all config
2169 items with matching section names or section.names.
2169 items with matching section names or section.names.
2170
2170
2171 With --edit, start an editor on the user-level config file. With
2171 With --edit, start an editor on the user-level config file. With
2172 --global, edit the system-wide config file. With --local, edit the
2172 --global, edit the system-wide config file. With --local, edit the
2173 repository-level config file.
2173 repository-level config file.
2174
2174
2175 With --debug, the source (filename and line number) is printed
2175 With --debug, the source (filename and line number) is printed
2176 for each config item.
2176 for each config item.
2177
2177
2178 See :hg:`help config` for more information about config files.
2178 See :hg:`help config` for more information about config files.
2179
2179
2180 .. container:: verbose
2180 .. container:: verbose
2181
2181
2182 Template:
2182 Template:
2183
2183
2184 The following keywords are supported. See also :hg:`help templates`.
2184 The following keywords are supported. See also :hg:`help templates`.
2185
2185
2186 :name: String. Config name.
2186 :name: String. Config name.
2187 :source: String. Filename and line number where the item is defined.
2187 :source: String. Filename and line number where the item is defined.
2188 :value: String. Config value.
2188 :value: String. Config value.
2189
2189
2190 Returns 0 on success, 1 if NAME does not exist.
2190 Returns 0 on success, 1 if NAME does not exist.
2191
2191
2192 """
2192 """
2193
2193
2194 opts = pycompat.byteskwargs(opts)
2194 opts = pycompat.byteskwargs(opts)
2195 if opts.get(b'edit') or opts.get(b'local') or opts.get(b'global'):
2195 if opts.get(b'edit') or opts.get(b'local') or opts.get(b'global'):
2196 if opts.get(b'local') and opts.get(b'global'):
2196 if opts.get(b'local') and opts.get(b'global'):
2197 raise error.Abort(_(b"can't use --local and --global together"))
2197 raise error.Abort(_(b"can't use --local and --global together"))
2198
2198
2199 if opts.get(b'local'):
2199 if opts.get(b'local'):
2200 if not repo:
2200 if not repo:
2201 raise error.Abort(_(b"can't use --local outside a repository"))
2201 raise error.Abort(_(b"can't use --local outside a repository"))
2202 paths = [repo.vfs.join(b'hgrc')]
2202 paths = [repo.vfs.join(b'hgrc')]
2203 elif opts.get(b'global'):
2203 elif opts.get(b'global'):
2204 paths = rcutil.systemrcpath()
2204 paths = rcutil.systemrcpath()
2205 else:
2205 else:
2206 paths = rcutil.userrcpath()
2206 paths = rcutil.userrcpath()
2207
2207
2208 for f in paths:
2208 for f in paths:
2209 if os.path.exists(f):
2209 if os.path.exists(f):
2210 break
2210 break
2211 else:
2211 else:
2212 if opts.get(b'global'):
2212 if opts.get(b'global'):
2213 samplehgrc = uimod.samplehgrcs[b'global']
2213 samplehgrc = uimod.samplehgrcs[b'global']
2214 elif opts.get(b'local'):
2214 elif opts.get(b'local'):
2215 samplehgrc = uimod.samplehgrcs[b'local']
2215 samplehgrc = uimod.samplehgrcs[b'local']
2216 else:
2216 else:
2217 samplehgrc = uimod.samplehgrcs[b'user']
2217 samplehgrc = uimod.samplehgrcs[b'user']
2218
2218
2219 f = paths[0]
2219 f = paths[0]
2220 fp = open(f, b"wb")
2220 fp = open(f, b"wb")
2221 fp.write(util.tonativeeol(samplehgrc))
2221 fp.write(util.tonativeeol(samplehgrc))
2222 fp.close()
2222 fp.close()
2223
2223
2224 editor = ui.geteditor()
2224 editor = ui.geteditor()
2225 ui.system(
2225 ui.system(
2226 b"%s \"%s\"" % (editor, f),
2226 b"%s \"%s\"" % (editor, f),
2227 onerr=error.Abort,
2227 onerr=error.Abort,
2228 errprefix=_(b"edit failed"),
2228 errprefix=_(b"edit failed"),
2229 blockedtag=b'config_edit',
2229 blockedtag=b'config_edit',
2230 )
2230 )
2231 return
2231 return
2232 ui.pager(b'config')
2232 ui.pager(b'config')
2233 fm = ui.formatter(b'config', opts)
2233 fm = ui.formatter(b'config', opts)
2234 for t, f in rcutil.rccomponents():
2234 for t, f in rcutil.rccomponents():
2235 if t == b'path':
2235 if t == b'path':
2236 ui.debug(b'read config from: %s\n' % f)
2236 ui.debug(b'read config from: %s\n' % f)
2237 elif t == b'items':
2237 elif t == b'items':
2238 for section, name, value, source in f:
2238 for section, name, value, source in f:
2239 ui.debug(b'set config by: %s\n' % source)
2239 ui.debug(b'set config by: %s\n' % source)
2240 else:
2240 else:
2241 raise error.ProgrammingError(b'unknown rctype: %s' % t)
2241 raise error.ProgrammingError(b'unknown rctype: %s' % t)
2242 untrusted = bool(opts.get(b'untrusted'))
2242 untrusted = bool(opts.get(b'untrusted'))
2243
2243
2244 selsections = selentries = []
2244 selsections = selentries = []
2245 if values:
2245 if values:
2246 selsections = [v for v in values if b'.' not in v]
2246 selsections = [v for v in values if b'.' not in v]
2247 selentries = [v for v in values if b'.' in v]
2247 selentries = [v for v in values if b'.' in v]
2248 uniquesel = len(selentries) == 1 and not selsections
2248 uniquesel = len(selentries) == 1 and not selsections
2249 selsections = set(selsections)
2249 selsections = set(selsections)
2250 selentries = set(selentries)
2250 selentries = set(selentries)
2251
2251
2252 matched = False
2252 matched = False
2253 for section, name, value in ui.walkconfig(untrusted=untrusted):
2253 for section, name, value in ui.walkconfig(untrusted=untrusted):
2254 source = ui.configsource(section, name, untrusted)
2254 source = ui.configsource(section, name, untrusted)
2255 value = pycompat.bytestr(value)
2255 value = pycompat.bytestr(value)
2256 defaultvalue = ui.configdefault(section, name)
2256 defaultvalue = ui.configdefault(section, name)
2257 if fm.isplain():
2257 if fm.isplain():
2258 source = source or b'none'
2258 source = source or b'none'
2259 value = value.replace(b'\n', b'\\n')
2259 value = value.replace(b'\n', b'\\n')
2260 entryname = section + b'.' + name
2260 entryname = section + b'.' + name
2261 if values and not (section in selsections or entryname in selentries):
2261 if values and not (section in selsections or entryname in selentries):
2262 continue
2262 continue
2263 fm.startitem()
2263 fm.startitem()
2264 fm.condwrite(ui.debugflag, b'source', b'%s: ', source)
2264 fm.condwrite(ui.debugflag, b'source', b'%s: ', source)
2265 if uniquesel:
2265 if uniquesel:
2266 fm.data(name=entryname)
2266 fm.data(name=entryname)
2267 fm.write(b'value', b'%s\n', value)
2267 fm.write(b'value', b'%s\n', value)
2268 else:
2268 else:
2269 fm.write(b'name value', b'%s=%s\n', entryname, value)
2269 fm.write(b'name value', b'%s=%s\n', entryname, value)
2270 fm.data(defaultvalue=defaultvalue)
2270 fm.data(defaultvalue=defaultvalue)
2271 matched = True
2271 matched = True
2272 fm.end()
2272 fm.end()
2273 if matched:
2273 if matched:
2274 return 0
2274 return 0
2275 return 1
2275 return 1
2276
2276
2277
2277
2278 @command(
2278 @command(
2279 b'continue',
2279 b'continue',
2280 dryrunopts,
2280 dryrunopts,
2281 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2281 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2282 helpbasic=True,
2282 helpbasic=True,
2283 )
2283 )
2284 def continuecmd(ui, repo, **opts):
2284 def continuecmd(ui, repo, **opts):
2285 """resumes an interrupted operation (EXPERIMENTAL)
2285 """resumes an interrupted operation (EXPERIMENTAL)
2286
2286
2287 Finishes a multistep operation like graft, histedit, rebase, merge,
2287 Finishes a multistep operation like graft, histedit, rebase, merge,
2288 and unshelve if they are in an interrupted state.
2288 and unshelve if they are in an interrupted state.
2289
2289
2290 use --dry-run/-n to dry run the command.
2290 use --dry-run/-n to dry run the command.
2291 """
2291 """
2292 dryrun = opts.get(r'dry_run')
2292 dryrun = opts.get(r'dry_run')
2293 contstate = cmdutil.getunfinishedstate(repo)
2293 contstate = cmdutil.getunfinishedstate(repo)
2294 if not contstate:
2294 if not contstate:
2295 raise error.Abort(_(b'no operation in progress'))
2295 raise error.Abort(_(b'no operation in progress'))
2296 if not contstate.continuefunc:
2296 if not contstate.continuefunc:
2297 raise error.Abort(
2297 raise error.Abort(
2298 (
2298 (
2299 _(b"%s in progress but does not support 'hg continue'")
2299 _(b"%s in progress but does not support 'hg continue'")
2300 % (contstate._opname)
2300 % (contstate._opname)
2301 ),
2301 ),
2302 hint=contstate.continuemsg(),
2302 hint=contstate.continuemsg(),
2303 )
2303 )
2304 if dryrun:
2304 if dryrun:
2305 ui.status(_(b'%s in progress, will be resumed\n') % (contstate._opname))
2305 ui.status(_(b'%s in progress, will be resumed\n') % (contstate._opname))
2306 return
2306 return
2307 return contstate.continuefunc(ui, repo)
2307 return contstate.continuefunc(ui, repo)
2308
2308
2309
2309
2310 @command(
2310 @command(
2311 b'copy|cp',
2311 b'copy|cp',
2312 [
2312 [
2313 (b'A', b'after', None, _(b'record a copy that has already occurred')),
2313 (b'A', b'after', None, _(b'record a copy that has already occurred')),
2314 (
2314 (
2315 b'f',
2315 b'f',
2316 b'force',
2316 b'force',
2317 None,
2317 None,
2318 _(b'forcibly copy over an existing managed file'),
2318 _(b'forcibly copy over an existing managed file'),
2319 ),
2319 ),
2320 ]
2320 ]
2321 + walkopts
2321 + walkopts
2322 + dryrunopts,
2322 + dryrunopts,
2323 _(b'[OPTION]... SOURCE... DEST'),
2323 _(b'[OPTION]... SOURCE... DEST'),
2324 helpcategory=command.CATEGORY_FILE_CONTENTS,
2324 helpcategory=command.CATEGORY_FILE_CONTENTS,
2325 )
2325 )
2326 def copy(ui, repo, *pats, **opts):
2326 def copy(ui, repo, *pats, **opts):
2327 """mark files as copied for the next commit
2327 """mark files as copied for the next commit
2328
2328
2329 Mark dest as having copies of source files. If dest is a
2329 Mark dest as having copies of source files. If dest is a
2330 directory, copies are put in that directory. If dest is a file,
2330 directory, copies are put in that directory. If dest is a file,
2331 the source must be a single file.
2331 the source must be a single file.
2332
2332
2333 By default, this command copies the contents of files as they
2333 By default, this command copies the contents of files as they
2334 exist in the working directory. If invoked with -A/--after, the
2334 exist in the working directory. If invoked with -A/--after, the
2335 operation is recorded, but no copying is performed.
2335 operation is recorded, but no copying is performed.
2336
2336
2337 This command takes effect with the next commit. To undo a copy
2337 This command takes effect with the next commit. To undo a copy
2338 before that, see :hg:`revert`.
2338 before that, see :hg:`revert`.
2339
2339
2340 Returns 0 on success, 1 if errors are encountered.
2340 Returns 0 on success, 1 if errors are encountered.
2341 """
2341 """
2342 opts = pycompat.byteskwargs(opts)
2342 opts = pycompat.byteskwargs(opts)
2343 with repo.wlock(False):
2343 with repo.wlock(False):
2344 return cmdutil.copy(ui, repo, pats, opts)
2344 return cmdutil.copy(ui, repo, pats, opts)
2345
2345
2346
2346
2347 @command(
2347 @command(
2348 b'debugcommands',
2348 b'debugcommands',
2349 [],
2349 [],
2350 _(b'[COMMAND]'),
2350 _(b'[COMMAND]'),
2351 helpcategory=command.CATEGORY_HELP,
2351 helpcategory=command.CATEGORY_HELP,
2352 norepo=True,
2352 norepo=True,
2353 )
2353 )
2354 def debugcommands(ui, cmd=b'', *args):
2354 def debugcommands(ui, cmd=b'', *args):
2355 """list all available commands and options"""
2355 """list all available commands and options"""
2356 for cmd, vals in sorted(pycompat.iteritems(table)):
2356 for cmd, vals in sorted(pycompat.iteritems(table)):
2357 cmd = cmd.split(b'|')[0]
2357 cmd = cmd.split(b'|')[0]
2358 opts = b', '.join([i[1] for i in vals[1]])
2358 opts = b', '.join([i[1] for i in vals[1]])
2359 ui.write(b'%s: %s\n' % (cmd, opts))
2359 ui.write(b'%s: %s\n' % (cmd, opts))
2360
2360
2361
2361
2362 @command(
2362 @command(
2363 b'debugcomplete',
2363 b'debugcomplete',
2364 [(b'o', b'options', None, _(b'show the command options'))],
2364 [(b'o', b'options', None, _(b'show the command options'))],
2365 _(b'[-o] CMD'),
2365 _(b'[-o] CMD'),
2366 helpcategory=command.CATEGORY_HELP,
2366 helpcategory=command.CATEGORY_HELP,
2367 norepo=True,
2367 norepo=True,
2368 )
2368 )
2369 def debugcomplete(ui, cmd=b'', **opts):
2369 def debugcomplete(ui, cmd=b'', **opts):
2370 """returns the completion list associated with the given command"""
2370 """returns the completion list associated with the given command"""
2371
2371
2372 if opts.get(r'options'):
2372 if opts.get(r'options'):
2373 options = []
2373 options = []
2374 otables = [globalopts]
2374 otables = [globalopts]
2375 if cmd:
2375 if cmd:
2376 aliases, entry = cmdutil.findcmd(cmd, table, False)
2376 aliases, entry = cmdutil.findcmd(cmd, table, False)
2377 otables.append(entry[1])
2377 otables.append(entry[1])
2378 for t in otables:
2378 for t in otables:
2379 for o in t:
2379 for o in t:
2380 if b"(DEPRECATED)" in o[3]:
2380 if b"(DEPRECATED)" in o[3]:
2381 continue
2381 continue
2382 if o[0]:
2382 if o[0]:
2383 options.append(b'-%s' % o[0])
2383 options.append(b'-%s' % o[0])
2384 options.append(b'--%s' % o[1])
2384 options.append(b'--%s' % o[1])
2385 ui.write(b"%s\n" % b"\n".join(options))
2385 ui.write(b"%s\n" % b"\n".join(options))
2386 return
2386 return
2387
2387
2388 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2388 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2389 if ui.verbose:
2389 if ui.verbose:
2390 cmdlist = [b' '.join(c[0]) for c in cmdlist.values()]
2390 cmdlist = [b' '.join(c[0]) for c in cmdlist.values()]
2391 ui.write(b"%s\n" % b"\n".join(sorted(cmdlist)))
2391 ui.write(b"%s\n" % b"\n".join(sorted(cmdlist)))
2392
2392
2393
2393
2394 @command(
2394 @command(
2395 b'diff',
2395 b'diff',
2396 [
2396 [
2397 (b'r', b'rev', [], _(b'revision'), _(b'REV')),
2397 (b'r', b'rev', [], _(b'revision'), _(b'REV')),
2398 (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')),
2398 (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')),
2399 ]
2399 ]
2400 + diffopts
2400 + diffopts
2401 + diffopts2
2401 + diffopts2
2402 + walkopts
2402 + walkopts
2403 + subrepoopts,
2403 + subrepoopts,
2404 _(b'[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
2404 _(b'[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
2405 helpcategory=command.CATEGORY_FILE_CONTENTS,
2405 helpcategory=command.CATEGORY_FILE_CONTENTS,
2406 helpbasic=True,
2406 helpbasic=True,
2407 inferrepo=True,
2407 inferrepo=True,
2408 intents={INTENT_READONLY},
2408 intents={INTENT_READONLY},
2409 )
2409 )
2410 def diff(ui, repo, *pats, **opts):
2410 def diff(ui, repo, *pats, **opts):
2411 """diff repository (or selected files)
2411 """diff repository (or selected files)
2412
2412
2413 Show differences between revisions for the specified files.
2413 Show differences between revisions for the specified files.
2414
2414
2415 Differences between files are shown using the unified diff format.
2415 Differences between files are shown using the unified diff format.
2416
2416
2417 .. note::
2417 .. note::
2418
2418
2419 :hg:`diff` may generate unexpected results for merges, as it will
2419 :hg:`diff` may generate unexpected results for merges, as it will
2420 default to comparing against the working directory's first
2420 default to comparing against the working directory's first
2421 parent changeset if no revisions are specified.
2421 parent changeset if no revisions are specified.
2422
2422
2423 When two revision arguments are given, then changes are shown
2423 When two revision arguments are given, then changes are shown
2424 between those revisions. If only one revision is specified then
2424 between those revisions. If only one revision is specified then
2425 that revision is compared to the working directory, and, when no
2425 that revision is compared to the working directory, and, when no
2426 revisions are specified, the working directory files are compared
2426 revisions are specified, the working directory files are compared
2427 to its first parent.
2427 to its first parent.
2428
2428
2429 Alternatively you can specify -c/--change with a revision to see
2429 Alternatively you can specify -c/--change with a revision to see
2430 the changes in that changeset relative to its first parent.
2430 the changes in that changeset relative to its first parent.
2431
2431
2432 Without the -a/--text option, diff will avoid generating diffs of
2432 Without the -a/--text option, diff will avoid generating diffs of
2433 files it detects as binary. With -a, diff will generate a diff
2433 files it detects as binary. With -a, diff will generate a diff
2434 anyway, probably with undesirable results.
2434 anyway, probably with undesirable results.
2435
2435
2436 Use the -g/--git option to generate diffs in the git extended diff
2436 Use the -g/--git option to generate diffs in the git extended diff
2437 format. For more information, read :hg:`help diffs`.
2437 format. For more information, read :hg:`help diffs`.
2438
2438
2439 .. container:: verbose
2439 .. container:: verbose
2440
2440
2441 Examples:
2441 Examples:
2442
2442
2443 - compare a file in the current working directory to its parent::
2443 - compare a file in the current working directory to its parent::
2444
2444
2445 hg diff foo.c
2445 hg diff foo.c
2446
2446
2447 - compare two historical versions of a directory, with rename info::
2447 - compare two historical versions of a directory, with rename info::
2448
2448
2449 hg diff --git -r 1.0:1.2 lib/
2449 hg diff --git -r 1.0:1.2 lib/
2450
2450
2451 - get change stats relative to the last change on some date::
2451 - get change stats relative to the last change on some date::
2452
2452
2453 hg diff --stat -r "date('may 2')"
2453 hg diff --stat -r "date('may 2')"
2454
2454
2455 - diff all newly-added files that contain a keyword::
2455 - diff all newly-added files that contain a keyword::
2456
2456
2457 hg diff "set:added() and grep(GNU)"
2457 hg diff "set:added() and grep(GNU)"
2458
2458
2459 - compare a revision and its parents::
2459 - compare a revision and its parents::
2460
2460
2461 hg diff -c 9353 # compare against first parent
2461 hg diff -c 9353 # compare against first parent
2462 hg diff -r 9353^:9353 # same using revset syntax
2462 hg diff -r 9353^:9353 # same using revset syntax
2463 hg diff -r 9353^2:9353 # compare against the second parent
2463 hg diff -r 9353^2:9353 # compare against the second parent
2464
2464
2465 Returns 0 on success.
2465 Returns 0 on success.
2466 """
2466 """
2467
2467
2468 opts = pycompat.byteskwargs(opts)
2468 opts = pycompat.byteskwargs(opts)
2469 revs = opts.get(b'rev')
2469 revs = opts.get(b'rev')
2470 change = opts.get(b'change')
2470 change = opts.get(b'change')
2471 stat = opts.get(b'stat')
2471 stat = opts.get(b'stat')
2472 reverse = opts.get(b'reverse')
2472 reverse = opts.get(b'reverse')
2473
2473
2474 if revs and change:
2474 if revs and change:
2475 msg = _(b'cannot specify --rev and --change at the same time')
2475 msg = _(b'cannot specify --rev and --change at the same time')
2476 raise error.Abort(msg)
2476 raise error.Abort(msg)
2477 elif change:
2477 elif change:
2478 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
2478 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
2479 ctx2 = scmutil.revsingle(repo, change, None)
2479 ctx2 = scmutil.revsingle(repo, change, None)
2480 ctx1 = ctx2.p1()
2480 ctx1 = ctx2.p1()
2481 else:
2481 else:
2482 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
2482 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
2483 ctx1, ctx2 = scmutil.revpair(repo, revs)
2483 ctx1, ctx2 = scmutil.revpair(repo, revs)
2484 node1, node2 = ctx1.node(), ctx2.node()
2484 node1, node2 = ctx1.node(), ctx2.node()
2485
2485
2486 if reverse:
2486 if reverse:
2487 node1, node2 = node2, node1
2487 node1, node2 = node2, node1
2488
2488
2489 diffopts = patch.diffallopts(ui, opts)
2489 diffopts = patch.diffallopts(ui, opts)
2490 m = scmutil.match(ctx2, pats, opts)
2490 m = scmutil.match(ctx2, pats, opts)
2491 m = repo.narrowmatch(m)
2491 m = repo.narrowmatch(m)
2492 ui.pager(b'diff')
2492 ui.pager(b'diff')
2493 logcmdutil.diffordiffstat(
2493 logcmdutil.diffordiffstat(
2494 ui,
2494 ui,
2495 repo,
2495 repo,
2496 diffopts,
2496 diffopts,
2497 node1,
2497 node1,
2498 node2,
2498 node2,
2499 m,
2499 m,
2500 stat=stat,
2500 stat=stat,
2501 listsubrepos=opts.get(b'subrepos'),
2501 listsubrepos=opts.get(b'subrepos'),
2502 root=opts.get(b'root'),
2502 root=opts.get(b'root'),
2503 )
2503 )
2504
2504
2505
2505
2506 @command(
2506 @command(
2507 b'export',
2507 b'export',
2508 [
2508 [
2509 (
2509 (
2510 b'B',
2510 b'B',
2511 b'bookmark',
2511 b'bookmark',
2512 b'',
2512 b'',
2513 _(b'export changes only reachable by given bookmark'),
2513 _(b'export changes only reachable by given bookmark'),
2514 _(b'BOOKMARK'),
2514 _(b'BOOKMARK'),
2515 ),
2515 ),
2516 (
2516 (
2517 b'o',
2517 b'o',
2518 b'output',
2518 b'output',
2519 b'',
2519 b'',
2520 _(b'print output to file with formatted name'),
2520 _(b'print output to file with formatted name'),
2521 _(b'FORMAT'),
2521 _(b'FORMAT'),
2522 ),
2522 ),
2523 (b'', b'switch-parent', None, _(b'diff against the second parent')),
2523 (b'', b'switch-parent', None, _(b'diff against the second parent')),
2524 (b'r', b'rev', [], _(b'revisions to export'), _(b'REV')),
2524 (b'r', b'rev', [], _(b'revisions to export'), _(b'REV')),
2525 ]
2525 ]
2526 + diffopts
2526 + diffopts
2527 + formatteropts,
2527 + formatteropts,
2528 _(b'[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2528 _(b'[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2529 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2529 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2530 helpbasic=True,
2530 helpbasic=True,
2531 intents={INTENT_READONLY},
2531 intents={INTENT_READONLY},
2532 )
2532 )
2533 def export(ui, repo, *changesets, **opts):
2533 def export(ui, repo, *changesets, **opts):
2534 """dump the header and diffs for one or more changesets
2534 """dump the header and diffs for one or more changesets
2535
2535
2536 Print the changeset header and diffs for one or more revisions.
2536 Print the changeset header and diffs for one or more revisions.
2537 If no revision is given, the parent of the working directory is used.
2537 If no revision is given, the parent of the working directory is used.
2538
2538
2539 The information shown in the changeset header is: author, date,
2539 The information shown in the changeset header is: author, date,
2540 branch name (if non-default), changeset hash, parent(s) and commit
2540 branch name (if non-default), changeset hash, parent(s) and commit
2541 comment.
2541 comment.
2542
2542
2543 .. note::
2543 .. note::
2544
2544
2545 :hg:`export` may generate unexpected diff output for merge
2545 :hg:`export` may generate unexpected diff output for merge
2546 changesets, as it will compare the merge changeset against its
2546 changesets, as it will compare the merge changeset against its
2547 first parent only.
2547 first parent only.
2548
2548
2549 Output may be to a file, in which case the name of the file is
2549 Output may be to a file, in which case the name of the file is
2550 given using a template string. See :hg:`help templates`. In addition
2550 given using a template string. See :hg:`help templates`. In addition
2551 to the common template keywords, the following formatting rules are
2551 to the common template keywords, the following formatting rules are
2552 supported:
2552 supported:
2553
2553
2554 :``%%``: literal "%" character
2554 :``%%``: literal "%" character
2555 :``%H``: changeset hash (40 hexadecimal digits)
2555 :``%H``: changeset hash (40 hexadecimal digits)
2556 :``%N``: number of patches being generated
2556 :``%N``: number of patches being generated
2557 :``%R``: changeset revision number
2557 :``%R``: changeset revision number
2558 :``%b``: basename of the exporting repository
2558 :``%b``: basename of the exporting repository
2559 :``%h``: short-form changeset hash (12 hexadecimal digits)
2559 :``%h``: short-form changeset hash (12 hexadecimal digits)
2560 :``%m``: first line of the commit message (only alphanumeric characters)
2560 :``%m``: first line of the commit message (only alphanumeric characters)
2561 :``%n``: zero-padded sequence number, starting at 1
2561 :``%n``: zero-padded sequence number, starting at 1
2562 :``%r``: zero-padded changeset revision number
2562 :``%r``: zero-padded changeset revision number
2563 :``\\``: literal "\\" character
2563 :``\\``: literal "\\" character
2564
2564
2565 Without the -a/--text option, export will avoid generating diffs
2565 Without the -a/--text option, export will avoid generating diffs
2566 of files it detects as binary. With -a, export will generate a
2566 of files it detects as binary. With -a, export will generate a
2567 diff anyway, probably with undesirable results.
2567 diff anyway, probably with undesirable results.
2568
2568
2569 With -B/--bookmark changesets reachable by the given bookmark are
2569 With -B/--bookmark changesets reachable by the given bookmark are
2570 selected.
2570 selected.
2571
2571
2572 Use the -g/--git option to generate diffs in the git extended diff
2572 Use the -g/--git option to generate diffs in the git extended diff
2573 format. See :hg:`help diffs` for more information.
2573 format. See :hg:`help diffs` for more information.
2574
2574
2575 With the --switch-parent option, the diff will be against the
2575 With the --switch-parent option, the diff will be against the
2576 second parent. It can be useful to review a merge.
2576 second parent. It can be useful to review a merge.
2577
2577
2578 .. container:: verbose
2578 .. container:: verbose
2579
2579
2580 Template:
2580 Template:
2581
2581
2582 The following keywords are supported in addition to the common template
2582 The following keywords are supported in addition to the common template
2583 keywords and functions. See also :hg:`help templates`.
2583 keywords and functions. See also :hg:`help templates`.
2584
2584
2585 :diff: String. Diff content.
2585 :diff: String. Diff content.
2586 :parents: List of strings. Parent nodes of the changeset.
2586 :parents: List of strings. Parent nodes of the changeset.
2587
2587
2588 Examples:
2588 Examples:
2589
2589
2590 - use export and import to transplant a bugfix to the current
2590 - use export and import to transplant a bugfix to the current
2591 branch::
2591 branch::
2592
2592
2593 hg export -r 9353 | hg import -
2593 hg export -r 9353 | hg import -
2594
2594
2595 - export all the changesets between two revisions to a file with
2595 - export all the changesets between two revisions to a file with
2596 rename information::
2596 rename information::
2597
2597
2598 hg export --git -r 123:150 > changes.txt
2598 hg export --git -r 123:150 > changes.txt
2599
2599
2600 - split outgoing changes into a series of patches with
2600 - split outgoing changes into a series of patches with
2601 descriptive names::
2601 descriptive names::
2602
2602
2603 hg export -r "outgoing()" -o "%n-%m.patch"
2603 hg export -r "outgoing()" -o "%n-%m.patch"
2604
2604
2605 Returns 0 on success.
2605 Returns 0 on success.
2606 """
2606 """
2607 opts = pycompat.byteskwargs(opts)
2607 opts = pycompat.byteskwargs(opts)
2608 bookmark = opts.get(b'bookmark')
2608 bookmark = opts.get(b'bookmark')
2609 changesets += tuple(opts.get(b'rev', []))
2609 changesets += tuple(opts.get(b'rev', []))
2610
2610
2611 if bookmark and changesets:
2611 if bookmark and changesets:
2612 raise error.Abort(_(b"-r and -B are mutually exclusive"))
2612 raise error.Abort(_(b"-r and -B are mutually exclusive"))
2613
2613
2614 if bookmark:
2614 if bookmark:
2615 if bookmark not in repo._bookmarks:
2615 if bookmark not in repo._bookmarks:
2616 raise error.Abort(_(b"bookmark '%s' not found") % bookmark)
2616 raise error.Abort(_(b"bookmark '%s' not found") % bookmark)
2617
2617
2618 revs = scmutil.bookmarkrevs(repo, bookmark)
2618 revs = scmutil.bookmarkrevs(repo, bookmark)
2619 else:
2619 else:
2620 if not changesets:
2620 if not changesets:
2621 changesets = [b'.']
2621 changesets = [b'.']
2622
2622
2623 repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
2623 repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
2624 revs = scmutil.revrange(repo, changesets)
2624 revs = scmutil.revrange(repo, changesets)
2625
2625
2626 if not revs:
2626 if not revs:
2627 raise error.Abort(_(b"export requires at least one changeset"))
2627 raise error.Abort(_(b"export requires at least one changeset"))
2628 if len(revs) > 1:
2628 if len(revs) > 1:
2629 ui.note(_(b'exporting patches:\n'))
2629 ui.note(_(b'exporting patches:\n'))
2630 else:
2630 else:
2631 ui.note(_(b'exporting patch:\n'))
2631 ui.note(_(b'exporting patch:\n'))
2632
2632
2633 fntemplate = opts.get(b'output')
2633 fntemplate = opts.get(b'output')
2634 if cmdutil.isstdiofilename(fntemplate):
2634 if cmdutil.isstdiofilename(fntemplate):
2635 fntemplate = b''
2635 fntemplate = b''
2636
2636
2637 if fntemplate:
2637 if fntemplate:
2638 fm = formatter.nullformatter(ui, b'export', opts)
2638 fm = formatter.nullformatter(ui, b'export', opts)
2639 else:
2639 else:
2640 ui.pager(b'export')
2640 ui.pager(b'export')
2641 fm = ui.formatter(b'export', opts)
2641 fm = ui.formatter(b'export', opts)
2642 with fm:
2642 with fm:
2643 cmdutil.export(
2643 cmdutil.export(
2644 repo,
2644 repo,
2645 revs,
2645 revs,
2646 fm,
2646 fm,
2647 fntemplate=fntemplate,
2647 fntemplate=fntemplate,
2648 switch_parent=opts.get(b'switch_parent'),
2648 switch_parent=opts.get(b'switch_parent'),
2649 opts=patch.diffallopts(ui, opts),
2649 opts=patch.diffallopts(ui, opts),
2650 )
2650 )
2651
2651
2652
2652
2653 @command(
2653 @command(
2654 b'files',
2654 b'files',
2655 [
2655 [
2656 (
2656 (
2657 b'r',
2657 b'r',
2658 b'rev',
2658 b'rev',
2659 b'',
2659 b'',
2660 _(b'search the repository as it is in REV'),
2660 _(b'search the repository as it is in REV'),
2661 _(b'REV'),
2661 _(b'REV'),
2662 ),
2662 ),
2663 (
2663 (
2664 b'0',
2664 b'0',
2665 b'print0',
2665 b'print0',
2666 None,
2666 None,
2667 _(b'end filenames with NUL, for use with xargs'),
2667 _(b'end filenames with NUL, for use with xargs'),
2668 ),
2668 ),
2669 ]
2669 ]
2670 + walkopts
2670 + walkopts
2671 + formatteropts
2671 + formatteropts
2672 + subrepoopts,
2672 + subrepoopts,
2673 _(b'[OPTION]... [FILE]...'),
2673 _(b'[OPTION]... [FILE]...'),
2674 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2674 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2675 intents={INTENT_READONLY},
2675 intents={INTENT_READONLY},
2676 )
2676 )
2677 def files(ui, repo, *pats, **opts):
2677 def files(ui, repo, *pats, **opts):
2678 """list tracked files
2678 """list tracked files
2679
2679
2680 Print files under Mercurial control in the working directory or
2680 Print files under Mercurial control in the working directory or
2681 specified revision for given files (excluding removed files).
2681 specified revision for given files (excluding removed files).
2682 Files can be specified as filenames or filesets.
2682 Files can be specified as filenames or filesets.
2683
2683
2684 If no files are given to match, this command prints the names
2684 If no files are given to match, this command prints the names
2685 of all files under Mercurial control.
2685 of all files under Mercurial control.
2686
2686
2687 .. container:: verbose
2687 .. container:: verbose
2688
2688
2689 Template:
2689 Template:
2690
2690
2691 The following keywords are supported in addition to the common template
2691 The following keywords are supported in addition to the common template
2692 keywords and functions. See also :hg:`help templates`.
2692 keywords and functions. See also :hg:`help templates`.
2693
2693
2694 :flags: String. Character denoting file's symlink and executable bits.
2694 :flags: String. Character denoting file's symlink and executable bits.
2695 :path: String. Repository-absolute path of the file.
2695 :path: String. Repository-absolute path of the file.
2696 :size: Integer. Size of the file in bytes.
2696 :size: Integer. Size of the file in bytes.
2697
2697
2698 Examples:
2698 Examples:
2699
2699
2700 - list all files under the current directory::
2700 - list all files under the current directory::
2701
2701
2702 hg files .
2702 hg files .
2703
2703
2704 - shows sizes and flags for current revision::
2704 - shows sizes and flags for current revision::
2705
2705
2706 hg files -vr .
2706 hg files -vr .
2707
2707
2708 - list all files named README::
2708 - list all files named README::
2709
2709
2710 hg files -I "**/README"
2710 hg files -I "**/README"
2711
2711
2712 - list all binary files::
2712 - list all binary files::
2713
2713
2714 hg files "set:binary()"
2714 hg files "set:binary()"
2715
2715
2716 - find files containing a regular expression::
2716 - find files containing a regular expression::
2717
2717
2718 hg files "set:grep('bob')"
2718 hg files "set:grep('bob')"
2719
2719
2720 - search tracked file contents with xargs and grep::
2720 - search tracked file contents with xargs and grep::
2721
2721
2722 hg files -0 | xargs -0 grep foo
2722 hg files -0 | xargs -0 grep foo
2723
2723
2724 See :hg:`help patterns` and :hg:`help filesets` for more information
2724 See :hg:`help patterns` and :hg:`help filesets` for more information
2725 on specifying file patterns.
2725 on specifying file patterns.
2726
2726
2727 Returns 0 if a match is found, 1 otherwise.
2727 Returns 0 if a match is found, 1 otherwise.
2728
2728
2729 """
2729 """
2730
2730
2731 opts = pycompat.byteskwargs(opts)
2731 opts = pycompat.byteskwargs(opts)
2732 rev = opts.get(b'rev')
2732 rev = opts.get(b'rev')
2733 if rev:
2733 if rev:
2734 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
2734 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
2735 ctx = scmutil.revsingle(repo, rev, None)
2735 ctx = scmutil.revsingle(repo, rev, None)
2736
2736
2737 end = b'\n'
2737 end = b'\n'
2738 if opts.get(b'print0'):
2738 if opts.get(b'print0'):
2739 end = b'\0'
2739 end = b'\0'
2740 fmt = b'%s' + end
2740 fmt = b'%s' + end
2741
2741
2742 m = scmutil.match(ctx, pats, opts)
2742 m = scmutil.match(ctx, pats, opts)
2743 ui.pager(b'files')
2743 ui.pager(b'files')
2744 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2744 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2745 with ui.formatter(b'files', opts) as fm:
2745 with ui.formatter(b'files', opts) as fm:
2746 return cmdutil.files(
2746 return cmdutil.files(
2747 ui, ctx, m, uipathfn, fm, fmt, opts.get(b'subrepos')
2747 ui, ctx, m, uipathfn, fm, fmt, opts.get(b'subrepos')
2748 )
2748 )
2749
2749
2750
2750
2751 @command(
2751 @command(
2752 b'forget',
2752 b'forget',
2753 [(b'i', b'interactive', None, _(b'use interactive mode')),]
2753 [(b'i', b'interactive', None, _(b'use interactive mode')),]
2754 + walkopts
2754 + walkopts
2755 + dryrunopts,
2755 + dryrunopts,
2756 _(b'[OPTION]... FILE...'),
2756 _(b'[OPTION]... FILE...'),
2757 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2757 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2758 helpbasic=True,
2758 helpbasic=True,
2759 inferrepo=True,
2759 inferrepo=True,
2760 )
2760 )
2761 def forget(ui, repo, *pats, **opts):
2761 def forget(ui, repo, *pats, **opts):
2762 """forget the specified files on the next commit
2762 """forget the specified files on the next commit
2763
2763
2764 Mark the specified files so they will no longer be tracked
2764 Mark the specified files so they will no longer be tracked
2765 after the next commit.
2765 after the next commit.
2766
2766
2767 This only removes files from the current branch, not from the
2767 This only removes files from the current branch, not from the
2768 entire project history, and it does not delete them from the
2768 entire project history, and it does not delete them from the
2769 working directory.
2769 working directory.
2770
2770
2771 To delete the file from the working directory, see :hg:`remove`.
2771 To delete the file from the working directory, see :hg:`remove`.
2772
2772
2773 To undo a forget before the next commit, see :hg:`add`.
2773 To undo a forget before the next commit, see :hg:`add`.
2774
2774
2775 .. container:: verbose
2775 .. container:: verbose
2776
2776
2777 Examples:
2777 Examples:
2778
2778
2779 - forget newly-added binary files::
2779 - forget newly-added binary files::
2780
2780
2781 hg forget "set:added() and binary()"
2781 hg forget "set:added() and binary()"
2782
2782
2783 - forget files that would be excluded by .hgignore::
2783 - forget files that would be excluded by .hgignore::
2784
2784
2785 hg forget "set:hgignore()"
2785 hg forget "set:hgignore()"
2786
2786
2787 Returns 0 on success.
2787 Returns 0 on success.
2788 """
2788 """
2789
2789
2790 opts = pycompat.byteskwargs(opts)
2790 opts = pycompat.byteskwargs(opts)
2791 if not pats:
2791 if not pats:
2792 raise error.Abort(_(b'no files specified'))
2792 raise error.Abort(_(b'no files specified'))
2793
2793
2794 m = scmutil.match(repo[None], pats, opts)
2794 m = scmutil.match(repo[None], pats, opts)
2795 dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive')
2795 dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive')
2796 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2796 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2797 rejected = cmdutil.forget(
2797 rejected = cmdutil.forget(
2798 ui,
2798 ui,
2799 repo,
2799 repo,
2800 m,
2800 m,
2801 prefix=b"",
2801 prefix=b"",
2802 uipathfn=uipathfn,
2802 uipathfn=uipathfn,
2803 explicitonly=False,
2803 explicitonly=False,
2804 dryrun=dryrun,
2804 dryrun=dryrun,
2805 interactive=interactive,
2805 interactive=interactive,
2806 )[0]
2806 )[0]
2807 return rejected and 1 or 0
2807 return rejected and 1 or 0
2808
2808
2809
2809
2810 @command(
2810 @command(
2811 b'graft',
2811 b'graft',
2812 [
2812 [
2813 (b'r', b'rev', [], _(b'revisions to graft'), _(b'REV')),
2813 (b'r', b'rev', [], _(b'revisions to graft'), _(b'REV')),
2814 (
2814 (
2815 b'',
2815 b'',
2816 b'base',
2816 b'base',
2817 b'',
2817 b'',
2818 _(b'base revision when doing the graft merge (ADVANCED)'),
2818 _(b'base revision when doing the graft merge (ADVANCED)'),
2819 _(b'REV'),
2819 _(b'REV'),
2820 ),
2820 ),
2821 (b'c', b'continue', False, _(b'resume interrupted graft')),
2821 (b'c', b'continue', False, _(b'resume interrupted graft')),
2822 (b'', b'stop', False, _(b'stop interrupted graft')),
2822 (b'', b'stop', False, _(b'stop interrupted graft')),
2823 (b'', b'abort', False, _(b'abort interrupted graft')),
2823 (b'', b'abort', False, _(b'abort interrupted graft')),
2824 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
2824 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
2825 (b'', b'log', None, _(b'append graft info to log message')),
2825 (b'', b'log', None, _(b'append graft info to log message')),
2826 (
2826 (
2827 b'',
2827 b'',
2828 b'no-commit',
2828 b'no-commit',
2829 None,
2829 None,
2830 _(b"don't commit, just apply the changes in working directory"),
2830 _(b"don't commit, just apply the changes in working directory"),
2831 ),
2831 ),
2832 (b'f', b'force', False, _(b'force graft')),
2832 (b'f', b'force', False, _(b'force graft')),
2833 (
2833 (
2834 b'D',
2834 b'D',
2835 b'currentdate',
2835 b'currentdate',
2836 False,
2836 False,
2837 _(b'record the current date as commit date'),
2837 _(b'record the current date as commit date'),
2838 ),
2838 ),
2839 (
2839 (
2840 b'U',
2840 b'U',
2841 b'currentuser',
2841 b'currentuser',
2842 False,
2842 False,
2843 _(b'record the current user as committer'),
2843 _(b'record the current user as committer'),
2844 ),
2844 ),
2845 ]
2845 ]
2846 + commitopts2
2846 + commitopts2
2847 + mergetoolopts
2847 + mergetoolopts
2848 + dryrunopts,
2848 + dryrunopts,
2849 _(b'[OPTION]... [-r REV]... REV...'),
2849 _(b'[OPTION]... [-r REV]... REV...'),
2850 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2850 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2851 )
2851 )
2852 def graft(ui, repo, *revs, **opts):
2852 def graft(ui, repo, *revs, **opts):
2853 '''copy changes from other branches onto the current branch
2853 '''copy changes from other branches onto the current branch
2854
2854
2855 This command uses Mercurial's merge logic to copy individual
2855 This command uses Mercurial's merge logic to copy individual
2856 changes from other branches without merging branches in the
2856 changes from other branches without merging branches in the
2857 history graph. This is sometimes known as 'backporting' or
2857 history graph. This is sometimes known as 'backporting' or
2858 'cherry-picking'. By default, graft will copy user, date, and
2858 'cherry-picking'. By default, graft will copy user, date, and
2859 description from the source changesets.
2859 description from the source changesets.
2860
2860
2861 Changesets that are ancestors of the current revision, that have
2861 Changesets that are ancestors of the current revision, that have
2862 already been grafted, or that are merges will be skipped.
2862 already been grafted, or that are merges will be skipped.
2863
2863
2864 If --log is specified, log messages will have a comment appended
2864 If --log is specified, log messages will have a comment appended
2865 of the form::
2865 of the form::
2866
2866
2867 (grafted from CHANGESETHASH)
2867 (grafted from CHANGESETHASH)
2868
2868
2869 If --force is specified, revisions will be grafted even if they
2869 If --force is specified, revisions will be grafted even if they
2870 are already ancestors of, or have been grafted to, the destination.
2870 are already ancestors of, or have been grafted to, the destination.
2871 This is useful when the revisions have since been backed out.
2871 This is useful when the revisions have since been backed out.
2872
2872
2873 If a graft merge results in conflicts, the graft process is
2873 If a graft merge results in conflicts, the graft process is
2874 interrupted so that the current merge can be manually resolved.
2874 interrupted so that the current merge can be manually resolved.
2875 Once all conflicts are addressed, the graft process can be
2875 Once all conflicts are addressed, the graft process can be
2876 continued with the -c/--continue option.
2876 continued with the -c/--continue option.
2877
2877
2878 The -c/--continue option reapplies all the earlier options.
2878 The -c/--continue option reapplies all the earlier options.
2879
2879
2880 .. container:: verbose
2880 .. container:: verbose
2881
2881
2882 The --base option exposes more of how graft internally uses merge with a
2882 The --base option exposes more of how graft internally uses merge with a
2883 custom base revision. --base can be used to specify another ancestor than
2883 custom base revision. --base can be used to specify another ancestor than
2884 the first and only parent.
2884 the first and only parent.
2885
2885
2886 The command::
2886 The command::
2887
2887
2888 hg graft -r 345 --base 234
2888 hg graft -r 345 --base 234
2889
2889
2890 is thus pretty much the same as::
2890 is thus pretty much the same as::
2891
2891
2892 hg diff -r 234 -r 345 | hg import
2892 hg diff -r 234 -r 345 | hg import
2893
2893
2894 but using merge to resolve conflicts and track moved files.
2894 but using merge to resolve conflicts and track moved files.
2895
2895
2896 The result of a merge can thus be backported as a single commit by
2896 The result of a merge can thus be backported as a single commit by
2897 specifying one of the merge parents as base, and thus effectively
2897 specifying one of the merge parents as base, and thus effectively
2898 grafting the changes from the other side.
2898 grafting the changes from the other side.
2899
2899
2900 It is also possible to collapse multiple changesets and clean up history
2900 It is also possible to collapse multiple changesets and clean up history
2901 by specifying another ancestor as base, much like rebase --collapse
2901 by specifying another ancestor as base, much like rebase --collapse
2902 --keep.
2902 --keep.
2903
2903
2904 The commit message can be tweaked after the fact using commit --amend .
2904 The commit message can be tweaked after the fact using commit --amend .
2905
2905
2906 For using non-ancestors as the base to backout changes, see the backout
2906 For using non-ancestors as the base to backout changes, see the backout
2907 command and the hidden --parent option.
2907 command and the hidden --parent option.
2908
2908
2909 .. container:: verbose
2909 .. container:: verbose
2910
2910
2911 Examples:
2911 Examples:
2912
2912
2913 - copy a single change to the stable branch and edit its description::
2913 - copy a single change to the stable branch and edit its description::
2914
2914
2915 hg update stable
2915 hg update stable
2916 hg graft --edit 9393
2916 hg graft --edit 9393
2917
2917
2918 - graft a range of changesets with one exception, updating dates::
2918 - graft a range of changesets with one exception, updating dates::
2919
2919
2920 hg graft -D "2085::2093 and not 2091"
2920 hg graft -D "2085::2093 and not 2091"
2921
2921
2922 - continue a graft after resolving conflicts::
2922 - continue a graft after resolving conflicts::
2923
2923
2924 hg graft -c
2924 hg graft -c
2925
2925
2926 - show the source of a grafted changeset::
2926 - show the source of a grafted changeset::
2927
2927
2928 hg log --debug -r .
2928 hg log --debug -r .
2929
2929
2930 - show revisions sorted by date::
2930 - show revisions sorted by date::
2931
2931
2932 hg log -r "sort(all(), date)"
2932 hg log -r "sort(all(), date)"
2933
2933
2934 - backport the result of a merge as a single commit::
2934 - backport the result of a merge as a single commit::
2935
2935
2936 hg graft -r 123 --base 123^
2936 hg graft -r 123 --base 123^
2937
2937
2938 - land a feature branch as one changeset::
2938 - land a feature branch as one changeset::
2939
2939
2940 hg up -cr default
2940 hg up -cr default
2941 hg graft -r featureX --base "ancestor('featureX', 'default')"
2941 hg graft -r featureX --base "ancestor('featureX', 'default')"
2942
2942
2943 See :hg:`help revisions` for more about specifying revisions.
2943 See :hg:`help revisions` for more about specifying revisions.
2944
2944
2945 Returns 0 on successful completion.
2945 Returns 0 on successful completion.
2946 '''
2946 '''
2947 with repo.wlock():
2947 with repo.wlock():
2948 return _dograft(ui, repo, *revs, **opts)
2948 return _dograft(ui, repo, *revs, **opts)
2949
2949
2950
2950
2951 def _dograft(ui, repo, *revs, **opts):
2951 def _dograft(ui, repo, *revs, **opts):
2952 opts = pycompat.byteskwargs(opts)
2952 opts = pycompat.byteskwargs(opts)
2953 if revs and opts.get(b'rev'):
2953 if revs and opts.get(b'rev'):
2954 ui.warn(
2954 ui.warn(
2955 _(
2955 _(
2956 b'warning: inconsistent use of --rev might give unexpected '
2956 b'warning: inconsistent use of --rev might give unexpected '
2957 b'revision ordering!\n'
2957 b'revision ordering!\n'
2958 )
2958 )
2959 )
2959 )
2960
2960
2961 revs = list(revs)
2961 revs = list(revs)
2962 revs.extend(opts.get(b'rev'))
2962 revs.extend(opts.get(b'rev'))
2963 basectx = None
2963 basectx = None
2964 if opts.get(b'base'):
2964 if opts.get(b'base'):
2965 basectx = scmutil.revsingle(repo, opts[b'base'], None)
2965 basectx = scmutil.revsingle(repo, opts[b'base'], None)
2966 # a dict of data to be stored in state file
2966 # a dict of data to be stored in state file
2967 statedata = {}
2967 statedata = {}
2968 # list of new nodes created by ongoing graft
2968 # list of new nodes created by ongoing graft
2969 statedata[b'newnodes'] = []
2969 statedata[b'newnodes'] = []
2970
2970
2971 if opts.get(b'user') and opts.get(b'currentuser'):
2971 if opts.get(b'user') and opts.get(b'currentuser'):
2972 raise error.Abort(_(b'--user and --currentuser are mutually exclusive'))
2972 raise error.Abort(_(b'--user and --currentuser are mutually exclusive'))
2973 if opts.get(b'date') and opts.get(b'currentdate'):
2973 if opts.get(b'date') and opts.get(b'currentdate'):
2974 raise error.Abort(_(b'--date and --currentdate are mutually exclusive'))
2974 raise error.Abort(_(b'--date and --currentdate are mutually exclusive'))
2975 if not opts.get(b'user') and opts.get(b'currentuser'):
2975 if not opts.get(b'user') and opts.get(b'currentuser'):
2976 opts[b'user'] = ui.username()
2976 opts[b'user'] = ui.username()
2977 if not opts.get(b'date') and opts.get(b'currentdate'):
2977 if not opts.get(b'date') and opts.get(b'currentdate'):
2978 opts[b'date'] = b"%d %d" % dateutil.makedate()
2978 opts[b'date'] = b"%d %d" % dateutil.makedate()
2979
2979
2980 editor = cmdutil.getcommiteditor(
2980 editor = cmdutil.getcommiteditor(
2981 editform=b'graft', **pycompat.strkwargs(opts)
2981 editform=b'graft', **pycompat.strkwargs(opts)
2982 )
2982 )
2983
2983
2984 cont = False
2984 cont = False
2985 if opts.get(b'no_commit'):
2985 if opts.get(b'no_commit'):
2986 if opts.get(b'edit'):
2986 if opts.get(b'edit'):
2987 raise error.Abort(
2987 raise error.Abort(
2988 _(b"cannot specify --no-commit and --edit together")
2988 _(b"cannot specify --no-commit and --edit together")
2989 )
2989 )
2990 if opts.get(b'currentuser'):
2990 if opts.get(b'currentuser'):
2991 raise error.Abort(
2991 raise error.Abort(
2992 _(b"cannot specify --no-commit and --currentuser together")
2992 _(b"cannot specify --no-commit and --currentuser together")
2993 )
2993 )
2994 if opts.get(b'currentdate'):
2994 if opts.get(b'currentdate'):
2995 raise error.Abort(
2995 raise error.Abort(
2996 _(b"cannot specify --no-commit and --currentdate together")
2996 _(b"cannot specify --no-commit and --currentdate together")
2997 )
2997 )
2998 if opts.get(b'log'):
2998 if opts.get(b'log'):
2999 raise error.Abort(
2999 raise error.Abort(
3000 _(b"cannot specify --no-commit and --log together")
3000 _(b"cannot specify --no-commit and --log together")
3001 )
3001 )
3002
3002
3003 graftstate = statemod.cmdstate(repo, b'graftstate')
3003 graftstate = statemod.cmdstate(repo, b'graftstate')
3004
3004
3005 if opts.get(b'stop'):
3005 if opts.get(b'stop'):
3006 if opts.get(b'continue'):
3006 if opts.get(b'continue'):
3007 raise error.Abort(
3007 raise error.Abort(
3008 _(b"cannot use '--continue' and '--stop' together")
3008 _(b"cannot use '--continue' and '--stop' together")
3009 )
3009 )
3010 if opts.get(b'abort'):
3010 if opts.get(b'abort'):
3011 raise error.Abort(_(b"cannot use '--abort' and '--stop' together"))
3011 raise error.Abort(_(b"cannot use '--abort' and '--stop' together"))
3012
3012
3013 if any(
3013 if any(
3014 (
3014 (
3015 opts.get(b'edit'),
3015 opts.get(b'edit'),
3016 opts.get(b'log'),
3016 opts.get(b'log'),
3017 opts.get(b'user'),
3017 opts.get(b'user'),
3018 opts.get(b'date'),
3018 opts.get(b'date'),
3019 opts.get(b'currentdate'),
3019 opts.get(b'currentdate'),
3020 opts.get(b'currentuser'),
3020 opts.get(b'currentuser'),
3021 opts.get(b'rev'),
3021 opts.get(b'rev'),
3022 )
3022 )
3023 ):
3023 ):
3024 raise error.Abort(_(b"cannot specify any other flag with '--stop'"))
3024 raise error.Abort(_(b"cannot specify any other flag with '--stop'"))
3025 return _stopgraft(ui, repo, graftstate)
3025 return _stopgraft(ui, repo, graftstate)
3026 elif opts.get(b'abort'):
3026 elif opts.get(b'abort'):
3027 if opts.get(b'continue'):
3027 if opts.get(b'continue'):
3028 raise error.Abort(
3028 raise error.Abort(
3029 _(b"cannot use '--continue' and '--abort' together")
3029 _(b"cannot use '--continue' and '--abort' together")
3030 )
3030 )
3031 if any(
3031 if any(
3032 (
3032 (
3033 opts.get(b'edit'),
3033 opts.get(b'edit'),
3034 opts.get(b'log'),
3034 opts.get(b'log'),
3035 opts.get(b'user'),
3035 opts.get(b'user'),
3036 opts.get(b'date'),
3036 opts.get(b'date'),
3037 opts.get(b'currentdate'),
3037 opts.get(b'currentdate'),
3038 opts.get(b'currentuser'),
3038 opts.get(b'currentuser'),
3039 opts.get(b'rev'),
3039 opts.get(b'rev'),
3040 )
3040 )
3041 ):
3041 ):
3042 raise error.Abort(
3042 raise error.Abort(
3043 _(b"cannot specify any other flag with '--abort'")
3043 _(b"cannot specify any other flag with '--abort'")
3044 )
3044 )
3045
3045
3046 return cmdutil.abortgraft(ui, repo, graftstate)
3046 return cmdutil.abortgraft(ui, repo, graftstate)
3047 elif opts.get(b'continue'):
3047 elif opts.get(b'continue'):
3048 cont = True
3048 cont = True
3049 if revs:
3049 if revs:
3050 raise error.Abort(_(b"can't specify --continue and revisions"))
3050 raise error.Abort(_(b"can't specify --continue and revisions"))
3051 # read in unfinished revisions
3051 # read in unfinished revisions
3052 if graftstate.exists():
3052 if graftstate.exists():
3053 statedata = cmdutil.readgraftstate(repo, graftstate)
3053 statedata = cmdutil.readgraftstate(repo, graftstate)
3054 if statedata.get(b'date'):
3054 if statedata.get(b'date'):
3055 opts[b'date'] = statedata[b'date']
3055 opts[b'date'] = statedata[b'date']
3056 if statedata.get(b'user'):
3056 if statedata.get(b'user'):
3057 opts[b'user'] = statedata[b'user']
3057 opts[b'user'] = statedata[b'user']
3058 if statedata.get(b'log'):
3058 if statedata.get(b'log'):
3059 opts[b'log'] = True
3059 opts[b'log'] = True
3060 if statedata.get(b'no_commit'):
3060 if statedata.get(b'no_commit'):
3061 opts[b'no_commit'] = statedata.get(b'no_commit')
3061 opts[b'no_commit'] = statedata.get(b'no_commit')
3062 nodes = statedata[b'nodes']
3062 nodes = statedata[b'nodes']
3063 revs = [repo[node].rev() for node in nodes]
3063 revs = [repo[node].rev() for node in nodes]
3064 else:
3064 else:
3065 cmdutil.wrongtooltocontinue(repo, _(b'graft'))
3065 cmdutil.wrongtooltocontinue(repo, _(b'graft'))
3066 else:
3066 else:
3067 if not revs:
3067 if not revs:
3068 raise error.Abort(_(b'no revisions specified'))
3068 raise error.Abort(_(b'no revisions specified'))
3069 cmdutil.checkunfinished(repo)
3069 cmdutil.checkunfinished(repo)
3070 cmdutil.bailifchanged(repo)
3070 cmdutil.bailifchanged(repo)
3071 revs = scmutil.revrange(repo, revs)
3071 revs = scmutil.revrange(repo, revs)
3072
3072
3073 skipped = set()
3073 skipped = set()
3074 if basectx is None:
3074 if basectx is None:
3075 # check for merges
3075 # check for merges
3076 for rev in repo.revs(b'%ld and merge()', revs):
3076 for rev in repo.revs(b'%ld and merge()', revs):
3077 ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev)
3077 ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev)
3078 skipped.add(rev)
3078 skipped.add(rev)
3079 revs = [r for r in revs if r not in skipped]
3079 revs = [r for r in revs if r not in skipped]
3080 if not revs:
3080 if not revs:
3081 return -1
3081 return -1
3082 if basectx is not None and len(revs) != 1:
3082 if basectx is not None and len(revs) != 1:
3083 raise error.Abort(_(b'only one revision allowed with --base '))
3083 raise error.Abort(_(b'only one revision allowed with --base '))
3084
3084
3085 # Don't check in the --continue case, in effect retaining --force across
3085 # Don't check in the --continue case, in effect retaining --force across
3086 # --continues. That's because without --force, any revisions we decided to
3086 # --continues. That's because without --force, any revisions we decided to
3087 # skip would have been filtered out here, so they wouldn't have made their
3087 # skip would have been filtered out here, so they wouldn't have made their
3088 # way to the graftstate. With --force, any revisions we would have otherwise
3088 # way to the graftstate. With --force, any revisions we would have otherwise
3089 # skipped would not have been filtered out, and if they hadn't been applied
3089 # skipped would not have been filtered out, and if they hadn't been applied
3090 # already, they'd have been in the graftstate.
3090 # already, they'd have been in the graftstate.
3091 if not (cont or opts.get(b'force')) and basectx is None:
3091 if not (cont or opts.get(b'force')) and basectx is None:
3092 # check for ancestors of dest branch
3092 # check for ancestors of dest branch
3093 crev = repo[b'.'].rev()
3093 crev = repo[b'.'].rev()
3094 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3094 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3095 # XXX make this lazy in the future
3095 # XXX make this lazy in the future
3096 # don't mutate while iterating, create a copy
3096 # don't mutate while iterating, create a copy
3097 for rev in list(revs):
3097 for rev in list(revs):
3098 if rev in ancestors:
3098 if rev in ancestors:
3099 ui.warn(
3099 ui.warn(
3100 _(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev])
3100 _(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev])
3101 )
3101 )
3102 # XXX remove on list is slow
3102 # XXX remove on list is slow
3103 revs.remove(rev)
3103 revs.remove(rev)
3104 if not revs:
3104 if not revs:
3105 return -1
3105 return -1
3106
3106
3107 # analyze revs for earlier grafts
3107 # analyze revs for earlier grafts
3108 ids = {}
3108 ids = {}
3109 for ctx in repo.set(b"%ld", revs):
3109 for ctx in repo.set(b"%ld", revs):
3110 ids[ctx.hex()] = ctx.rev()
3110 ids[ctx.hex()] = ctx.rev()
3111 n = ctx.extra().get(b'source')
3111 n = ctx.extra().get(b'source')
3112 if n:
3112 if n:
3113 ids[n] = ctx.rev()
3113 ids[n] = ctx.rev()
3114
3114
3115 # check ancestors for earlier grafts
3115 # check ancestors for earlier grafts
3116 ui.debug(b'scanning for duplicate grafts\n')
3116 ui.debug(b'scanning for duplicate grafts\n')
3117
3117
3118 # The only changesets we can be sure doesn't contain grafts of any
3118 # The only changesets we can be sure doesn't contain grafts of any
3119 # revs, are the ones that are common ancestors of *all* revs:
3119 # revs, are the ones that are common ancestors of *all* revs:
3120 for rev in repo.revs(b'only(%d,ancestor(%ld))', crev, revs):
3120 for rev in repo.revs(b'only(%d,ancestor(%ld))', crev, revs):
3121 ctx = repo[rev]
3121 ctx = repo[rev]
3122 n = ctx.extra().get(b'source')
3122 n = ctx.extra().get(b'source')
3123 if n in ids:
3123 if n in ids:
3124 try:
3124 try:
3125 r = repo[n].rev()
3125 r = repo[n].rev()
3126 except error.RepoLookupError:
3126 except error.RepoLookupError:
3127 r = None
3127 r = None
3128 if r in revs:
3128 if r in revs:
3129 ui.warn(
3129 ui.warn(
3130 _(
3130 _(
3131 b'skipping revision %d:%s '
3131 b'skipping revision %d:%s '
3132 b'(already grafted to %d:%s)\n'
3132 b'(already grafted to %d:%s)\n'
3133 )
3133 )
3134 % (r, repo[r], rev, ctx)
3134 % (r, repo[r], rev, ctx)
3135 )
3135 )
3136 revs.remove(r)
3136 revs.remove(r)
3137 elif ids[n] in revs:
3137 elif ids[n] in revs:
3138 if r is None:
3138 if r is None:
3139 ui.warn(
3139 ui.warn(
3140 _(
3140 _(
3141 b'skipping already grafted revision %d:%s '
3141 b'skipping already grafted revision %d:%s '
3142 b'(%d:%s also has unknown origin %s)\n'
3142 b'(%d:%s also has unknown origin %s)\n'
3143 )
3143 )
3144 % (ids[n], repo[ids[n]], rev, ctx, n[:12])
3144 % (ids[n], repo[ids[n]], rev, ctx, n[:12])
3145 )
3145 )
3146 else:
3146 else:
3147 ui.warn(
3147 ui.warn(
3148 _(
3148 _(
3149 b'skipping already grafted revision %d:%s '
3149 b'skipping already grafted revision %d:%s '
3150 b'(%d:%s also has origin %d:%s)\n'
3150 b'(%d:%s also has origin %d:%s)\n'
3151 )
3151 )
3152 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
3152 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
3153 )
3153 )
3154 revs.remove(ids[n])
3154 revs.remove(ids[n])
3155 elif ctx.hex() in ids:
3155 elif ctx.hex() in ids:
3156 r = ids[ctx.hex()]
3156 r = ids[ctx.hex()]
3157 if r in revs:
3157 if r in revs:
3158 ui.warn(
3158 ui.warn(
3159 _(
3159 _(
3160 b'skipping already grafted revision %d:%s '
3160 b'skipping already grafted revision %d:%s '
3161 b'(was grafted from %d:%s)\n'
3161 b'(was grafted from %d:%s)\n'
3162 )
3162 )
3163 % (r, repo[r], rev, ctx)
3163 % (r, repo[r], rev, ctx)
3164 )
3164 )
3165 revs.remove(r)
3165 revs.remove(r)
3166 if not revs:
3166 if not revs:
3167 return -1
3167 return -1
3168
3168
3169 if opts.get(b'no_commit'):
3169 if opts.get(b'no_commit'):
3170 statedata[b'no_commit'] = True
3170 statedata[b'no_commit'] = True
3171 for pos, ctx in enumerate(repo.set(b"%ld", revs)):
3171 for pos, ctx in enumerate(repo.set(b"%ld", revs)):
3172 desc = b'%d:%s "%s"' % (
3172 desc = b'%d:%s "%s"' % (
3173 ctx.rev(),
3173 ctx.rev(),
3174 ctx,
3174 ctx,
3175 ctx.description().split(b'\n', 1)[0],
3175 ctx.description().split(b'\n', 1)[0],
3176 )
3176 )
3177 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3177 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3178 if names:
3178 if names:
3179 desc += b' (%s)' % b' '.join(names)
3179 desc += b' (%s)' % b' '.join(names)
3180 ui.status(_(b'grafting %s\n') % desc)
3180 ui.status(_(b'grafting %s\n') % desc)
3181 if opts.get(b'dry_run'):
3181 if opts.get(b'dry_run'):
3182 continue
3182 continue
3183
3183
3184 source = ctx.extra().get(b'source')
3184 source = ctx.extra().get(b'source')
3185 extra = {}
3185 extra = {}
3186 if source:
3186 if source:
3187 extra[b'source'] = source
3187 extra[b'source'] = source
3188 extra[b'intermediate-source'] = ctx.hex()
3188 extra[b'intermediate-source'] = ctx.hex()
3189 else:
3189 else:
3190 extra[b'source'] = ctx.hex()
3190 extra[b'source'] = ctx.hex()
3191 user = ctx.user()
3191 user = ctx.user()
3192 if opts.get(b'user'):
3192 if opts.get(b'user'):
3193 user = opts[b'user']
3193 user = opts[b'user']
3194 statedata[b'user'] = user
3194 statedata[b'user'] = user
3195 date = ctx.date()
3195 date = ctx.date()
3196 if opts.get(b'date'):
3196 if opts.get(b'date'):
3197 date = opts[b'date']
3197 date = opts[b'date']
3198 statedata[b'date'] = date
3198 statedata[b'date'] = date
3199 message = ctx.description()
3199 message = ctx.description()
3200 if opts.get(b'log'):
3200 if opts.get(b'log'):
3201 message += b'\n(grafted from %s)' % ctx.hex()
3201 message += b'\n(grafted from %s)' % ctx.hex()
3202 statedata[b'log'] = True
3202 statedata[b'log'] = True
3203
3203
3204 # we don't merge the first commit when continuing
3204 # we don't merge the first commit when continuing
3205 if not cont:
3205 if not cont:
3206 # perform the graft merge with p1(rev) as 'ancestor'
3206 # perform the graft merge with p1(rev) as 'ancestor'
3207 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
3207 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
3208 base = ctx.p1() if basectx is None else basectx
3208 base = ctx.p1() if basectx is None else basectx
3209 with ui.configoverride(overrides, b'graft'):
3209 with ui.configoverride(overrides, b'graft'):
3210 stats = mergemod.graft(repo, ctx, base, [b'local', b'graft'])
3210 stats = mergemod.graft(repo, ctx, base, [b'local', b'graft'])
3211 # report any conflicts
3211 # report any conflicts
3212 if stats.unresolvedcount > 0:
3212 if stats.unresolvedcount > 0:
3213 # write out state for --continue
3213 # write out state for --continue
3214 nodes = [repo[rev].hex() for rev in revs[pos:]]
3214 nodes = [repo[rev].hex() for rev in revs[pos:]]
3215 statedata[b'nodes'] = nodes
3215 statedata[b'nodes'] = nodes
3216 stateversion = 1
3216 stateversion = 1
3217 graftstate.save(stateversion, statedata)
3217 graftstate.save(stateversion, statedata)
3218 hint = _(b"use 'hg resolve' and 'hg graft --continue'")
3218 hint = _(b"use 'hg resolve' and 'hg graft --continue'")
3219 raise error.Abort(
3219 raise error.Abort(
3220 _(b"unresolved conflicts, can't continue"), hint=hint
3220 _(b"unresolved conflicts, can't continue"), hint=hint
3221 )
3221 )
3222 else:
3222 else:
3223 cont = False
3223 cont = False
3224
3224
3225 # commit if --no-commit is false
3225 # commit if --no-commit is false
3226 if not opts.get(b'no_commit'):
3226 if not opts.get(b'no_commit'):
3227 node = repo.commit(
3227 node = repo.commit(
3228 text=message, user=user, date=date, extra=extra, editor=editor
3228 text=message, user=user, date=date, extra=extra, editor=editor
3229 )
3229 )
3230 if node is None:
3230 if node is None:
3231 ui.warn(
3231 ui.warn(
3232 _(b'note: graft of %d:%s created no changes to commit\n')
3232 _(b'note: graft of %d:%s created no changes to commit\n')
3233 % (ctx.rev(), ctx)
3233 % (ctx.rev(), ctx)
3234 )
3234 )
3235 # checking that newnodes exist because old state files won't have it
3235 # checking that newnodes exist because old state files won't have it
3236 elif statedata.get(b'newnodes') is not None:
3236 elif statedata.get(b'newnodes') is not None:
3237 statedata[b'newnodes'].append(node)
3237 statedata[b'newnodes'].append(node)
3238
3238
3239 # remove state when we complete successfully
3239 # remove state when we complete successfully
3240 if not opts.get(b'dry_run'):
3240 if not opts.get(b'dry_run'):
3241 graftstate.delete()
3241 graftstate.delete()
3242
3242
3243 return 0
3243 return 0
3244
3244
3245
3245
3246 def _stopgraft(ui, repo, graftstate):
3246 def _stopgraft(ui, repo, graftstate):
3247 """stop the interrupted graft"""
3247 """stop the interrupted graft"""
3248 if not graftstate.exists():
3248 if not graftstate.exists():
3249 raise error.Abort(_(b"no interrupted graft found"))
3249 raise error.Abort(_(b"no interrupted graft found"))
3250 pctx = repo[b'.']
3250 pctx = repo[b'.']
3251 hg.updaterepo(repo, pctx.node(), overwrite=True)
3251 hg.updaterepo(repo, pctx.node(), overwrite=True)
3252 graftstate.delete()
3252 graftstate.delete()
3253 ui.status(_(b"stopped the interrupted graft\n"))
3253 ui.status(_(b"stopped the interrupted graft\n"))
3254 ui.status(_(b"working directory is now at %s\n") % pctx.hex()[:12])
3254 ui.status(_(b"working directory is now at %s\n") % pctx.hex()[:12])
3255 return 0
3255 return 0
3256
3256
3257
3257
3258 statemod.addunfinished(
3258 statemod.addunfinished(
3259 b'graft',
3259 b'graft',
3260 fname=b'graftstate',
3260 fname=b'graftstate',
3261 clearable=True,
3261 clearable=True,
3262 stopflag=True,
3262 stopflag=True,
3263 continueflag=True,
3263 continueflag=True,
3264 abortfunc=cmdutil.hgabortgraft,
3264 abortfunc=cmdutil.hgabortgraft,
3265 cmdhint=_(b"use 'hg graft --continue' or 'hg graft --stop' to stop"),
3265 cmdhint=_(b"use 'hg graft --continue' or 'hg graft --stop' to stop"),
3266 )
3266 )
3267
3267
3268
3268
3269 @command(
3269 @command(
3270 b'grep',
3270 b'grep',
3271 [
3271 [
3272 (b'0', b'print0', None, _(b'end fields with NUL')),
3272 (b'0', b'print0', None, _(b'end fields with NUL')),
3273 (b'', b'all', None, _(b'print all revisions that match (DEPRECATED) ')),
3273 (b'', b'all', None, _(b'print all revisions that match (DEPRECATED) ')),
3274 (
3274 (
3275 b'',
3275 b'',
3276 b'diff',
3276 b'diff',
3277 None,
3277 None,
3278 _(
3278 _(
3279 b'print all revisions when the term was introduced '
3279 b'search revision differences for when the pattern was added '
3280 b'or removed'
3280 b'or removed'
3281 ),
3281 ),
3282 ),
3282 ),
3283 (b'a', b'text', None, _(b'treat all files as text')),
3283 (b'a', b'text', None, _(b'treat all files as text')),
3284 (
3284 (
3285 b'f',
3285 b'f',
3286 b'follow',
3286 b'follow',
3287 None,
3287 None,
3288 _(
3288 _(
3289 b'follow changeset history,'
3289 b'follow changeset history,'
3290 b' or file history across copies and renames'
3290 b' or file history across copies and renames'
3291 ),
3291 ),
3292 ),
3292 ),
3293 (b'i', b'ignore-case', None, _(b'ignore case when matching')),
3293 (b'i', b'ignore-case', None, _(b'ignore case when matching')),
3294 (
3294 (
3295 b'l',
3295 b'l',
3296 b'files-with-matches',
3296 b'files-with-matches',
3297 None,
3297 None,
3298 _(b'print only filenames and revisions that match'),
3298 _(b'print only filenames and revisions that match'),
3299 ),
3299 ),
3300 (b'n', b'line-number', None, _(b'print matching line numbers')),
3300 (b'n', b'line-number', None, _(b'print matching line numbers')),
3301 (
3301 (
3302 b'r',
3302 b'r',
3303 b'rev',
3303 b'rev',
3304 [],
3304 [],
3305 _(b'only search files changed within revision range'),
3305 _(b'search files changed within revision range'),
3306 _(b'REV'),
3306 _(b'REV'),
3307 ),
3307 ),
3308 (
3308 (
3309 b'',
3309 b'',
3310 b'all-files',
3310 b'all-files',
3311 None,
3311 None,
3312 _(
3312 _(
3313 b'include all files in the changeset while grepping (DEPRECATED)'
3313 b'include all files in the changeset while grepping (DEPRECATED)'
3314 ),
3314 ),
3315 ),
3315 ),
3316 (b'u', b'user', None, _(b'list the author (long with -v)')),
3316 (b'u', b'user', None, _(b'list the author (long with -v)')),
3317 (b'd', b'date', None, _(b'list the date (short with -q)')),
3317 (b'd', b'date', None, _(b'list the date (short with -q)')),
3318 ]
3318 ]
3319 + formatteropts
3319 + formatteropts
3320 + walkopts,
3320 + walkopts,
3321 _(b'[--diff] [OPTION]... PATTERN [FILE]...'),
3321 _(b'[--diff] [OPTION]... PATTERN [FILE]...'),
3322 helpcategory=command.CATEGORY_FILE_CONTENTS,
3322 helpcategory=command.CATEGORY_FILE_CONTENTS,
3323 inferrepo=True,
3323 inferrepo=True,
3324 intents={INTENT_READONLY},
3324 intents={INTENT_READONLY},
3325 )
3325 )
3326 def grep(ui, repo, pattern, *pats, **opts):
3326 def grep(ui, repo, pattern, *pats, **opts):
3327 """search revision history for a pattern in specified files
3327 """search for a pattern in specified files
3328
3328
3329 Search revision history for a regular expression in the specified
3329 Search the working directory or revision history for a regular
3330 files or the entire project.
3330 expression in the specified files for the entire repository.
3331
3331
3332 By default, grep prints the most recent revision number for each
3332 By default, grep searches the repository files in the working
3333 file in which it finds a match. To get it to print every revision
3333 directory and prints the files where it finds a match. To specify
3334 that contains a change in match status ("-" for a match that becomes
3334 historical revisions instead of the working directory, use the
3335 a non-match, or "+" for a non-match that becomes a match), use the
3335 --rev flag.
3336 --diff flag.
3336
3337 To search instead historical revision differences that contains a
3338 change in match status ("-" for a match that becomes a non-match,
3339 or "+" for a non-match that becomes a match), use the --diff flag.
3337
3340
3338 PATTERN can be any Python (roughly Perl-compatible) regular
3341 PATTERN can be any Python (roughly Perl-compatible) regular
3339 expression.
3342 expression.
3340
3343
3341 If no FILEs are specified (and -f/--follow isn't set), all files in
3344 If no FILEs are specified and the --rev flag isn't supplied, all
3342 the repository are searched, including those that don't exist in the
3345 files in the working directory are searched. When using the --rev
3343 current branch or have been deleted in a prior changeset.
3346 flag and specifying FILEs, use the --follow argument to also
3347 follow the specified FILEs across renames and copies.
3344
3348
3345 .. container:: verbose
3349 .. container:: verbose
3346
3350
3347 Template:
3351 Template:
3348
3352
3349 The following keywords are supported in addition to the common template
3353 The following keywords are supported in addition to the common template
3350 keywords and functions. See also :hg:`help templates`.
3354 keywords and functions. See also :hg:`help templates`.
3351
3355
3352 :change: String. Character denoting insertion ``+`` or removal ``-``.
3356 :change: String. Character denoting insertion ``+`` or removal ``-``.
3353 Available if ``--diff`` is specified.
3357 Available if ``--diff`` is specified.
3354 :lineno: Integer. Line number of the match.
3358 :lineno: Integer. Line number of the match.
3355 :path: String. Repository-absolute path of the file.
3359 :path: String. Repository-absolute path of the file.
3356 :texts: List of text chunks.
3360 :texts: List of text chunks.
3357
3361
3358 And each entry of ``{texts}`` provides the following sub-keywords.
3362 And each entry of ``{texts}`` provides the following sub-keywords.
3359
3363
3360 :matched: Boolean. True if the chunk matches the specified pattern.
3364 :matched: Boolean. True if the chunk matches the specified pattern.
3361 :text: String. Chunk content.
3365 :text: String. Chunk content.
3362
3366
3363 See :hg:`help templates.operators` for the list expansion syntax.
3367 See :hg:`help templates.operators` for the list expansion syntax.
3364
3368
3365 Returns 0 if a match is found, 1 otherwise.
3369 Returns 0 if a match is found, 1 otherwise.
3370
3366 """
3371 """
3367 opts = pycompat.byteskwargs(opts)
3372 opts = pycompat.byteskwargs(opts)
3368 diff = opts.get(b'all') or opts.get(b'diff')
3373 diff = opts.get(b'all') or opts.get(b'diff')
3369 if diff and opts.get(b'all_files'):
3374 if diff and opts.get(b'all_files'):
3370 raise error.Abort(_(b'--diff and --all-files are mutually exclusive'))
3375 raise error.Abort(_(b'--diff and --all-files are mutually exclusive'))
3371 if opts.get(b'all_files') is None and not diff:
3376 if opts.get(b'all_files') is None and not diff:
3372 opts[b'all_files'] = True
3377 opts[b'all_files'] = True
3373 plaingrep = opts.get(b'all_files') and not opts.get(b'rev')
3378 plaingrep = opts.get(b'all_files') and not opts.get(b'rev')
3374 all_files = opts.get(b'all_files')
3379 all_files = opts.get(b'all_files')
3375 if plaingrep:
3380 if plaingrep:
3376 opts[b'rev'] = [b'wdir()']
3381 opts[b'rev'] = [b'wdir()']
3377
3382
3378 reflags = re.M
3383 reflags = re.M
3379 if opts.get(b'ignore_case'):
3384 if opts.get(b'ignore_case'):
3380 reflags |= re.I
3385 reflags |= re.I
3381 try:
3386 try:
3382 regexp = util.re.compile(pattern, reflags)
3387 regexp = util.re.compile(pattern, reflags)
3383 except re.error as inst:
3388 except re.error as inst:
3384 ui.warn(
3389 ui.warn(
3385 _(b"grep: invalid match pattern: %s\n") % pycompat.bytestr(inst)
3390 _(b"grep: invalid match pattern: %s\n") % pycompat.bytestr(inst)
3386 )
3391 )
3387 return 1
3392 return 1
3388 sep, eol = b':', b'\n'
3393 sep, eol = b':', b'\n'
3389 if opts.get(b'print0'):
3394 if opts.get(b'print0'):
3390 sep = eol = b'\0'
3395 sep = eol = b'\0'
3391
3396
3392 getfile = util.lrucachefunc(repo.file)
3397 getfile = util.lrucachefunc(repo.file)
3393
3398
3394 def matchlines(body):
3399 def matchlines(body):
3395 begin = 0
3400 begin = 0
3396 linenum = 0
3401 linenum = 0
3397 while begin < len(body):
3402 while begin < len(body):
3398 match = regexp.search(body, begin)
3403 match = regexp.search(body, begin)
3399 if not match:
3404 if not match:
3400 break
3405 break
3401 mstart, mend = match.span()
3406 mstart, mend = match.span()
3402 linenum += body.count(b'\n', begin, mstart) + 1
3407 linenum += body.count(b'\n', begin, mstart) + 1
3403 lstart = body.rfind(b'\n', begin, mstart) + 1 or begin
3408 lstart = body.rfind(b'\n', begin, mstart) + 1 or begin
3404 begin = body.find(b'\n', mend) + 1 or len(body) + 1
3409 begin = body.find(b'\n', mend) + 1 or len(body) + 1
3405 lend = begin - 1
3410 lend = begin - 1
3406 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3411 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3407
3412
3408 class linestate(object):
3413 class linestate(object):
3409 def __init__(self, line, linenum, colstart, colend):
3414 def __init__(self, line, linenum, colstart, colend):
3410 self.line = line
3415 self.line = line
3411 self.linenum = linenum
3416 self.linenum = linenum
3412 self.colstart = colstart
3417 self.colstart = colstart
3413 self.colend = colend
3418 self.colend = colend
3414
3419
3415 def __hash__(self):
3420 def __hash__(self):
3416 return hash((self.linenum, self.line))
3421 return hash((self.linenum, self.line))
3417
3422
3418 def __eq__(self, other):
3423 def __eq__(self, other):
3419 return self.line == other.line
3424 return self.line == other.line
3420
3425
3421 def findpos(self):
3426 def findpos(self):
3422 """Iterate all (start, end) indices of matches"""
3427 """Iterate all (start, end) indices of matches"""
3423 yield self.colstart, self.colend
3428 yield self.colstart, self.colend
3424 p = self.colend
3429 p = self.colend
3425 while p < len(self.line):
3430 while p < len(self.line):
3426 m = regexp.search(self.line, p)
3431 m = regexp.search(self.line, p)
3427 if not m:
3432 if not m:
3428 break
3433 break
3429 yield m.span()
3434 yield m.span()
3430 p = m.end()
3435 p = m.end()
3431
3436
3432 matches = {}
3437 matches = {}
3433 copies = {}
3438 copies = {}
3434
3439
3435 def grepbody(fn, rev, body):
3440 def grepbody(fn, rev, body):
3436 matches[rev].setdefault(fn, [])
3441 matches[rev].setdefault(fn, [])
3437 m = matches[rev][fn]
3442 m = matches[rev][fn]
3438 for lnum, cstart, cend, line in matchlines(body):
3443 for lnum, cstart, cend, line in matchlines(body):
3439 s = linestate(line, lnum, cstart, cend)
3444 s = linestate(line, lnum, cstart, cend)
3440 m.append(s)
3445 m.append(s)
3441
3446
3442 def difflinestates(a, b):
3447 def difflinestates(a, b):
3443 sm = difflib.SequenceMatcher(None, a, b)
3448 sm = difflib.SequenceMatcher(None, a, b)
3444 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3449 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3445 if tag == r'insert':
3450 if tag == r'insert':
3446 for i in pycompat.xrange(blo, bhi):
3451 for i in pycompat.xrange(blo, bhi):
3447 yield (b'+', b[i])
3452 yield (b'+', b[i])
3448 elif tag == r'delete':
3453 elif tag == r'delete':
3449 for i in pycompat.xrange(alo, ahi):
3454 for i in pycompat.xrange(alo, ahi):
3450 yield (b'-', a[i])
3455 yield (b'-', a[i])
3451 elif tag == r'replace':
3456 elif tag == r'replace':
3452 for i in pycompat.xrange(alo, ahi):
3457 for i in pycompat.xrange(alo, ahi):
3453 yield (b'-', a[i])
3458 yield (b'-', a[i])
3454 for i in pycompat.xrange(blo, bhi):
3459 for i in pycompat.xrange(blo, bhi):
3455 yield (b'+', b[i])
3460 yield (b'+', b[i])
3456
3461
3457 uipathfn = scmutil.getuipathfn(repo)
3462 uipathfn = scmutil.getuipathfn(repo)
3458
3463
3459 def display(fm, fn, ctx, pstates, states):
3464 def display(fm, fn, ctx, pstates, states):
3460 rev = scmutil.intrev(ctx)
3465 rev = scmutil.intrev(ctx)
3461 if fm.isplain():
3466 if fm.isplain():
3462 formatuser = ui.shortuser
3467 formatuser = ui.shortuser
3463 else:
3468 else:
3464 formatuser = pycompat.bytestr
3469 formatuser = pycompat.bytestr
3465 if ui.quiet:
3470 if ui.quiet:
3466 datefmt = b'%Y-%m-%d'
3471 datefmt = b'%Y-%m-%d'
3467 else:
3472 else:
3468 datefmt = b'%a %b %d %H:%M:%S %Y %1%2'
3473 datefmt = b'%a %b %d %H:%M:%S %Y %1%2'
3469 found = False
3474 found = False
3470
3475
3471 @util.cachefunc
3476 @util.cachefunc
3472 def binary():
3477 def binary():
3473 flog = getfile(fn)
3478 flog = getfile(fn)
3474 try:
3479 try:
3475 return stringutil.binary(flog.read(ctx.filenode(fn)))
3480 return stringutil.binary(flog.read(ctx.filenode(fn)))
3476 except error.WdirUnsupported:
3481 except error.WdirUnsupported:
3477 return ctx[fn].isbinary()
3482 return ctx[fn].isbinary()
3478
3483
3479 fieldnamemap = {b'linenumber': b'lineno'}
3484 fieldnamemap = {b'linenumber': b'lineno'}
3480 if diff:
3485 if diff:
3481 iter = difflinestates(pstates, states)
3486 iter = difflinestates(pstates, states)
3482 else:
3487 else:
3483 iter = [(b'', l) for l in states]
3488 iter = [(b'', l) for l in states]
3484 for change, l in iter:
3489 for change, l in iter:
3485 fm.startitem()
3490 fm.startitem()
3486 fm.context(ctx=ctx)
3491 fm.context(ctx=ctx)
3487 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
3492 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
3488 fm.plain(uipathfn(fn), label=b'grep.filename')
3493 fm.plain(uipathfn(fn), label=b'grep.filename')
3489
3494
3490 cols = [
3495 cols = [
3491 (b'rev', b'%d', rev, not plaingrep, b''),
3496 (b'rev', b'%d', rev, not plaingrep, b''),
3492 (
3497 (
3493 b'linenumber',
3498 b'linenumber',
3494 b'%d',
3499 b'%d',
3495 l.linenum,
3500 l.linenum,
3496 opts.get(b'line_number'),
3501 opts.get(b'line_number'),
3497 b'',
3502 b'',
3498 ),
3503 ),
3499 ]
3504 ]
3500 if diff:
3505 if diff:
3501 cols.append(
3506 cols.append(
3502 (
3507 (
3503 b'change',
3508 b'change',
3504 b'%s',
3509 b'%s',
3505 change,
3510 change,
3506 True,
3511 True,
3507 b'grep.inserted '
3512 b'grep.inserted '
3508 if change == b'+'
3513 if change == b'+'
3509 else b'grep.deleted ',
3514 else b'grep.deleted ',
3510 )
3515 )
3511 )
3516 )
3512 cols.extend(
3517 cols.extend(
3513 [
3518 [
3514 (
3519 (
3515 b'user',
3520 b'user',
3516 b'%s',
3521 b'%s',
3517 formatuser(ctx.user()),
3522 formatuser(ctx.user()),
3518 opts.get(b'user'),
3523 opts.get(b'user'),
3519 b'',
3524 b'',
3520 ),
3525 ),
3521 (
3526 (
3522 b'date',
3527 b'date',
3523 b'%s',
3528 b'%s',
3524 fm.formatdate(ctx.date(), datefmt),
3529 fm.formatdate(ctx.date(), datefmt),
3525 opts.get(b'date'),
3530 opts.get(b'date'),
3526 b'',
3531 b'',
3527 ),
3532 ),
3528 ]
3533 ]
3529 )
3534 )
3530 for name, fmt, data, cond, extra_label in cols:
3535 for name, fmt, data, cond, extra_label in cols:
3531 if cond:
3536 if cond:
3532 fm.plain(sep, label=b'grep.sep')
3537 fm.plain(sep, label=b'grep.sep')
3533 field = fieldnamemap.get(name, name)
3538 field = fieldnamemap.get(name, name)
3534 label = extra_label + (b'grep.%s' % name)
3539 label = extra_label + (b'grep.%s' % name)
3535 fm.condwrite(cond, field, fmt, data, label=label)
3540 fm.condwrite(cond, field, fmt, data, label=label)
3536 if not opts.get(b'files_with_matches'):
3541 if not opts.get(b'files_with_matches'):
3537 fm.plain(sep, label=b'grep.sep')
3542 fm.plain(sep, label=b'grep.sep')
3538 if not opts.get(b'text') and binary():
3543 if not opts.get(b'text') and binary():
3539 fm.plain(_(b" Binary file matches"))
3544 fm.plain(_(b" Binary file matches"))
3540 else:
3545 else:
3541 displaymatches(fm.nested(b'texts', tmpl=b'{text}'), l)
3546 displaymatches(fm.nested(b'texts', tmpl=b'{text}'), l)
3542 fm.plain(eol)
3547 fm.plain(eol)
3543 found = True
3548 found = True
3544 if opts.get(b'files_with_matches'):
3549 if opts.get(b'files_with_matches'):
3545 break
3550 break
3546 return found
3551 return found
3547
3552
3548 def displaymatches(fm, l):
3553 def displaymatches(fm, l):
3549 p = 0
3554 p = 0
3550 for s, e in l.findpos():
3555 for s, e in l.findpos():
3551 if p < s:
3556 if p < s:
3552 fm.startitem()
3557 fm.startitem()
3553 fm.write(b'text', b'%s', l.line[p:s])
3558 fm.write(b'text', b'%s', l.line[p:s])
3554 fm.data(matched=False)
3559 fm.data(matched=False)
3555 fm.startitem()
3560 fm.startitem()
3556 fm.write(b'text', b'%s', l.line[s:e], label=b'grep.match')
3561 fm.write(b'text', b'%s', l.line[s:e], label=b'grep.match')
3557 fm.data(matched=True)
3562 fm.data(matched=True)
3558 p = e
3563 p = e
3559 if p < len(l.line):
3564 if p < len(l.line):
3560 fm.startitem()
3565 fm.startitem()
3561 fm.write(b'text', b'%s', l.line[p:])
3566 fm.write(b'text', b'%s', l.line[p:])
3562 fm.data(matched=False)
3567 fm.data(matched=False)
3563 fm.end()
3568 fm.end()
3564
3569
3565 skip = set()
3570 skip = set()
3566 revfiles = {}
3571 revfiles = {}
3567 match = scmutil.match(repo[None], pats, opts)
3572 match = scmutil.match(repo[None], pats, opts)
3568 found = False
3573 found = False
3569 follow = opts.get(b'follow')
3574 follow = opts.get(b'follow')
3570
3575
3571 getrenamed = scmutil.getrenamedfn(repo)
3576 getrenamed = scmutil.getrenamedfn(repo)
3572
3577
3573 def prep(ctx, fns):
3578 def prep(ctx, fns):
3574 rev = ctx.rev()
3579 rev = ctx.rev()
3575 pctx = ctx.p1()
3580 pctx = ctx.p1()
3576 parent = pctx.rev()
3581 parent = pctx.rev()
3577 matches.setdefault(rev, {})
3582 matches.setdefault(rev, {})
3578 matches.setdefault(parent, {})
3583 matches.setdefault(parent, {})
3579 files = revfiles.setdefault(rev, [])
3584 files = revfiles.setdefault(rev, [])
3580 for fn in fns:
3585 for fn in fns:
3581 flog = getfile(fn)
3586 flog = getfile(fn)
3582 try:
3587 try:
3583 fnode = ctx.filenode(fn)
3588 fnode = ctx.filenode(fn)
3584 except error.LookupError:
3589 except error.LookupError:
3585 continue
3590 continue
3586
3591
3587 copy = None
3592 copy = None
3588 if follow:
3593 if follow:
3589 copy = getrenamed(fn, rev)
3594 copy = getrenamed(fn, rev)
3590 if copy:
3595 if copy:
3591 copies.setdefault(rev, {})[fn] = copy
3596 copies.setdefault(rev, {})[fn] = copy
3592 if fn in skip:
3597 if fn in skip:
3593 skip.add(copy)
3598 skip.add(copy)
3594 if fn in skip:
3599 if fn in skip:
3595 continue
3600 continue
3596 files.append(fn)
3601 files.append(fn)
3597
3602
3598 if fn not in matches[rev]:
3603 if fn not in matches[rev]:
3599 try:
3604 try:
3600 content = flog.read(fnode)
3605 content = flog.read(fnode)
3601 except error.WdirUnsupported:
3606 except error.WdirUnsupported:
3602 content = ctx[fn].data()
3607 content = ctx[fn].data()
3603 grepbody(fn, rev, content)
3608 grepbody(fn, rev, content)
3604
3609
3605 pfn = copy or fn
3610 pfn = copy or fn
3606 if pfn not in matches[parent]:
3611 if pfn not in matches[parent]:
3607 try:
3612 try:
3608 fnode = pctx.filenode(pfn)
3613 fnode = pctx.filenode(pfn)
3609 grepbody(pfn, parent, flog.read(fnode))
3614 grepbody(pfn, parent, flog.read(fnode))
3610 except error.LookupError:
3615 except error.LookupError:
3611 pass
3616 pass
3612
3617
3613 ui.pager(b'grep')
3618 ui.pager(b'grep')
3614 fm = ui.formatter(b'grep', opts)
3619 fm = ui.formatter(b'grep', opts)
3615 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
3620 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
3616 rev = ctx.rev()
3621 rev = ctx.rev()
3617 parent = ctx.p1().rev()
3622 parent = ctx.p1().rev()
3618 for fn in sorted(revfiles.get(rev, [])):
3623 for fn in sorted(revfiles.get(rev, [])):
3619 states = matches[rev][fn]
3624 states = matches[rev][fn]
3620 copy = copies.get(rev, {}).get(fn)
3625 copy = copies.get(rev, {}).get(fn)
3621 if fn in skip:
3626 if fn in skip:
3622 if copy:
3627 if copy:
3623 skip.add(copy)
3628 skip.add(copy)
3624 continue
3629 continue
3625 pstates = matches.get(parent, {}).get(copy or fn, [])
3630 pstates = matches.get(parent, {}).get(copy or fn, [])
3626 if pstates or states:
3631 if pstates or states:
3627 r = display(fm, fn, ctx, pstates, states)
3632 r = display(fm, fn, ctx, pstates, states)
3628 found = found or r
3633 found = found or r
3629 if r and not diff and not all_files:
3634 if r and not diff and not all_files:
3630 skip.add(fn)
3635 skip.add(fn)
3631 if copy:
3636 if copy:
3632 skip.add(copy)
3637 skip.add(copy)
3633 del revfiles[rev]
3638 del revfiles[rev]
3634 # We will keep the matches dict for the duration of the window
3639 # We will keep the matches dict for the duration of the window
3635 # clear the matches dict once the window is over
3640 # clear the matches dict once the window is over
3636 if not revfiles:
3641 if not revfiles:
3637 matches.clear()
3642 matches.clear()
3638 fm.end()
3643 fm.end()
3639
3644
3640 return not found
3645 return not found
3641
3646
3642
3647
3643 @command(
3648 @command(
3644 b'heads',
3649 b'heads',
3645 [
3650 [
3646 (
3651 (
3647 b'r',
3652 b'r',
3648 b'rev',
3653 b'rev',
3649 b'',
3654 b'',
3650 _(b'show only heads which are descendants of STARTREV'),
3655 _(b'show only heads which are descendants of STARTREV'),
3651 _(b'STARTREV'),
3656 _(b'STARTREV'),
3652 ),
3657 ),
3653 (b't', b'topo', False, _(b'show topological heads only')),
3658 (b't', b'topo', False, _(b'show topological heads only')),
3654 (
3659 (
3655 b'a',
3660 b'a',
3656 b'active',
3661 b'active',
3657 False,
3662 False,
3658 _(b'show active branchheads only (DEPRECATED)'),
3663 _(b'show active branchheads only (DEPRECATED)'),
3659 ),
3664 ),
3660 (b'c', b'closed', False, _(b'show normal and closed branch heads')),
3665 (b'c', b'closed', False, _(b'show normal and closed branch heads')),
3661 ]
3666 ]
3662 + templateopts,
3667 + templateopts,
3663 _(b'[-ct] [-r STARTREV] [REV]...'),
3668 _(b'[-ct] [-r STARTREV] [REV]...'),
3664 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3669 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3665 intents={INTENT_READONLY},
3670 intents={INTENT_READONLY},
3666 )
3671 )
3667 def heads(ui, repo, *branchrevs, **opts):
3672 def heads(ui, repo, *branchrevs, **opts):
3668 """show branch heads
3673 """show branch heads
3669
3674
3670 With no arguments, show all open branch heads in the repository.
3675 With no arguments, show all open branch heads in the repository.
3671 Branch heads are changesets that have no descendants on the
3676 Branch heads are changesets that have no descendants on the
3672 same branch. They are where development generally takes place and
3677 same branch. They are where development generally takes place and
3673 are the usual targets for update and merge operations.
3678 are the usual targets for update and merge operations.
3674
3679
3675 If one or more REVs are given, only open branch heads on the
3680 If one or more REVs are given, only open branch heads on the
3676 branches associated with the specified changesets are shown. This
3681 branches associated with the specified changesets are shown. This
3677 means that you can use :hg:`heads .` to see the heads on the
3682 means that you can use :hg:`heads .` to see the heads on the
3678 currently checked-out branch.
3683 currently checked-out branch.
3679
3684
3680 If -c/--closed is specified, also show branch heads marked closed
3685 If -c/--closed is specified, also show branch heads marked closed
3681 (see :hg:`commit --close-branch`).
3686 (see :hg:`commit --close-branch`).
3682
3687
3683 If STARTREV is specified, only those heads that are descendants of
3688 If STARTREV is specified, only those heads that are descendants of
3684 STARTREV will be displayed.
3689 STARTREV will be displayed.
3685
3690
3686 If -t/--topo is specified, named branch mechanics will be ignored and only
3691 If -t/--topo is specified, named branch mechanics will be ignored and only
3687 topological heads (changesets with no children) will be shown.
3692 topological heads (changesets with no children) will be shown.
3688
3693
3689 Returns 0 if matching heads are found, 1 if not.
3694 Returns 0 if matching heads are found, 1 if not.
3690 """
3695 """
3691
3696
3692 opts = pycompat.byteskwargs(opts)
3697 opts = pycompat.byteskwargs(opts)
3693 start = None
3698 start = None
3694 rev = opts.get(b'rev')
3699 rev = opts.get(b'rev')
3695 if rev:
3700 if rev:
3696 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3701 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3697 start = scmutil.revsingle(repo, rev, None).node()
3702 start = scmutil.revsingle(repo, rev, None).node()
3698
3703
3699 if opts.get(b'topo'):
3704 if opts.get(b'topo'):
3700 heads = [repo[h] for h in repo.heads(start)]
3705 heads = [repo[h] for h in repo.heads(start)]
3701 else:
3706 else:
3702 heads = []
3707 heads = []
3703 for branch in repo.branchmap():
3708 for branch in repo.branchmap():
3704 heads += repo.branchheads(branch, start, opts.get(b'closed'))
3709 heads += repo.branchheads(branch, start, opts.get(b'closed'))
3705 heads = [repo[h] for h in heads]
3710 heads = [repo[h] for h in heads]
3706
3711
3707 if branchrevs:
3712 if branchrevs:
3708 branches = set(
3713 branches = set(
3709 repo[r].branch() for r in scmutil.revrange(repo, branchrevs)
3714 repo[r].branch() for r in scmutil.revrange(repo, branchrevs)
3710 )
3715 )
3711 heads = [h for h in heads if h.branch() in branches]
3716 heads = [h for h in heads if h.branch() in branches]
3712
3717
3713 if opts.get(b'active') and branchrevs:
3718 if opts.get(b'active') and branchrevs:
3714 dagheads = repo.heads(start)
3719 dagheads = repo.heads(start)
3715 heads = [h for h in heads if h.node() in dagheads]
3720 heads = [h for h in heads if h.node() in dagheads]
3716
3721
3717 if branchrevs:
3722 if branchrevs:
3718 haveheads = set(h.branch() for h in heads)
3723 haveheads = set(h.branch() for h in heads)
3719 if branches - haveheads:
3724 if branches - haveheads:
3720 headless = b', '.join(b for b in branches - haveheads)
3725 headless = b', '.join(b for b in branches - haveheads)
3721 msg = _(b'no open branch heads found on branches %s')
3726 msg = _(b'no open branch heads found on branches %s')
3722 if opts.get(b'rev'):
3727 if opts.get(b'rev'):
3723 msg += _(b' (started at %s)') % opts[b'rev']
3728 msg += _(b' (started at %s)') % opts[b'rev']
3724 ui.warn((msg + b'\n') % headless)
3729 ui.warn((msg + b'\n') % headless)
3725
3730
3726 if not heads:
3731 if not heads:
3727 return 1
3732 return 1
3728
3733
3729 ui.pager(b'heads')
3734 ui.pager(b'heads')
3730 heads = sorted(heads, key=lambda x: -(x.rev()))
3735 heads = sorted(heads, key=lambda x: -(x.rev()))
3731 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3736 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3732 for ctx in heads:
3737 for ctx in heads:
3733 displayer.show(ctx)
3738 displayer.show(ctx)
3734 displayer.close()
3739 displayer.close()
3735
3740
3736
3741
3737 @command(
3742 @command(
3738 b'help',
3743 b'help',
3739 [
3744 [
3740 (b'e', b'extension', None, _(b'show only help for extensions')),
3745 (b'e', b'extension', None, _(b'show only help for extensions')),
3741 (b'c', b'command', None, _(b'show only help for commands')),
3746 (b'c', b'command', None, _(b'show only help for commands')),
3742 (b'k', b'keyword', None, _(b'show topics matching keyword')),
3747 (b'k', b'keyword', None, _(b'show topics matching keyword')),
3743 (
3748 (
3744 b's',
3749 b's',
3745 b'system',
3750 b'system',
3746 [],
3751 [],
3747 _(b'show help for specific platform(s)'),
3752 _(b'show help for specific platform(s)'),
3748 _(b'PLATFORM'),
3753 _(b'PLATFORM'),
3749 ),
3754 ),
3750 ],
3755 ],
3751 _(b'[-eck] [-s PLATFORM] [TOPIC]'),
3756 _(b'[-eck] [-s PLATFORM] [TOPIC]'),
3752 helpcategory=command.CATEGORY_HELP,
3757 helpcategory=command.CATEGORY_HELP,
3753 norepo=True,
3758 norepo=True,
3754 intents={INTENT_READONLY},
3759 intents={INTENT_READONLY},
3755 )
3760 )
3756 def help_(ui, name=None, **opts):
3761 def help_(ui, name=None, **opts):
3757 """show help for a given topic or a help overview
3762 """show help for a given topic or a help overview
3758
3763
3759 With no arguments, print a list of commands with short help messages.
3764 With no arguments, print a list of commands with short help messages.
3760
3765
3761 Given a topic, extension, or command name, print help for that
3766 Given a topic, extension, or command name, print help for that
3762 topic.
3767 topic.
3763
3768
3764 Returns 0 if successful.
3769 Returns 0 if successful.
3765 """
3770 """
3766
3771
3767 keep = opts.get(r'system') or []
3772 keep = opts.get(r'system') or []
3768 if len(keep) == 0:
3773 if len(keep) == 0:
3769 if pycompat.sysplatform.startswith(b'win'):
3774 if pycompat.sysplatform.startswith(b'win'):
3770 keep.append(b'windows')
3775 keep.append(b'windows')
3771 elif pycompat.sysplatform == b'OpenVMS':
3776 elif pycompat.sysplatform == b'OpenVMS':
3772 keep.append(b'vms')
3777 keep.append(b'vms')
3773 elif pycompat.sysplatform == b'plan9':
3778 elif pycompat.sysplatform == b'plan9':
3774 keep.append(b'plan9')
3779 keep.append(b'plan9')
3775 else:
3780 else:
3776 keep.append(b'unix')
3781 keep.append(b'unix')
3777 keep.append(pycompat.sysplatform.lower())
3782 keep.append(pycompat.sysplatform.lower())
3778 if ui.verbose:
3783 if ui.verbose:
3779 keep.append(b'verbose')
3784 keep.append(b'verbose')
3780
3785
3781 commands = sys.modules[__name__]
3786 commands = sys.modules[__name__]
3782 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3787 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3783 ui.pager(b'help')
3788 ui.pager(b'help')
3784 ui.write(formatted)
3789 ui.write(formatted)
3785
3790
3786
3791
3787 @command(
3792 @command(
3788 b'identify|id',
3793 b'identify|id',
3789 [
3794 [
3790 (b'r', b'rev', b'', _(b'identify the specified revision'), _(b'REV')),
3795 (b'r', b'rev', b'', _(b'identify the specified revision'), _(b'REV')),
3791 (b'n', b'num', None, _(b'show local revision number')),
3796 (b'n', b'num', None, _(b'show local revision number')),
3792 (b'i', b'id', None, _(b'show global revision id')),
3797 (b'i', b'id', None, _(b'show global revision id')),
3793 (b'b', b'branch', None, _(b'show branch')),
3798 (b'b', b'branch', None, _(b'show branch')),
3794 (b't', b'tags', None, _(b'show tags')),
3799 (b't', b'tags', None, _(b'show tags')),
3795 (b'B', b'bookmarks', None, _(b'show bookmarks')),
3800 (b'B', b'bookmarks', None, _(b'show bookmarks')),
3796 ]
3801 ]
3797 + remoteopts
3802 + remoteopts
3798 + formatteropts,
3803 + formatteropts,
3799 _(b'[-nibtB] [-r REV] [SOURCE]'),
3804 _(b'[-nibtB] [-r REV] [SOURCE]'),
3800 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3805 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3801 optionalrepo=True,
3806 optionalrepo=True,
3802 intents={INTENT_READONLY},
3807 intents={INTENT_READONLY},
3803 )
3808 )
3804 def identify(
3809 def identify(
3805 ui,
3810 ui,
3806 repo,
3811 repo,
3807 source=None,
3812 source=None,
3808 rev=None,
3813 rev=None,
3809 num=None,
3814 num=None,
3810 id=None,
3815 id=None,
3811 branch=None,
3816 branch=None,
3812 tags=None,
3817 tags=None,
3813 bookmarks=None,
3818 bookmarks=None,
3814 **opts
3819 **opts
3815 ):
3820 ):
3816 """identify the working directory or specified revision
3821 """identify the working directory or specified revision
3817
3822
3818 Print a summary identifying the repository state at REV using one or
3823 Print a summary identifying the repository state at REV using one or
3819 two parent hash identifiers, followed by a "+" if the working
3824 two parent hash identifiers, followed by a "+" if the working
3820 directory has uncommitted changes, the branch name (if not default),
3825 directory has uncommitted changes, the branch name (if not default),
3821 a list of tags, and a list of bookmarks.
3826 a list of tags, and a list of bookmarks.
3822
3827
3823 When REV is not given, print a summary of the current state of the
3828 When REV is not given, print a summary of the current state of the
3824 repository including the working directory. Specify -r. to get information
3829 repository including the working directory. Specify -r. to get information
3825 of the working directory parent without scanning uncommitted changes.
3830 of the working directory parent without scanning uncommitted changes.
3826
3831
3827 Specifying a path to a repository root or Mercurial bundle will
3832 Specifying a path to a repository root or Mercurial bundle will
3828 cause lookup to operate on that repository/bundle.
3833 cause lookup to operate on that repository/bundle.
3829
3834
3830 .. container:: verbose
3835 .. container:: verbose
3831
3836
3832 Template:
3837 Template:
3833
3838
3834 The following keywords are supported in addition to the common template
3839 The following keywords are supported in addition to the common template
3835 keywords and functions. See also :hg:`help templates`.
3840 keywords and functions. See also :hg:`help templates`.
3836
3841
3837 :dirty: String. Character ``+`` denoting if the working directory has
3842 :dirty: String. Character ``+`` denoting if the working directory has
3838 uncommitted changes.
3843 uncommitted changes.
3839 :id: String. One or two nodes, optionally followed by ``+``.
3844 :id: String. One or two nodes, optionally followed by ``+``.
3840 :parents: List of strings. Parent nodes of the changeset.
3845 :parents: List of strings. Parent nodes of the changeset.
3841
3846
3842 Examples:
3847 Examples:
3843
3848
3844 - generate a build identifier for the working directory::
3849 - generate a build identifier for the working directory::
3845
3850
3846 hg id --id > build-id.dat
3851 hg id --id > build-id.dat
3847
3852
3848 - find the revision corresponding to a tag::
3853 - find the revision corresponding to a tag::
3849
3854
3850 hg id -n -r 1.3
3855 hg id -n -r 1.3
3851
3856
3852 - check the most recent revision of a remote repository::
3857 - check the most recent revision of a remote repository::
3853
3858
3854 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3859 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3855
3860
3856 See :hg:`log` for generating more information about specific revisions,
3861 See :hg:`log` for generating more information about specific revisions,
3857 including full hash identifiers.
3862 including full hash identifiers.
3858
3863
3859 Returns 0 if successful.
3864 Returns 0 if successful.
3860 """
3865 """
3861
3866
3862 opts = pycompat.byteskwargs(opts)
3867 opts = pycompat.byteskwargs(opts)
3863 if not repo and not source:
3868 if not repo and not source:
3864 raise error.Abort(
3869 raise error.Abort(
3865 _(b"there is no Mercurial repository here (.hg not found)")
3870 _(b"there is no Mercurial repository here (.hg not found)")
3866 )
3871 )
3867
3872
3868 default = not (num or id or branch or tags or bookmarks)
3873 default = not (num or id or branch or tags or bookmarks)
3869 output = []
3874 output = []
3870 revs = []
3875 revs = []
3871
3876
3872 if source:
3877 if source:
3873 source, branches = hg.parseurl(ui.expandpath(source))
3878 source, branches = hg.parseurl(ui.expandpath(source))
3874 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3879 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3875 repo = peer.local()
3880 repo = peer.local()
3876 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3881 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3877
3882
3878 fm = ui.formatter(b'identify', opts)
3883 fm = ui.formatter(b'identify', opts)
3879 fm.startitem()
3884 fm.startitem()
3880
3885
3881 if not repo:
3886 if not repo:
3882 if num or branch or tags:
3887 if num or branch or tags:
3883 raise error.Abort(
3888 raise error.Abort(
3884 _(b"can't query remote revision number, branch, or tags")
3889 _(b"can't query remote revision number, branch, or tags")
3885 )
3890 )
3886 if not rev and revs:
3891 if not rev and revs:
3887 rev = revs[0]
3892 rev = revs[0]
3888 if not rev:
3893 if not rev:
3889 rev = b"tip"
3894 rev = b"tip"
3890
3895
3891 remoterev = peer.lookup(rev)
3896 remoterev = peer.lookup(rev)
3892 hexrev = fm.hexfunc(remoterev)
3897 hexrev = fm.hexfunc(remoterev)
3893 if default or id:
3898 if default or id:
3894 output = [hexrev]
3899 output = [hexrev]
3895 fm.data(id=hexrev)
3900 fm.data(id=hexrev)
3896
3901
3897 @util.cachefunc
3902 @util.cachefunc
3898 def getbms():
3903 def getbms():
3899 bms = []
3904 bms = []
3900
3905
3901 if b'bookmarks' in peer.listkeys(b'namespaces'):
3906 if b'bookmarks' in peer.listkeys(b'namespaces'):
3902 hexremoterev = hex(remoterev)
3907 hexremoterev = hex(remoterev)
3903 bms = [
3908 bms = [
3904 bm
3909 bm
3905 for bm, bmr in pycompat.iteritems(
3910 for bm, bmr in pycompat.iteritems(
3906 peer.listkeys(b'bookmarks')
3911 peer.listkeys(b'bookmarks')
3907 )
3912 )
3908 if bmr == hexremoterev
3913 if bmr == hexremoterev
3909 ]
3914 ]
3910
3915
3911 return sorted(bms)
3916 return sorted(bms)
3912
3917
3913 if fm.isplain():
3918 if fm.isplain():
3914 if bookmarks:
3919 if bookmarks:
3915 output.extend(getbms())
3920 output.extend(getbms())
3916 elif default and not ui.quiet:
3921 elif default and not ui.quiet:
3917 # multiple bookmarks for a single parent separated by '/'
3922 # multiple bookmarks for a single parent separated by '/'
3918 bm = b'/'.join(getbms())
3923 bm = b'/'.join(getbms())
3919 if bm:
3924 if bm:
3920 output.append(bm)
3925 output.append(bm)
3921 else:
3926 else:
3922 fm.data(node=hex(remoterev))
3927 fm.data(node=hex(remoterev))
3923 if bookmarks or b'bookmarks' in fm.datahint():
3928 if bookmarks or b'bookmarks' in fm.datahint():
3924 fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
3929 fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
3925 else:
3930 else:
3926 if rev:
3931 if rev:
3927 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3932 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3928 ctx = scmutil.revsingle(repo, rev, None)
3933 ctx = scmutil.revsingle(repo, rev, None)
3929
3934
3930 if ctx.rev() is None:
3935 if ctx.rev() is None:
3931 ctx = repo[None]
3936 ctx = repo[None]
3932 parents = ctx.parents()
3937 parents = ctx.parents()
3933 taglist = []
3938 taglist = []
3934 for p in parents:
3939 for p in parents:
3935 taglist.extend(p.tags())
3940 taglist.extend(p.tags())
3936
3941
3937 dirty = b""
3942 dirty = b""
3938 if ctx.dirty(missing=True, merge=False, branch=False):
3943 if ctx.dirty(missing=True, merge=False, branch=False):
3939 dirty = b'+'
3944 dirty = b'+'
3940 fm.data(dirty=dirty)
3945 fm.data(dirty=dirty)
3941
3946
3942 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3947 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3943 if default or id:
3948 if default or id:
3944 output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
3949 output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
3945 fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
3950 fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
3946
3951
3947 if num:
3952 if num:
3948 numoutput = [b"%d" % p.rev() for p in parents]
3953 numoutput = [b"%d" % p.rev() for p in parents]
3949 output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
3954 output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
3950
3955
3951 fm.data(
3956 fm.data(
3952 parents=fm.formatlist(
3957 parents=fm.formatlist(
3953 [fm.hexfunc(p.node()) for p in parents], name=b'node'
3958 [fm.hexfunc(p.node()) for p in parents], name=b'node'
3954 )
3959 )
3955 )
3960 )
3956 else:
3961 else:
3957 hexoutput = fm.hexfunc(ctx.node())
3962 hexoutput = fm.hexfunc(ctx.node())
3958 if default or id:
3963 if default or id:
3959 output = [hexoutput]
3964 output = [hexoutput]
3960 fm.data(id=hexoutput)
3965 fm.data(id=hexoutput)
3961
3966
3962 if num:
3967 if num:
3963 output.append(pycompat.bytestr(ctx.rev()))
3968 output.append(pycompat.bytestr(ctx.rev()))
3964 taglist = ctx.tags()
3969 taglist = ctx.tags()
3965
3970
3966 if default and not ui.quiet:
3971 if default and not ui.quiet:
3967 b = ctx.branch()
3972 b = ctx.branch()
3968 if b != b'default':
3973 if b != b'default':
3969 output.append(b"(%s)" % b)
3974 output.append(b"(%s)" % b)
3970
3975
3971 # multiple tags for a single parent separated by '/'
3976 # multiple tags for a single parent separated by '/'
3972 t = b'/'.join(taglist)
3977 t = b'/'.join(taglist)
3973 if t:
3978 if t:
3974 output.append(t)
3979 output.append(t)
3975
3980
3976 # multiple bookmarks for a single parent separated by '/'
3981 # multiple bookmarks for a single parent separated by '/'
3977 bm = b'/'.join(ctx.bookmarks())
3982 bm = b'/'.join(ctx.bookmarks())
3978 if bm:
3983 if bm:
3979 output.append(bm)
3984 output.append(bm)
3980 else:
3985 else:
3981 if branch:
3986 if branch:
3982 output.append(ctx.branch())
3987 output.append(ctx.branch())
3983
3988
3984 if tags:
3989 if tags:
3985 output.extend(taglist)
3990 output.extend(taglist)
3986
3991
3987 if bookmarks:
3992 if bookmarks:
3988 output.extend(ctx.bookmarks())
3993 output.extend(ctx.bookmarks())
3989
3994
3990 fm.data(node=ctx.hex())
3995 fm.data(node=ctx.hex())
3991 fm.data(branch=ctx.branch())
3996 fm.data(branch=ctx.branch())
3992 fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
3997 fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
3993 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
3998 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
3994 fm.context(ctx=ctx)
3999 fm.context(ctx=ctx)
3995
4000
3996 fm.plain(b"%s\n" % b' '.join(output))
4001 fm.plain(b"%s\n" % b' '.join(output))
3997 fm.end()
4002 fm.end()
3998
4003
3999
4004
4000 @command(
4005 @command(
4001 b'import|patch',
4006 b'import|patch',
4002 [
4007 [
4003 (
4008 (
4004 b'p',
4009 b'p',
4005 b'strip',
4010 b'strip',
4006 1,
4011 1,
4007 _(
4012 _(
4008 b'directory strip option for patch. This has the same '
4013 b'directory strip option for patch. This has the same '
4009 b'meaning as the corresponding patch option'
4014 b'meaning as the corresponding patch option'
4010 ),
4015 ),
4011 _(b'NUM'),
4016 _(b'NUM'),
4012 ),
4017 ),
4013 (b'b', b'base', b'', _(b'base path (DEPRECATED)'), _(b'PATH')),
4018 (b'b', b'base', b'', _(b'base path (DEPRECATED)'), _(b'PATH')),
4014 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
4019 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
4015 (
4020 (
4016 b'f',
4021 b'f',
4017 b'force',
4022 b'force',
4018 None,
4023 None,
4019 _(b'skip check for outstanding uncommitted changes (DEPRECATED)'),
4024 _(b'skip check for outstanding uncommitted changes (DEPRECATED)'),
4020 ),
4025 ),
4021 (
4026 (
4022 b'',
4027 b'',
4023 b'no-commit',
4028 b'no-commit',
4024 None,
4029 None,
4025 _(b"don't commit, just update the working directory"),
4030 _(b"don't commit, just update the working directory"),
4026 ),
4031 ),
4027 (
4032 (
4028 b'',
4033 b'',
4029 b'bypass',
4034 b'bypass',
4030 None,
4035 None,
4031 _(b"apply patch without touching the working directory"),
4036 _(b"apply patch without touching the working directory"),
4032 ),
4037 ),
4033 (b'', b'partial', None, _(b'commit even if some hunks fail')),
4038 (b'', b'partial', None, _(b'commit even if some hunks fail')),
4034 (b'', b'exact', None, _(b'abort if patch would apply lossily')),
4039 (b'', b'exact', None, _(b'abort if patch would apply lossily')),
4035 (b'', b'prefix', b'', _(b'apply patch to subdirectory'), _(b'DIR')),
4040 (b'', b'prefix', b'', _(b'apply patch to subdirectory'), _(b'DIR')),
4036 (
4041 (
4037 b'',
4042 b'',
4038 b'import-branch',
4043 b'import-branch',
4039 None,
4044 None,
4040 _(b'use any branch information in patch (implied by --exact)'),
4045 _(b'use any branch information in patch (implied by --exact)'),
4041 ),
4046 ),
4042 ]
4047 ]
4043 + commitopts
4048 + commitopts
4044 + commitopts2
4049 + commitopts2
4045 + similarityopts,
4050 + similarityopts,
4046 _(b'[OPTION]... PATCH...'),
4051 _(b'[OPTION]... PATCH...'),
4047 helpcategory=command.CATEGORY_IMPORT_EXPORT,
4052 helpcategory=command.CATEGORY_IMPORT_EXPORT,
4048 )
4053 )
4049 def import_(ui, repo, patch1=None, *patches, **opts):
4054 def import_(ui, repo, patch1=None, *patches, **opts):
4050 """import an ordered set of patches
4055 """import an ordered set of patches
4051
4056
4052 Import a list of patches and commit them individually (unless
4057 Import a list of patches and commit them individually (unless
4053 --no-commit is specified).
4058 --no-commit is specified).
4054
4059
4055 To read a patch from standard input (stdin), use "-" as the patch
4060 To read a patch from standard input (stdin), use "-" as the patch
4056 name. If a URL is specified, the patch will be downloaded from
4061 name. If a URL is specified, the patch will be downloaded from
4057 there.
4062 there.
4058
4063
4059 Import first applies changes to the working directory (unless
4064 Import first applies changes to the working directory (unless
4060 --bypass is specified), import will abort if there are outstanding
4065 --bypass is specified), import will abort if there are outstanding
4061 changes.
4066 changes.
4062
4067
4063 Use --bypass to apply and commit patches directly to the
4068 Use --bypass to apply and commit patches directly to the
4064 repository, without affecting the working directory. Without
4069 repository, without affecting the working directory. Without
4065 --exact, patches will be applied on top of the working directory
4070 --exact, patches will be applied on top of the working directory
4066 parent revision.
4071 parent revision.
4067
4072
4068 You can import a patch straight from a mail message. Even patches
4073 You can import a patch straight from a mail message. Even patches
4069 as attachments work (to use the body part, it must have type
4074 as attachments work (to use the body part, it must have type
4070 text/plain or text/x-patch). From and Subject headers of email
4075 text/plain or text/x-patch). From and Subject headers of email
4071 message are used as default committer and commit message. All
4076 message are used as default committer and commit message. All
4072 text/plain body parts before first diff are added to the commit
4077 text/plain body parts before first diff are added to the commit
4073 message.
4078 message.
4074
4079
4075 If the imported patch was generated by :hg:`export`, user and
4080 If the imported patch was generated by :hg:`export`, user and
4076 description from patch override values from message headers and
4081 description from patch override values from message headers and
4077 body. Values given on command line with -m/--message and -u/--user
4082 body. Values given on command line with -m/--message and -u/--user
4078 override these.
4083 override these.
4079
4084
4080 If --exact is specified, import will set the working directory to
4085 If --exact is specified, import will set the working directory to
4081 the parent of each patch before applying it, and will abort if the
4086 the parent of each patch before applying it, and will abort if the
4082 resulting changeset has a different ID than the one recorded in
4087 resulting changeset has a different ID than the one recorded in
4083 the patch. This will guard against various ways that portable
4088 the patch. This will guard against various ways that portable
4084 patch formats and mail systems might fail to transfer Mercurial
4089 patch formats and mail systems might fail to transfer Mercurial
4085 data or metadata. See :hg:`bundle` for lossless transmission.
4090 data or metadata. See :hg:`bundle` for lossless transmission.
4086
4091
4087 Use --partial to ensure a changeset will be created from the patch
4092 Use --partial to ensure a changeset will be created from the patch
4088 even if some hunks fail to apply. Hunks that fail to apply will be
4093 even if some hunks fail to apply. Hunks that fail to apply will be
4089 written to a <target-file>.rej file. Conflicts can then be resolved
4094 written to a <target-file>.rej file. Conflicts can then be resolved
4090 by hand before :hg:`commit --amend` is run to update the created
4095 by hand before :hg:`commit --amend` is run to update the created
4091 changeset. This flag exists to let people import patches that
4096 changeset. This flag exists to let people import patches that
4092 partially apply without losing the associated metadata (author,
4097 partially apply without losing the associated metadata (author,
4093 date, description, ...).
4098 date, description, ...).
4094
4099
4095 .. note::
4100 .. note::
4096
4101
4097 When no hunks apply cleanly, :hg:`import --partial` will create
4102 When no hunks apply cleanly, :hg:`import --partial` will create
4098 an empty changeset, importing only the patch metadata.
4103 an empty changeset, importing only the patch metadata.
4099
4104
4100 With -s/--similarity, hg will attempt to discover renames and
4105 With -s/--similarity, hg will attempt to discover renames and
4101 copies in the patch in the same way as :hg:`addremove`.
4106 copies in the patch in the same way as :hg:`addremove`.
4102
4107
4103 It is possible to use external patch programs to perform the patch
4108 It is possible to use external patch programs to perform the patch
4104 by setting the ``ui.patch`` configuration option. For the default
4109 by setting the ``ui.patch`` configuration option. For the default
4105 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4110 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4106 See :hg:`help config` for more information about configuration
4111 See :hg:`help config` for more information about configuration
4107 files and how to use these options.
4112 files and how to use these options.
4108
4113
4109 See :hg:`help dates` for a list of formats valid for -d/--date.
4114 See :hg:`help dates` for a list of formats valid for -d/--date.
4110
4115
4111 .. container:: verbose
4116 .. container:: verbose
4112
4117
4113 Examples:
4118 Examples:
4114
4119
4115 - import a traditional patch from a website and detect renames::
4120 - import a traditional patch from a website and detect renames::
4116
4121
4117 hg import -s 80 http://example.com/bugfix.patch
4122 hg import -s 80 http://example.com/bugfix.patch
4118
4123
4119 - import a changeset from an hgweb server::
4124 - import a changeset from an hgweb server::
4120
4125
4121 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
4126 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
4122
4127
4123 - import all the patches in an Unix-style mbox::
4128 - import all the patches in an Unix-style mbox::
4124
4129
4125 hg import incoming-patches.mbox
4130 hg import incoming-patches.mbox
4126
4131
4127 - import patches from stdin::
4132 - import patches from stdin::
4128
4133
4129 hg import -
4134 hg import -
4130
4135
4131 - attempt to exactly restore an exported changeset (not always
4136 - attempt to exactly restore an exported changeset (not always
4132 possible)::
4137 possible)::
4133
4138
4134 hg import --exact proposed-fix.patch
4139 hg import --exact proposed-fix.patch
4135
4140
4136 - use an external tool to apply a patch which is too fuzzy for
4141 - use an external tool to apply a patch which is too fuzzy for
4137 the default internal tool.
4142 the default internal tool.
4138
4143
4139 hg import --config ui.patch="patch --merge" fuzzy.patch
4144 hg import --config ui.patch="patch --merge" fuzzy.patch
4140
4145
4141 - change the default fuzzing from 2 to a less strict 7
4146 - change the default fuzzing from 2 to a less strict 7
4142
4147
4143 hg import --config ui.fuzz=7 fuzz.patch
4148 hg import --config ui.fuzz=7 fuzz.patch
4144
4149
4145 Returns 0 on success, 1 on partial success (see --partial).
4150 Returns 0 on success, 1 on partial success (see --partial).
4146 """
4151 """
4147
4152
4148 opts = pycompat.byteskwargs(opts)
4153 opts = pycompat.byteskwargs(opts)
4149 if not patch1:
4154 if not patch1:
4150 raise error.Abort(_(b'need at least one patch to import'))
4155 raise error.Abort(_(b'need at least one patch to import'))
4151
4156
4152 patches = (patch1,) + patches
4157 patches = (patch1,) + patches
4153
4158
4154 date = opts.get(b'date')
4159 date = opts.get(b'date')
4155 if date:
4160 if date:
4156 opts[b'date'] = dateutil.parsedate(date)
4161 opts[b'date'] = dateutil.parsedate(date)
4157
4162
4158 exact = opts.get(b'exact')
4163 exact = opts.get(b'exact')
4159 update = not opts.get(b'bypass')
4164 update = not opts.get(b'bypass')
4160 if not update and opts.get(b'no_commit'):
4165 if not update and opts.get(b'no_commit'):
4161 raise error.Abort(_(b'cannot use --no-commit with --bypass'))
4166 raise error.Abort(_(b'cannot use --no-commit with --bypass'))
4162 try:
4167 try:
4163 sim = float(opts.get(b'similarity') or 0)
4168 sim = float(opts.get(b'similarity') or 0)
4164 except ValueError:
4169 except ValueError:
4165 raise error.Abort(_(b'similarity must be a number'))
4170 raise error.Abort(_(b'similarity must be a number'))
4166 if sim < 0 or sim > 100:
4171 if sim < 0 or sim > 100:
4167 raise error.Abort(_(b'similarity must be between 0 and 100'))
4172 raise error.Abort(_(b'similarity must be between 0 and 100'))
4168 if sim and not update:
4173 if sim and not update:
4169 raise error.Abort(_(b'cannot use --similarity with --bypass'))
4174 raise error.Abort(_(b'cannot use --similarity with --bypass'))
4170 if exact:
4175 if exact:
4171 if opts.get(b'edit'):
4176 if opts.get(b'edit'):
4172 raise error.Abort(_(b'cannot use --exact with --edit'))
4177 raise error.Abort(_(b'cannot use --exact with --edit'))
4173 if opts.get(b'prefix'):
4178 if opts.get(b'prefix'):
4174 raise error.Abort(_(b'cannot use --exact with --prefix'))
4179 raise error.Abort(_(b'cannot use --exact with --prefix'))
4175
4180
4176 base = opts[b"base"]
4181 base = opts[b"base"]
4177 msgs = []
4182 msgs = []
4178 ret = 0
4183 ret = 0
4179
4184
4180 with repo.wlock():
4185 with repo.wlock():
4181 if update:
4186 if update:
4182 cmdutil.checkunfinished(repo)
4187 cmdutil.checkunfinished(repo)
4183 if exact or not opts.get(b'force'):
4188 if exact or not opts.get(b'force'):
4184 cmdutil.bailifchanged(repo)
4189 cmdutil.bailifchanged(repo)
4185
4190
4186 if not opts.get(b'no_commit'):
4191 if not opts.get(b'no_commit'):
4187 lock = repo.lock
4192 lock = repo.lock
4188 tr = lambda: repo.transaction(b'import')
4193 tr = lambda: repo.transaction(b'import')
4189 dsguard = util.nullcontextmanager
4194 dsguard = util.nullcontextmanager
4190 else:
4195 else:
4191 lock = util.nullcontextmanager
4196 lock = util.nullcontextmanager
4192 tr = util.nullcontextmanager
4197 tr = util.nullcontextmanager
4193 dsguard = lambda: dirstateguard.dirstateguard(repo, b'import')
4198 dsguard = lambda: dirstateguard.dirstateguard(repo, b'import')
4194 with lock(), tr(), dsguard():
4199 with lock(), tr(), dsguard():
4195 parents = repo[None].parents()
4200 parents = repo[None].parents()
4196 for patchurl in patches:
4201 for patchurl in patches:
4197 if patchurl == b'-':
4202 if patchurl == b'-':
4198 ui.status(_(b'applying patch from stdin\n'))
4203 ui.status(_(b'applying patch from stdin\n'))
4199 patchfile = ui.fin
4204 patchfile = ui.fin
4200 patchurl = b'stdin' # for error message
4205 patchurl = b'stdin' # for error message
4201 else:
4206 else:
4202 patchurl = os.path.join(base, patchurl)
4207 patchurl = os.path.join(base, patchurl)
4203 ui.status(_(b'applying %s\n') % patchurl)
4208 ui.status(_(b'applying %s\n') % patchurl)
4204 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
4209 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
4205
4210
4206 haspatch = False
4211 haspatch = False
4207 for hunk in patch.split(patchfile):
4212 for hunk in patch.split(patchfile):
4208 with patch.extract(ui, hunk) as patchdata:
4213 with patch.extract(ui, hunk) as patchdata:
4209 msg, node, rej = cmdutil.tryimportone(
4214 msg, node, rej = cmdutil.tryimportone(
4210 ui, repo, patchdata, parents, opts, msgs, hg.clean
4215 ui, repo, patchdata, parents, opts, msgs, hg.clean
4211 )
4216 )
4212 if msg:
4217 if msg:
4213 haspatch = True
4218 haspatch = True
4214 ui.note(msg + b'\n')
4219 ui.note(msg + b'\n')
4215 if update or exact:
4220 if update or exact:
4216 parents = repo[None].parents()
4221 parents = repo[None].parents()
4217 else:
4222 else:
4218 parents = [repo[node]]
4223 parents = [repo[node]]
4219 if rej:
4224 if rej:
4220 ui.write_err(_(b"patch applied partially\n"))
4225 ui.write_err(_(b"patch applied partially\n"))
4221 ui.write_err(
4226 ui.write_err(
4222 _(
4227 _(
4223 b"(fix the .rej files and run "
4228 b"(fix the .rej files and run "
4224 b"`hg commit --amend`)\n"
4229 b"`hg commit --amend`)\n"
4225 )
4230 )
4226 )
4231 )
4227 ret = 1
4232 ret = 1
4228 break
4233 break
4229
4234
4230 if not haspatch:
4235 if not haspatch:
4231 raise error.Abort(_(b'%s: no diffs found') % patchurl)
4236 raise error.Abort(_(b'%s: no diffs found') % patchurl)
4232
4237
4233 if msgs:
4238 if msgs:
4234 repo.savecommitmessage(b'\n* * *\n'.join(msgs))
4239 repo.savecommitmessage(b'\n* * *\n'.join(msgs))
4235 return ret
4240 return ret
4236
4241
4237
4242
4238 @command(
4243 @command(
4239 b'incoming|in',
4244 b'incoming|in',
4240 [
4245 [
4241 (
4246 (
4242 b'f',
4247 b'f',
4243 b'force',
4248 b'force',
4244 None,
4249 None,
4245 _(b'run even if remote repository is unrelated'),
4250 _(b'run even if remote repository is unrelated'),
4246 ),
4251 ),
4247 (b'n', b'newest-first', None, _(b'show newest record first')),
4252 (b'n', b'newest-first', None, _(b'show newest record first')),
4248 (b'', b'bundle', b'', _(b'file to store the bundles into'), _(b'FILE')),
4253 (b'', b'bundle', b'', _(b'file to store the bundles into'), _(b'FILE')),
4249 (
4254 (
4250 b'r',
4255 b'r',
4251 b'rev',
4256 b'rev',
4252 [],
4257 [],
4253 _(b'a remote changeset intended to be added'),
4258 _(b'a remote changeset intended to be added'),
4254 _(b'REV'),
4259 _(b'REV'),
4255 ),
4260 ),
4256 (b'B', b'bookmarks', False, _(b"compare bookmarks")),
4261 (b'B', b'bookmarks', False, _(b"compare bookmarks")),
4257 (
4262 (
4258 b'b',
4263 b'b',
4259 b'branch',
4264 b'branch',
4260 [],
4265 [],
4261 _(b'a specific branch you would like to pull'),
4266 _(b'a specific branch you would like to pull'),
4262 _(b'BRANCH'),
4267 _(b'BRANCH'),
4263 ),
4268 ),
4264 ]
4269 ]
4265 + logopts
4270 + logopts
4266 + remoteopts
4271 + remoteopts
4267 + subrepoopts,
4272 + subrepoopts,
4268 _(b'[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
4273 _(b'[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
4269 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4274 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4270 )
4275 )
4271 def incoming(ui, repo, source=b"default", **opts):
4276 def incoming(ui, repo, source=b"default", **opts):
4272 """show new changesets found in source
4277 """show new changesets found in source
4273
4278
4274 Show new changesets found in the specified path/URL or the default
4279 Show new changesets found in the specified path/URL or the default
4275 pull location. These are the changesets that would have been pulled
4280 pull location. These are the changesets that would have been pulled
4276 by :hg:`pull` at the time you issued this command.
4281 by :hg:`pull` at the time you issued this command.
4277
4282
4278 See pull for valid source format details.
4283 See pull for valid source format details.
4279
4284
4280 .. container:: verbose
4285 .. container:: verbose
4281
4286
4282 With -B/--bookmarks, the result of bookmark comparison between
4287 With -B/--bookmarks, the result of bookmark comparison between
4283 local and remote repositories is displayed. With -v/--verbose,
4288 local and remote repositories is displayed. With -v/--verbose,
4284 status is also displayed for each bookmark like below::
4289 status is also displayed for each bookmark like below::
4285
4290
4286 BM1 01234567890a added
4291 BM1 01234567890a added
4287 BM2 1234567890ab advanced
4292 BM2 1234567890ab advanced
4288 BM3 234567890abc diverged
4293 BM3 234567890abc diverged
4289 BM4 34567890abcd changed
4294 BM4 34567890abcd changed
4290
4295
4291 The action taken locally when pulling depends on the
4296 The action taken locally when pulling depends on the
4292 status of each bookmark:
4297 status of each bookmark:
4293
4298
4294 :``added``: pull will create it
4299 :``added``: pull will create it
4295 :``advanced``: pull will update it
4300 :``advanced``: pull will update it
4296 :``diverged``: pull will create a divergent bookmark
4301 :``diverged``: pull will create a divergent bookmark
4297 :``changed``: result depends on remote changesets
4302 :``changed``: result depends on remote changesets
4298
4303
4299 From the point of view of pulling behavior, bookmark
4304 From the point of view of pulling behavior, bookmark
4300 existing only in the remote repository are treated as ``added``,
4305 existing only in the remote repository are treated as ``added``,
4301 even if it is in fact locally deleted.
4306 even if it is in fact locally deleted.
4302
4307
4303 .. container:: verbose
4308 .. container:: verbose
4304
4309
4305 For remote repository, using --bundle avoids downloading the
4310 For remote repository, using --bundle avoids downloading the
4306 changesets twice if the incoming is followed by a pull.
4311 changesets twice if the incoming is followed by a pull.
4307
4312
4308 Examples:
4313 Examples:
4309
4314
4310 - show incoming changes with patches and full description::
4315 - show incoming changes with patches and full description::
4311
4316
4312 hg incoming -vp
4317 hg incoming -vp
4313
4318
4314 - show incoming changes excluding merges, store a bundle::
4319 - show incoming changes excluding merges, store a bundle::
4315
4320
4316 hg in -vpM --bundle incoming.hg
4321 hg in -vpM --bundle incoming.hg
4317 hg pull incoming.hg
4322 hg pull incoming.hg
4318
4323
4319 - briefly list changes inside a bundle::
4324 - briefly list changes inside a bundle::
4320
4325
4321 hg in changes.hg -T "{desc|firstline}\\n"
4326 hg in changes.hg -T "{desc|firstline}\\n"
4322
4327
4323 Returns 0 if there are incoming changes, 1 otherwise.
4328 Returns 0 if there are incoming changes, 1 otherwise.
4324 """
4329 """
4325 opts = pycompat.byteskwargs(opts)
4330 opts = pycompat.byteskwargs(opts)
4326 if opts.get(b'graph'):
4331 if opts.get(b'graph'):
4327 logcmdutil.checkunsupportedgraphflags([], opts)
4332 logcmdutil.checkunsupportedgraphflags([], opts)
4328
4333
4329 def display(other, chlist, displayer):
4334 def display(other, chlist, displayer):
4330 revdag = logcmdutil.graphrevs(other, chlist, opts)
4335 revdag = logcmdutil.graphrevs(other, chlist, opts)
4331 logcmdutil.displaygraph(
4336 logcmdutil.displaygraph(
4332 ui, repo, revdag, displayer, graphmod.asciiedges
4337 ui, repo, revdag, displayer, graphmod.asciiedges
4333 )
4338 )
4334
4339
4335 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4340 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4336 return 0
4341 return 0
4337
4342
4338 if opts.get(b'bundle') and opts.get(b'subrepos'):
4343 if opts.get(b'bundle') and opts.get(b'subrepos'):
4339 raise error.Abort(_(b'cannot combine --bundle and --subrepos'))
4344 raise error.Abort(_(b'cannot combine --bundle and --subrepos'))
4340
4345
4341 if opts.get(b'bookmarks'):
4346 if opts.get(b'bookmarks'):
4342 source, branches = hg.parseurl(
4347 source, branches = hg.parseurl(
4343 ui.expandpath(source), opts.get(b'branch')
4348 ui.expandpath(source), opts.get(b'branch')
4344 )
4349 )
4345 other = hg.peer(repo, opts, source)
4350 other = hg.peer(repo, opts, source)
4346 if b'bookmarks' not in other.listkeys(b'namespaces'):
4351 if b'bookmarks' not in other.listkeys(b'namespaces'):
4347 ui.warn(_(b"remote doesn't support bookmarks\n"))
4352 ui.warn(_(b"remote doesn't support bookmarks\n"))
4348 return 0
4353 return 0
4349 ui.pager(b'incoming')
4354 ui.pager(b'incoming')
4350 ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
4355 ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
4351 return bookmarks.incoming(ui, repo, other)
4356 return bookmarks.incoming(ui, repo, other)
4352
4357
4353 repo._subtoppath = ui.expandpath(source)
4358 repo._subtoppath = ui.expandpath(source)
4354 try:
4359 try:
4355 return hg.incoming(ui, repo, source, opts)
4360 return hg.incoming(ui, repo, source, opts)
4356 finally:
4361 finally:
4357 del repo._subtoppath
4362 del repo._subtoppath
4358
4363
4359
4364
4360 @command(
4365 @command(
4361 b'init',
4366 b'init',
4362 remoteopts,
4367 remoteopts,
4363 _(b'[-e CMD] [--remotecmd CMD] [DEST]'),
4368 _(b'[-e CMD] [--remotecmd CMD] [DEST]'),
4364 helpcategory=command.CATEGORY_REPO_CREATION,
4369 helpcategory=command.CATEGORY_REPO_CREATION,
4365 helpbasic=True,
4370 helpbasic=True,
4366 norepo=True,
4371 norepo=True,
4367 )
4372 )
4368 def init(ui, dest=b".", **opts):
4373 def init(ui, dest=b".", **opts):
4369 """create a new repository in the given directory
4374 """create a new repository in the given directory
4370
4375
4371 Initialize a new repository in the given directory. If the given
4376 Initialize a new repository in the given directory. If the given
4372 directory does not exist, it will be created.
4377 directory does not exist, it will be created.
4373
4378
4374 If no directory is given, the current directory is used.
4379 If no directory is given, the current directory is used.
4375
4380
4376 It is possible to specify an ``ssh://`` URL as the destination.
4381 It is possible to specify an ``ssh://`` URL as the destination.
4377 See :hg:`help urls` for more information.
4382 See :hg:`help urls` for more information.
4378
4383
4379 Returns 0 on success.
4384 Returns 0 on success.
4380 """
4385 """
4381 opts = pycompat.byteskwargs(opts)
4386 opts = pycompat.byteskwargs(opts)
4382 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4387 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4383
4388
4384
4389
4385 @command(
4390 @command(
4386 b'locate',
4391 b'locate',
4387 [
4392 [
4388 (
4393 (
4389 b'r',
4394 b'r',
4390 b'rev',
4395 b'rev',
4391 b'',
4396 b'',
4392 _(b'search the repository as it is in REV'),
4397 _(b'search the repository as it is in REV'),
4393 _(b'REV'),
4398 _(b'REV'),
4394 ),
4399 ),
4395 (
4400 (
4396 b'0',
4401 b'0',
4397 b'print0',
4402 b'print0',
4398 None,
4403 None,
4399 _(b'end filenames with NUL, for use with xargs'),
4404 _(b'end filenames with NUL, for use with xargs'),
4400 ),
4405 ),
4401 (
4406 (
4402 b'f',
4407 b'f',
4403 b'fullpath',
4408 b'fullpath',
4404 None,
4409 None,
4405 _(b'print complete paths from the filesystem root'),
4410 _(b'print complete paths from the filesystem root'),
4406 ),
4411 ),
4407 ]
4412 ]
4408 + walkopts,
4413 + walkopts,
4409 _(b'[OPTION]... [PATTERN]...'),
4414 _(b'[OPTION]... [PATTERN]...'),
4410 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4415 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4411 )
4416 )
4412 def locate(ui, repo, *pats, **opts):
4417 def locate(ui, repo, *pats, **opts):
4413 """locate files matching specific patterns (DEPRECATED)
4418 """locate files matching specific patterns (DEPRECATED)
4414
4419
4415 Print files under Mercurial control in the working directory whose
4420 Print files under Mercurial control in the working directory whose
4416 names match the given patterns.
4421 names match the given patterns.
4417
4422
4418 By default, this command searches all directories in the working
4423 By default, this command searches all directories in the working
4419 directory. To search just the current directory and its
4424 directory. To search just the current directory and its
4420 subdirectories, use "--include .".
4425 subdirectories, use "--include .".
4421
4426
4422 If no patterns are given to match, this command prints the names
4427 If no patterns are given to match, this command prints the names
4423 of all files under Mercurial control in the working directory.
4428 of all files under Mercurial control in the working directory.
4424
4429
4425 If you want to feed the output of this command into the "xargs"
4430 If you want to feed the output of this command into the "xargs"
4426 command, use the -0 option to both this command and "xargs". This
4431 command, use the -0 option to both this command and "xargs". This
4427 will avoid the problem of "xargs" treating single filenames that
4432 will avoid the problem of "xargs" treating single filenames that
4428 contain whitespace as multiple filenames.
4433 contain whitespace as multiple filenames.
4429
4434
4430 See :hg:`help files` for a more versatile command.
4435 See :hg:`help files` for a more versatile command.
4431
4436
4432 Returns 0 if a match is found, 1 otherwise.
4437 Returns 0 if a match is found, 1 otherwise.
4433 """
4438 """
4434 opts = pycompat.byteskwargs(opts)
4439 opts = pycompat.byteskwargs(opts)
4435 if opts.get(b'print0'):
4440 if opts.get(b'print0'):
4436 end = b'\0'
4441 end = b'\0'
4437 else:
4442 else:
4438 end = b'\n'
4443 end = b'\n'
4439 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
4444 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
4440
4445
4441 ret = 1
4446 ret = 1
4442 m = scmutil.match(
4447 m = scmutil.match(
4443 ctx, pats, opts, default=b'relglob', badfn=lambda x, y: False
4448 ctx, pats, opts, default=b'relglob', badfn=lambda x, y: False
4444 )
4449 )
4445
4450
4446 ui.pager(b'locate')
4451 ui.pager(b'locate')
4447 if ctx.rev() is None:
4452 if ctx.rev() is None:
4448 # When run on the working copy, "locate" includes removed files, so
4453 # When run on the working copy, "locate" includes removed files, so
4449 # we get the list of files from the dirstate.
4454 # we get the list of files from the dirstate.
4450 filesgen = sorted(repo.dirstate.matches(m))
4455 filesgen = sorted(repo.dirstate.matches(m))
4451 else:
4456 else:
4452 filesgen = ctx.matches(m)
4457 filesgen = ctx.matches(m)
4453 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
4458 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
4454 for abs in filesgen:
4459 for abs in filesgen:
4455 if opts.get(b'fullpath'):
4460 if opts.get(b'fullpath'):
4456 ui.write(repo.wjoin(abs), end)
4461 ui.write(repo.wjoin(abs), end)
4457 else:
4462 else:
4458 ui.write(uipathfn(abs), end)
4463 ui.write(uipathfn(abs), end)
4459 ret = 0
4464 ret = 0
4460
4465
4461 return ret
4466 return ret
4462
4467
4463
4468
4464 @command(
4469 @command(
4465 b'log|history',
4470 b'log|history',
4466 [
4471 [
4467 (
4472 (
4468 b'f',
4473 b'f',
4469 b'follow',
4474 b'follow',
4470 None,
4475 None,
4471 _(
4476 _(
4472 b'follow changeset history, or file history across copies and renames'
4477 b'follow changeset history, or file history across copies and renames'
4473 ),
4478 ),
4474 ),
4479 ),
4475 (
4480 (
4476 b'',
4481 b'',
4477 b'follow-first',
4482 b'follow-first',
4478 None,
4483 None,
4479 _(b'only follow the first parent of merge changesets (DEPRECATED)'),
4484 _(b'only follow the first parent of merge changesets (DEPRECATED)'),
4480 ),
4485 ),
4481 (
4486 (
4482 b'd',
4487 b'd',
4483 b'date',
4488 b'date',
4484 b'',
4489 b'',
4485 _(b'show revisions matching date spec'),
4490 _(b'show revisions matching date spec'),
4486 _(b'DATE'),
4491 _(b'DATE'),
4487 ),
4492 ),
4488 (b'C', b'copies', None, _(b'show copied files')),
4493 (b'C', b'copies', None, _(b'show copied files')),
4489 (
4494 (
4490 b'k',
4495 b'k',
4491 b'keyword',
4496 b'keyword',
4492 [],
4497 [],
4493 _(b'do case-insensitive search for a given text'),
4498 _(b'do case-insensitive search for a given text'),
4494 _(b'TEXT'),
4499 _(b'TEXT'),
4495 ),
4500 ),
4496 (
4501 (
4497 b'r',
4502 b'r',
4498 b'rev',
4503 b'rev',
4499 [],
4504 [],
4500 _(b'show the specified revision or revset'),
4505 _(b'show the specified revision or revset'),
4501 _(b'REV'),
4506 _(b'REV'),
4502 ),
4507 ),
4503 (
4508 (
4504 b'L',
4509 b'L',
4505 b'line-range',
4510 b'line-range',
4506 [],
4511 [],
4507 _(b'follow line range of specified file (EXPERIMENTAL)'),
4512 _(b'follow line range of specified file (EXPERIMENTAL)'),
4508 _(b'FILE,RANGE'),
4513 _(b'FILE,RANGE'),
4509 ),
4514 ),
4510 (
4515 (
4511 b'',
4516 b'',
4512 b'removed',
4517 b'removed',
4513 None,
4518 None,
4514 _(b'include revisions where files were removed'),
4519 _(b'include revisions where files were removed'),
4515 ),
4520 ),
4516 (
4521 (
4517 b'm',
4522 b'm',
4518 b'only-merges',
4523 b'only-merges',
4519 None,
4524 None,
4520 _(b'show only merges (DEPRECATED) (use -r "merge()" instead)'),
4525 _(b'show only merges (DEPRECATED) (use -r "merge()" instead)'),
4521 ),
4526 ),
4522 (b'u', b'user', [], _(b'revisions committed by user'), _(b'USER')),
4527 (b'u', b'user', [], _(b'revisions committed by user'), _(b'USER')),
4523 (
4528 (
4524 b'',
4529 b'',
4525 b'only-branch',
4530 b'only-branch',
4526 [],
4531 [],
4527 _(
4532 _(
4528 b'show only changesets within the given named branch (DEPRECATED)'
4533 b'show only changesets within the given named branch (DEPRECATED)'
4529 ),
4534 ),
4530 _(b'BRANCH'),
4535 _(b'BRANCH'),
4531 ),
4536 ),
4532 (
4537 (
4533 b'b',
4538 b'b',
4534 b'branch',
4539 b'branch',
4535 [],
4540 [],
4536 _(b'show changesets within the given named branch'),
4541 _(b'show changesets within the given named branch'),
4537 _(b'BRANCH'),
4542 _(b'BRANCH'),
4538 ),
4543 ),
4539 (
4544 (
4540 b'P',
4545 b'P',
4541 b'prune',
4546 b'prune',
4542 [],
4547 [],
4543 _(b'do not display revision or any of its ancestors'),
4548 _(b'do not display revision or any of its ancestors'),
4544 _(b'REV'),
4549 _(b'REV'),
4545 ),
4550 ),
4546 ]
4551 ]
4547 + logopts
4552 + logopts
4548 + walkopts,
4553 + walkopts,
4549 _(b'[OPTION]... [FILE]'),
4554 _(b'[OPTION]... [FILE]'),
4550 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4555 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4551 helpbasic=True,
4556 helpbasic=True,
4552 inferrepo=True,
4557 inferrepo=True,
4553 intents={INTENT_READONLY},
4558 intents={INTENT_READONLY},
4554 )
4559 )
4555 def log(ui, repo, *pats, **opts):
4560 def log(ui, repo, *pats, **opts):
4556 """show revision history of entire repository or files
4561 """show revision history of entire repository or files
4557
4562
4558 Print the revision history of the specified files or the entire
4563 Print the revision history of the specified files or the entire
4559 project.
4564 project.
4560
4565
4561 If no revision range is specified, the default is ``tip:0`` unless
4566 If no revision range is specified, the default is ``tip:0`` unless
4562 --follow is set, in which case the working directory parent is
4567 --follow is set, in which case the working directory parent is
4563 used as the starting revision.
4568 used as the starting revision.
4564
4569
4565 File history is shown without following rename or copy history of
4570 File history is shown without following rename or copy history of
4566 files. Use -f/--follow with a filename to follow history across
4571 files. Use -f/--follow with a filename to follow history across
4567 renames and copies. --follow without a filename will only show
4572 renames and copies. --follow without a filename will only show
4568 ancestors of the starting revision.
4573 ancestors of the starting revision.
4569
4574
4570 By default this command prints revision number and changeset id,
4575 By default this command prints revision number and changeset id,
4571 tags, non-trivial parents, user, date and time, and a summary for
4576 tags, non-trivial parents, user, date and time, and a summary for
4572 each commit. When the -v/--verbose switch is used, the list of
4577 each commit. When the -v/--verbose switch is used, the list of
4573 changed files and full commit message are shown.
4578 changed files and full commit message are shown.
4574
4579
4575 With --graph the revisions are shown as an ASCII art DAG with the most
4580 With --graph the revisions are shown as an ASCII art DAG with the most
4576 recent changeset at the top.
4581 recent changeset at the top.
4577 'o' is a changeset, '@' is a working directory parent, '_' closes a branch,
4582 'o' is a changeset, '@' is a working directory parent, '_' closes a branch,
4578 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
4583 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
4579 changeset from the lines below is a parent of the 'o' merge on the same
4584 changeset from the lines below is a parent of the 'o' merge on the same
4580 line.
4585 line.
4581 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
4586 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
4582 of a '|' indicates one or more revisions in a path are omitted.
4587 of a '|' indicates one or more revisions in a path are omitted.
4583
4588
4584 .. container:: verbose
4589 .. container:: verbose
4585
4590
4586 Use -L/--line-range FILE,M:N options to follow the history of lines
4591 Use -L/--line-range FILE,M:N options to follow the history of lines
4587 from M to N in FILE. With -p/--patch only diff hunks affecting
4592 from M to N in FILE. With -p/--patch only diff hunks affecting
4588 specified line range will be shown. This option requires --follow;
4593 specified line range will be shown. This option requires --follow;
4589 it can be specified multiple times. Currently, this option is not
4594 it can be specified multiple times. Currently, this option is not
4590 compatible with --graph. This option is experimental.
4595 compatible with --graph. This option is experimental.
4591
4596
4592 .. note::
4597 .. note::
4593
4598
4594 :hg:`log --patch` may generate unexpected diff output for merge
4599 :hg:`log --patch` may generate unexpected diff output for merge
4595 changesets, as it will only compare the merge changeset against
4600 changesets, as it will only compare the merge changeset against
4596 its first parent. Also, only files different from BOTH parents
4601 its first parent. Also, only files different from BOTH parents
4597 will appear in files:.
4602 will appear in files:.
4598
4603
4599 .. note::
4604 .. note::
4600
4605
4601 For performance reasons, :hg:`log FILE` may omit duplicate changes
4606 For performance reasons, :hg:`log FILE` may omit duplicate changes
4602 made on branches and will not show removals or mode changes. To
4607 made on branches and will not show removals or mode changes. To
4603 see all such changes, use the --removed switch.
4608 see all such changes, use the --removed switch.
4604
4609
4605 .. container:: verbose
4610 .. container:: verbose
4606
4611
4607 .. note::
4612 .. note::
4608
4613
4609 The history resulting from -L/--line-range options depends on diff
4614 The history resulting from -L/--line-range options depends on diff
4610 options; for instance if white-spaces are ignored, respective changes
4615 options; for instance if white-spaces are ignored, respective changes
4611 with only white-spaces in specified line range will not be listed.
4616 with only white-spaces in specified line range will not be listed.
4612
4617
4613 .. container:: verbose
4618 .. container:: verbose
4614
4619
4615 Some examples:
4620 Some examples:
4616
4621
4617 - changesets with full descriptions and file lists::
4622 - changesets with full descriptions and file lists::
4618
4623
4619 hg log -v
4624 hg log -v
4620
4625
4621 - changesets ancestral to the working directory::
4626 - changesets ancestral to the working directory::
4622
4627
4623 hg log -f
4628 hg log -f
4624
4629
4625 - last 10 commits on the current branch::
4630 - last 10 commits on the current branch::
4626
4631
4627 hg log -l 10 -b .
4632 hg log -l 10 -b .
4628
4633
4629 - changesets showing all modifications of a file, including removals::
4634 - changesets showing all modifications of a file, including removals::
4630
4635
4631 hg log --removed file.c
4636 hg log --removed file.c
4632
4637
4633 - all changesets that touch a directory, with diffs, excluding merges::
4638 - all changesets that touch a directory, with diffs, excluding merges::
4634
4639
4635 hg log -Mp lib/
4640 hg log -Mp lib/
4636
4641
4637 - all revision numbers that match a keyword::
4642 - all revision numbers that match a keyword::
4638
4643
4639 hg log -k bug --template "{rev}\\n"
4644 hg log -k bug --template "{rev}\\n"
4640
4645
4641 - the full hash identifier of the working directory parent::
4646 - the full hash identifier of the working directory parent::
4642
4647
4643 hg log -r . --template "{node}\\n"
4648 hg log -r . --template "{node}\\n"
4644
4649
4645 - list available log templates::
4650 - list available log templates::
4646
4651
4647 hg log -T list
4652 hg log -T list
4648
4653
4649 - check if a given changeset is included in a tagged release::
4654 - check if a given changeset is included in a tagged release::
4650
4655
4651 hg log -r "a21ccf and ancestor(1.9)"
4656 hg log -r "a21ccf and ancestor(1.9)"
4652
4657
4653 - find all changesets by some user in a date range::
4658 - find all changesets by some user in a date range::
4654
4659
4655 hg log -k alice -d "may 2008 to jul 2008"
4660 hg log -k alice -d "may 2008 to jul 2008"
4656
4661
4657 - summary of all changesets after the last tag::
4662 - summary of all changesets after the last tag::
4658
4663
4659 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4664 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4660
4665
4661 - changesets touching lines 13 to 23 for file.c::
4666 - changesets touching lines 13 to 23 for file.c::
4662
4667
4663 hg log -L file.c,13:23
4668 hg log -L file.c,13:23
4664
4669
4665 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
4670 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
4666 main.c with patch::
4671 main.c with patch::
4667
4672
4668 hg log -L file.c,13:23 -L main.c,2:6 -p
4673 hg log -L file.c,13:23 -L main.c,2:6 -p
4669
4674
4670 See :hg:`help dates` for a list of formats valid for -d/--date.
4675 See :hg:`help dates` for a list of formats valid for -d/--date.
4671
4676
4672 See :hg:`help revisions` for more about specifying and ordering
4677 See :hg:`help revisions` for more about specifying and ordering
4673 revisions.
4678 revisions.
4674
4679
4675 See :hg:`help templates` for more about pre-packaged styles and
4680 See :hg:`help templates` for more about pre-packaged styles and
4676 specifying custom templates. The default template used by the log
4681 specifying custom templates. The default template used by the log
4677 command can be customized via the ``ui.logtemplate`` configuration
4682 command can be customized via the ``ui.logtemplate`` configuration
4678 setting.
4683 setting.
4679
4684
4680 Returns 0 on success.
4685 Returns 0 on success.
4681
4686
4682 """
4687 """
4683 opts = pycompat.byteskwargs(opts)
4688 opts = pycompat.byteskwargs(opts)
4684 linerange = opts.get(b'line_range')
4689 linerange = opts.get(b'line_range')
4685
4690
4686 if linerange and not opts.get(b'follow'):
4691 if linerange and not opts.get(b'follow'):
4687 raise error.Abort(_(b'--line-range requires --follow'))
4692 raise error.Abort(_(b'--line-range requires --follow'))
4688
4693
4689 if linerange and pats:
4694 if linerange and pats:
4690 # TODO: take pats as patterns with no line-range filter
4695 # TODO: take pats as patterns with no line-range filter
4691 raise error.Abort(
4696 raise error.Abort(
4692 _(b'FILE arguments are not compatible with --line-range option')
4697 _(b'FILE arguments are not compatible with --line-range option')
4693 )
4698 )
4694
4699
4695 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
4700 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
4696 revs, differ = logcmdutil.getrevs(repo, pats, opts)
4701 revs, differ = logcmdutil.getrevs(repo, pats, opts)
4697 if linerange:
4702 if linerange:
4698 # TODO: should follow file history from logcmdutil._initialrevs(),
4703 # TODO: should follow file history from logcmdutil._initialrevs(),
4699 # then filter the result by logcmdutil._makerevset() and --limit
4704 # then filter the result by logcmdutil._makerevset() and --limit
4700 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
4705 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
4701
4706
4702 getcopies = None
4707 getcopies = None
4703 if opts.get(b'copies'):
4708 if opts.get(b'copies'):
4704 endrev = None
4709 endrev = None
4705 if revs:
4710 if revs:
4706 endrev = revs.max() + 1
4711 endrev = revs.max() + 1
4707 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
4712 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
4708
4713
4709 ui.pager(b'log')
4714 ui.pager(b'log')
4710 displayer = logcmdutil.changesetdisplayer(
4715 displayer = logcmdutil.changesetdisplayer(
4711 ui, repo, opts, differ, buffered=True
4716 ui, repo, opts, differ, buffered=True
4712 )
4717 )
4713 if opts.get(b'graph'):
4718 if opts.get(b'graph'):
4714 displayfn = logcmdutil.displaygraphrevs
4719 displayfn = logcmdutil.displaygraphrevs
4715 else:
4720 else:
4716 displayfn = logcmdutil.displayrevs
4721 displayfn = logcmdutil.displayrevs
4717 displayfn(ui, repo, revs, displayer, getcopies)
4722 displayfn(ui, repo, revs, displayer, getcopies)
4718
4723
4719
4724
4720 @command(
4725 @command(
4721 b'manifest',
4726 b'manifest',
4722 [
4727 [
4723 (b'r', b'rev', b'', _(b'revision to display'), _(b'REV')),
4728 (b'r', b'rev', b'', _(b'revision to display'), _(b'REV')),
4724 (b'', b'all', False, _(b"list files from all revisions")),
4729 (b'', b'all', False, _(b"list files from all revisions")),
4725 ]
4730 ]
4726 + formatteropts,
4731 + formatteropts,
4727 _(b'[-r REV]'),
4732 _(b'[-r REV]'),
4728 helpcategory=command.CATEGORY_MAINTENANCE,
4733 helpcategory=command.CATEGORY_MAINTENANCE,
4729 intents={INTENT_READONLY},
4734 intents={INTENT_READONLY},
4730 )
4735 )
4731 def manifest(ui, repo, node=None, rev=None, **opts):
4736 def manifest(ui, repo, node=None, rev=None, **opts):
4732 """output the current or given revision of the project manifest
4737 """output the current or given revision of the project manifest
4733
4738
4734 Print a list of version controlled files for the given revision.
4739 Print a list of version controlled files for the given revision.
4735 If no revision is given, the first parent of the working directory
4740 If no revision is given, the first parent of the working directory
4736 is used, or the null revision if no revision is checked out.
4741 is used, or the null revision if no revision is checked out.
4737
4742
4738 With -v, print file permissions, symlink and executable bits.
4743 With -v, print file permissions, symlink and executable bits.
4739 With --debug, print file revision hashes.
4744 With --debug, print file revision hashes.
4740
4745
4741 If option --all is specified, the list of all files from all revisions
4746 If option --all is specified, the list of all files from all revisions
4742 is printed. This includes deleted and renamed files.
4747 is printed. This includes deleted and renamed files.
4743
4748
4744 Returns 0 on success.
4749 Returns 0 on success.
4745 """
4750 """
4746 opts = pycompat.byteskwargs(opts)
4751 opts = pycompat.byteskwargs(opts)
4747 fm = ui.formatter(b'manifest', opts)
4752 fm = ui.formatter(b'manifest', opts)
4748
4753
4749 if opts.get(b'all'):
4754 if opts.get(b'all'):
4750 if rev or node:
4755 if rev or node:
4751 raise error.Abort(_(b"can't specify a revision with --all"))
4756 raise error.Abort(_(b"can't specify a revision with --all"))
4752
4757
4753 res = set()
4758 res = set()
4754 for rev in repo:
4759 for rev in repo:
4755 ctx = repo[rev]
4760 ctx = repo[rev]
4756 res |= set(ctx.files())
4761 res |= set(ctx.files())
4757
4762
4758 ui.pager(b'manifest')
4763 ui.pager(b'manifest')
4759 for f in sorted(res):
4764 for f in sorted(res):
4760 fm.startitem()
4765 fm.startitem()
4761 fm.write(b"path", b'%s\n', f)
4766 fm.write(b"path", b'%s\n', f)
4762 fm.end()
4767 fm.end()
4763 return
4768 return
4764
4769
4765 if rev and node:
4770 if rev and node:
4766 raise error.Abort(_(b"please specify just one revision"))
4771 raise error.Abort(_(b"please specify just one revision"))
4767
4772
4768 if not node:
4773 if not node:
4769 node = rev
4774 node = rev
4770
4775
4771 char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'}
4776 char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'}
4772 mode = {b'l': b'644', b'x': b'755', b'': b'644', b't': b'755'}
4777 mode = {b'l': b'644', b'x': b'755', b'': b'644', b't': b'755'}
4773 if node:
4778 if node:
4774 repo = scmutil.unhidehashlikerevs(repo, [node], b'nowarn')
4779 repo = scmutil.unhidehashlikerevs(repo, [node], b'nowarn')
4775 ctx = scmutil.revsingle(repo, node)
4780 ctx = scmutil.revsingle(repo, node)
4776 mf = ctx.manifest()
4781 mf = ctx.manifest()
4777 ui.pager(b'manifest')
4782 ui.pager(b'manifest')
4778 for f in ctx:
4783 for f in ctx:
4779 fm.startitem()
4784 fm.startitem()
4780 fm.context(ctx=ctx)
4785 fm.context(ctx=ctx)
4781 fl = ctx[f].flags()
4786 fl = ctx[f].flags()
4782 fm.condwrite(ui.debugflag, b'hash', b'%s ', hex(mf[f]))
4787 fm.condwrite(ui.debugflag, b'hash', b'%s ', hex(mf[f]))
4783 fm.condwrite(ui.verbose, b'mode type', b'%s %1s ', mode[fl], char[fl])
4788 fm.condwrite(ui.verbose, b'mode type', b'%s %1s ', mode[fl], char[fl])
4784 fm.write(b'path', b'%s\n', f)
4789 fm.write(b'path', b'%s\n', f)
4785 fm.end()
4790 fm.end()
4786
4791
4787
4792
4788 @command(
4793 @command(
4789 b'merge',
4794 b'merge',
4790 [
4795 [
4791 (
4796 (
4792 b'f',
4797 b'f',
4793 b'force',
4798 b'force',
4794 None,
4799 None,
4795 _(b'force a merge including outstanding changes (DEPRECATED)'),
4800 _(b'force a merge including outstanding changes (DEPRECATED)'),
4796 ),
4801 ),
4797 (b'r', b'rev', b'', _(b'revision to merge'), _(b'REV')),
4802 (b'r', b'rev', b'', _(b'revision to merge'), _(b'REV')),
4798 (
4803 (
4799 b'P',
4804 b'P',
4800 b'preview',
4805 b'preview',
4801 None,
4806 None,
4802 _(b'review revisions to merge (no merge is performed)'),
4807 _(b'review revisions to merge (no merge is performed)'),
4803 ),
4808 ),
4804 (b'', b'abort', None, _(b'abort the ongoing merge')),
4809 (b'', b'abort', None, _(b'abort the ongoing merge')),
4805 ]
4810 ]
4806 + mergetoolopts,
4811 + mergetoolopts,
4807 _(b'[-P] [[-r] REV]'),
4812 _(b'[-P] [[-r] REV]'),
4808 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
4813 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
4809 helpbasic=True,
4814 helpbasic=True,
4810 )
4815 )
4811 def merge(ui, repo, node=None, **opts):
4816 def merge(ui, repo, node=None, **opts):
4812 """merge another revision into working directory
4817 """merge another revision into working directory
4813
4818
4814 The current working directory is updated with all changes made in
4819 The current working directory is updated with all changes made in
4815 the requested revision since the last common predecessor revision.
4820 the requested revision since the last common predecessor revision.
4816
4821
4817 Files that changed between either parent are marked as changed for
4822 Files that changed between either parent are marked as changed for
4818 the next commit and a commit must be performed before any further
4823 the next commit and a commit must be performed before any further
4819 updates to the repository are allowed. The next commit will have
4824 updates to the repository are allowed. The next commit will have
4820 two parents.
4825 two parents.
4821
4826
4822 ``--tool`` can be used to specify the merge tool used for file
4827 ``--tool`` can be used to specify the merge tool used for file
4823 merges. It overrides the HGMERGE environment variable and your
4828 merges. It overrides the HGMERGE environment variable and your
4824 configuration files. See :hg:`help merge-tools` for options.
4829 configuration files. See :hg:`help merge-tools` for options.
4825
4830
4826 If no revision is specified, the working directory's parent is a
4831 If no revision is specified, the working directory's parent is a
4827 head revision, and the current branch contains exactly one other
4832 head revision, and the current branch contains exactly one other
4828 head, the other head is merged with by default. Otherwise, an
4833 head, the other head is merged with by default. Otherwise, an
4829 explicit revision with which to merge must be provided.
4834 explicit revision with which to merge must be provided.
4830
4835
4831 See :hg:`help resolve` for information on handling file conflicts.
4836 See :hg:`help resolve` for information on handling file conflicts.
4832
4837
4833 To undo an uncommitted merge, use :hg:`merge --abort` which
4838 To undo an uncommitted merge, use :hg:`merge --abort` which
4834 will check out a clean copy of the original merge parent, losing
4839 will check out a clean copy of the original merge parent, losing
4835 all changes.
4840 all changes.
4836
4841
4837 Returns 0 on success, 1 if there are unresolved files.
4842 Returns 0 on success, 1 if there are unresolved files.
4838 """
4843 """
4839
4844
4840 opts = pycompat.byteskwargs(opts)
4845 opts = pycompat.byteskwargs(opts)
4841 abort = opts.get(b'abort')
4846 abort = opts.get(b'abort')
4842 if abort and repo.dirstate.p2() == nullid:
4847 if abort and repo.dirstate.p2() == nullid:
4843 cmdutil.wrongtooltocontinue(repo, _(b'merge'))
4848 cmdutil.wrongtooltocontinue(repo, _(b'merge'))
4844 if abort:
4849 if abort:
4845 state = cmdutil.getunfinishedstate(repo)
4850 state = cmdutil.getunfinishedstate(repo)
4846 if state and state._opname != b'merge':
4851 if state and state._opname != b'merge':
4847 raise error.Abort(
4852 raise error.Abort(
4848 _(b'cannot abort merge with %s in progress') % (state._opname),
4853 _(b'cannot abort merge with %s in progress') % (state._opname),
4849 hint=state.hint(),
4854 hint=state.hint(),
4850 )
4855 )
4851 if node:
4856 if node:
4852 raise error.Abort(_(b"cannot specify a node with --abort"))
4857 raise error.Abort(_(b"cannot specify a node with --abort"))
4853 if opts.get(b'rev'):
4858 if opts.get(b'rev'):
4854 raise error.Abort(_(b"cannot specify both --rev and --abort"))
4859 raise error.Abort(_(b"cannot specify both --rev and --abort"))
4855 if opts.get(b'preview'):
4860 if opts.get(b'preview'):
4856 raise error.Abort(_(b"cannot specify --preview with --abort"))
4861 raise error.Abort(_(b"cannot specify --preview with --abort"))
4857 if opts.get(b'rev') and node:
4862 if opts.get(b'rev') and node:
4858 raise error.Abort(_(b"please specify just one revision"))
4863 raise error.Abort(_(b"please specify just one revision"))
4859 if not node:
4864 if not node:
4860 node = opts.get(b'rev')
4865 node = opts.get(b'rev')
4861
4866
4862 if node:
4867 if node:
4863 node = scmutil.revsingle(repo, node).node()
4868 node = scmutil.revsingle(repo, node).node()
4864
4869
4865 if not node and not abort:
4870 if not node and not abort:
4866 node = repo[destutil.destmerge(repo)].node()
4871 node = repo[destutil.destmerge(repo)].node()
4867
4872
4868 if opts.get(b'preview'):
4873 if opts.get(b'preview'):
4869 # find nodes that are ancestors of p2 but not of p1
4874 # find nodes that are ancestors of p2 but not of p1
4870 p1 = repo.lookup(b'.')
4875 p1 = repo.lookup(b'.')
4871 p2 = node
4876 p2 = node
4872 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4877 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4873
4878
4874 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4879 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4875 for node in nodes:
4880 for node in nodes:
4876 displayer.show(repo[node])
4881 displayer.show(repo[node])
4877 displayer.close()
4882 displayer.close()
4878 return 0
4883 return 0
4879
4884
4880 # ui.forcemerge is an internal variable, do not document
4885 # ui.forcemerge is an internal variable, do not document
4881 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
4886 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
4882 with ui.configoverride(overrides, b'merge'):
4887 with ui.configoverride(overrides, b'merge'):
4883 force = opts.get(b'force')
4888 force = opts.get(b'force')
4884 labels = [b'working copy', b'merge rev']
4889 labels = [b'working copy', b'merge rev']
4885 return hg.merge(
4890 return hg.merge(
4886 repo,
4891 repo,
4887 node,
4892 node,
4888 force=force,
4893 force=force,
4889 mergeforce=force,
4894 mergeforce=force,
4890 labels=labels,
4895 labels=labels,
4891 abort=abort,
4896 abort=abort,
4892 )
4897 )
4893
4898
4894
4899
4895 statemod.addunfinished(
4900 statemod.addunfinished(
4896 b'merge',
4901 b'merge',
4897 fname=None,
4902 fname=None,
4898 clearable=True,
4903 clearable=True,
4899 allowcommit=True,
4904 allowcommit=True,
4900 cmdmsg=_(b'outstanding uncommitted merge'),
4905 cmdmsg=_(b'outstanding uncommitted merge'),
4901 abortfunc=hg.abortmerge,
4906 abortfunc=hg.abortmerge,
4902 statushint=_(
4907 statushint=_(
4903 b'To continue: hg commit\nTo abort: hg merge --abort'
4908 b'To continue: hg commit\nTo abort: hg merge --abort'
4904 ),
4909 ),
4905 cmdhint=_(b"use 'hg commit' or 'hg merge --abort'"),
4910 cmdhint=_(b"use 'hg commit' or 'hg merge --abort'"),
4906 )
4911 )
4907
4912
4908
4913
4909 @command(
4914 @command(
4910 b'outgoing|out',
4915 b'outgoing|out',
4911 [
4916 [
4912 (
4917 (
4913 b'f',
4918 b'f',
4914 b'force',
4919 b'force',
4915 None,
4920 None,
4916 _(b'run even when the destination is unrelated'),
4921 _(b'run even when the destination is unrelated'),
4917 ),
4922 ),
4918 (
4923 (
4919 b'r',
4924 b'r',
4920 b'rev',
4925 b'rev',
4921 [],
4926 [],
4922 _(b'a changeset intended to be included in the destination'),
4927 _(b'a changeset intended to be included in the destination'),
4923 _(b'REV'),
4928 _(b'REV'),
4924 ),
4929 ),
4925 (b'n', b'newest-first', None, _(b'show newest record first')),
4930 (b'n', b'newest-first', None, _(b'show newest record first')),
4926 (b'B', b'bookmarks', False, _(b'compare bookmarks')),
4931 (b'B', b'bookmarks', False, _(b'compare bookmarks')),
4927 (
4932 (
4928 b'b',
4933 b'b',
4929 b'branch',
4934 b'branch',
4930 [],
4935 [],
4931 _(b'a specific branch you would like to push'),
4936 _(b'a specific branch you would like to push'),
4932 _(b'BRANCH'),
4937 _(b'BRANCH'),
4933 ),
4938 ),
4934 ]
4939 ]
4935 + logopts
4940 + logopts
4936 + remoteopts
4941 + remoteopts
4937 + subrepoopts,
4942 + subrepoopts,
4938 _(b'[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4943 _(b'[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4939 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4944 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4940 )
4945 )
4941 def outgoing(ui, repo, dest=None, **opts):
4946 def outgoing(ui, repo, dest=None, **opts):
4942 """show changesets not found in the destination
4947 """show changesets not found in the destination
4943
4948
4944 Show changesets not found in the specified destination repository
4949 Show changesets not found in the specified destination repository
4945 or the default push location. These are the changesets that would
4950 or the default push location. These are the changesets that would
4946 be pushed if a push was requested.
4951 be pushed if a push was requested.
4947
4952
4948 See pull for details of valid destination formats.
4953 See pull for details of valid destination formats.
4949
4954
4950 .. container:: verbose
4955 .. container:: verbose
4951
4956
4952 With -B/--bookmarks, the result of bookmark comparison between
4957 With -B/--bookmarks, the result of bookmark comparison between
4953 local and remote repositories is displayed. With -v/--verbose,
4958 local and remote repositories is displayed. With -v/--verbose,
4954 status is also displayed for each bookmark like below::
4959 status is also displayed for each bookmark like below::
4955
4960
4956 BM1 01234567890a added
4961 BM1 01234567890a added
4957 BM2 deleted
4962 BM2 deleted
4958 BM3 234567890abc advanced
4963 BM3 234567890abc advanced
4959 BM4 34567890abcd diverged
4964 BM4 34567890abcd diverged
4960 BM5 4567890abcde changed
4965 BM5 4567890abcde changed
4961
4966
4962 The action taken when pushing depends on the
4967 The action taken when pushing depends on the
4963 status of each bookmark:
4968 status of each bookmark:
4964
4969
4965 :``added``: push with ``-B`` will create it
4970 :``added``: push with ``-B`` will create it
4966 :``deleted``: push with ``-B`` will delete it
4971 :``deleted``: push with ``-B`` will delete it
4967 :``advanced``: push will update it
4972 :``advanced``: push will update it
4968 :``diverged``: push with ``-B`` will update it
4973 :``diverged``: push with ``-B`` will update it
4969 :``changed``: push with ``-B`` will update it
4974 :``changed``: push with ``-B`` will update it
4970
4975
4971 From the point of view of pushing behavior, bookmarks
4976 From the point of view of pushing behavior, bookmarks
4972 existing only in the remote repository are treated as
4977 existing only in the remote repository are treated as
4973 ``deleted``, even if it is in fact added remotely.
4978 ``deleted``, even if it is in fact added remotely.
4974
4979
4975 Returns 0 if there are outgoing changes, 1 otherwise.
4980 Returns 0 if there are outgoing changes, 1 otherwise.
4976 """
4981 """
4977 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4982 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4978 # style URLs, so don't overwrite dest.
4983 # style URLs, so don't overwrite dest.
4979 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
4984 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
4980 if not path:
4985 if not path:
4981 raise error.Abort(
4986 raise error.Abort(
4982 _(b'default repository not configured!'),
4987 _(b'default repository not configured!'),
4983 hint=_(b"see 'hg help config.paths'"),
4988 hint=_(b"see 'hg help config.paths'"),
4984 )
4989 )
4985
4990
4986 opts = pycompat.byteskwargs(opts)
4991 opts = pycompat.byteskwargs(opts)
4987 if opts.get(b'graph'):
4992 if opts.get(b'graph'):
4988 logcmdutil.checkunsupportedgraphflags([], opts)
4993 logcmdutil.checkunsupportedgraphflags([], opts)
4989 o, other = hg._outgoing(ui, repo, dest, opts)
4994 o, other = hg._outgoing(ui, repo, dest, opts)
4990 if not o:
4995 if not o:
4991 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4996 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4992 return
4997 return
4993
4998
4994 revdag = logcmdutil.graphrevs(repo, o, opts)
4999 revdag = logcmdutil.graphrevs(repo, o, opts)
4995 ui.pager(b'outgoing')
5000 ui.pager(b'outgoing')
4996 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
5001 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4997 logcmdutil.displaygraph(
5002 logcmdutil.displaygraph(
4998 ui, repo, revdag, displayer, graphmod.asciiedges
5003 ui, repo, revdag, displayer, graphmod.asciiedges
4999 )
5004 )
5000 cmdutil.outgoinghooks(ui, repo, other, opts, o)
5005 cmdutil.outgoinghooks(ui, repo, other, opts, o)
5001 return 0
5006 return 0
5002
5007
5003 if opts.get(b'bookmarks'):
5008 if opts.get(b'bookmarks'):
5004 dest = path.pushloc or path.loc
5009 dest = path.pushloc or path.loc
5005 other = hg.peer(repo, opts, dest)
5010 other = hg.peer(repo, opts, dest)
5006 if b'bookmarks' not in other.listkeys(b'namespaces'):
5011 if b'bookmarks' not in other.listkeys(b'namespaces'):
5007 ui.warn(_(b"remote doesn't support bookmarks\n"))
5012 ui.warn(_(b"remote doesn't support bookmarks\n"))
5008 return 0
5013 return 0
5009 ui.status(_(b'comparing with %s\n') % util.hidepassword(dest))
5014 ui.status(_(b'comparing with %s\n') % util.hidepassword(dest))
5010 ui.pager(b'outgoing')
5015 ui.pager(b'outgoing')
5011 return bookmarks.outgoing(ui, repo, other)
5016 return bookmarks.outgoing(ui, repo, other)
5012
5017
5013 repo._subtoppath = path.pushloc or path.loc
5018 repo._subtoppath = path.pushloc or path.loc
5014 try:
5019 try:
5015 return hg.outgoing(ui, repo, dest, opts)
5020 return hg.outgoing(ui, repo, dest, opts)
5016 finally:
5021 finally:
5017 del repo._subtoppath
5022 del repo._subtoppath
5018
5023
5019
5024
5020 @command(
5025 @command(
5021 b'parents',
5026 b'parents',
5022 [
5027 [
5023 (
5028 (
5024 b'r',
5029 b'r',
5025 b'rev',
5030 b'rev',
5026 b'',
5031 b'',
5027 _(b'show parents of the specified revision'),
5032 _(b'show parents of the specified revision'),
5028 _(b'REV'),
5033 _(b'REV'),
5029 ),
5034 ),
5030 ]
5035 ]
5031 + templateopts,
5036 + templateopts,
5032 _(b'[-r REV] [FILE]'),
5037 _(b'[-r REV] [FILE]'),
5033 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
5038 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
5034 inferrepo=True,
5039 inferrepo=True,
5035 )
5040 )
5036 def parents(ui, repo, file_=None, **opts):
5041 def parents(ui, repo, file_=None, **opts):
5037 """show the parents of the working directory or revision (DEPRECATED)
5042 """show the parents of the working directory or revision (DEPRECATED)
5038
5043
5039 Print the working directory's parent revisions. If a revision is
5044 Print the working directory's parent revisions. If a revision is
5040 given via -r/--rev, the parent of that revision will be printed.
5045 given via -r/--rev, the parent of that revision will be printed.
5041 If a file argument is given, the revision in which the file was
5046 If a file argument is given, the revision in which the file was
5042 last changed (before the working directory revision or the
5047 last changed (before the working directory revision or the
5043 argument to --rev if given) is printed.
5048 argument to --rev if given) is printed.
5044
5049
5045 This command is equivalent to::
5050 This command is equivalent to::
5046
5051
5047 hg log -r "p1()+p2()" or
5052 hg log -r "p1()+p2()" or
5048 hg log -r "p1(REV)+p2(REV)" or
5053 hg log -r "p1(REV)+p2(REV)" or
5049 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
5054 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
5050 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
5055 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
5051
5056
5052 See :hg:`summary` and :hg:`help revsets` for related information.
5057 See :hg:`summary` and :hg:`help revsets` for related information.
5053
5058
5054 Returns 0 on success.
5059 Returns 0 on success.
5055 """
5060 """
5056
5061
5057 opts = pycompat.byteskwargs(opts)
5062 opts = pycompat.byteskwargs(opts)
5058 rev = opts.get(b'rev')
5063 rev = opts.get(b'rev')
5059 if rev:
5064 if rev:
5060 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
5065 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
5061 ctx = scmutil.revsingle(repo, rev, None)
5066 ctx = scmutil.revsingle(repo, rev, None)
5062
5067
5063 if file_:
5068 if file_:
5064 m = scmutil.match(ctx, (file_,), opts)
5069 m = scmutil.match(ctx, (file_,), opts)
5065 if m.anypats() or len(m.files()) != 1:
5070 if m.anypats() or len(m.files()) != 1:
5066 raise error.Abort(_(b'can only specify an explicit filename'))
5071 raise error.Abort(_(b'can only specify an explicit filename'))
5067 file_ = m.files()[0]
5072 file_ = m.files()[0]
5068 filenodes = []
5073 filenodes = []
5069 for cp in ctx.parents():
5074 for cp in ctx.parents():
5070 if not cp:
5075 if not cp:
5071 continue
5076 continue
5072 try:
5077 try:
5073 filenodes.append(cp.filenode(file_))
5078 filenodes.append(cp.filenode(file_))
5074 except error.LookupError:
5079 except error.LookupError:
5075 pass
5080 pass
5076 if not filenodes:
5081 if not filenodes:
5077 raise error.Abort(_(b"'%s' not found in manifest!") % file_)
5082 raise error.Abort(_(b"'%s' not found in manifest!") % file_)
5078 p = []
5083 p = []
5079 for fn in filenodes:
5084 for fn in filenodes:
5080 fctx = repo.filectx(file_, fileid=fn)
5085 fctx = repo.filectx(file_, fileid=fn)
5081 p.append(fctx.node())
5086 p.append(fctx.node())
5082 else:
5087 else:
5083 p = [cp.node() for cp in ctx.parents()]
5088 p = [cp.node() for cp in ctx.parents()]
5084
5089
5085 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5090 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5086 for n in p:
5091 for n in p:
5087 if n != nullid:
5092 if n != nullid:
5088 displayer.show(repo[n])
5093 displayer.show(repo[n])
5089 displayer.close()
5094 displayer.close()
5090
5095
5091
5096
5092 @command(
5097 @command(
5093 b'paths',
5098 b'paths',
5094 formatteropts,
5099 formatteropts,
5095 _(b'[NAME]'),
5100 _(b'[NAME]'),
5096 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5101 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5097 optionalrepo=True,
5102 optionalrepo=True,
5098 intents={INTENT_READONLY},
5103 intents={INTENT_READONLY},
5099 )
5104 )
5100 def paths(ui, repo, search=None, **opts):
5105 def paths(ui, repo, search=None, **opts):
5101 """show aliases for remote repositories
5106 """show aliases for remote repositories
5102
5107
5103 Show definition of symbolic path name NAME. If no name is given,
5108 Show definition of symbolic path name NAME. If no name is given,
5104 show definition of all available names.
5109 show definition of all available names.
5105
5110
5106 Option -q/--quiet suppresses all output when searching for NAME
5111 Option -q/--quiet suppresses all output when searching for NAME
5107 and shows only the path names when listing all definitions.
5112 and shows only the path names when listing all definitions.
5108
5113
5109 Path names are defined in the [paths] section of your
5114 Path names are defined in the [paths] section of your
5110 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5115 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5111 repository, ``.hg/hgrc`` is used, too.
5116 repository, ``.hg/hgrc`` is used, too.
5112
5117
5113 The path names ``default`` and ``default-push`` have a special
5118 The path names ``default`` and ``default-push`` have a special
5114 meaning. When performing a push or pull operation, they are used
5119 meaning. When performing a push or pull operation, they are used
5115 as fallbacks if no location is specified on the command-line.
5120 as fallbacks if no location is specified on the command-line.
5116 When ``default-push`` is set, it will be used for push and
5121 When ``default-push`` is set, it will be used for push and
5117 ``default`` will be used for pull; otherwise ``default`` is used
5122 ``default`` will be used for pull; otherwise ``default`` is used
5118 as the fallback for both. When cloning a repository, the clone
5123 as the fallback for both. When cloning a repository, the clone
5119 source is written as ``default`` in ``.hg/hgrc``.
5124 source is written as ``default`` in ``.hg/hgrc``.
5120
5125
5121 .. note::
5126 .. note::
5122
5127
5123 ``default`` and ``default-push`` apply to all inbound (e.g.
5128 ``default`` and ``default-push`` apply to all inbound (e.g.
5124 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
5129 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
5125 and :hg:`bundle`) operations.
5130 and :hg:`bundle`) operations.
5126
5131
5127 See :hg:`help urls` for more information.
5132 See :hg:`help urls` for more information.
5128
5133
5129 .. container:: verbose
5134 .. container:: verbose
5130
5135
5131 Template:
5136 Template:
5132
5137
5133 The following keywords are supported. See also :hg:`help templates`.
5138 The following keywords are supported. See also :hg:`help templates`.
5134
5139
5135 :name: String. Symbolic name of the path alias.
5140 :name: String. Symbolic name of the path alias.
5136 :pushurl: String. URL for push operations.
5141 :pushurl: String. URL for push operations.
5137 :url: String. URL or directory path for the other operations.
5142 :url: String. URL or directory path for the other operations.
5138
5143
5139 Returns 0 on success.
5144 Returns 0 on success.
5140 """
5145 """
5141
5146
5142 opts = pycompat.byteskwargs(opts)
5147 opts = pycompat.byteskwargs(opts)
5143 ui.pager(b'paths')
5148 ui.pager(b'paths')
5144 if search:
5149 if search:
5145 pathitems = [
5150 pathitems = [
5146 (name, path)
5151 (name, path)
5147 for name, path in pycompat.iteritems(ui.paths)
5152 for name, path in pycompat.iteritems(ui.paths)
5148 if name == search
5153 if name == search
5149 ]
5154 ]
5150 else:
5155 else:
5151 pathitems = sorted(pycompat.iteritems(ui.paths))
5156 pathitems = sorted(pycompat.iteritems(ui.paths))
5152
5157
5153 fm = ui.formatter(b'paths', opts)
5158 fm = ui.formatter(b'paths', opts)
5154 if fm.isplain():
5159 if fm.isplain():
5155 hidepassword = util.hidepassword
5160 hidepassword = util.hidepassword
5156 else:
5161 else:
5157 hidepassword = bytes
5162 hidepassword = bytes
5158 if ui.quiet:
5163 if ui.quiet:
5159 namefmt = b'%s\n'
5164 namefmt = b'%s\n'
5160 else:
5165 else:
5161 namefmt = b'%s = '
5166 namefmt = b'%s = '
5162 showsubopts = not search and not ui.quiet
5167 showsubopts = not search and not ui.quiet
5163
5168
5164 for name, path in pathitems:
5169 for name, path in pathitems:
5165 fm.startitem()
5170 fm.startitem()
5166 fm.condwrite(not search, b'name', namefmt, name)
5171 fm.condwrite(not search, b'name', namefmt, name)
5167 fm.condwrite(not ui.quiet, b'url', b'%s\n', hidepassword(path.rawloc))
5172 fm.condwrite(not ui.quiet, b'url', b'%s\n', hidepassword(path.rawloc))
5168 for subopt, value in sorted(path.suboptions.items()):
5173 for subopt, value in sorted(path.suboptions.items()):
5169 assert subopt not in (b'name', b'url')
5174 assert subopt not in (b'name', b'url')
5170 if showsubopts:
5175 if showsubopts:
5171 fm.plain(b'%s:%s = ' % (name, subopt))
5176 fm.plain(b'%s:%s = ' % (name, subopt))
5172 fm.condwrite(showsubopts, subopt, b'%s\n', value)
5177 fm.condwrite(showsubopts, subopt, b'%s\n', value)
5173
5178
5174 fm.end()
5179 fm.end()
5175
5180
5176 if search and not pathitems:
5181 if search and not pathitems:
5177 if not ui.quiet:
5182 if not ui.quiet:
5178 ui.warn(_(b"not found!\n"))
5183 ui.warn(_(b"not found!\n"))
5179 return 1
5184 return 1
5180 else:
5185 else:
5181 return 0
5186 return 0
5182
5187
5183
5188
5184 @command(
5189 @command(
5185 b'phase',
5190 b'phase',
5186 [
5191 [
5187 (b'p', b'public', False, _(b'set changeset phase to public')),
5192 (b'p', b'public', False, _(b'set changeset phase to public')),
5188 (b'd', b'draft', False, _(b'set changeset phase to draft')),
5193 (b'd', b'draft', False, _(b'set changeset phase to draft')),
5189 (b's', b'secret', False, _(b'set changeset phase to secret')),
5194 (b's', b'secret', False, _(b'set changeset phase to secret')),
5190 (b'f', b'force', False, _(b'allow to move boundary backward')),
5195 (b'f', b'force', False, _(b'allow to move boundary backward')),
5191 (b'r', b'rev', [], _(b'target revision'), _(b'REV')),
5196 (b'r', b'rev', [], _(b'target revision'), _(b'REV')),
5192 ],
5197 ],
5193 _(b'[-p|-d|-s] [-f] [-r] [REV...]'),
5198 _(b'[-p|-d|-s] [-f] [-r] [REV...]'),
5194 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5199 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5195 )
5200 )
5196 def phase(ui, repo, *revs, **opts):
5201 def phase(ui, repo, *revs, **opts):
5197 """set or show the current phase name
5202 """set or show the current phase name
5198
5203
5199 With no argument, show the phase name of the current revision(s).
5204 With no argument, show the phase name of the current revision(s).
5200
5205
5201 With one of -p/--public, -d/--draft or -s/--secret, change the
5206 With one of -p/--public, -d/--draft or -s/--secret, change the
5202 phase value of the specified revisions.
5207 phase value of the specified revisions.
5203
5208
5204 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
5209 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
5205 lower phase to a higher phase. Phases are ordered as follows::
5210 lower phase to a higher phase. Phases are ordered as follows::
5206
5211
5207 public < draft < secret
5212 public < draft < secret
5208
5213
5209 Returns 0 on success, 1 if some phases could not be changed.
5214 Returns 0 on success, 1 if some phases could not be changed.
5210
5215
5211 (For more information about the phases concept, see :hg:`help phases`.)
5216 (For more information about the phases concept, see :hg:`help phases`.)
5212 """
5217 """
5213 opts = pycompat.byteskwargs(opts)
5218 opts = pycompat.byteskwargs(opts)
5214 # search for a unique phase argument
5219 # search for a unique phase argument
5215 targetphase = None
5220 targetphase = None
5216 for idx, name in enumerate(phases.cmdphasenames):
5221 for idx, name in enumerate(phases.cmdphasenames):
5217 if opts[name]:
5222 if opts[name]:
5218 if targetphase is not None:
5223 if targetphase is not None:
5219 raise error.Abort(_(b'only one phase can be specified'))
5224 raise error.Abort(_(b'only one phase can be specified'))
5220 targetphase = idx
5225 targetphase = idx
5221
5226
5222 # look for specified revision
5227 # look for specified revision
5223 revs = list(revs)
5228 revs = list(revs)
5224 revs.extend(opts[b'rev'])
5229 revs.extend(opts[b'rev'])
5225 if not revs:
5230 if not revs:
5226 # display both parents as the second parent phase can influence
5231 # display both parents as the second parent phase can influence
5227 # the phase of a merge commit
5232 # the phase of a merge commit
5228 revs = [c.rev() for c in repo[None].parents()]
5233 revs = [c.rev() for c in repo[None].parents()]
5229
5234
5230 revs = scmutil.revrange(repo, revs)
5235 revs = scmutil.revrange(repo, revs)
5231
5236
5232 ret = 0
5237 ret = 0
5233 if targetphase is None:
5238 if targetphase is None:
5234 # display
5239 # display
5235 for r in revs:
5240 for r in revs:
5236 ctx = repo[r]
5241 ctx = repo[r]
5237 ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5242 ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5238 else:
5243 else:
5239 with repo.lock(), repo.transaction(b"phase") as tr:
5244 with repo.lock(), repo.transaction(b"phase") as tr:
5240 # set phase
5245 # set phase
5241 if not revs:
5246 if not revs:
5242 raise error.Abort(_(b'empty revision set'))
5247 raise error.Abort(_(b'empty revision set'))
5243 nodes = [repo[r].node() for r in revs]
5248 nodes = [repo[r].node() for r in revs]
5244 # moving revision from public to draft may hide them
5249 # moving revision from public to draft may hide them
5245 # We have to check result on an unfiltered repository
5250 # We have to check result on an unfiltered repository
5246 unfi = repo.unfiltered()
5251 unfi = repo.unfiltered()
5247 getphase = unfi._phasecache.phase
5252 getphase = unfi._phasecache.phase
5248 olddata = [getphase(unfi, r) for r in unfi]
5253 olddata = [getphase(unfi, r) for r in unfi]
5249 phases.advanceboundary(repo, tr, targetphase, nodes)
5254 phases.advanceboundary(repo, tr, targetphase, nodes)
5250 if opts[b'force']:
5255 if opts[b'force']:
5251 phases.retractboundary(repo, tr, targetphase, nodes)
5256 phases.retractboundary(repo, tr, targetphase, nodes)
5252 getphase = unfi._phasecache.phase
5257 getphase = unfi._phasecache.phase
5253 newdata = [getphase(unfi, r) for r in unfi]
5258 newdata = [getphase(unfi, r) for r in unfi]
5254 changes = sum(newdata[r] != olddata[r] for r in unfi)
5259 changes = sum(newdata[r] != olddata[r] for r in unfi)
5255 cl = unfi.changelog
5260 cl = unfi.changelog
5256 rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
5261 rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
5257 if rejected:
5262 if rejected:
5258 ui.warn(
5263 ui.warn(
5259 _(
5264 _(
5260 b'cannot move %i changesets to a higher '
5265 b'cannot move %i changesets to a higher '
5261 b'phase, use --force\n'
5266 b'phase, use --force\n'
5262 )
5267 )
5263 % len(rejected)
5268 % len(rejected)
5264 )
5269 )
5265 ret = 1
5270 ret = 1
5266 if changes:
5271 if changes:
5267 msg = _(b'phase changed for %i changesets\n') % changes
5272 msg = _(b'phase changed for %i changesets\n') % changes
5268 if ret:
5273 if ret:
5269 ui.status(msg)
5274 ui.status(msg)
5270 else:
5275 else:
5271 ui.note(msg)
5276 ui.note(msg)
5272 else:
5277 else:
5273 ui.warn(_(b'no phases changed\n'))
5278 ui.warn(_(b'no phases changed\n'))
5274 return ret
5279 return ret
5275
5280
5276
5281
5277 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
5282 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
5278 """Run after a changegroup has been added via pull/unbundle
5283 """Run after a changegroup has been added via pull/unbundle
5279
5284
5280 This takes arguments below:
5285 This takes arguments below:
5281
5286
5282 :modheads: change of heads by pull/unbundle
5287 :modheads: change of heads by pull/unbundle
5283 :optupdate: updating working directory is needed or not
5288 :optupdate: updating working directory is needed or not
5284 :checkout: update destination revision (or None to default destination)
5289 :checkout: update destination revision (or None to default destination)
5285 :brev: a name, which might be a bookmark to be activated after updating
5290 :brev: a name, which might be a bookmark to be activated after updating
5286 """
5291 """
5287 if modheads == 0:
5292 if modheads == 0:
5288 return
5293 return
5289 if optupdate:
5294 if optupdate:
5290 try:
5295 try:
5291 return hg.updatetotally(ui, repo, checkout, brev)
5296 return hg.updatetotally(ui, repo, checkout, brev)
5292 except error.UpdateAbort as inst:
5297 except error.UpdateAbort as inst:
5293 msg = _(b"not updating: %s") % stringutil.forcebytestr(inst)
5298 msg = _(b"not updating: %s") % stringutil.forcebytestr(inst)
5294 hint = inst.hint
5299 hint = inst.hint
5295 raise error.UpdateAbort(msg, hint=hint)
5300 raise error.UpdateAbort(msg, hint=hint)
5296 if modheads is not None and modheads > 1:
5301 if modheads is not None and modheads > 1:
5297 currentbranchheads = len(repo.branchheads())
5302 currentbranchheads = len(repo.branchheads())
5298 if currentbranchheads == modheads:
5303 if currentbranchheads == modheads:
5299 ui.status(
5304 ui.status(
5300 _(b"(run 'hg heads' to see heads, 'hg merge' to merge)\n")
5305 _(b"(run 'hg heads' to see heads, 'hg merge' to merge)\n")
5301 )
5306 )
5302 elif currentbranchheads > 1:
5307 elif currentbranchheads > 1:
5303 ui.status(
5308 ui.status(
5304 _(b"(run 'hg heads .' to see heads, 'hg merge' to merge)\n")
5309 _(b"(run 'hg heads .' to see heads, 'hg merge' to merge)\n")
5305 )
5310 )
5306 else:
5311 else:
5307 ui.status(_(b"(run 'hg heads' to see heads)\n"))
5312 ui.status(_(b"(run 'hg heads' to see heads)\n"))
5308 elif not ui.configbool(b'commands', b'update.requiredest'):
5313 elif not ui.configbool(b'commands', b'update.requiredest'):
5309 ui.status(_(b"(run 'hg update' to get a working copy)\n"))
5314 ui.status(_(b"(run 'hg update' to get a working copy)\n"))
5310
5315
5311
5316
5312 @command(
5317 @command(
5313 b'pull',
5318 b'pull',
5314 [
5319 [
5315 (
5320 (
5316 b'u',
5321 b'u',
5317 b'update',
5322 b'update',
5318 None,
5323 None,
5319 _(b'update to new branch head if new descendants were pulled'),
5324 _(b'update to new branch head if new descendants were pulled'),
5320 ),
5325 ),
5321 (
5326 (
5322 b'f',
5327 b'f',
5323 b'force',
5328 b'force',
5324 None,
5329 None,
5325 _(b'run even when remote repository is unrelated'),
5330 _(b'run even when remote repository is unrelated'),
5326 ),
5331 ),
5327 (
5332 (
5328 b'r',
5333 b'r',
5329 b'rev',
5334 b'rev',
5330 [],
5335 [],
5331 _(b'a remote changeset intended to be added'),
5336 _(b'a remote changeset intended to be added'),
5332 _(b'REV'),
5337 _(b'REV'),
5333 ),
5338 ),
5334 (b'B', b'bookmark', [], _(b"bookmark to pull"), _(b'BOOKMARK')),
5339 (b'B', b'bookmark', [], _(b"bookmark to pull"), _(b'BOOKMARK')),
5335 (
5340 (
5336 b'b',
5341 b'b',
5337 b'branch',
5342 b'branch',
5338 [],
5343 [],
5339 _(b'a specific branch you would like to pull'),
5344 _(b'a specific branch you would like to pull'),
5340 _(b'BRANCH'),
5345 _(b'BRANCH'),
5341 ),
5346 ),
5342 ]
5347 ]
5343 + remoteopts,
5348 + remoteopts,
5344 _(b'[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
5349 _(b'[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
5345 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5350 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5346 helpbasic=True,
5351 helpbasic=True,
5347 )
5352 )
5348 def pull(ui, repo, source=b"default", **opts):
5353 def pull(ui, repo, source=b"default", **opts):
5349 """pull changes from the specified source
5354 """pull changes from the specified source
5350
5355
5351 Pull changes from a remote repository to a local one.
5356 Pull changes from a remote repository to a local one.
5352
5357
5353 This finds all changes from the repository at the specified path
5358 This finds all changes from the repository at the specified path
5354 or URL and adds them to a local repository (the current one unless
5359 or URL and adds them to a local repository (the current one unless
5355 -R is specified). By default, this does not update the copy of the
5360 -R is specified). By default, this does not update the copy of the
5356 project in the working directory.
5361 project in the working directory.
5357
5362
5358 When cloning from servers that support it, Mercurial may fetch
5363 When cloning from servers that support it, Mercurial may fetch
5359 pre-generated data. When this is done, hooks operating on incoming
5364 pre-generated data. When this is done, hooks operating on incoming
5360 changesets and changegroups may fire more than once, once for each
5365 changesets and changegroups may fire more than once, once for each
5361 pre-generated bundle and as well as for any additional remaining
5366 pre-generated bundle and as well as for any additional remaining
5362 data. See :hg:`help -e clonebundles` for more.
5367 data. See :hg:`help -e clonebundles` for more.
5363
5368
5364 Use :hg:`incoming` if you want to see what would have been added
5369 Use :hg:`incoming` if you want to see what would have been added
5365 by a pull at the time you issued this command. If you then decide
5370 by a pull at the time you issued this command. If you then decide
5366 to add those changes to the repository, you should use :hg:`pull
5371 to add those changes to the repository, you should use :hg:`pull
5367 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5372 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5368
5373
5369 If SOURCE is omitted, the 'default' path will be used.
5374 If SOURCE is omitted, the 'default' path will be used.
5370 See :hg:`help urls` for more information.
5375 See :hg:`help urls` for more information.
5371
5376
5372 Specifying bookmark as ``.`` is equivalent to specifying the active
5377 Specifying bookmark as ``.`` is equivalent to specifying the active
5373 bookmark's name.
5378 bookmark's name.
5374
5379
5375 Returns 0 on success, 1 if an update had unresolved files.
5380 Returns 0 on success, 1 if an update had unresolved files.
5376 """
5381 """
5377
5382
5378 opts = pycompat.byteskwargs(opts)
5383 opts = pycompat.byteskwargs(opts)
5379 if ui.configbool(b'commands', b'update.requiredest') and opts.get(
5384 if ui.configbool(b'commands', b'update.requiredest') and opts.get(
5380 b'update'
5385 b'update'
5381 ):
5386 ):
5382 msg = _(b'update destination required by configuration')
5387 msg = _(b'update destination required by configuration')
5383 hint = _(b'use hg pull followed by hg update DEST')
5388 hint = _(b'use hg pull followed by hg update DEST')
5384 raise error.Abort(msg, hint=hint)
5389 raise error.Abort(msg, hint=hint)
5385
5390
5386 source, branches = hg.parseurl(ui.expandpath(source), opts.get(b'branch'))
5391 source, branches = hg.parseurl(ui.expandpath(source), opts.get(b'branch'))
5387 ui.status(_(b'pulling from %s\n') % util.hidepassword(source))
5392 ui.status(_(b'pulling from %s\n') % util.hidepassword(source))
5388 other = hg.peer(repo, opts, source)
5393 other = hg.peer(repo, opts, source)
5389 try:
5394 try:
5390 revs, checkout = hg.addbranchrevs(
5395 revs, checkout = hg.addbranchrevs(
5391 repo, other, branches, opts.get(b'rev')
5396 repo, other, branches, opts.get(b'rev')
5392 )
5397 )
5393
5398
5394 pullopargs = {}
5399 pullopargs = {}
5395
5400
5396 nodes = None
5401 nodes = None
5397 if opts.get(b'bookmark') or revs:
5402 if opts.get(b'bookmark') or revs:
5398 # The list of bookmark used here is the same used to actually update
5403 # The list of bookmark used here is the same used to actually update
5399 # the bookmark names, to avoid the race from issue 4689 and we do
5404 # the bookmark names, to avoid the race from issue 4689 and we do
5400 # all lookup and bookmark queries in one go so they see the same
5405 # all lookup and bookmark queries in one go so they see the same
5401 # version of the server state (issue 4700).
5406 # version of the server state (issue 4700).
5402 nodes = []
5407 nodes = []
5403 fnodes = []
5408 fnodes = []
5404 revs = revs or []
5409 revs = revs or []
5405 if revs and not other.capable(b'lookup'):
5410 if revs and not other.capable(b'lookup'):
5406 err = _(
5411 err = _(
5407 b"other repository doesn't support revision lookup, "
5412 b"other repository doesn't support revision lookup, "
5408 b"so a rev cannot be specified."
5413 b"so a rev cannot be specified."
5409 )
5414 )
5410 raise error.Abort(err)
5415 raise error.Abort(err)
5411 with other.commandexecutor() as e:
5416 with other.commandexecutor() as e:
5412 fremotebookmarks = e.callcommand(
5417 fremotebookmarks = e.callcommand(
5413 b'listkeys', {b'namespace': b'bookmarks'}
5418 b'listkeys', {b'namespace': b'bookmarks'}
5414 )
5419 )
5415 for r in revs:
5420 for r in revs:
5416 fnodes.append(e.callcommand(b'lookup', {b'key': r}))
5421 fnodes.append(e.callcommand(b'lookup', {b'key': r}))
5417 remotebookmarks = fremotebookmarks.result()
5422 remotebookmarks = fremotebookmarks.result()
5418 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
5423 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
5419 pullopargs[b'remotebookmarks'] = remotebookmarks
5424 pullopargs[b'remotebookmarks'] = remotebookmarks
5420 for b in opts.get(b'bookmark', []):
5425 for b in opts.get(b'bookmark', []):
5421 b = repo._bookmarks.expandname(b)
5426 b = repo._bookmarks.expandname(b)
5422 if b not in remotebookmarks:
5427 if b not in remotebookmarks:
5423 raise error.Abort(_(b'remote bookmark %s not found!') % b)
5428 raise error.Abort(_(b'remote bookmark %s not found!') % b)
5424 nodes.append(remotebookmarks[b])
5429 nodes.append(remotebookmarks[b])
5425 for i, rev in enumerate(revs):
5430 for i, rev in enumerate(revs):
5426 node = fnodes[i].result()
5431 node = fnodes[i].result()
5427 nodes.append(node)
5432 nodes.append(node)
5428 if rev == checkout:
5433 if rev == checkout:
5429 checkout = node
5434 checkout = node
5430
5435
5431 wlock = util.nullcontextmanager()
5436 wlock = util.nullcontextmanager()
5432 if opts.get(b'update'):
5437 if opts.get(b'update'):
5433 wlock = repo.wlock()
5438 wlock = repo.wlock()
5434 with wlock:
5439 with wlock:
5435 pullopargs.update(opts.get(b'opargs', {}))
5440 pullopargs.update(opts.get(b'opargs', {}))
5436 modheads = exchange.pull(
5441 modheads = exchange.pull(
5437 repo,
5442 repo,
5438 other,
5443 other,
5439 heads=nodes,
5444 heads=nodes,
5440 force=opts.get(b'force'),
5445 force=opts.get(b'force'),
5441 bookmarks=opts.get(b'bookmark', ()),
5446 bookmarks=opts.get(b'bookmark', ()),
5442 opargs=pullopargs,
5447 opargs=pullopargs,
5443 ).cgresult
5448 ).cgresult
5444
5449
5445 # brev is a name, which might be a bookmark to be activated at
5450 # brev is a name, which might be a bookmark to be activated at
5446 # the end of the update. In other words, it is an explicit
5451 # the end of the update. In other words, it is an explicit
5447 # destination of the update
5452 # destination of the update
5448 brev = None
5453 brev = None
5449
5454
5450 if checkout:
5455 if checkout:
5451 checkout = repo.unfiltered().changelog.rev(checkout)
5456 checkout = repo.unfiltered().changelog.rev(checkout)
5452
5457
5453 # order below depends on implementation of
5458 # order below depends on implementation of
5454 # hg.addbranchrevs(). opts['bookmark'] is ignored,
5459 # hg.addbranchrevs(). opts['bookmark'] is ignored,
5455 # because 'checkout' is determined without it.
5460 # because 'checkout' is determined without it.
5456 if opts.get(b'rev'):
5461 if opts.get(b'rev'):
5457 brev = opts[b'rev'][0]
5462 brev = opts[b'rev'][0]
5458 elif opts.get(b'branch'):
5463 elif opts.get(b'branch'):
5459 brev = opts[b'branch'][0]
5464 brev = opts[b'branch'][0]
5460 else:
5465 else:
5461 brev = branches[0]
5466 brev = branches[0]
5462 repo._subtoppath = source
5467 repo._subtoppath = source
5463 try:
5468 try:
5464 ret = postincoming(
5469 ret = postincoming(
5465 ui, repo, modheads, opts.get(b'update'), checkout, brev
5470 ui, repo, modheads, opts.get(b'update'), checkout, brev
5466 )
5471 )
5467 except error.FilteredRepoLookupError as exc:
5472 except error.FilteredRepoLookupError as exc:
5468 msg = _(b'cannot update to target: %s') % exc.args[0]
5473 msg = _(b'cannot update to target: %s') % exc.args[0]
5469 exc.args = (msg,) + exc.args[1:]
5474 exc.args = (msg,) + exc.args[1:]
5470 raise
5475 raise
5471 finally:
5476 finally:
5472 del repo._subtoppath
5477 del repo._subtoppath
5473
5478
5474 finally:
5479 finally:
5475 other.close()
5480 other.close()
5476 return ret
5481 return ret
5477
5482
5478
5483
5479 @command(
5484 @command(
5480 b'push',
5485 b'push',
5481 [
5486 [
5482 (b'f', b'force', None, _(b'force push')),
5487 (b'f', b'force', None, _(b'force push')),
5483 (
5488 (
5484 b'r',
5489 b'r',
5485 b'rev',
5490 b'rev',
5486 [],
5491 [],
5487 _(b'a changeset intended to be included in the destination'),
5492 _(b'a changeset intended to be included in the destination'),
5488 _(b'REV'),
5493 _(b'REV'),
5489 ),
5494 ),
5490 (b'B', b'bookmark', [], _(b"bookmark to push"), _(b'BOOKMARK')),
5495 (b'B', b'bookmark', [], _(b"bookmark to push"), _(b'BOOKMARK')),
5491 (
5496 (
5492 b'b',
5497 b'b',
5493 b'branch',
5498 b'branch',
5494 [],
5499 [],
5495 _(b'a specific branch you would like to push'),
5500 _(b'a specific branch you would like to push'),
5496 _(b'BRANCH'),
5501 _(b'BRANCH'),
5497 ),
5502 ),
5498 (b'', b'new-branch', False, _(b'allow pushing a new branch')),
5503 (b'', b'new-branch', False, _(b'allow pushing a new branch')),
5499 (
5504 (
5500 b'',
5505 b'',
5501 b'pushvars',
5506 b'pushvars',
5502 [],
5507 [],
5503 _(b'variables that can be sent to server (ADVANCED)'),
5508 _(b'variables that can be sent to server (ADVANCED)'),
5504 ),
5509 ),
5505 (
5510 (
5506 b'',
5511 b'',
5507 b'publish',
5512 b'publish',
5508 False,
5513 False,
5509 _(b'push the changeset as public (EXPERIMENTAL)'),
5514 _(b'push the changeset as public (EXPERIMENTAL)'),
5510 ),
5515 ),
5511 ]
5516 ]
5512 + remoteopts,
5517 + remoteopts,
5513 _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
5518 _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
5514 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5519 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5515 helpbasic=True,
5520 helpbasic=True,
5516 )
5521 )
5517 def push(ui, repo, dest=None, **opts):
5522 def push(ui, repo, dest=None, **opts):
5518 """push changes to the specified destination
5523 """push changes to the specified destination
5519
5524
5520 Push changesets from the local repository to the specified
5525 Push changesets from the local repository to the specified
5521 destination.
5526 destination.
5522
5527
5523 This operation is symmetrical to pull: it is identical to a pull
5528 This operation is symmetrical to pull: it is identical to a pull
5524 in the destination repository from the current one.
5529 in the destination repository from the current one.
5525
5530
5526 By default, push will not allow creation of new heads at the
5531 By default, push will not allow creation of new heads at the
5527 destination, since multiple heads would make it unclear which head
5532 destination, since multiple heads would make it unclear which head
5528 to use. In this situation, it is recommended to pull and merge
5533 to use. In this situation, it is recommended to pull and merge
5529 before pushing.
5534 before pushing.
5530
5535
5531 Use --new-branch if you want to allow push to create a new named
5536 Use --new-branch if you want to allow push to create a new named
5532 branch that is not present at the destination. This allows you to
5537 branch that is not present at the destination. This allows you to
5533 only create a new branch without forcing other changes.
5538 only create a new branch without forcing other changes.
5534
5539
5535 .. note::
5540 .. note::
5536
5541
5537 Extra care should be taken with the -f/--force option,
5542 Extra care should be taken with the -f/--force option,
5538 which will push all new heads on all branches, an action which will
5543 which will push all new heads on all branches, an action which will
5539 almost always cause confusion for collaborators.
5544 almost always cause confusion for collaborators.
5540
5545
5541 If -r/--rev is used, the specified revision and all its ancestors
5546 If -r/--rev is used, the specified revision and all its ancestors
5542 will be pushed to the remote repository.
5547 will be pushed to the remote repository.
5543
5548
5544 If -B/--bookmark is used, the specified bookmarked revision, its
5549 If -B/--bookmark is used, the specified bookmarked revision, its
5545 ancestors, and the bookmark will be pushed to the remote
5550 ancestors, and the bookmark will be pushed to the remote
5546 repository. Specifying ``.`` is equivalent to specifying the active
5551 repository. Specifying ``.`` is equivalent to specifying the active
5547 bookmark's name.
5552 bookmark's name.
5548
5553
5549 Please see :hg:`help urls` for important details about ``ssh://``
5554 Please see :hg:`help urls` for important details about ``ssh://``
5550 URLs. If DESTINATION is omitted, a default path will be used.
5555 URLs. If DESTINATION is omitted, a default path will be used.
5551
5556
5552 .. container:: verbose
5557 .. container:: verbose
5553
5558
5554 The --pushvars option sends strings to the server that become
5559 The --pushvars option sends strings to the server that become
5555 environment variables prepended with ``HG_USERVAR_``. For example,
5560 environment variables prepended with ``HG_USERVAR_``. For example,
5556 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
5561 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
5557 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
5562 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
5558
5563
5559 pushvars can provide for user-overridable hooks as well as set debug
5564 pushvars can provide for user-overridable hooks as well as set debug
5560 levels. One example is having a hook that blocks commits containing
5565 levels. One example is having a hook that blocks commits containing
5561 conflict markers, but enables the user to override the hook if the file
5566 conflict markers, but enables the user to override the hook if the file
5562 is using conflict markers for testing purposes or the file format has
5567 is using conflict markers for testing purposes or the file format has
5563 strings that look like conflict markers.
5568 strings that look like conflict markers.
5564
5569
5565 By default, servers will ignore `--pushvars`. To enable it add the
5570 By default, servers will ignore `--pushvars`. To enable it add the
5566 following to your configuration file::
5571 following to your configuration file::
5567
5572
5568 [push]
5573 [push]
5569 pushvars.server = true
5574 pushvars.server = true
5570
5575
5571 Returns 0 if push was successful, 1 if nothing to push.
5576 Returns 0 if push was successful, 1 if nothing to push.
5572 """
5577 """
5573
5578
5574 opts = pycompat.byteskwargs(opts)
5579 opts = pycompat.byteskwargs(opts)
5575 if opts.get(b'bookmark'):
5580 if opts.get(b'bookmark'):
5576 ui.setconfig(b'bookmarks', b'pushing', opts[b'bookmark'], b'push')
5581 ui.setconfig(b'bookmarks', b'pushing', opts[b'bookmark'], b'push')
5577 for b in opts[b'bookmark']:
5582 for b in opts[b'bookmark']:
5578 # translate -B options to -r so changesets get pushed
5583 # translate -B options to -r so changesets get pushed
5579 b = repo._bookmarks.expandname(b)
5584 b = repo._bookmarks.expandname(b)
5580 if b in repo._bookmarks:
5585 if b in repo._bookmarks:
5581 opts.setdefault(b'rev', []).append(b)
5586 opts.setdefault(b'rev', []).append(b)
5582 else:
5587 else:
5583 # if we try to push a deleted bookmark, translate it to null
5588 # if we try to push a deleted bookmark, translate it to null
5584 # this lets simultaneous -r, -b options continue working
5589 # this lets simultaneous -r, -b options continue working
5585 opts.setdefault(b'rev', []).append(b"null")
5590 opts.setdefault(b'rev', []).append(b"null")
5586
5591
5587 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
5592 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
5588 if not path:
5593 if not path:
5589 raise error.Abort(
5594 raise error.Abort(
5590 _(b'default repository not configured!'),
5595 _(b'default repository not configured!'),
5591 hint=_(b"see 'hg help config.paths'"),
5596 hint=_(b"see 'hg help config.paths'"),
5592 )
5597 )
5593 dest = path.pushloc or path.loc
5598 dest = path.pushloc or path.loc
5594 branches = (path.branch, opts.get(b'branch') or [])
5599 branches = (path.branch, opts.get(b'branch') or [])
5595 ui.status(_(b'pushing to %s\n') % util.hidepassword(dest))
5600 ui.status(_(b'pushing to %s\n') % util.hidepassword(dest))
5596 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get(b'rev'))
5601 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get(b'rev'))
5597 other = hg.peer(repo, opts, dest)
5602 other = hg.peer(repo, opts, dest)
5598
5603
5599 if revs:
5604 if revs:
5600 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
5605 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
5601 if not revs:
5606 if not revs:
5602 raise error.Abort(
5607 raise error.Abort(
5603 _(b"specified revisions evaluate to an empty set"),
5608 _(b"specified revisions evaluate to an empty set"),
5604 hint=_(b"use different revision arguments"),
5609 hint=_(b"use different revision arguments"),
5605 )
5610 )
5606 elif path.pushrev:
5611 elif path.pushrev:
5607 # It doesn't make any sense to specify ancestor revisions. So limit
5612 # It doesn't make any sense to specify ancestor revisions. So limit
5608 # to DAG heads to make discovery simpler.
5613 # to DAG heads to make discovery simpler.
5609 expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
5614 expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
5610 revs = scmutil.revrange(repo, [expr])
5615 revs = scmutil.revrange(repo, [expr])
5611 revs = [repo[rev].node() for rev in revs]
5616 revs = [repo[rev].node() for rev in revs]
5612 if not revs:
5617 if not revs:
5613 raise error.Abort(
5618 raise error.Abort(
5614 _(b'default push revset for path evaluates to an empty set')
5619 _(b'default push revset for path evaluates to an empty set')
5615 )
5620 )
5616 elif ui.configbool(b'commands', b'push.require-revs'):
5621 elif ui.configbool(b'commands', b'push.require-revs'):
5617 raise error.Abort(
5622 raise error.Abort(
5618 _(b'no revisions specified to push'),
5623 _(b'no revisions specified to push'),
5619 hint=_(b'did you mean "hg push -r ."?'),
5624 hint=_(b'did you mean "hg push -r ."?'),
5620 )
5625 )
5621
5626
5622 repo._subtoppath = dest
5627 repo._subtoppath = dest
5623 try:
5628 try:
5624 # push subrepos depth-first for coherent ordering
5629 # push subrepos depth-first for coherent ordering
5625 c = repo[b'.']
5630 c = repo[b'.']
5626 subs = c.substate # only repos that are committed
5631 subs = c.substate # only repos that are committed
5627 for s in sorted(subs):
5632 for s in sorted(subs):
5628 result = c.sub(s).push(opts)
5633 result = c.sub(s).push(opts)
5629 if result == 0:
5634 if result == 0:
5630 return not result
5635 return not result
5631 finally:
5636 finally:
5632 del repo._subtoppath
5637 del repo._subtoppath
5633
5638
5634 opargs = dict(opts.get(b'opargs', {})) # copy opargs since we may mutate it
5639 opargs = dict(opts.get(b'opargs', {})) # copy opargs since we may mutate it
5635 opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
5640 opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
5636
5641
5637 pushop = exchange.push(
5642 pushop = exchange.push(
5638 repo,
5643 repo,
5639 other,
5644 other,
5640 opts.get(b'force'),
5645 opts.get(b'force'),
5641 revs=revs,
5646 revs=revs,
5642 newbranch=opts.get(b'new_branch'),
5647 newbranch=opts.get(b'new_branch'),
5643 bookmarks=opts.get(b'bookmark', ()),
5648 bookmarks=opts.get(b'bookmark', ()),
5644 publish=opts.get(b'publish'),
5649 publish=opts.get(b'publish'),
5645 opargs=opargs,
5650 opargs=opargs,
5646 )
5651 )
5647
5652
5648 result = not pushop.cgresult
5653 result = not pushop.cgresult
5649
5654
5650 if pushop.bkresult is not None:
5655 if pushop.bkresult is not None:
5651 if pushop.bkresult == 2:
5656 if pushop.bkresult == 2:
5652 result = 2
5657 result = 2
5653 elif not result and pushop.bkresult:
5658 elif not result and pushop.bkresult:
5654 result = 2
5659 result = 2
5655
5660
5656 return result
5661 return result
5657
5662
5658
5663
5659 @command(
5664 @command(
5660 b'recover',
5665 b'recover',
5661 [(b'', b'verify', True, b"run `hg verify` after succesful recover"),],
5666 [(b'', b'verify', True, b"run `hg verify` after succesful recover"),],
5662 helpcategory=command.CATEGORY_MAINTENANCE,
5667 helpcategory=command.CATEGORY_MAINTENANCE,
5663 )
5668 )
5664 def recover(ui, repo, **opts):
5669 def recover(ui, repo, **opts):
5665 """roll back an interrupted transaction
5670 """roll back an interrupted transaction
5666
5671
5667 Recover from an interrupted commit or pull.
5672 Recover from an interrupted commit or pull.
5668
5673
5669 This command tries to fix the repository status after an
5674 This command tries to fix the repository status after an
5670 interrupted operation. It should only be necessary when Mercurial
5675 interrupted operation. It should only be necessary when Mercurial
5671 suggests it.
5676 suggests it.
5672
5677
5673 Returns 0 if successful, 1 if nothing to recover or verify fails.
5678 Returns 0 if successful, 1 if nothing to recover or verify fails.
5674 """
5679 """
5675 ret = repo.recover()
5680 ret = repo.recover()
5676 if ret:
5681 if ret:
5677 if opts[r'verify']:
5682 if opts[r'verify']:
5678 return hg.verify(repo)
5683 return hg.verify(repo)
5679 else:
5684 else:
5680 msg = _(
5685 msg = _(
5681 b"(verify step skipped, run `hg verify` to check your "
5686 b"(verify step skipped, run `hg verify` to check your "
5682 b"repository content)\n"
5687 b"repository content)\n"
5683 )
5688 )
5684 ui.warn(msg)
5689 ui.warn(msg)
5685 return 0
5690 return 0
5686 return 1
5691 return 1
5687
5692
5688
5693
5689 @command(
5694 @command(
5690 b'remove|rm',
5695 b'remove|rm',
5691 [
5696 [
5692 (b'A', b'after', None, _(b'record delete for missing files')),
5697 (b'A', b'after', None, _(b'record delete for missing files')),
5693 (b'f', b'force', None, _(b'forget added files, delete modified files')),
5698 (b'f', b'force', None, _(b'forget added files, delete modified files')),
5694 ]
5699 ]
5695 + subrepoopts
5700 + subrepoopts
5696 + walkopts
5701 + walkopts
5697 + dryrunopts,
5702 + dryrunopts,
5698 _(b'[OPTION]... FILE...'),
5703 _(b'[OPTION]... FILE...'),
5699 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5704 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5700 helpbasic=True,
5705 helpbasic=True,
5701 inferrepo=True,
5706 inferrepo=True,
5702 )
5707 )
5703 def remove(ui, repo, *pats, **opts):
5708 def remove(ui, repo, *pats, **opts):
5704 """remove the specified files on the next commit
5709 """remove the specified files on the next commit
5705
5710
5706 Schedule the indicated files for removal from the current branch.
5711 Schedule the indicated files for removal from the current branch.
5707
5712
5708 This command schedules the files to be removed at the next commit.
5713 This command schedules the files to be removed at the next commit.
5709 To undo a remove before that, see :hg:`revert`. To undo added
5714 To undo a remove before that, see :hg:`revert`. To undo added
5710 files, see :hg:`forget`.
5715 files, see :hg:`forget`.
5711
5716
5712 .. container:: verbose
5717 .. container:: verbose
5713
5718
5714 -A/--after can be used to remove only files that have already
5719 -A/--after can be used to remove only files that have already
5715 been deleted, -f/--force can be used to force deletion, and -Af
5720 been deleted, -f/--force can be used to force deletion, and -Af
5716 can be used to remove files from the next revision without
5721 can be used to remove files from the next revision without
5717 deleting them from the working directory.
5722 deleting them from the working directory.
5718
5723
5719 The following table details the behavior of remove for different
5724 The following table details the behavior of remove for different
5720 file states (columns) and option combinations (rows). The file
5725 file states (columns) and option combinations (rows). The file
5721 states are Added [A], Clean [C], Modified [M] and Missing [!]
5726 states are Added [A], Clean [C], Modified [M] and Missing [!]
5722 (as reported by :hg:`status`). The actions are Warn, Remove
5727 (as reported by :hg:`status`). The actions are Warn, Remove
5723 (from branch) and Delete (from disk):
5728 (from branch) and Delete (from disk):
5724
5729
5725 ========= == == == ==
5730 ========= == == == ==
5726 opt/state A C M !
5731 opt/state A C M !
5727 ========= == == == ==
5732 ========= == == == ==
5728 none W RD W R
5733 none W RD W R
5729 -f R RD RD R
5734 -f R RD RD R
5730 -A W W W R
5735 -A W W W R
5731 -Af R R R R
5736 -Af R R R R
5732 ========= == == == ==
5737 ========= == == == ==
5733
5738
5734 .. note::
5739 .. note::
5735
5740
5736 :hg:`remove` never deletes files in Added [A] state from the
5741 :hg:`remove` never deletes files in Added [A] state from the
5737 working directory, not even if ``--force`` is specified.
5742 working directory, not even if ``--force`` is specified.
5738
5743
5739 Returns 0 on success, 1 if any warnings encountered.
5744 Returns 0 on success, 1 if any warnings encountered.
5740 """
5745 """
5741
5746
5742 opts = pycompat.byteskwargs(opts)
5747 opts = pycompat.byteskwargs(opts)
5743 after, force = opts.get(b'after'), opts.get(b'force')
5748 after, force = opts.get(b'after'), opts.get(b'force')
5744 dryrun = opts.get(b'dry_run')
5749 dryrun = opts.get(b'dry_run')
5745 if not pats and not after:
5750 if not pats and not after:
5746 raise error.Abort(_(b'no files specified'))
5751 raise error.Abort(_(b'no files specified'))
5747
5752
5748 m = scmutil.match(repo[None], pats, opts)
5753 m = scmutil.match(repo[None], pats, opts)
5749 subrepos = opts.get(b'subrepos')
5754 subrepos = opts.get(b'subrepos')
5750 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
5755 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
5751 return cmdutil.remove(
5756 return cmdutil.remove(
5752 ui, repo, m, b"", uipathfn, after, force, subrepos, dryrun=dryrun
5757 ui, repo, m, b"", uipathfn, after, force, subrepos, dryrun=dryrun
5753 )
5758 )
5754
5759
5755
5760
5756 @command(
5761 @command(
5757 b'rename|move|mv',
5762 b'rename|move|mv',
5758 [
5763 [
5759 (b'A', b'after', None, _(b'record a rename that has already occurred')),
5764 (b'A', b'after', None, _(b'record a rename that has already occurred')),
5760 (
5765 (
5761 b'f',
5766 b'f',
5762 b'force',
5767 b'force',
5763 None,
5768 None,
5764 _(b'forcibly move over an existing managed file'),
5769 _(b'forcibly move over an existing managed file'),
5765 ),
5770 ),
5766 ]
5771 ]
5767 + walkopts
5772 + walkopts
5768 + dryrunopts,
5773 + dryrunopts,
5769 _(b'[OPTION]... SOURCE... DEST'),
5774 _(b'[OPTION]... SOURCE... DEST'),
5770 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5775 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5771 )
5776 )
5772 def rename(ui, repo, *pats, **opts):
5777 def rename(ui, repo, *pats, **opts):
5773 """rename files; equivalent of copy + remove
5778 """rename files; equivalent of copy + remove
5774
5779
5775 Mark dest as copies of sources; mark sources for deletion. If dest
5780 Mark dest as copies of sources; mark sources for deletion. If dest
5776 is a directory, copies are put in that directory. If dest is a
5781 is a directory, copies are put in that directory. If dest is a
5777 file, there can only be one source.
5782 file, there can only be one source.
5778
5783
5779 By default, this command copies the contents of files as they
5784 By default, this command copies the contents of files as they
5780 exist in the working directory. If invoked with -A/--after, the
5785 exist in the working directory. If invoked with -A/--after, the
5781 operation is recorded, but no copying is performed.
5786 operation is recorded, but no copying is performed.
5782
5787
5783 This command takes effect at the next commit. To undo a rename
5788 This command takes effect at the next commit. To undo a rename
5784 before that, see :hg:`revert`.
5789 before that, see :hg:`revert`.
5785
5790
5786 Returns 0 on success, 1 if errors are encountered.
5791 Returns 0 on success, 1 if errors are encountered.
5787 """
5792 """
5788 opts = pycompat.byteskwargs(opts)
5793 opts = pycompat.byteskwargs(opts)
5789 with repo.wlock(False):
5794 with repo.wlock(False):
5790 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5795 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5791
5796
5792
5797
5793 @command(
5798 @command(
5794 b'resolve',
5799 b'resolve',
5795 [
5800 [
5796 (b'a', b'all', None, _(b'select all unresolved files')),
5801 (b'a', b'all', None, _(b'select all unresolved files')),
5797 (b'l', b'list', None, _(b'list state of files needing merge')),
5802 (b'l', b'list', None, _(b'list state of files needing merge')),
5798 (b'm', b'mark', None, _(b'mark files as resolved')),
5803 (b'm', b'mark', None, _(b'mark files as resolved')),
5799 (b'u', b'unmark', None, _(b'mark files as unresolved')),
5804 (b'u', b'unmark', None, _(b'mark files as unresolved')),
5800 (b'n', b'no-status', None, _(b'hide status prefix')),
5805 (b'n', b'no-status', None, _(b'hide status prefix')),
5801 (b'', b're-merge', None, _(b're-merge files')),
5806 (b'', b're-merge', None, _(b're-merge files')),
5802 ]
5807 ]
5803 + mergetoolopts
5808 + mergetoolopts
5804 + walkopts
5809 + walkopts
5805 + formatteropts,
5810 + formatteropts,
5806 _(b'[OPTION]... [FILE]...'),
5811 _(b'[OPTION]... [FILE]...'),
5807 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5812 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5808 inferrepo=True,
5813 inferrepo=True,
5809 )
5814 )
5810 def resolve(ui, repo, *pats, **opts):
5815 def resolve(ui, repo, *pats, **opts):
5811 """redo merges or set/view the merge status of files
5816 """redo merges or set/view the merge status of files
5812
5817
5813 Merges with unresolved conflicts are often the result of
5818 Merges with unresolved conflicts are often the result of
5814 non-interactive merging using the ``internal:merge`` configuration
5819 non-interactive merging using the ``internal:merge`` configuration
5815 setting, or a command-line merge tool like ``diff3``. The resolve
5820 setting, or a command-line merge tool like ``diff3``. The resolve
5816 command is used to manage the files involved in a merge, after
5821 command is used to manage the files involved in a merge, after
5817 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5822 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5818 working directory must have two parents). See :hg:`help
5823 working directory must have two parents). See :hg:`help
5819 merge-tools` for information on configuring merge tools.
5824 merge-tools` for information on configuring merge tools.
5820
5825
5821 The resolve command can be used in the following ways:
5826 The resolve command can be used in the following ways:
5822
5827
5823 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
5828 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
5824 the specified files, discarding any previous merge attempts. Re-merging
5829 the specified files, discarding any previous merge attempts. Re-merging
5825 is not performed for files already marked as resolved. Use ``--all/-a``
5830 is not performed for files already marked as resolved. Use ``--all/-a``
5826 to select all unresolved files. ``--tool`` can be used to specify
5831 to select all unresolved files. ``--tool`` can be used to specify
5827 the merge tool used for the given files. It overrides the HGMERGE
5832 the merge tool used for the given files. It overrides the HGMERGE
5828 environment variable and your configuration files. Previous file
5833 environment variable and your configuration files. Previous file
5829 contents are saved with a ``.orig`` suffix.
5834 contents are saved with a ``.orig`` suffix.
5830
5835
5831 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5836 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5832 (e.g. after having manually fixed-up the files). The default is
5837 (e.g. after having manually fixed-up the files). The default is
5833 to mark all unresolved files.
5838 to mark all unresolved files.
5834
5839
5835 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5840 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5836 default is to mark all resolved files.
5841 default is to mark all resolved files.
5837
5842
5838 - :hg:`resolve -l`: list files which had or still have conflicts.
5843 - :hg:`resolve -l`: list files which had or still have conflicts.
5839 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5844 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5840 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
5845 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
5841 the list. See :hg:`help filesets` for details.
5846 the list. See :hg:`help filesets` for details.
5842
5847
5843 .. note::
5848 .. note::
5844
5849
5845 Mercurial will not let you commit files with unresolved merge
5850 Mercurial will not let you commit files with unresolved merge
5846 conflicts. You must use :hg:`resolve -m ...` before you can
5851 conflicts. You must use :hg:`resolve -m ...` before you can
5847 commit after a conflicting merge.
5852 commit after a conflicting merge.
5848
5853
5849 .. container:: verbose
5854 .. container:: verbose
5850
5855
5851 Template:
5856 Template:
5852
5857
5853 The following keywords are supported in addition to the common template
5858 The following keywords are supported in addition to the common template
5854 keywords and functions. See also :hg:`help templates`.
5859 keywords and functions. See also :hg:`help templates`.
5855
5860
5856 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
5861 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
5857 :path: String. Repository-absolute path of the file.
5862 :path: String. Repository-absolute path of the file.
5858
5863
5859 Returns 0 on success, 1 if any files fail a resolve attempt.
5864 Returns 0 on success, 1 if any files fail a resolve attempt.
5860 """
5865 """
5861
5866
5862 opts = pycompat.byteskwargs(opts)
5867 opts = pycompat.byteskwargs(opts)
5863 confirm = ui.configbool(b'commands', b'resolve.confirm')
5868 confirm = ui.configbool(b'commands', b'resolve.confirm')
5864 flaglist = b'all mark unmark list no_status re_merge'.split()
5869 flaglist = b'all mark unmark list no_status re_merge'.split()
5865 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
5870 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
5866
5871
5867 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
5872 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
5868 if actioncount > 1:
5873 if actioncount > 1:
5869 raise error.Abort(_(b"too many actions specified"))
5874 raise error.Abort(_(b"too many actions specified"))
5870 elif actioncount == 0 and ui.configbool(
5875 elif actioncount == 0 and ui.configbool(
5871 b'commands', b'resolve.explicit-re-merge'
5876 b'commands', b'resolve.explicit-re-merge'
5872 ):
5877 ):
5873 hint = _(b'use --mark, --unmark, --list or --re-merge')
5878 hint = _(b'use --mark, --unmark, --list or --re-merge')
5874 raise error.Abort(_(b'no action specified'), hint=hint)
5879 raise error.Abort(_(b'no action specified'), hint=hint)
5875 if pats and all:
5880 if pats and all:
5876 raise error.Abort(_(b"can't specify --all and patterns"))
5881 raise error.Abort(_(b"can't specify --all and patterns"))
5877 if not (all or pats or show or mark or unmark):
5882 if not (all or pats or show or mark or unmark):
5878 raise error.Abort(
5883 raise error.Abort(
5879 _(b'no files or directories specified'),
5884 _(b'no files or directories specified'),
5880 hint=b'use --all to re-merge all unresolved files',
5885 hint=b'use --all to re-merge all unresolved files',
5881 )
5886 )
5882
5887
5883 if confirm:
5888 if confirm:
5884 if all:
5889 if all:
5885 if ui.promptchoice(
5890 if ui.promptchoice(
5886 _(b're-merge all unresolved files (yn)?$$ &Yes $$ &No')
5891 _(b're-merge all unresolved files (yn)?$$ &Yes $$ &No')
5887 ):
5892 ):
5888 raise error.Abort(_(b'user quit'))
5893 raise error.Abort(_(b'user quit'))
5889 if mark and not pats:
5894 if mark and not pats:
5890 if ui.promptchoice(
5895 if ui.promptchoice(
5891 _(
5896 _(
5892 b'mark all unresolved files as resolved (yn)?'
5897 b'mark all unresolved files as resolved (yn)?'
5893 b'$$ &Yes $$ &No'
5898 b'$$ &Yes $$ &No'
5894 )
5899 )
5895 ):
5900 ):
5896 raise error.Abort(_(b'user quit'))
5901 raise error.Abort(_(b'user quit'))
5897 if unmark and not pats:
5902 if unmark and not pats:
5898 if ui.promptchoice(
5903 if ui.promptchoice(
5899 _(
5904 _(
5900 b'mark all resolved files as unresolved (yn)?'
5905 b'mark all resolved files as unresolved (yn)?'
5901 b'$$ &Yes $$ &No'
5906 b'$$ &Yes $$ &No'
5902 )
5907 )
5903 ):
5908 ):
5904 raise error.Abort(_(b'user quit'))
5909 raise error.Abort(_(b'user quit'))
5905
5910
5906 uipathfn = scmutil.getuipathfn(repo)
5911 uipathfn = scmutil.getuipathfn(repo)
5907
5912
5908 if show:
5913 if show:
5909 ui.pager(b'resolve')
5914 ui.pager(b'resolve')
5910 fm = ui.formatter(b'resolve', opts)
5915 fm = ui.formatter(b'resolve', opts)
5911 ms = mergemod.mergestate.read(repo)
5916 ms = mergemod.mergestate.read(repo)
5912 wctx = repo[None]
5917 wctx = repo[None]
5913 m = scmutil.match(wctx, pats, opts)
5918 m = scmutil.match(wctx, pats, opts)
5914
5919
5915 # Labels and keys based on merge state. Unresolved path conflicts show
5920 # Labels and keys based on merge state. Unresolved path conflicts show
5916 # as 'P'. Resolved path conflicts show as 'R', the same as normal
5921 # as 'P'. Resolved path conflicts show as 'R', the same as normal
5917 # resolved conflicts.
5922 # resolved conflicts.
5918 mergestateinfo = {
5923 mergestateinfo = {
5919 mergemod.MERGE_RECORD_UNRESOLVED: (b'resolve.unresolved', b'U'),
5924 mergemod.MERGE_RECORD_UNRESOLVED: (b'resolve.unresolved', b'U'),
5920 mergemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
5925 mergemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
5921 mergemod.MERGE_RECORD_UNRESOLVED_PATH: (
5926 mergemod.MERGE_RECORD_UNRESOLVED_PATH: (
5922 b'resolve.unresolved',
5927 b'resolve.unresolved',
5923 b'P',
5928 b'P',
5924 ),
5929 ),
5925 mergemod.MERGE_RECORD_RESOLVED_PATH: (b'resolve.resolved', b'R'),
5930 mergemod.MERGE_RECORD_RESOLVED_PATH: (b'resolve.resolved', b'R'),
5926 mergemod.MERGE_RECORD_DRIVER_RESOLVED: (
5931 mergemod.MERGE_RECORD_DRIVER_RESOLVED: (
5927 b'resolve.driverresolved',
5932 b'resolve.driverresolved',
5928 b'D',
5933 b'D',
5929 ),
5934 ),
5930 }
5935 }
5931
5936
5932 for f in ms:
5937 for f in ms:
5933 if not m(f):
5938 if not m(f):
5934 continue
5939 continue
5935
5940
5936 label, key = mergestateinfo[ms[f]]
5941 label, key = mergestateinfo[ms[f]]
5937 fm.startitem()
5942 fm.startitem()
5938 fm.context(ctx=wctx)
5943 fm.context(ctx=wctx)
5939 fm.condwrite(not nostatus, b'mergestatus', b'%s ', key, label=label)
5944 fm.condwrite(not nostatus, b'mergestatus', b'%s ', key, label=label)
5940 fm.data(path=f)
5945 fm.data(path=f)
5941 fm.plain(b'%s\n' % uipathfn(f), label=label)
5946 fm.plain(b'%s\n' % uipathfn(f), label=label)
5942 fm.end()
5947 fm.end()
5943 return 0
5948 return 0
5944
5949
5945 with repo.wlock():
5950 with repo.wlock():
5946 ms = mergemod.mergestate.read(repo)
5951 ms = mergemod.mergestate.read(repo)
5947
5952
5948 if not (ms.active() or repo.dirstate.p2() != nullid):
5953 if not (ms.active() or repo.dirstate.p2() != nullid):
5949 raise error.Abort(
5954 raise error.Abort(
5950 _(b'resolve command not applicable when not merging')
5955 _(b'resolve command not applicable when not merging')
5951 )
5956 )
5952
5957
5953 wctx = repo[None]
5958 wctx = repo[None]
5954
5959
5955 if (
5960 if (
5956 ms.mergedriver
5961 ms.mergedriver
5957 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED
5962 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED
5958 ):
5963 ):
5959 proceed = mergemod.driverpreprocess(repo, ms, wctx)
5964 proceed = mergemod.driverpreprocess(repo, ms, wctx)
5960 ms.commit()
5965 ms.commit()
5961 # allow mark and unmark to go through
5966 # allow mark and unmark to go through
5962 if not mark and not unmark and not proceed:
5967 if not mark and not unmark and not proceed:
5963 return 1
5968 return 1
5964
5969
5965 m = scmutil.match(wctx, pats, opts)
5970 m = scmutil.match(wctx, pats, opts)
5966 ret = 0
5971 ret = 0
5967 didwork = False
5972 didwork = False
5968 runconclude = False
5973 runconclude = False
5969
5974
5970 tocomplete = []
5975 tocomplete = []
5971 hasconflictmarkers = []
5976 hasconflictmarkers = []
5972 if mark:
5977 if mark:
5973 markcheck = ui.config(b'commands', b'resolve.mark-check')
5978 markcheck = ui.config(b'commands', b'resolve.mark-check')
5974 if markcheck not in [b'warn', b'abort']:
5979 if markcheck not in [b'warn', b'abort']:
5975 # Treat all invalid / unrecognized values as 'none'.
5980 # Treat all invalid / unrecognized values as 'none'.
5976 markcheck = False
5981 markcheck = False
5977 for f in ms:
5982 for f in ms:
5978 if not m(f):
5983 if not m(f):
5979 continue
5984 continue
5980
5985
5981 didwork = True
5986 didwork = True
5982
5987
5983 # don't let driver-resolved files be marked, and run the conclude
5988 # don't let driver-resolved files be marked, and run the conclude
5984 # step if asked to resolve
5989 # step if asked to resolve
5985 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
5990 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
5986 exact = m.exact(f)
5991 exact = m.exact(f)
5987 if mark:
5992 if mark:
5988 if exact:
5993 if exact:
5989 ui.warn(
5994 ui.warn(
5990 _(b'not marking %s as it is driver-resolved\n')
5995 _(b'not marking %s as it is driver-resolved\n')
5991 % uipathfn(f)
5996 % uipathfn(f)
5992 )
5997 )
5993 elif unmark:
5998 elif unmark:
5994 if exact:
5999 if exact:
5995 ui.warn(
6000 ui.warn(
5996 _(b'not unmarking %s as it is driver-resolved\n')
6001 _(b'not unmarking %s as it is driver-resolved\n')
5997 % uipathfn(f)
6002 % uipathfn(f)
5998 )
6003 )
5999 else:
6004 else:
6000 runconclude = True
6005 runconclude = True
6001 continue
6006 continue
6002
6007
6003 # path conflicts must be resolved manually
6008 # path conflicts must be resolved manually
6004 if ms[f] in (
6009 if ms[f] in (
6005 mergemod.MERGE_RECORD_UNRESOLVED_PATH,
6010 mergemod.MERGE_RECORD_UNRESOLVED_PATH,
6006 mergemod.MERGE_RECORD_RESOLVED_PATH,
6011 mergemod.MERGE_RECORD_RESOLVED_PATH,
6007 ):
6012 ):
6008 if mark:
6013 if mark:
6009 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
6014 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
6010 elif unmark:
6015 elif unmark:
6011 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
6016 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
6012 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
6017 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
6013 ui.warn(
6018 ui.warn(
6014 _(b'%s: path conflict must be resolved manually\n')
6019 _(b'%s: path conflict must be resolved manually\n')
6015 % uipathfn(f)
6020 % uipathfn(f)
6016 )
6021 )
6017 continue
6022 continue
6018
6023
6019 if mark:
6024 if mark:
6020 if markcheck:
6025 if markcheck:
6021 fdata = repo.wvfs.tryread(f)
6026 fdata = repo.wvfs.tryread(f)
6022 if (
6027 if (
6023 filemerge.hasconflictmarkers(fdata)
6028 filemerge.hasconflictmarkers(fdata)
6024 and ms[f] != mergemod.MERGE_RECORD_RESOLVED
6029 and ms[f] != mergemod.MERGE_RECORD_RESOLVED
6025 ):
6030 ):
6026 hasconflictmarkers.append(f)
6031 hasconflictmarkers.append(f)
6027 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
6032 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
6028 elif unmark:
6033 elif unmark:
6029 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
6034 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
6030 else:
6035 else:
6031 # backup pre-resolve (merge uses .orig for its own purposes)
6036 # backup pre-resolve (merge uses .orig for its own purposes)
6032 a = repo.wjoin(f)
6037 a = repo.wjoin(f)
6033 try:
6038 try:
6034 util.copyfile(a, a + b".resolve")
6039 util.copyfile(a, a + b".resolve")
6035 except (IOError, OSError) as inst:
6040 except (IOError, OSError) as inst:
6036 if inst.errno != errno.ENOENT:
6041 if inst.errno != errno.ENOENT:
6037 raise
6042 raise
6038
6043
6039 try:
6044 try:
6040 # preresolve file
6045 # preresolve file
6041 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
6046 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
6042 with ui.configoverride(overrides, b'resolve'):
6047 with ui.configoverride(overrides, b'resolve'):
6043 complete, r = ms.preresolve(f, wctx)
6048 complete, r = ms.preresolve(f, wctx)
6044 if not complete:
6049 if not complete:
6045 tocomplete.append(f)
6050 tocomplete.append(f)
6046 elif r:
6051 elif r:
6047 ret = 1
6052 ret = 1
6048 finally:
6053 finally:
6049 ms.commit()
6054 ms.commit()
6050
6055
6051 # replace filemerge's .orig file with our resolve file, but only
6056 # replace filemerge's .orig file with our resolve file, but only
6052 # for merges that are complete
6057 # for merges that are complete
6053 if complete:
6058 if complete:
6054 try:
6059 try:
6055 util.rename(
6060 util.rename(
6056 a + b".resolve", scmutil.backuppath(ui, repo, f)
6061 a + b".resolve", scmutil.backuppath(ui, repo, f)
6057 )
6062 )
6058 except OSError as inst:
6063 except OSError as inst:
6059 if inst.errno != errno.ENOENT:
6064 if inst.errno != errno.ENOENT:
6060 raise
6065 raise
6061
6066
6062 if hasconflictmarkers:
6067 if hasconflictmarkers:
6063 ui.warn(
6068 ui.warn(
6064 _(
6069 _(
6065 b'warning: the following files still have conflict '
6070 b'warning: the following files still have conflict '
6066 b'markers:\n'
6071 b'markers:\n'
6067 )
6072 )
6068 + b''.join(
6073 + b''.join(
6069 b' ' + uipathfn(f) + b'\n' for f in hasconflictmarkers
6074 b' ' + uipathfn(f) + b'\n' for f in hasconflictmarkers
6070 )
6075 )
6071 )
6076 )
6072 if markcheck == b'abort' and not all and not pats:
6077 if markcheck == b'abort' and not all and not pats:
6073 raise error.Abort(
6078 raise error.Abort(
6074 _(b'conflict markers detected'),
6079 _(b'conflict markers detected'),
6075 hint=_(b'use --all to mark anyway'),
6080 hint=_(b'use --all to mark anyway'),
6076 )
6081 )
6077
6082
6078 for f in tocomplete:
6083 for f in tocomplete:
6079 try:
6084 try:
6080 # resolve file
6085 # resolve file
6081 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
6086 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
6082 with ui.configoverride(overrides, b'resolve'):
6087 with ui.configoverride(overrides, b'resolve'):
6083 r = ms.resolve(f, wctx)
6088 r = ms.resolve(f, wctx)
6084 if r:
6089 if r:
6085 ret = 1
6090 ret = 1
6086 finally:
6091 finally:
6087 ms.commit()
6092 ms.commit()
6088
6093
6089 # replace filemerge's .orig file with our resolve file
6094 # replace filemerge's .orig file with our resolve file
6090 a = repo.wjoin(f)
6095 a = repo.wjoin(f)
6091 try:
6096 try:
6092 util.rename(a + b".resolve", scmutil.backuppath(ui, repo, f))
6097 util.rename(a + b".resolve", scmutil.backuppath(ui, repo, f))
6093 except OSError as inst:
6098 except OSError as inst:
6094 if inst.errno != errno.ENOENT:
6099 if inst.errno != errno.ENOENT:
6095 raise
6100 raise
6096
6101
6097 ms.commit()
6102 ms.commit()
6098 ms.recordactions()
6103 ms.recordactions()
6099
6104
6100 if not didwork and pats:
6105 if not didwork and pats:
6101 hint = None
6106 hint = None
6102 if not any([p for p in pats if p.find(b':') >= 0]):
6107 if not any([p for p in pats if p.find(b':') >= 0]):
6103 pats = [b'path:%s' % p for p in pats]
6108 pats = [b'path:%s' % p for p in pats]
6104 m = scmutil.match(wctx, pats, opts)
6109 m = scmutil.match(wctx, pats, opts)
6105 for f in ms:
6110 for f in ms:
6106 if not m(f):
6111 if not m(f):
6107 continue
6112 continue
6108
6113
6109 def flag(o):
6114 def flag(o):
6110 if o == b're_merge':
6115 if o == b're_merge':
6111 return b'--re-merge '
6116 return b'--re-merge '
6112 return b'-%s ' % o[0:1]
6117 return b'-%s ' % o[0:1]
6113
6118
6114 flags = b''.join([flag(o) for o in flaglist if opts.get(o)])
6119 flags = b''.join([flag(o) for o in flaglist if opts.get(o)])
6115 hint = _(b"(try: hg resolve %s%s)\n") % (
6120 hint = _(b"(try: hg resolve %s%s)\n") % (
6116 flags,
6121 flags,
6117 b' '.join(pats),
6122 b' '.join(pats),
6118 )
6123 )
6119 break
6124 break
6120 ui.warn(_(b"arguments do not match paths that need resolving\n"))
6125 ui.warn(_(b"arguments do not match paths that need resolving\n"))
6121 if hint:
6126 if hint:
6122 ui.warn(hint)
6127 ui.warn(hint)
6123 elif ms.mergedriver and ms.mdstate() != b's':
6128 elif ms.mergedriver and ms.mdstate() != b's':
6124 # run conclude step when either a driver-resolved file is requested
6129 # run conclude step when either a driver-resolved file is requested
6125 # or there are no driver-resolved files
6130 # or there are no driver-resolved files
6126 # we can't use 'ret' to determine whether any files are unresolved
6131 # we can't use 'ret' to determine whether any files are unresolved
6127 # because we might not have tried to resolve some
6132 # because we might not have tried to resolve some
6128 if (runconclude or not list(ms.driverresolved())) and not list(
6133 if (runconclude or not list(ms.driverresolved())) and not list(
6129 ms.unresolved()
6134 ms.unresolved()
6130 ):
6135 ):
6131 proceed = mergemod.driverconclude(repo, ms, wctx)
6136 proceed = mergemod.driverconclude(repo, ms, wctx)
6132 ms.commit()
6137 ms.commit()
6133 if not proceed:
6138 if not proceed:
6134 return 1
6139 return 1
6135
6140
6136 # Nudge users into finishing an unfinished operation
6141 # Nudge users into finishing an unfinished operation
6137 unresolvedf = list(ms.unresolved())
6142 unresolvedf = list(ms.unresolved())
6138 driverresolvedf = list(ms.driverresolved())
6143 driverresolvedf = list(ms.driverresolved())
6139 if not unresolvedf and not driverresolvedf:
6144 if not unresolvedf and not driverresolvedf:
6140 ui.status(_(b'(no more unresolved files)\n'))
6145 ui.status(_(b'(no more unresolved files)\n'))
6141 cmdutil.checkafterresolved(repo)
6146 cmdutil.checkafterresolved(repo)
6142 elif not unresolvedf:
6147 elif not unresolvedf:
6143 ui.status(
6148 ui.status(
6144 _(
6149 _(
6145 b'(no more unresolved files -- '
6150 b'(no more unresolved files -- '
6146 b'run "hg resolve --all" to conclude)\n'
6151 b'run "hg resolve --all" to conclude)\n'
6147 )
6152 )
6148 )
6153 )
6149
6154
6150 return ret
6155 return ret
6151
6156
6152
6157
6153 @command(
6158 @command(
6154 b'revert',
6159 b'revert',
6155 [
6160 [
6156 (b'a', b'all', None, _(b'revert all changes when no arguments given')),
6161 (b'a', b'all', None, _(b'revert all changes when no arguments given')),
6157 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
6162 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
6158 (b'r', b'rev', b'', _(b'revert to the specified revision'), _(b'REV')),
6163 (b'r', b'rev', b'', _(b'revert to the specified revision'), _(b'REV')),
6159 (b'C', b'no-backup', None, _(b'do not save backup copies of files')),
6164 (b'C', b'no-backup', None, _(b'do not save backup copies of files')),
6160 (b'i', b'interactive', None, _(b'interactively select the changes')),
6165 (b'i', b'interactive', None, _(b'interactively select the changes')),
6161 ]
6166 ]
6162 + walkopts
6167 + walkopts
6163 + dryrunopts,
6168 + dryrunopts,
6164 _(b'[OPTION]... [-r REV] [NAME]...'),
6169 _(b'[OPTION]... [-r REV] [NAME]...'),
6165 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6170 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6166 )
6171 )
6167 def revert(ui, repo, *pats, **opts):
6172 def revert(ui, repo, *pats, **opts):
6168 """restore files to their checkout state
6173 """restore files to their checkout state
6169
6174
6170 .. note::
6175 .. note::
6171
6176
6172 To check out earlier revisions, you should use :hg:`update REV`.
6177 To check out earlier revisions, you should use :hg:`update REV`.
6173 To cancel an uncommitted merge (and lose your changes),
6178 To cancel an uncommitted merge (and lose your changes),
6174 use :hg:`merge --abort`.
6179 use :hg:`merge --abort`.
6175
6180
6176 With no revision specified, revert the specified files or directories
6181 With no revision specified, revert the specified files or directories
6177 to the contents they had in the parent of the working directory.
6182 to the contents they had in the parent of the working directory.
6178 This restores the contents of files to an unmodified
6183 This restores the contents of files to an unmodified
6179 state and unschedules adds, removes, copies, and renames. If the
6184 state and unschedules adds, removes, copies, and renames. If the
6180 working directory has two parents, you must explicitly specify a
6185 working directory has two parents, you must explicitly specify a
6181 revision.
6186 revision.
6182
6187
6183 Using the -r/--rev or -d/--date options, revert the given files or
6188 Using the -r/--rev or -d/--date options, revert the given files or
6184 directories to their states as of a specific revision. Because
6189 directories to their states as of a specific revision. Because
6185 revert does not change the working directory parents, this will
6190 revert does not change the working directory parents, this will
6186 cause these files to appear modified. This can be helpful to "back
6191 cause these files to appear modified. This can be helpful to "back
6187 out" some or all of an earlier change. See :hg:`backout` for a
6192 out" some or all of an earlier change. See :hg:`backout` for a
6188 related method.
6193 related method.
6189
6194
6190 Modified files are saved with a .orig suffix before reverting.
6195 Modified files are saved with a .orig suffix before reverting.
6191 To disable these backups, use --no-backup. It is possible to store
6196 To disable these backups, use --no-backup. It is possible to store
6192 the backup files in a custom directory relative to the root of the
6197 the backup files in a custom directory relative to the root of the
6193 repository by setting the ``ui.origbackuppath`` configuration
6198 repository by setting the ``ui.origbackuppath`` configuration
6194 option.
6199 option.
6195
6200
6196 See :hg:`help dates` for a list of formats valid for -d/--date.
6201 See :hg:`help dates` for a list of formats valid for -d/--date.
6197
6202
6198 See :hg:`help backout` for a way to reverse the effect of an
6203 See :hg:`help backout` for a way to reverse the effect of an
6199 earlier changeset.
6204 earlier changeset.
6200
6205
6201 Returns 0 on success.
6206 Returns 0 on success.
6202 """
6207 """
6203
6208
6204 opts = pycompat.byteskwargs(opts)
6209 opts = pycompat.byteskwargs(opts)
6205 if opts.get(b"date"):
6210 if opts.get(b"date"):
6206 if opts.get(b"rev"):
6211 if opts.get(b"rev"):
6207 raise error.Abort(_(b"you can't specify a revision and a date"))
6212 raise error.Abort(_(b"you can't specify a revision and a date"))
6208 opts[b"rev"] = cmdutil.finddate(ui, repo, opts[b"date"])
6213 opts[b"rev"] = cmdutil.finddate(ui, repo, opts[b"date"])
6209
6214
6210 parent, p2 = repo.dirstate.parents()
6215 parent, p2 = repo.dirstate.parents()
6211 if not opts.get(b'rev') and p2 != nullid:
6216 if not opts.get(b'rev') and p2 != nullid:
6212 # revert after merge is a trap for new users (issue2915)
6217 # revert after merge is a trap for new users (issue2915)
6213 raise error.Abort(
6218 raise error.Abort(
6214 _(b'uncommitted merge with no revision specified'),
6219 _(b'uncommitted merge with no revision specified'),
6215 hint=_(b"use 'hg update' or see 'hg help revert'"),
6220 hint=_(b"use 'hg update' or see 'hg help revert'"),
6216 )
6221 )
6217
6222
6218 rev = opts.get(b'rev')
6223 rev = opts.get(b'rev')
6219 if rev:
6224 if rev:
6220 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
6225 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
6221 ctx = scmutil.revsingle(repo, rev)
6226 ctx = scmutil.revsingle(repo, rev)
6222
6227
6223 if not (
6228 if not (
6224 pats
6229 pats
6225 or opts.get(b'include')
6230 or opts.get(b'include')
6226 or opts.get(b'exclude')
6231 or opts.get(b'exclude')
6227 or opts.get(b'all')
6232 or opts.get(b'all')
6228 or opts.get(b'interactive')
6233 or opts.get(b'interactive')
6229 ):
6234 ):
6230 msg = _(b"no files or directories specified")
6235 msg = _(b"no files or directories specified")
6231 if p2 != nullid:
6236 if p2 != nullid:
6232 hint = _(
6237 hint = _(
6233 b"uncommitted merge, use --all to discard all changes,"
6238 b"uncommitted merge, use --all to discard all changes,"
6234 b" or 'hg update -C .' to abort the merge"
6239 b" or 'hg update -C .' to abort the merge"
6235 )
6240 )
6236 raise error.Abort(msg, hint=hint)
6241 raise error.Abort(msg, hint=hint)
6237 dirty = any(repo.status())
6242 dirty = any(repo.status())
6238 node = ctx.node()
6243 node = ctx.node()
6239 if node != parent:
6244 if node != parent:
6240 if dirty:
6245 if dirty:
6241 hint = (
6246 hint = (
6242 _(
6247 _(
6243 b"uncommitted changes, use --all to discard all"
6248 b"uncommitted changes, use --all to discard all"
6244 b" changes, or 'hg update %d' to update"
6249 b" changes, or 'hg update %d' to update"
6245 )
6250 )
6246 % ctx.rev()
6251 % ctx.rev()
6247 )
6252 )
6248 else:
6253 else:
6249 hint = (
6254 hint = (
6250 _(
6255 _(
6251 b"use --all to revert all files,"
6256 b"use --all to revert all files,"
6252 b" or 'hg update %d' to update"
6257 b" or 'hg update %d' to update"
6253 )
6258 )
6254 % ctx.rev()
6259 % ctx.rev()
6255 )
6260 )
6256 elif dirty:
6261 elif dirty:
6257 hint = _(b"uncommitted changes, use --all to discard all changes")
6262 hint = _(b"uncommitted changes, use --all to discard all changes")
6258 else:
6263 else:
6259 hint = _(b"use --all to revert all files")
6264 hint = _(b"use --all to revert all files")
6260 raise error.Abort(msg, hint=hint)
6265 raise error.Abort(msg, hint=hint)
6261
6266
6262 return cmdutil.revert(
6267 return cmdutil.revert(
6263 ui, repo, ctx, (parent, p2), *pats, **pycompat.strkwargs(opts)
6268 ui, repo, ctx, (parent, p2), *pats, **pycompat.strkwargs(opts)
6264 )
6269 )
6265
6270
6266
6271
6267 @command(
6272 @command(
6268 b'rollback',
6273 b'rollback',
6269 dryrunopts + [(b'f', b'force', False, _(b'ignore safety measures'))],
6274 dryrunopts + [(b'f', b'force', False, _(b'ignore safety measures'))],
6270 helpcategory=command.CATEGORY_MAINTENANCE,
6275 helpcategory=command.CATEGORY_MAINTENANCE,
6271 )
6276 )
6272 def rollback(ui, repo, **opts):
6277 def rollback(ui, repo, **opts):
6273 """roll back the last transaction (DANGEROUS) (DEPRECATED)
6278 """roll back the last transaction (DANGEROUS) (DEPRECATED)
6274
6279
6275 Please use :hg:`commit --amend` instead of rollback to correct
6280 Please use :hg:`commit --amend` instead of rollback to correct
6276 mistakes in the last commit.
6281 mistakes in the last commit.
6277
6282
6278 This command should be used with care. There is only one level of
6283 This command should be used with care. There is only one level of
6279 rollback, and there is no way to undo a rollback. It will also
6284 rollback, and there is no way to undo a rollback. It will also
6280 restore the dirstate at the time of the last transaction, losing
6285 restore the dirstate at the time of the last transaction, losing
6281 any dirstate changes since that time. This command does not alter
6286 any dirstate changes since that time. This command does not alter
6282 the working directory.
6287 the working directory.
6283
6288
6284 Transactions are used to encapsulate the effects of all commands
6289 Transactions are used to encapsulate the effects of all commands
6285 that create new changesets or propagate existing changesets into a
6290 that create new changesets or propagate existing changesets into a
6286 repository.
6291 repository.
6287
6292
6288 .. container:: verbose
6293 .. container:: verbose
6289
6294
6290 For example, the following commands are transactional, and their
6295 For example, the following commands are transactional, and their
6291 effects can be rolled back:
6296 effects can be rolled back:
6292
6297
6293 - commit
6298 - commit
6294 - import
6299 - import
6295 - pull
6300 - pull
6296 - push (with this repository as the destination)
6301 - push (with this repository as the destination)
6297 - unbundle
6302 - unbundle
6298
6303
6299 To avoid permanent data loss, rollback will refuse to rollback a
6304 To avoid permanent data loss, rollback will refuse to rollback a
6300 commit transaction if it isn't checked out. Use --force to
6305 commit transaction if it isn't checked out. Use --force to
6301 override this protection.
6306 override this protection.
6302
6307
6303 The rollback command can be entirely disabled by setting the
6308 The rollback command can be entirely disabled by setting the
6304 ``ui.rollback`` configuration setting to false. If you're here
6309 ``ui.rollback`` configuration setting to false. If you're here
6305 because you want to use rollback and it's disabled, you can
6310 because you want to use rollback and it's disabled, you can
6306 re-enable the command by setting ``ui.rollback`` to true.
6311 re-enable the command by setting ``ui.rollback`` to true.
6307
6312
6308 This command is not intended for use on public repositories. Once
6313 This command is not intended for use on public repositories. Once
6309 changes are visible for pull by other users, rolling a transaction
6314 changes are visible for pull by other users, rolling a transaction
6310 back locally is ineffective (someone else may already have pulled
6315 back locally is ineffective (someone else may already have pulled
6311 the changes). Furthermore, a race is possible with readers of the
6316 the changes). Furthermore, a race is possible with readers of the
6312 repository; for example an in-progress pull from the repository
6317 repository; for example an in-progress pull from the repository
6313 may fail if a rollback is performed.
6318 may fail if a rollback is performed.
6314
6319
6315 Returns 0 on success, 1 if no rollback data is available.
6320 Returns 0 on success, 1 if no rollback data is available.
6316 """
6321 """
6317 if not ui.configbool(b'ui', b'rollback'):
6322 if not ui.configbool(b'ui', b'rollback'):
6318 raise error.Abort(
6323 raise error.Abort(
6319 _(b'rollback is disabled because it is unsafe'),
6324 _(b'rollback is disabled because it is unsafe'),
6320 hint=b'see `hg help -v rollback` for information',
6325 hint=b'see `hg help -v rollback` for information',
6321 )
6326 )
6322 return repo.rollback(dryrun=opts.get(r'dry_run'), force=opts.get(r'force'))
6327 return repo.rollback(dryrun=opts.get(r'dry_run'), force=opts.get(r'force'))
6323
6328
6324
6329
6325 @command(
6330 @command(
6326 b'root',
6331 b'root',
6327 [] + formatteropts,
6332 [] + formatteropts,
6328 intents={INTENT_READONLY},
6333 intents={INTENT_READONLY},
6329 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6334 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6330 )
6335 )
6331 def root(ui, repo, **opts):
6336 def root(ui, repo, **opts):
6332 """print the root (top) of the current working directory
6337 """print the root (top) of the current working directory
6333
6338
6334 Print the root directory of the current repository.
6339 Print the root directory of the current repository.
6335
6340
6336 .. container:: verbose
6341 .. container:: verbose
6337
6342
6338 Template:
6343 Template:
6339
6344
6340 The following keywords are supported in addition to the common template
6345 The following keywords are supported in addition to the common template
6341 keywords and functions. See also :hg:`help templates`.
6346 keywords and functions. See also :hg:`help templates`.
6342
6347
6343 :hgpath: String. Path to the .hg directory.
6348 :hgpath: String. Path to the .hg directory.
6344 :storepath: String. Path to the directory holding versioned data.
6349 :storepath: String. Path to the directory holding versioned data.
6345
6350
6346 Returns 0 on success.
6351 Returns 0 on success.
6347 """
6352 """
6348 opts = pycompat.byteskwargs(opts)
6353 opts = pycompat.byteskwargs(opts)
6349 with ui.formatter(b'root', opts) as fm:
6354 with ui.formatter(b'root', opts) as fm:
6350 fm.startitem()
6355 fm.startitem()
6351 fm.write(b'reporoot', b'%s\n', repo.root)
6356 fm.write(b'reporoot', b'%s\n', repo.root)
6352 fm.data(hgpath=repo.path, storepath=repo.spath)
6357 fm.data(hgpath=repo.path, storepath=repo.spath)
6353
6358
6354
6359
6355 @command(
6360 @command(
6356 b'serve',
6361 b'serve',
6357 [
6362 [
6358 (
6363 (
6359 b'A',
6364 b'A',
6360 b'accesslog',
6365 b'accesslog',
6361 b'',
6366 b'',
6362 _(b'name of access log file to write to'),
6367 _(b'name of access log file to write to'),
6363 _(b'FILE'),
6368 _(b'FILE'),
6364 ),
6369 ),
6365 (b'd', b'daemon', None, _(b'run server in background')),
6370 (b'd', b'daemon', None, _(b'run server in background')),
6366 (b'', b'daemon-postexec', [], _(b'used internally by daemon mode')),
6371 (b'', b'daemon-postexec', [], _(b'used internally by daemon mode')),
6367 (
6372 (
6368 b'E',
6373 b'E',
6369 b'errorlog',
6374 b'errorlog',
6370 b'',
6375 b'',
6371 _(b'name of error log file to write to'),
6376 _(b'name of error log file to write to'),
6372 _(b'FILE'),
6377 _(b'FILE'),
6373 ),
6378 ),
6374 # use string type, then we can check if something was passed
6379 # use string type, then we can check if something was passed
6375 (
6380 (
6376 b'p',
6381 b'p',
6377 b'port',
6382 b'port',
6378 b'',
6383 b'',
6379 _(b'port to listen on (default: 8000)'),
6384 _(b'port to listen on (default: 8000)'),
6380 _(b'PORT'),
6385 _(b'PORT'),
6381 ),
6386 ),
6382 (
6387 (
6383 b'a',
6388 b'a',
6384 b'address',
6389 b'address',
6385 b'',
6390 b'',
6386 _(b'address to listen on (default: all interfaces)'),
6391 _(b'address to listen on (default: all interfaces)'),
6387 _(b'ADDR'),
6392 _(b'ADDR'),
6388 ),
6393 ),
6389 (
6394 (
6390 b'',
6395 b'',
6391 b'prefix',
6396 b'prefix',
6392 b'',
6397 b'',
6393 _(b'prefix path to serve from (default: server root)'),
6398 _(b'prefix path to serve from (default: server root)'),
6394 _(b'PREFIX'),
6399 _(b'PREFIX'),
6395 ),
6400 ),
6396 (
6401 (
6397 b'n',
6402 b'n',
6398 b'name',
6403 b'name',
6399 b'',
6404 b'',
6400 _(b'name to show in web pages (default: working directory)'),
6405 _(b'name to show in web pages (default: working directory)'),
6401 _(b'NAME'),
6406 _(b'NAME'),
6402 ),
6407 ),
6403 (
6408 (
6404 b'',
6409 b'',
6405 b'web-conf',
6410 b'web-conf',
6406 b'',
6411 b'',
6407 _(b"name of the hgweb config file (see 'hg help hgweb')"),
6412 _(b"name of the hgweb config file (see 'hg help hgweb')"),
6408 _(b'FILE'),
6413 _(b'FILE'),
6409 ),
6414 ),
6410 (
6415 (
6411 b'',
6416 b'',
6412 b'webdir-conf',
6417 b'webdir-conf',
6413 b'',
6418 b'',
6414 _(b'name of the hgweb config file (DEPRECATED)'),
6419 _(b'name of the hgweb config file (DEPRECATED)'),
6415 _(b'FILE'),
6420 _(b'FILE'),
6416 ),
6421 ),
6417 (
6422 (
6418 b'',
6423 b'',
6419 b'pid-file',
6424 b'pid-file',
6420 b'',
6425 b'',
6421 _(b'name of file to write process ID to'),
6426 _(b'name of file to write process ID to'),
6422 _(b'FILE'),
6427 _(b'FILE'),
6423 ),
6428 ),
6424 (b'', b'stdio', None, _(b'for remote clients (ADVANCED)')),
6429 (b'', b'stdio', None, _(b'for remote clients (ADVANCED)')),
6425 (
6430 (
6426 b'',
6431 b'',
6427 b'cmdserver',
6432 b'cmdserver',
6428 b'',
6433 b'',
6429 _(b'for remote clients (ADVANCED)'),
6434 _(b'for remote clients (ADVANCED)'),
6430 _(b'MODE'),
6435 _(b'MODE'),
6431 ),
6436 ),
6432 (b't', b'templates', b'', _(b'web templates to use'), _(b'TEMPLATE')),
6437 (b't', b'templates', b'', _(b'web templates to use'), _(b'TEMPLATE')),
6433 (b'', b'style', b'', _(b'template style to use'), _(b'STYLE')),
6438 (b'', b'style', b'', _(b'template style to use'), _(b'STYLE')),
6434 (b'6', b'ipv6', None, _(b'use IPv6 in addition to IPv4')),
6439 (b'6', b'ipv6', None, _(b'use IPv6 in addition to IPv4')),
6435 (b'', b'certificate', b'', _(b'SSL certificate file'), _(b'FILE')),
6440 (b'', b'certificate', b'', _(b'SSL certificate file'), _(b'FILE')),
6436 (b'', b'print-url', None, _(b'start and print only the URL')),
6441 (b'', b'print-url', None, _(b'start and print only the URL')),
6437 ]
6442 ]
6438 + subrepoopts,
6443 + subrepoopts,
6439 _(b'[OPTION]...'),
6444 _(b'[OPTION]...'),
6440 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
6445 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
6441 helpbasic=True,
6446 helpbasic=True,
6442 optionalrepo=True,
6447 optionalrepo=True,
6443 )
6448 )
6444 def serve(ui, repo, **opts):
6449 def serve(ui, repo, **opts):
6445 """start stand-alone webserver
6450 """start stand-alone webserver
6446
6451
6447 Start a local HTTP repository browser and pull server. You can use
6452 Start a local HTTP repository browser and pull server. You can use
6448 this for ad-hoc sharing and browsing of repositories. It is
6453 this for ad-hoc sharing and browsing of repositories. It is
6449 recommended to use a real web server to serve a repository for
6454 recommended to use a real web server to serve a repository for
6450 longer periods of time.
6455 longer periods of time.
6451
6456
6452 Please note that the server does not implement access control.
6457 Please note that the server does not implement access control.
6453 This means that, by default, anybody can read from the server and
6458 This means that, by default, anybody can read from the server and
6454 nobody can write to it by default. Set the ``web.allow-push``
6459 nobody can write to it by default. Set the ``web.allow-push``
6455 option to ``*`` to allow everybody to push to the server. You
6460 option to ``*`` to allow everybody to push to the server. You
6456 should use a real web server if you need to authenticate users.
6461 should use a real web server if you need to authenticate users.
6457
6462
6458 By default, the server logs accesses to stdout and errors to
6463 By default, the server logs accesses to stdout and errors to
6459 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
6464 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
6460 files.
6465 files.
6461
6466
6462 To have the server choose a free port number to listen on, specify
6467 To have the server choose a free port number to listen on, specify
6463 a port number of 0; in this case, the server will print the port
6468 a port number of 0; in this case, the server will print the port
6464 number it uses.
6469 number it uses.
6465
6470
6466 Returns 0 on success.
6471 Returns 0 on success.
6467 """
6472 """
6468
6473
6469 opts = pycompat.byteskwargs(opts)
6474 opts = pycompat.byteskwargs(opts)
6470 if opts[b"stdio"] and opts[b"cmdserver"]:
6475 if opts[b"stdio"] and opts[b"cmdserver"]:
6471 raise error.Abort(_(b"cannot use --stdio with --cmdserver"))
6476 raise error.Abort(_(b"cannot use --stdio with --cmdserver"))
6472 if opts[b"print_url"] and ui.verbose:
6477 if opts[b"print_url"] and ui.verbose:
6473 raise error.Abort(_(b"cannot use --print-url with --verbose"))
6478 raise error.Abort(_(b"cannot use --print-url with --verbose"))
6474
6479
6475 if opts[b"stdio"]:
6480 if opts[b"stdio"]:
6476 if repo is None:
6481 if repo is None:
6477 raise error.RepoError(
6482 raise error.RepoError(
6478 _(b"there is no Mercurial repository here (.hg not found)")
6483 _(b"there is no Mercurial repository here (.hg not found)")
6479 )
6484 )
6480 s = wireprotoserver.sshserver(ui, repo)
6485 s = wireprotoserver.sshserver(ui, repo)
6481 s.serve_forever()
6486 s.serve_forever()
6482
6487
6483 service = server.createservice(ui, repo, opts)
6488 service = server.createservice(ui, repo, opts)
6484 return server.runservice(opts, initfn=service.init, runfn=service.run)
6489 return server.runservice(opts, initfn=service.init, runfn=service.run)
6485
6490
6486
6491
6487 @command(
6492 @command(
6488 b'shelve',
6493 b'shelve',
6489 [
6494 [
6490 (
6495 (
6491 b'A',
6496 b'A',
6492 b'addremove',
6497 b'addremove',
6493 None,
6498 None,
6494 _(b'mark new/missing files as added/removed before shelving'),
6499 _(b'mark new/missing files as added/removed before shelving'),
6495 ),
6500 ),
6496 (b'u', b'unknown', None, _(b'store unknown files in the shelve')),
6501 (b'u', b'unknown', None, _(b'store unknown files in the shelve')),
6497 (b'', b'cleanup', None, _(b'delete all shelved changes')),
6502 (b'', b'cleanup', None, _(b'delete all shelved changes')),
6498 (
6503 (
6499 b'',
6504 b'',
6500 b'date',
6505 b'date',
6501 b'',
6506 b'',
6502 _(b'shelve with the specified commit date'),
6507 _(b'shelve with the specified commit date'),
6503 _(b'DATE'),
6508 _(b'DATE'),
6504 ),
6509 ),
6505 (b'd', b'delete', None, _(b'delete the named shelved change(s)')),
6510 (b'd', b'delete', None, _(b'delete the named shelved change(s)')),
6506 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
6511 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
6507 (
6512 (
6508 b'k',
6513 b'k',
6509 b'keep',
6514 b'keep',
6510 False,
6515 False,
6511 _(b'shelve, but keep changes in the working directory'),
6516 _(b'shelve, but keep changes in the working directory'),
6512 ),
6517 ),
6513 (b'l', b'list', None, _(b'list current shelves')),
6518 (b'l', b'list', None, _(b'list current shelves')),
6514 (b'm', b'message', b'', _(b'use text as shelve message'), _(b'TEXT')),
6519 (b'm', b'message', b'', _(b'use text as shelve message'), _(b'TEXT')),
6515 (
6520 (
6516 b'n',
6521 b'n',
6517 b'name',
6522 b'name',
6518 b'',
6523 b'',
6519 _(b'use the given name for the shelved commit'),
6524 _(b'use the given name for the shelved commit'),
6520 _(b'NAME'),
6525 _(b'NAME'),
6521 ),
6526 ),
6522 (
6527 (
6523 b'p',
6528 b'p',
6524 b'patch',
6529 b'patch',
6525 None,
6530 None,
6526 _(
6531 _(
6527 b'output patches for changes (provide the names of the shelved '
6532 b'output patches for changes (provide the names of the shelved '
6528 b'changes as positional arguments)'
6533 b'changes as positional arguments)'
6529 ),
6534 ),
6530 ),
6535 ),
6531 (b'i', b'interactive', None, _(b'interactive mode')),
6536 (b'i', b'interactive', None, _(b'interactive mode')),
6532 (
6537 (
6533 b'',
6538 b'',
6534 b'stat',
6539 b'stat',
6535 None,
6540 None,
6536 _(
6541 _(
6537 b'output diffstat-style summary of changes (provide the names of '
6542 b'output diffstat-style summary of changes (provide the names of '
6538 b'the shelved changes as positional arguments)'
6543 b'the shelved changes as positional arguments)'
6539 ),
6544 ),
6540 ),
6545 ),
6541 ]
6546 ]
6542 + cmdutil.walkopts,
6547 + cmdutil.walkopts,
6543 _(b'hg shelve [OPTION]... [FILE]...'),
6548 _(b'hg shelve [OPTION]... [FILE]...'),
6544 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6549 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6545 )
6550 )
6546 def shelve(ui, repo, *pats, **opts):
6551 def shelve(ui, repo, *pats, **opts):
6547 '''save and set aside changes from the working directory
6552 '''save and set aside changes from the working directory
6548
6553
6549 Shelving takes files that "hg status" reports as not clean, saves
6554 Shelving takes files that "hg status" reports as not clean, saves
6550 the modifications to a bundle (a shelved change), and reverts the
6555 the modifications to a bundle (a shelved change), and reverts the
6551 files so that their state in the working directory becomes clean.
6556 files so that their state in the working directory becomes clean.
6552
6557
6553 To restore these changes to the working directory, using "hg
6558 To restore these changes to the working directory, using "hg
6554 unshelve"; this will work even if you switch to a different
6559 unshelve"; this will work even if you switch to a different
6555 commit.
6560 commit.
6556
6561
6557 When no files are specified, "hg shelve" saves all not-clean
6562 When no files are specified, "hg shelve" saves all not-clean
6558 files. If specific files or directories are named, only changes to
6563 files. If specific files or directories are named, only changes to
6559 those files are shelved.
6564 those files are shelved.
6560
6565
6561 In bare shelve (when no files are specified, without interactive,
6566 In bare shelve (when no files are specified, without interactive,
6562 include and exclude option), shelving remembers information if the
6567 include and exclude option), shelving remembers information if the
6563 working directory was on newly created branch, in other words working
6568 working directory was on newly created branch, in other words working
6564 directory was on different branch than its first parent. In this
6569 directory was on different branch than its first parent. In this
6565 situation unshelving restores branch information to the working directory.
6570 situation unshelving restores branch information to the working directory.
6566
6571
6567 Each shelved change has a name that makes it easier to find later.
6572 Each shelved change has a name that makes it easier to find later.
6568 The name of a shelved change defaults to being based on the active
6573 The name of a shelved change defaults to being based on the active
6569 bookmark, or if there is no active bookmark, the current named
6574 bookmark, or if there is no active bookmark, the current named
6570 branch. To specify a different name, use ``--name``.
6575 branch. To specify a different name, use ``--name``.
6571
6576
6572 To see a list of existing shelved changes, use the ``--list``
6577 To see a list of existing shelved changes, use the ``--list``
6573 option. For each shelved change, this will print its name, age,
6578 option. For each shelved change, this will print its name, age,
6574 and description; use ``--patch`` or ``--stat`` for more details.
6579 and description; use ``--patch`` or ``--stat`` for more details.
6575
6580
6576 To delete specific shelved changes, use ``--delete``. To delete
6581 To delete specific shelved changes, use ``--delete``. To delete
6577 all shelved changes, use ``--cleanup``.
6582 all shelved changes, use ``--cleanup``.
6578 '''
6583 '''
6579 opts = pycompat.byteskwargs(opts)
6584 opts = pycompat.byteskwargs(opts)
6580 allowables = [
6585 allowables = [
6581 (b'addremove', {b'create'}), # 'create' is pseudo action
6586 (b'addremove', {b'create'}), # 'create' is pseudo action
6582 (b'unknown', {b'create'}),
6587 (b'unknown', {b'create'}),
6583 (b'cleanup', {b'cleanup'}),
6588 (b'cleanup', {b'cleanup'}),
6584 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
6589 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
6585 (b'delete', {b'delete'}),
6590 (b'delete', {b'delete'}),
6586 (b'edit', {b'create'}),
6591 (b'edit', {b'create'}),
6587 (b'keep', {b'create'}),
6592 (b'keep', {b'create'}),
6588 (b'list', {b'list'}),
6593 (b'list', {b'list'}),
6589 (b'message', {b'create'}),
6594 (b'message', {b'create'}),
6590 (b'name', {b'create'}),
6595 (b'name', {b'create'}),
6591 (b'patch', {b'patch', b'list'}),
6596 (b'patch', {b'patch', b'list'}),
6592 (b'stat', {b'stat', b'list'}),
6597 (b'stat', {b'stat', b'list'}),
6593 ]
6598 ]
6594
6599
6595 def checkopt(opt):
6600 def checkopt(opt):
6596 if opts.get(opt):
6601 if opts.get(opt):
6597 for i, allowable in allowables:
6602 for i, allowable in allowables:
6598 if opts[i] and opt not in allowable:
6603 if opts[i] and opt not in allowable:
6599 raise error.Abort(
6604 raise error.Abort(
6600 _(
6605 _(
6601 b"options '--%s' and '--%s' may not be "
6606 b"options '--%s' and '--%s' may not be "
6602 b"used together"
6607 b"used together"
6603 )
6608 )
6604 % (opt, i)
6609 % (opt, i)
6605 )
6610 )
6606 return True
6611 return True
6607
6612
6608 if checkopt(b'cleanup'):
6613 if checkopt(b'cleanup'):
6609 if pats:
6614 if pats:
6610 raise error.Abort(_(b"cannot specify names when using '--cleanup'"))
6615 raise error.Abort(_(b"cannot specify names when using '--cleanup'"))
6611 return shelvemod.cleanupcmd(ui, repo)
6616 return shelvemod.cleanupcmd(ui, repo)
6612 elif checkopt(b'delete'):
6617 elif checkopt(b'delete'):
6613 return shelvemod.deletecmd(ui, repo, pats)
6618 return shelvemod.deletecmd(ui, repo, pats)
6614 elif checkopt(b'list'):
6619 elif checkopt(b'list'):
6615 return shelvemod.listcmd(ui, repo, pats, opts)
6620 return shelvemod.listcmd(ui, repo, pats, opts)
6616 elif checkopt(b'patch') or checkopt(b'stat'):
6621 elif checkopt(b'patch') or checkopt(b'stat'):
6617 return shelvemod.patchcmds(ui, repo, pats, opts)
6622 return shelvemod.patchcmds(ui, repo, pats, opts)
6618 else:
6623 else:
6619 return shelvemod.createcmd(ui, repo, pats, opts)
6624 return shelvemod.createcmd(ui, repo, pats, opts)
6620
6625
6621
6626
6622 _NOTTERSE = b'nothing'
6627 _NOTTERSE = b'nothing'
6623
6628
6624
6629
6625 @command(
6630 @command(
6626 b'status|st',
6631 b'status|st',
6627 [
6632 [
6628 (b'A', b'all', None, _(b'show status of all files')),
6633 (b'A', b'all', None, _(b'show status of all files')),
6629 (b'm', b'modified', None, _(b'show only modified files')),
6634 (b'm', b'modified', None, _(b'show only modified files')),
6630 (b'a', b'added', None, _(b'show only added files')),
6635 (b'a', b'added', None, _(b'show only added files')),
6631 (b'r', b'removed', None, _(b'show only removed files')),
6636 (b'r', b'removed', None, _(b'show only removed files')),
6632 (b'd', b'deleted', None, _(b'show only deleted (but tracked) files')),
6637 (b'd', b'deleted', None, _(b'show only deleted (but tracked) files')),
6633 (b'c', b'clean', None, _(b'show only files without changes')),
6638 (b'c', b'clean', None, _(b'show only files without changes')),
6634 (b'u', b'unknown', None, _(b'show only unknown (not tracked) files')),
6639 (b'u', b'unknown', None, _(b'show only unknown (not tracked) files')),
6635 (b'i', b'ignored', None, _(b'show only ignored files')),
6640 (b'i', b'ignored', None, _(b'show only ignored files')),
6636 (b'n', b'no-status', None, _(b'hide status prefix')),
6641 (b'n', b'no-status', None, _(b'hide status prefix')),
6637 (b't', b'terse', _NOTTERSE, _(b'show the terse output (EXPERIMENTAL)')),
6642 (b't', b'terse', _NOTTERSE, _(b'show the terse output (EXPERIMENTAL)')),
6638 (b'C', b'copies', None, _(b'show source of copied files')),
6643 (b'C', b'copies', None, _(b'show source of copied files')),
6639 (
6644 (
6640 b'0',
6645 b'0',
6641 b'print0',
6646 b'print0',
6642 None,
6647 None,
6643 _(b'end filenames with NUL, for use with xargs'),
6648 _(b'end filenames with NUL, for use with xargs'),
6644 ),
6649 ),
6645 (b'', b'rev', [], _(b'show difference from revision'), _(b'REV')),
6650 (b'', b'rev', [], _(b'show difference from revision'), _(b'REV')),
6646 (
6651 (
6647 b'',
6652 b'',
6648 b'change',
6653 b'change',
6649 b'',
6654 b'',
6650 _(b'list the changed files of a revision'),
6655 _(b'list the changed files of a revision'),
6651 _(b'REV'),
6656 _(b'REV'),
6652 ),
6657 ),
6653 ]
6658 ]
6654 + walkopts
6659 + walkopts
6655 + subrepoopts
6660 + subrepoopts
6656 + formatteropts,
6661 + formatteropts,
6657 _(b'[OPTION]... [FILE]...'),
6662 _(b'[OPTION]... [FILE]...'),
6658 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6663 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6659 helpbasic=True,
6664 helpbasic=True,
6660 inferrepo=True,
6665 inferrepo=True,
6661 intents={INTENT_READONLY},
6666 intents={INTENT_READONLY},
6662 )
6667 )
6663 def status(ui, repo, *pats, **opts):
6668 def status(ui, repo, *pats, **opts):
6664 """show changed files in the working directory
6669 """show changed files in the working directory
6665
6670
6666 Show status of files in the repository. If names are given, only
6671 Show status of files in the repository. If names are given, only
6667 files that match are shown. Files that are clean or ignored or
6672 files that match are shown. Files that are clean or ignored or
6668 the source of a copy/move operation, are not listed unless
6673 the source of a copy/move operation, are not listed unless
6669 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6674 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6670 Unless options described with "show only ..." are given, the
6675 Unless options described with "show only ..." are given, the
6671 options -mardu are used.
6676 options -mardu are used.
6672
6677
6673 Option -q/--quiet hides untracked (unknown and ignored) files
6678 Option -q/--quiet hides untracked (unknown and ignored) files
6674 unless explicitly requested with -u/--unknown or -i/--ignored.
6679 unless explicitly requested with -u/--unknown or -i/--ignored.
6675
6680
6676 .. note::
6681 .. note::
6677
6682
6678 :hg:`status` may appear to disagree with diff if permissions have
6683 :hg:`status` may appear to disagree with diff if permissions have
6679 changed or a merge has occurred. The standard diff format does
6684 changed or a merge has occurred. The standard diff format does
6680 not report permission changes and diff only reports changes
6685 not report permission changes and diff only reports changes
6681 relative to one merge parent.
6686 relative to one merge parent.
6682
6687
6683 If one revision is given, it is used as the base revision.
6688 If one revision is given, it is used as the base revision.
6684 If two revisions are given, the differences between them are
6689 If two revisions are given, the differences between them are
6685 shown. The --change option can also be used as a shortcut to list
6690 shown. The --change option can also be used as a shortcut to list
6686 the changed files of a revision from its first parent.
6691 the changed files of a revision from its first parent.
6687
6692
6688 The codes used to show the status of files are::
6693 The codes used to show the status of files are::
6689
6694
6690 M = modified
6695 M = modified
6691 A = added
6696 A = added
6692 R = removed
6697 R = removed
6693 C = clean
6698 C = clean
6694 ! = missing (deleted by non-hg command, but still tracked)
6699 ! = missing (deleted by non-hg command, but still tracked)
6695 ? = not tracked
6700 ? = not tracked
6696 I = ignored
6701 I = ignored
6697 = origin of the previous file (with --copies)
6702 = origin of the previous file (with --copies)
6698
6703
6699 .. container:: verbose
6704 .. container:: verbose
6700
6705
6701 The -t/--terse option abbreviates the output by showing only the directory
6706 The -t/--terse option abbreviates the output by showing only the directory
6702 name if all the files in it share the same status. The option takes an
6707 name if all the files in it share the same status. The option takes an
6703 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
6708 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
6704 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
6709 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
6705 for 'ignored' and 'c' for clean.
6710 for 'ignored' and 'c' for clean.
6706
6711
6707 It abbreviates only those statuses which are passed. Note that clean and
6712 It abbreviates only those statuses which are passed. Note that clean and
6708 ignored files are not displayed with '--terse ic' unless the -c/--clean
6713 ignored files are not displayed with '--terse ic' unless the -c/--clean
6709 and -i/--ignored options are also used.
6714 and -i/--ignored options are also used.
6710
6715
6711 The -v/--verbose option shows information when the repository is in an
6716 The -v/--verbose option shows information when the repository is in an
6712 unfinished merge, shelve, rebase state etc. You can have this behavior
6717 unfinished merge, shelve, rebase state etc. You can have this behavior
6713 turned on by default by enabling the ``commands.status.verbose`` option.
6718 turned on by default by enabling the ``commands.status.verbose`` option.
6714
6719
6715 You can skip displaying some of these states by setting
6720 You can skip displaying some of these states by setting
6716 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
6721 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
6717 'histedit', 'merge', 'rebase', or 'unshelve'.
6722 'histedit', 'merge', 'rebase', or 'unshelve'.
6718
6723
6719 Template:
6724 Template:
6720
6725
6721 The following keywords are supported in addition to the common template
6726 The following keywords are supported in addition to the common template
6722 keywords and functions. See also :hg:`help templates`.
6727 keywords and functions. See also :hg:`help templates`.
6723
6728
6724 :path: String. Repository-absolute path of the file.
6729 :path: String. Repository-absolute path of the file.
6725 :source: String. Repository-absolute path of the file originated from.
6730 :source: String. Repository-absolute path of the file originated from.
6726 Available if ``--copies`` is specified.
6731 Available if ``--copies`` is specified.
6727 :status: String. Character denoting file's status.
6732 :status: String. Character denoting file's status.
6728
6733
6729 Examples:
6734 Examples:
6730
6735
6731 - show changes in the working directory relative to a
6736 - show changes in the working directory relative to a
6732 changeset::
6737 changeset::
6733
6738
6734 hg status --rev 9353
6739 hg status --rev 9353
6735
6740
6736 - show changes in the working directory relative to the
6741 - show changes in the working directory relative to the
6737 current directory (see :hg:`help patterns` for more information)::
6742 current directory (see :hg:`help patterns` for more information)::
6738
6743
6739 hg status re:
6744 hg status re:
6740
6745
6741 - show all changes including copies in an existing changeset::
6746 - show all changes including copies in an existing changeset::
6742
6747
6743 hg status --copies --change 9353
6748 hg status --copies --change 9353
6744
6749
6745 - get a NUL separated list of added files, suitable for xargs::
6750 - get a NUL separated list of added files, suitable for xargs::
6746
6751
6747 hg status -an0
6752 hg status -an0
6748
6753
6749 - show more information about the repository status, abbreviating
6754 - show more information about the repository status, abbreviating
6750 added, removed, modified, deleted, and untracked paths::
6755 added, removed, modified, deleted, and untracked paths::
6751
6756
6752 hg status -v -t mardu
6757 hg status -v -t mardu
6753
6758
6754 Returns 0 on success.
6759 Returns 0 on success.
6755
6760
6756 """
6761 """
6757
6762
6758 opts = pycompat.byteskwargs(opts)
6763 opts = pycompat.byteskwargs(opts)
6759 revs = opts.get(b'rev')
6764 revs = opts.get(b'rev')
6760 change = opts.get(b'change')
6765 change = opts.get(b'change')
6761 terse = opts.get(b'terse')
6766 terse = opts.get(b'terse')
6762 if terse is _NOTTERSE:
6767 if terse is _NOTTERSE:
6763 if revs:
6768 if revs:
6764 terse = b''
6769 terse = b''
6765 else:
6770 else:
6766 terse = ui.config(b'commands', b'status.terse')
6771 terse = ui.config(b'commands', b'status.terse')
6767
6772
6768 if revs and change:
6773 if revs and change:
6769 msg = _(b'cannot specify --rev and --change at the same time')
6774 msg = _(b'cannot specify --rev and --change at the same time')
6770 raise error.Abort(msg)
6775 raise error.Abort(msg)
6771 elif revs and terse:
6776 elif revs and terse:
6772 msg = _(b'cannot use --terse with --rev')
6777 msg = _(b'cannot use --terse with --rev')
6773 raise error.Abort(msg)
6778 raise error.Abort(msg)
6774 elif change:
6779 elif change:
6775 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
6780 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
6776 ctx2 = scmutil.revsingle(repo, change, None)
6781 ctx2 = scmutil.revsingle(repo, change, None)
6777 ctx1 = ctx2.p1()
6782 ctx1 = ctx2.p1()
6778 else:
6783 else:
6779 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
6784 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
6780 ctx1, ctx2 = scmutil.revpair(repo, revs)
6785 ctx1, ctx2 = scmutil.revpair(repo, revs)
6781
6786
6782 forcerelativevalue = None
6787 forcerelativevalue = None
6783 if ui.hasconfig(b'commands', b'status.relative'):
6788 if ui.hasconfig(b'commands', b'status.relative'):
6784 forcerelativevalue = ui.configbool(b'commands', b'status.relative')
6789 forcerelativevalue = ui.configbool(b'commands', b'status.relative')
6785 uipathfn = scmutil.getuipathfn(
6790 uipathfn = scmutil.getuipathfn(
6786 repo,
6791 repo,
6787 legacyrelativevalue=bool(pats),
6792 legacyrelativevalue=bool(pats),
6788 forcerelativevalue=forcerelativevalue,
6793 forcerelativevalue=forcerelativevalue,
6789 )
6794 )
6790
6795
6791 if opts.get(b'print0'):
6796 if opts.get(b'print0'):
6792 end = b'\0'
6797 end = b'\0'
6793 else:
6798 else:
6794 end = b'\n'
6799 end = b'\n'
6795 copy = {}
6800 copy = {}
6796 states = b'modified added removed deleted unknown ignored clean'.split()
6801 states = b'modified added removed deleted unknown ignored clean'.split()
6797 show = [k for k in states if opts.get(k)]
6802 show = [k for k in states if opts.get(k)]
6798 if opts.get(b'all'):
6803 if opts.get(b'all'):
6799 show += ui.quiet and (states[:4] + [b'clean']) or states
6804 show += ui.quiet and (states[:4] + [b'clean']) or states
6800
6805
6801 if not show:
6806 if not show:
6802 if ui.quiet:
6807 if ui.quiet:
6803 show = states[:4]
6808 show = states[:4]
6804 else:
6809 else:
6805 show = states[:5]
6810 show = states[:5]
6806
6811
6807 m = scmutil.match(ctx2, pats, opts)
6812 m = scmutil.match(ctx2, pats, opts)
6808 if terse:
6813 if terse:
6809 # we need to compute clean and unknown to terse
6814 # we need to compute clean and unknown to terse
6810 stat = repo.status(
6815 stat = repo.status(
6811 ctx1.node(),
6816 ctx1.node(),
6812 ctx2.node(),
6817 ctx2.node(),
6813 m,
6818 m,
6814 b'ignored' in show or b'i' in terse,
6819 b'ignored' in show or b'i' in terse,
6815 clean=True,
6820 clean=True,
6816 unknown=True,
6821 unknown=True,
6817 listsubrepos=opts.get(b'subrepos'),
6822 listsubrepos=opts.get(b'subrepos'),
6818 )
6823 )
6819
6824
6820 stat = cmdutil.tersedir(stat, terse)
6825 stat = cmdutil.tersedir(stat, terse)
6821 else:
6826 else:
6822 stat = repo.status(
6827 stat = repo.status(
6823 ctx1.node(),
6828 ctx1.node(),
6824 ctx2.node(),
6829 ctx2.node(),
6825 m,
6830 m,
6826 b'ignored' in show,
6831 b'ignored' in show,
6827 b'clean' in show,
6832 b'clean' in show,
6828 b'unknown' in show,
6833 b'unknown' in show,
6829 opts.get(b'subrepos'),
6834 opts.get(b'subrepos'),
6830 )
6835 )
6831
6836
6832 changestates = zip(states, pycompat.iterbytestr(b'MAR!?IC'), stat)
6837 changestates = zip(states, pycompat.iterbytestr(b'MAR!?IC'), stat)
6833
6838
6834 if (
6839 if (
6835 opts.get(b'all')
6840 opts.get(b'all')
6836 or opts.get(b'copies')
6841 or opts.get(b'copies')
6837 or ui.configbool(b'ui', b'statuscopies')
6842 or ui.configbool(b'ui', b'statuscopies')
6838 ) and not opts.get(b'no_status'):
6843 ) and not opts.get(b'no_status'):
6839 copy = copies.pathcopies(ctx1, ctx2, m)
6844 copy = copies.pathcopies(ctx1, ctx2, m)
6840
6845
6841 ui.pager(b'status')
6846 ui.pager(b'status')
6842 fm = ui.formatter(b'status', opts)
6847 fm = ui.formatter(b'status', opts)
6843 fmt = b'%s' + end
6848 fmt = b'%s' + end
6844 showchar = not opts.get(b'no_status')
6849 showchar = not opts.get(b'no_status')
6845
6850
6846 for state, char, files in changestates:
6851 for state, char, files in changestates:
6847 if state in show:
6852 if state in show:
6848 label = b'status.' + state
6853 label = b'status.' + state
6849 for f in files:
6854 for f in files:
6850 fm.startitem()
6855 fm.startitem()
6851 fm.context(ctx=ctx2)
6856 fm.context(ctx=ctx2)
6852 fm.data(path=f)
6857 fm.data(path=f)
6853 fm.condwrite(showchar, b'status', b'%s ', char, label=label)
6858 fm.condwrite(showchar, b'status', b'%s ', char, label=label)
6854 fm.plain(fmt % uipathfn(f), label=label)
6859 fm.plain(fmt % uipathfn(f), label=label)
6855 if f in copy:
6860 if f in copy:
6856 fm.data(source=copy[f])
6861 fm.data(source=copy[f])
6857 fm.plain(
6862 fm.plain(
6858 (b' %s' + end) % uipathfn(copy[f]),
6863 (b' %s' + end) % uipathfn(copy[f]),
6859 label=b'status.copied',
6864 label=b'status.copied',
6860 )
6865 )
6861
6866
6862 if (
6867 if (
6863 ui.verbose or ui.configbool(b'commands', b'status.verbose')
6868 ui.verbose or ui.configbool(b'commands', b'status.verbose')
6864 ) and not ui.plain():
6869 ) and not ui.plain():
6865 cmdutil.morestatus(repo, fm)
6870 cmdutil.morestatus(repo, fm)
6866 fm.end()
6871 fm.end()
6867
6872
6868
6873
6869 @command(
6874 @command(
6870 b'summary|sum',
6875 b'summary|sum',
6871 [(b'', b'remote', None, _(b'check for push and pull'))],
6876 [(b'', b'remote', None, _(b'check for push and pull'))],
6872 b'[--remote]',
6877 b'[--remote]',
6873 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6878 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6874 helpbasic=True,
6879 helpbasic=True,
6875 intents={INTENT_READONLY},
6880 intents={INTENT_READONLY},
6876 )
6881 )
6877 def summary(ui, repo, **opts):
6882 def summary(ui, repo, **opts):
6878 """summarize working directory state
6883 """summarize working directory state
6879
6884
6880 This generates a brief summary of the working directory state,
6885 This generates a brief summary of the working directory state,
6881 including parents, branch, commit status, phase and available updates.
6886 including parents, branch, commit status, phase and available updates.
6882
6887
6883 With the --remote option, this will check the default paths for
6888 With the --remote option, this will check the default paths for
6884 incoming and outgoing changes. This can be time-consuming.
6889 incoming and outgoing changes. This can be time-consuming.
6885
6890
6886 Returns 0 on success.
6891 Returns 0 on success.
6887 """
6892 """
6888
6893
6889 opts = pycompat.byteskwargs(opts)
6894 opts = pycompat.byteskwargs(opts)
6890 ui.pager(b'summary')
6895 ui.pager(b'summary')
6891 ctx = repo[None]
6896 ctx = repo[None]
6892 parents = ctx.parents()
6897 parents = ctx.parents()
6893 pnode = parents[0].node()
6898 pnode = parents[0].node()
6894 marks = []
6899 marks = []
6895
6900
6896 try:
6901 try:
6897 ms = mergemod.mergestate.read(repo)
6902 ms = mergemod.mergestate.read(repo)
6898 except error.UnsupportedMergeRecords as e:
6903 except error.UnsupportedMergeRecords as e:
6899 s = b' '.join(e.recordtypes)
6904 s = b' '.join(e.recordtypes)
6900 ui.warn(
6905 ui.warn(
6901 _(b'warning: merge state has unsupported record types: %s\n') % s
6906 _(b'warning: merge state has unsupported record types: %s\n') % s
6902 )
6907 )
6903 unresolved = []
6908 unresolved = []
6904 else:
6909 else:
6905 unresolved = list(ms.unresolved())
6910 unresolved = list(ms.unresolved())
6906
6911
6907 for p in parents:
6912 for p in parents:
6908 # label with log.changeset (instead of log.parent) since this
6913 # label with log.changeset (instead of log.parent) since this
6909 # shows a working directory parent *changeset*:
6914 # shows a working directory parent *changeset*:
6910 # i18n: column positioning for "hg summary"
6915 # i18n: column positioning for "hg summary"
6911 ui.write(
6916 ui.write(
6912 _(b'parent: %d:%s ') % (p.rev(), p),
6917 _(b'parent: %d:%s ') % (p.rev(), p),
6913 label=logcmdutil.changesetlabels(p),
6918 label=logcmdutil.changesetlabels(p),
6914 )
6919 )
6915 ui.write(b' '.join(p.tags()), label=b'log.tag')
6920 ui.write(b' '.join(p.tags()), label=b'log.tag')
6916 if p.bookmarks():
6921 if p.bookmarks():
6917 marks.extend(p.bookmarks())
6922 marks.extend(p.bookmarks())
6918 if p.rev() == -1:
6923 if p.rev() == -1:
6919 if not len(repo):
6924 if not len(repo):
6920 ui.write(_(b' (empty repository)'))
6925 ui.write(_(b' (empty repository)'))
6921 else:
6926 else:
6922 ui.write(_(b' (no revision checked out)'))
6927 ui.write(_(b' (no revision checked out)'))
6923 if p.obsolete():
6928 if p.obsolete():
6924 ui.write(_(b' (obsolete)'))
6929 ui.write(_(b' (obsolete)'))
6925 if p.isunstable():
6930 if p.isunstable():
6926 instabilities = (
6931 instabilities = (
6927 ui.label(instability, b'trouble.%s' % instability)
6932 ui.label(instability, b'trouble.%s' % instability)
6928 for instability in p.instabilities()
6933 for instability in p.instabilities()
6929 )
6934 )
6930 ui.write(b' (' + b', '.join(instabilities) + b')')
6935 ui.write(b' (' + b', '.join(instabilities) + b')')
6931 ui.write(b'\n')
6936 ui.write(b'\n')
6932 if p.description():
6937 if p.description():
6933 ui.status(
6938 ui.status(
6934 b' ' + p.description().splitlines()[0].strip() + b'\n',
6939 b' ' + p.description().splitlines()[0].strip() + b'\n',
6935 label=b'log.summary',
6940 label=b'log.summary',
6936 )
6941 )
6937
6942
6938 branch = ctx.branch()
6943 branch = ctx.branch()
6939 bheads = repo.branchheads(branch)
6944 bheads = repo.branchheads(branch)
6940 # i18n: column positioning for "hg summary"
6945 # i18n: column positioning for "hg summary"
6941 m = _(b'branch: %s\n') % branch
6946 m = _(b'branch: %s\n') % branch
6942 if branch != b'default':
6947 if branch != b'default':
6943 ui.write(m, label=b'log.branch')
6948 ui.write(m, label=b'log.branch')
6944 else:
6949 else:
6945 ui.status(m, label=b'log.branch')
6950 ui.status(m, label=b'log.branch')
6946
6951
6947 if marks:
6952 if marks:
6948 active = repo._activebookmark
6953 active = repo._activebookmark
6949 # i18n: column positioning for "hg summary"
6954 # i18n: column positioning for "hg summary"
6950 ui.write(_(b'bookmarks:'), label=b'log.bookmark')
6955 ui.write(_(b'bookmarks:'), label=b'log.bookmark')
6951 if active is not None:
6956 if active is not None:
6952 if active in marks:
6957 if active in marks:
6953 ui.write(b' *' + active, label=bookmarks.activebookmarklabel)
6958 ui.write(b' *' + active, label=bookmarks.activebookmarklabel)
6954 marks.remove(active)
6959 marks.remove(active)
6955 else:
6960 else:
6956 ui.write(b' [%s]' % active, label=bookmarks.activebookmarklabel)
6961 ui.write(b' [%s]' % active, label=bookmarks.activebookmarklabel)
6957 for m in marks:
6962 for m in marks:
6958 ui.write(b' ' + m, label=b'log.bookmark')
6963 ui.write(b' ' + m, label=b'log.bookmark')
6959 ui.write(b'\n', label=b'log.bookmark')
6964 ui.write(b'\n', label=b'log.bookmark')
6960
6965
6961 status = repo.status(unknown=True)
6966 status = repo.status(unknown=True)
6962
6967
6963 c = repo.dirstate.copies()
6968 c = repo.dirstate.copies()
6964 copied, renamed = [], []
6969 copied, renamed = [], []
6965 for d, s in pycompat.iteritems(c):
6970 for d, s in pycompat.iteritems(c):
6966 if s in status.removed:
6971 if s in status.removed:
6967 status.removed.remove(s)
6972 status.removed.remove(s)
6968 renamed.append(d)
6973 renamed.append(d)
6969 else:
6974 else:
6970 copied.append(d)
6975 copied.append(d)
6971 if d in status.added:
6976 if d in status.added:
6972 status.added.remove(d)
6977 status.added.remove(d)
6973
6978
6974 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6979 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6975
6980
6976 labels = [
6981 labels = [
6977 (ui.label(_(b'%d modified'), b'status.modified'), status.modified),
6982 (ui.label(_(b'%d modified'), b'status.modified'), status.modified),
6978 (ui.label(_(b'%d added'), b'status.added'), status.added),
6983 (ui.label(_(b'%d added'), b'status.added'), status.added),
6979 (ui.label(_(b'%d removed'), b'status.removed'), status.removed),
6984 (ui.label(_(b'%d removed'), b'status.removed'), status.removed),
6980 (ui.label(_(b'%d renamed'), b'status.copied'), renamed),
6985 (ui.label(_(b'%d renamed'), b'status.copied'), renamed),
6981 (ui.label(_(b'%d copied'), b'status.copied'), copied),
6986 (ui.label(_(b'%d copied'), b'status.copied'), copied),
6982 (ui.label(_(b'%d deleted'), b'status.deleted'), status.deleted),
6987 (ui.label(_(b'%d deleted'), b'status.deleted'), status.deleted),
6983 (ui.label(_(b'%d unknown'), b'status.unknown'), status.unknown),
6988 (ui.label(_(b'%d unknown'), b'status.unknown'), status.unknown),
6984 (ui.label(_(b'%d unresolved'), b'resolve.unresolved'), unresolved),
6989 (ui.label(_(b'%d unresolved'), b'resolve.unresolved'), unresolved),
6985 (ui.label(_(b'%d subrepos'), b'status.modified'), subs),
6990 (ui.label(_(b'%d subrepos'), b'status.modified'), subs),
6986 ]
6991 ]
6987 t = []
6992 t = []
6988 for l, s in labels:
6993 for l, s in labels:
6989 if s:
6994 if s:
6990 t.append(l % len(s))
6995 t.append(l % len(s))
6991
6996
6992 t = b', '.join(t)
6997 t = b', '.join(t)
6993 cleanworkdir = False
6998 cleanworkdir = False
6994
6999
6995 if repo.vfs.exists(b'graftstate'):
7000 if repo.vfs.exists(b'graftstate'):
6996 t += _(b' (graft in progress)')
7001 t += _(b' (graft in progress)')
6997 if repo.vfs.exists(b'updatestate'):
7002 if repo.vfs.exists(b'updatestate'):
6998 t += _(b' (interrupted update)')
7003 t += _(b' (interrupted update)')
6999 elif len(parents) > 1:
7004 elif len(parents) > 1:
7000 t += _(b' (merge)')
7005 t += _(b' (merge)')
7001 elif branch != parents[0].branch():
7006 elif branch != parents[0].branch():
7002 t += _(b' (new branch)')
7007 t += _(b' (new branch)')
7003 elif parents[0].closesbranch() and pnode in repo.branchheads(
7008 elif parents[0].closesbranch() and pnode in repo.branchheads(
7004 branch, closed=True
7009 branch, closed=True
7005 ):
7010 ):
7006 t += _(b' (head closed)')
7011 t += _(b' (head closed)')
7007 elif not (
7012 elif not (
7008 status.modified
7013 status.modified
7009 or status.added
7014 or status.added
7010 or status.removed
7015 or status.removed
7011 or renamed
7016 or renamed
7012 or copied
7017 or copied
7013 or subs
7018 or subs
7014 ):
7019 ):
7015 t += _(b' (clean)')
7020 t += _(b' (clean)')
7016 cleanworkdir = True
7021 cleanworkdir = True
7017 elif pnode not in bheads:
7022 elif pnode not in bheads:
7018 t += _(b' (new branch head)')
7023 t += _(b' (new branch head)')
7019
7024
7020 if parents:
7025 if parents:
7021 pendingphase = max(p.phase() for p in parents)
7026 pendingphase = max(p.phase() for p in parents)
7022 else:
7027 else:
7023 pendingphase = phases.public
7028 pendingphase = phases.public
7024
7029
7025 if pendingphase > phases.newcommitphase(ui):
7030 if pendingphase > phases.newcommitphase(ui):
7026 t += b' (%s)' % phases.phasenames[pendingphase]
7031 t += b' (%s)' % phases.phasenames[pendingphase]
7027
7032
7028 if cleanworkdir:
7033 if cleanworkdir:
7029 # i18n: column positioning for "hg summary"
7034 # i18n: column positioning for "hg summary"
7030 ui.status(_(b'commit: %s\n') % t.strip())
7035 ui.status(_(b'commit: %s\n') % t.strip())
7031 else:
7036 else:
7032 # i18n: column positioning for "hg summary"
7037 # i18n: column positioning for "hg summary"
7033 ui.write(_(b'commit: %s\n') % t.strip())
7038 ui.write(_(b'commit: %s\n') % t.strip())
7034
7039
7035 # all ancestors of branch heads - all ancestors of parent = new csets
7040 # all ancestors of branch heads - all ancestors of parent = new csets
7036 new = len(
7041 new = len(
7037 repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
7042 repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
7038 )
7043 )
7039
7044
7040 if new == 0:
7045 if new == 0:
7041 # i18n: column positioning for "hg summary"
7046 # i18n: column positioning for "hg summary"
7042 ui.status(_(b'update: (current)\n'))
7047 ui.status(_(b'update: (current)\n'))
7043 elif pnode not in bheads:
7048 elif pnode not in bheads:
7044 # i18n: column positioning for "hg summary"
7049 # i18n: column positioning for "hg summary"
7045 ui.write(_(b'update: %d new changesets (update)\n') % new)
7050 ui.write(_(b'update: %d new changesets (update)\n') % new)
7046 else:
7051 else:
7047 # i18n: column positioning for "hg summary"
7052 # i18n: column positioning for "hg summary"
7048 ui.write(
7053 ui.write(
7049 _(b'update: %d new changesets, %d branch heads (merge)\n')
7054 _(b'update: %d new changesets, %d branch heads (merge)\n')
7050 % (new, len(bheads))
7055 % (new, len(bheads))
7051 )
7056 )
7052
7057
7053 t = []
7058 t = []
7054 draft = len(repo.revs(b'draft()'))
7059 draft = len(repo.revs(b'draft()'))
7055 if draft:
7060 if draft:
7056 t.append(_(b'%d draft') % draft)
7061 t.append(_(b'%d draft') % draft)
7057 secret = len(repo.revs(b'secret()'))
7062 secret = len(repo.revs(b'secret()'))
7058 if secret:
7063 if secret:
7059 t.append(_(b'%d secret') % secret)
7064 t.append(_(b'%d secret') % secret)
7060
7065
7061 if draft or secret:
7066 if draft or secret:
7062 ui.status(_(b'phases: %s\n') % b', '.join(t))
7067 ui.status(_(b'phases: %s\n') % b', '.join(t))
7063
7068
7064 if obsolete.isenabled(repo, obsolete.createmarkersopt):
7069 if obsolete.isenabled(repo, obsolete.createmarkersopt):
7065 for trouble in (b"orphan", b"contentdivergent", b"phasedivergent"):
7070 for trouble in (b"orphan", b"contentdivergent", b"phasedivergent"):
7066 numtrouble = len(repo.revs(trouble + b"()"))
7071 numtrouble = len(repo.revs(trouble + b"()"))
7067 # We write all the possibilities to ease translation
7072 # We write all the possibilities to ease translation
7068 troublemsg = {
7073 troublemsg = {
7069 b"orphan": _(b"orphan: %d changesets"),
7074 b"orphan": _(b"orphan: %d changesets"),
7070 b"contentdivergent": _(b"content-divergent: %d changesets"),
7075 b"contentdivergent": _(b"content-divergent: %d changesets"),
7071 b"phasedivergent": _(b"phase-divergent: %d changesets"),
7076 b"phasedivergent": _(b"phase-divergent: %d changesets"),
7072 }
7077 }
7073 if numtrouble > 0:
7078 if numtrouble > 0:
7074 ui.status(troublemsg[trouble] % numtrouble + b"\n")
7079 ui.status(troublemsg[trouble] % numtrouble + b"\n")
7075
7080
7076 cmdutil.summaryhooks(ui, repo)
7081 cmdutil.summaryhooks(ui, repo)
7077
7082
7078 if opts.get(b'remote'):
7083 if opts.get(b'remote'):
7079 needsincoming, needsoutgoing = True, True
7084 needsincoming, needsoutgoing = True, True
7080 else:
7085 else:
7081 needsincoming, needsoutgoing = False, False
7086 needsincoming, needsoutgoing = False, False
7082 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
7087 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
7083 if i:
7088 if i:
7084 needsincoming = True
7089 needsincoming = True
7085 if o:
7090 if o:
7086 needsoutgoing = True
7091 needsoutgoing = True
7087 if not needsincoming and not needsoutgoing:
7092 if not needsincoming and not needsoutgoing:
7088 return
7093 return
7089
7094
7090 def getincoming():
7095 def getincoming():
7091 source, branches = hg.parseurl(ui.expandpath(b'default'))
7096 source, branches = hg.parseurl(ui.expandpath(b'default'))
7092 sbranch = branches[0]
7097 sbranch = branches[0]
7093 try:
7098 try:
7094 other = hg.peer(repo, {}, source)
7099 other = hg.peer(repo, {}, source)
7095 except error.RepoError:
7100 except error.RepoError:
7096 if opts.get(b'remote'):
7101 if opts.get(b'remote'):
7097 raise
7102 raise
7098 return source, sbranch, None, None, None
7103 return source, sbranch, None, None, None
7099 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
7104 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
7100 if revs:
7105 if revs:
7101 revs = [other.lookup(rev) for rev in revs]
7106 revs = [other.lookup(rev) for rev in revs]
7102 ui.debug(b'comparing with %s\n' % util.hidepassword(source))
7107 ui.debug(b'comparing with %s\n' % util.hidepassword(source))
7103 repo.ui.pushbuffer()
7108 repo.ui.pushbuffer()
7104 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
7109 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
7105 repo.ui.popbuffer()
7110 repo.ui.popbuffer()
7106 return source, sbranch, other, commoninc, commoninc[1]
7111 return source, sbranch, other, commoninc, commoninc[1]
7107
7112
7108 if needsincoming:
7113 if needsincoming:
7109 source, sbranch, sother, commoninc, incoming = getincoming()
7114 source, sbranch, sother, commoninc, incoming = getincoming()
7110 else:
7115 else:
7111 source = sbranch = sother = commoninc = incoming = None
7116 source = sbranch = sother = commoninc = incoming = None
7112
7117
7113 def getoutgoing():
7118 def getoutgoing():
7114 dest, branches = hg.parseurl(ui.expandpath(b'default-push', b'default'))
7119 dest, branches = hg.parseurl(ui.expandpath(b'default-push', b'default'))
7115 dbranch = branches[0]
7120 dbranch = branches[0]
7116 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
7121 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
7117 if source != dest:
7122 if source != dest:
7118 try:
7123 try:
7119 dother = hg.peer(repo, {}, dest)
7124 dother = hg.peer(repo, {}, dest)
7120 except error.RepoError:
7125 except error.RepoError:
7121 if opts.get(b'remote'):
7126 if opts.get(b'remote'):
7122 raise
7127 raise
7123 return dest, dbranch, None, None
7128 return dest, dbranch, None, None
7124 ui.debug(b'comparing with %s\n' % util.hidepassword(dest))
7129 ui.debug(b'comparing with %s\n' % util.hidepassword(dest))
7125 elif sother is None:
7130 elif sother is None:
7126 # there is no explicit destination peer, but source one is invalid
7131 # there is no explicit destination peer, but source one is invalid
7127 return dest, dbranch, None, None
7132 return dest, dbranch, None, None
7128 else:
7133 else:
7129 dother = sother
7134 dother = sother
7130 if source != dest or (sbranch is not None and sbranch != dbranch):
7135 if source != dest or (sbranch is not None and sbranch != dbranch):
7131 common = None
7136 common = None
7132 else:
7137 else:
7133 common = commoninc
7138 common = commoninc
7134 if revs:
7139 if revs:
7135 revs = [repo.lookup(rev) for rev in revs]
7140 revs = [repo.lookup(rev) for rev in revs]
7136 repo.ui.pushbuffer()
7141 repo.ui.pushbuffer()
7137 outgoing = discovery.findcommonoutgoing(
7142 outgoing = discovery.findcommonoutgoing(
7138 repo, dother, onlyheads=revs, commoninc=common
7143 repo, dother, onlyheads=revs, commoninc=common
7139 )
7144 )
7140 repo.ui.popbuffer()
7145 repo.ui.popbuffer()
7141 return dest, dbranch, dother, outgoing
7146 return dest, dbranch, dother, outgoing
7142
7147
7143 if needsoutgoing:
7148 if needsoutgoing:
7144 dest, dbranch, dother, outgoing = getoutgoing()
7149 dest, dbranch, dother, outgoing = getoutgoing()
7145 else:
7150 else:
7146 dest = dbranch = dother = outgoing = None
7151 dest = dbranch = dother = outgoing = None
7147
7152
7148 if opts.get(b'remote'):
7153 if opts.get(b'remote'):
7149 t = []
7154 t = []
7150 if incoming:
7155 if incoming:
7151 t.append(_(b'1 or more incoming'))
7156 t.append(_(b'1 or more incoming'))
7152 o = outgoing.missing
7157 o = outgoing.missing
7153 if o:
7158 if o:
7154 t.append(_(b'%d outgoing') % len(o))
7159 t.append(_(b'%d outgoing') % len(o))
7155 other = dother or sother
7160 other = dother or sother
7156 if b'bookmarks' in other.listkeys(b'namespaces'):
7161 if b'bookmarks' in other.listkeys(b'namespaces'):
7157 counts = bookmarks.summary(repo, other)
7162 counts = bookmarks.summary(repo, other)
7158 if counts[0] > 0:
7163 if counts[0] > 0:
7159 t.append(_(b'%d incoming bookmarks') % counts[0])
7164 t.append(_(b'%d incoming bookmarks') % counts[0])
7160 if counts[1] > 0:
7165 if counts[1] > 0:
7161 t.append(_(b'%d outgoing bookmarks') % counts[1])
7166 t.append(_(b'%d outgoing bookmarks') % counts[1])
7162
7167
7163 if t:
7168 if t:
7164 # i18n: column positioning for "hg summary"
7169 # i18n: column positioning for "hg summary"
7165 ui.write(_(b'remote: %s\n') % (b', '.join(t)))
7170 ui.write(_(b'remote: %s\n') % (b', '.join(t)))
7166 else:
7171 else:
7167 # i18n: column positioning for "hg summary"
7172 # i18n: column positioning for "hg summary"
7168 ui.status(_(b'remote: (synced)\n'))
7173 ui.status(_(b'remote: (synced)\n'))
7169
7174
7170 cmdutil.summaryremotehooks(
7175 cmdutil.summaryremotehooks(
7171 ui,
7176 ui,
7172 repo,
7177 repo,
7173 opts,
7178 opts,
7174 (
7179 (
7175 (source, sbranch, sother, commoninc),
7180 (source, sbranch, sother, commoninc),
7176 (dest, dbranch, dother, outgoing),
7181 (dest, dbranch, dother, outgoing),
7177 ),
7182 ),
7178 )
7183 )
7179
7184
7180
7185
7181 @command(
7186 @command(
7182 b'tag',
7187 b'tag',
7183 [
7188 [
7184 (b'f', b'force', None, _(b'force tag')),
7189 (b'f', b'force', None, _(b'force tag')),
7185 (b'l', b'local', None, _(b'make the tag local')),
7190 (b'l', b'local', None, _(b'make the tag local')),
7186 (b'r', b'rev', b'', _(b'revision to tag'), _(b'REV')),
7191 (b'r', b'rev', b'', _(b'revision to tag'), _(b'REV')),
7187 (b'', b'remove', None, _(b'remove a tag')),
7192 (b'', b'remove', None, _(b'remove a tag')),
7188 # -l/--local is already there, commitopts cannot be used
7193 # -l/--local is already there, commitopts cannot be used
7189 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
7194 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
7190 (b'm', b'message', b'', _(b'use text as commit message'), _(b'TEXT')),
7195 (b'm', b'message', b'', _(b'use text as commit message'), _(b'TEXT')),
7191 ]
7196 ]
7192 + commitopts2,
7197 + commitopts2,
7193 _(b'[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
7198 _(b'[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
7194 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7199 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7195 )
7200 )
7196 def tag(ui, repo, name1, *names, **opts):
7201 def tag(ui, repo, name1, *names, **opts):
7197 """add one or more tags for the current or given revision
7202 """add one or more tags for the current or given revision
7198
7203
7199 Name a particular revision using <name>.
7204 Name a particular revision using <name>.
7200
7205
7201 Tags are used to name particular revisions of the repository and are
7206 Tags are used to name particular revisions of the repository and are
7202 very useful to compare different revisions, to go back to significant
7207 very useful to compare different revisions, to go back to significant
7203 earlier versions or to mark branch points as releases, etc. Changing
7208 earlier versions or to mark branch points as releases, etc. Changing
7204 an existing tag is normally disallowed; use -f/--force to override.
7209 an existing tag is normally disallowed; use -f/--force to override.
7205
7210
7206 If no revision is given, the parent of the working directory is
7211 If no revision is given, the parent of the working directory is
7207 used.
7212 used.
7208
7213
7209 To facilitate version control, distribution, and merging of tags,
7214 To facilitate version control, distribution, and merging of tags,
7210 they are stored as a file named ".hgtags" which is managed similarly
7215 they are stored as a file named ".hgtags" which is managed similarly
7211 to other project files and can be hand-edited if necessary. This
7216 to other project files and can be hand-edited if necessary. This
7212 also means that tagging creates a new commit. The file
7217 also means that tagging creates a new commit. The file
7213 ".hg/localtags" is used for local tags (not shared among
7218 ".hg/localtags" is used for local tags (not shared among
7214 repositories).
7219 repositories).
7215
7220
7216 Tag commits are usually made at the head of a branch. If the parent
7221 Tag commits are usually made at the head of a branch. If the parent
7217 of the working directory is not a branch head, :hg:`tag` aborts; use
7222 of the working directory is not a branch head, :hg:`tag` aborts; use
7218 -f/--force to force the tag commit to be based on a non-head
7223 -f/--force to force the tag commit to be based on a non-head
7219 changeset.
7224 changeset.
7220
7225
7221 See :hg:`help dates` for a list of formats valid for -d/--date.
7226 See :hg:`help dates` for a list of formats valid for -d/--date.
7222
7227
7223 Since tag names have priority over branch names during revision
7228 Since tag names have priority over branch names during revision
7224 lookup, using an existing branch name as a tag name is discouraged.
7229 lookup, using an existing branch name as a tag name is discouraged.
7225
7230
7226 Returns 0 on success.
7231 Returns 0 on success.
7227 """
7232 """
7228 opts = pycompat.byteskwargs(opts)
7233 opts = pycompat.byteskwargs(opts)
7229 with repo.wlock(), repo.lock():
7234 with repo.wlock(), repo.lock():
7230 rev_ = b"."
7235 rev_ = b"."
7231 names = [t.strip() for t in (name1,) + names]
7236 names = [t.strip() for t in (name1,) + names]
7232 if len(names) != len(set(names)):
7237 if len(names) != len(set(names)):
7233 raise error.Abort(_(b'tag names must be unique'))
7238 raise error.Abort(_(b'tag names must be unique'))
7234 for n in names:
7239 for n in names:
7235 scmutil.checknewlabel(repo, n, b'tag')
7240 scmutil.checknewlabel(repo, n, b'tag')
7236 if not n:
7241 if not n:
7237 raise error.Abort(
7242 raise error.Abort(
7238 _(b'tag names cannot consist entirely of whitespace')
7243 _(b'tag names cannot consist entirely of whitespace')
7239 )
7244 )
7240 if opts.get(b'rev') and opts.get(b'remove'):
7245 if opts.get(b'rev') and opts.get(b'remove'):
7241 raise error.Abort(_(b"--rev and --remove are incompatible"))
7246 raise error.Abort(_(b"--rev and --remove are incompatible"))
7242 if opts.get(b'rev'):
7247 if opts.get(b'rev'):
7243 rev_ = opts[b'rev']
7248 rev_ = opts[b'rev']
7244 message = opts.get(b'message')
7249 message = opts.get(b'message')
7245 if opts.get(b'remove'):
7250 if opts.get(b'remove'):
7246 if opts.get(b'local'):
7251 if opts.get(b'local'):
7247 expectedtype = b'local'
7252 expectedtype = b'local'
7248 else:
7253 else:
7249 expectedtype = b'global'
7254 expectedtype = b'global'
7250
7255
7251 for n in names:
7256 for n in names:
7252 if repo.tagtype(n) == b'global':
7257 if repo.tagtype(n) == b'global':
7253 alltags = tagsmod.findglobaltags(ui, repo)
7258 alltags = tagsmod.findglobaltags(ui, repo)
7254 if alltags[n][0] == nullid:
7259 if alltags[n][0] == nullid:
7255 raise error.Abort(_(b"tag '%s' is already removed") % n)
7260 raise error.Abort(_(b"tag '%s' is already removed") % n)
7256 if not repo.tagtype(n):
7261 if not repo.tagtype(n):
7257 raise error.Abort(_(b"tag '%s' does not exist") % n)
7262 raise error.Abort(_(b"tag '%s' does not exist") % n)
7258 if repo.tagtype(n) != expectedtype:
7263 if repo.tagtype(n) != expectedtype:
7259 if expectedtype == b'global':
7264 if expectedtype == b'global':
7260 raise error.Abort(
7265 raise error.Abort(
7261 _(b"tag '%s' is not a global tag") % n
7266 _(b"tag '%s' is not a global tag") % n
7262 )
7267 )
7263 else:
7268 else:
7264 raise error.Abort(_(b"tag '%s' is not a local tag") % n)
7269 raise error.Abort(_(b"tag '%s' is not a local tag") % n)
7265 rev_ = b'null'
7270 rev_ = b'null'
7266 if not message:
7271 if not message:
7267 # we don't translate commit messages
7272 # we don't translate commit messages
7268 message = b'Removed tag %s' % b', '.join(names)
7273 message = b'Removed tag %s' % b', '.join(names)
7269 elif not opts.get(b'force'):
7274 elif not opts.get(b'force'):
7270 for n in names:
7275 for n in names:
7271 if n in repo.tags():
7276 if n in repo.tags():
7272 raise error.Abort(
7277 raise error.Abort(
7273 _(b"tag '%s' already exists (use -f to force)") % n
7278 _(b"tag '%s' already exists (use -f to force)") % n
7274 )
7279 )
7275 if not opts.get(b'local'):
7280 if not opts.get(b'local'):
7276 p1, p2 = repo.dirstate.parents()
7281 p1, p2 = repo.dirstate.parents()
7277 if p2 != nullid:
7282 if p2 != nullid:
7278 raise error.Abort(_(b'uncommitted merge'))
7283 raise error.Abort(_(b'uncommitted merge'))
7279 bheads = repo.branchheads()
7284 bheads = repo.branchheads()
7280 if not opts.get(b'force') and bheads and p1 not in bheads:
7285 if not opts.get(b'force') and bheads and p1 not in bheads:
7281 raise error.Abort(
7286 raise error.Abort(
7282 _(
7287 _(
7283 b'working directory is not at a branch head '
7288 b'working directory is not at a branch head '
7284 b'(use -f to force)'
7289 b'(use -f to force)'
7285 )
7290 )
7286 )
7291 )
7287 node = scmutil.revsingle(repo, rev_).node()
7292 node = scmutil.revsingle(repo, rev_).node()
7288
7293
7289 if not message:
7294 if not message:
7290 # we don't translate commit messages
7295 # we don't translate commit messages
7291 message = b'Added tag %s for changeset %s' % (
7296 message = b'Added tag %s for changeset %s' % (
7292 b', '.join(names),
7297 b', '.join(names),
7293 short(node),
7298 short(node),
7294 )
7299 )
7295
7300
7296 date = opts.get(b'date')
7301 date = opts.get(b'date')
7297 if date:
7302 if date:
7298 date = dateutil.parsedate(date)
7303 date = dateutil.parsedate(date)
7299
7304
7300 if opts.get(b'remove'):
7305 if opts.get(b'remove'):
7301 editform = b'tag.remove'
7306 editform = b'tag.remove'
7302 else:
7307 else:
7303 editform = b'tag.add'
7308 editform = b'tag.add'
7304 editor = cmdutil.getcommiteditor(
7309 editor = cmdutil.getcommiteditor(
7305 editform=editform, **pycompat.strkwargs(opts)
7310 editform=editform, **pycompat.strkwargs(opts)
7306 )
7311 )
7307
7312
7308 # don't allow tagging the null rev
7313 # don't allow tagging the null rev
7309 if (
7314 if (
7310 not opts.get(b'remove')
7315 not opts.get(b'remove')
7311 and scmutil.revsingle(repo, rev_).rev() == nullrev
7316 and scmutil.revsingle(repo, rev_).rev() == nullrev
7312 ):
7317 ):
7313 raise error.Abort(_(b"cannot tag null revision"))
7318 raise error.Abort(_(b"cannot tag null revision"))
7314
7319
7315 tagsmod.tag(
7320 tagsmod.tag(
7316 repo,
7321 repo,
7317 names,
7322 names,
7318 node,
7323 node,
7319 message,
7324 message,
7320 opts.get(b'local'),
7325 opts.get(b'local'),
7321 opts.get(b'user'),
7326 opts.get(b'user'),
7322 date,
7327 date,
7323 editor=editor,
7328 editor=editor,
7324 )
7329 )
7325
7330
7326
7331
7327 @command(
7332 @command(
7328 b'tags',
7333 b'tags',
7329 formatteropts,
7334 formatteropts,
7330 b'',
7335 b'',
7331 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7336 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7332 intents={INTENT_READONLY},
7337 intents={INTENT_READONLY},
7333 )
7338 )
7334 def tags(ui, repo, **opts):
7339 def tags(ui, repo, **opts):
7335 """list repository tags
7340 """list repository tags
7336
7341
7337 This lists both regular and local tags. When the -v/--verbose
7342 This lists both regular and local tags. When the -v/--verbose
7338 switch is used, a third column "local" is printed for local tags.
7343 switch is used, a third column "local" is printed for local tags.
7339 When the -q/--quiet switch is used, only the tag name is printed.
7344 When the -q/--quiet switch is used, only the tag name is printed.
7340
7345
7341 .. container:: verbose
7346 .. container:: verbose
7342
7347
7343 Template:
7348 Template:
7344
7349
7345 The following keywords are supported in addition to the common template
7350 The following keywords are supported in addition to the common template
7346 keywords and functions such as ``{tag}``. See also
7351 keywords and functions such as ``{tag}``. See also
7347 :hg:`help templates`.
7352 :hg:`help templates`.
7348
7353
7349 :type: String. ``local`` for local tags.
7354 :type: String. ``local`` for local tags.
7350
7355
7351 Returns 0 on success.
7356 Returns 0 on success.
7352 """
7357 """
7353
7358
7354 opts = pycompat.byteskwargs(opts)
7359 opts = pycompat.byteskwargs(opts)
7355 ui.pager(b'tags')
7360 ui.pager(b'tags')
7356 fm = ui.formatter(b'tags', opts)
7361 fm = ui.formatter(b'tags', opts)
7357 hexfunc = fm.hexfunc
7362 hexfunc = fm.hexfunc
7358
7363
7359 for t, n in reversed(repo.tagslist()):
7364 for t, n in reversed(repo.tagslist()):
7360 hn = hexfunc(n)
7365 hn = hexfunc(n)
7361 label = b'tags.normal'
7366 label = b'tags.normal'
7362 tagtype = b''
7367 tagtype = b''
7363 if repo.tagtype(t) == b'local':
7368 if repo.tagtype(t) == b'local':
7364 label = b'tags.local'
7369 label = b'tags.local'
7365 tagtype = b'local'
7370 tagtype = b'local'
7366
7371
7367 fm.startitem()
7372 fm.startitem()
7368 fm.context(repo=repo)
7373 fm.context(repo=repo)
7369 fm.write(b'tag', b'%s', t, label=label)
7374 fm.write(b'tag', b'%s', t, label=label)
7370 fmt = b" " * (30 - encoding.colwidth(t)) + b' %5d:%s'
7375 fmt = b" " * (30 - encoding.colwidth(t)) + b' %5d:%s'
7371 fm.condwrite(
7376 fm.condwrite(
7372 not ui.quiet,
7377 not ui.quiet,
7373 b'rev node',
7378 b'rev node',
7374 fmt,
7379 fmt,
7375 repo.changelog.rev(n),
7380 repo.changelog.rev(n),
7376 hn,
7381 hn,
7377 label=label,
7382 label=label,
7378 )
7383 )
7379 fm.condwrite(
7384 fm.condwrite(
7380 ui.verbose and tagtype, b'type', b' %s', tagtype, label=label
7385 ui.verbose and tagtype, b'type', b' %s', tagtype, label=label
7381 )
7386 )
7382 fm.plain(b'\n')
7387 fm.plain(b'\n')
7383 fm.end()
7388 fm.end()
7384
7389
7385
7390
7386 @command(
7391 @command(
7387 b'tip',
7392 b'tip',
7388 [
7393 [
7389 (b'p', b'patch', None, _(b'show patch')),
7394 (b'p', b'patch', None, _(b'show patch')),
7390 (b'g', b'git', None, _(b'use git extended diff format')),
7395 (b'g', b'git', None, _(b'use git extended diff format')),
7391 ]
7396 ]
7392 + templateopts,
7397 + templateopts,
7393 _(b'[-p] [-g]'),
7398 _(b'[-p] [-g]'),
7394 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
7399 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
7395 )
7400 )
7396 def tip(ui, repo, **opts):
7401 def tip(ui, repo, **opts):
7397 """show the tip revision (DEPRECATED)
7402 """show the tip revision (DEPRECATED)
7398
7403
7399 The tip revision (usually just called the tip) is the changeset
7404 The tip revision (usually just called the tip) is the changeset
7400 most recently added to the repository (and therefore the most
7405 most recently added to the repository (and therefore the most
7401 recently changed head).
7406 recently changed head).
7402
7407
7403 If you have just made a commit, that commit will be the tip. If
7408 If you have just made a commit, that commit will be the tip. If
7404 you have just pulled changes from another repository, the tip of
7409 you have just pulled changes from another repository, the tip of
7405 that repository becomes the current tip. The "tip" tag is special
7410 that repository becomes the current tip. The "tip" tag is special
7406 and cannot be renamed or assigned to a different changeset.
7411 and cannot be renamed or assigned to a different changeset.
7407
7412
7408 This command is deprecated, please use :hg:`heads` instead.
7413 This command is deprecated, please use :hg:`heads` instead.
7409
7414
7410 Returns 0 on success.
7415 Returns 0 on success.
7411 """
7416 """
7412 opts = pycompat.byteskwargs(opts)
7417 opts = pycompat.byteskwargs(opts)
7413 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
7418 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
7414 displayer.show(repo[b'tip'])
7419 displayer.show(repo[b'tip'])
7415 displayer.close()
7420 displayer.close()
7416
7421
7417
7422
7418 @command(
7423 @command(
7419 b'unbundle',
7424 b'unbundle',
7420 [
7425 [
7421 (
7426 (
7422 b'u',
7427 b'u',
7423 b'update',
7428 b'update',
7424 None,
7429 None,
7425 _(b'update to new branch head if changesets were unbundled'),
7430 _(b'update to new branch head if changesets were unbundled'),
7426 )
7431 )
7427 ],
7432 ],
7428 _(b'[-u] FILE...'),
7433 _(b'[-u] FILE...'),
7429 helpcategory=command.CATEGORY_IMPORT_EXPORT,
7434 helpcategory=command.CATEGORY_IMPORT_EXPORT,
7430 )
7435 )
7431 def unbundle(ui, repo, fname1, *fnames, **opts):
7436 def unbundle(ui, repo, fname1, *fnames, **opts):
7432 """apply one or more bundle files
7437 """apply one or more bundle files
7433
7438
7434 Apply one or more bundle files generated by :hg:`bundle`.
7439 Apply one or more bundle files generated by :hg:`bundle`.
7435
7440
7436 Returns 0 on success, 1 if an update has unresolved files.
7441 Returns 0 on success, 1 if an update has unresolved files.
7437 """
7442 """
7438 fnames = (fname1,) + fnames
7443 fnames = (fname1,) + fnames
7439
7444
7440 with repo.lock():
7445 with repo.lock():
7441 for fname in fnames:
7446 for fname in fnames:
7442 f = hg.openpath(ui, fname)
7447 f = hg.openpath(ui, fname)
7443 gen = exchange.readbundle(ui, f, fname)
7448 gen = exchange.readbundle(ui, f, fname)
7444 if isinstance(gen, streamclone.streamcloneapplier):
7449 if isinstance(gen, streamclone.streamcloneapplier):
7445 raise error.Abort(
7450 raise error.Abort(
7446 _(
7451 _(
7447 b'packed bundles cannot be applied with '
7452 b'packed bundles cannot be applied with '
7448 b'"hg unbundle"'
7453 b'"hg unbundle"'
7449 ),
7454 ),
7450 hint=_(b'use "hg debugapplystreamclonebundle"'),
7455 hint=_(b'use "hg debugapplystreamclonebundle"'),
7451 )
7456 )
7452 url = b'bundle:' + fname
7457 url = b'bundle:' + fname
7453 try:
7458 try:
7454 txnname = b'unbundle'
7459 txnname = b'unbundle'
7455 if not isinstance(gen, bundle2.unbundle20):
7460 if not isinstance(gen, bundle2.unbundle20):
7456 txnname = b'unbundle\n%s' % util.hidepassword(url)
7461 txnname = b'unbundle\n%s' % util.hidepassword(url)
7457 with repo.transaction(txnname) as tr:
7462 with repo.transaction(txnname) as tr:
7458 op = bundle2.applybundle(
7463 op = bundle2.applybundle(
7459 repo, gen, tr, source=b'unbundle', url=url
7464 repo, gen, tr, source=b'unbundle', url=url
7460 )
7465 )
7461 except error.BundleUnknownFeatureError as exc:
7466 except error.BundleUnknownFeatureError as exc:
7462 raise error.Abort(
7467 raise error.Abort(
7463 _(b'%s: unknown bundle feature, %s') % (fname, exc),
7468 _(b'%s: unknown bundle feature, %s') % (fname, exc),
7464 hint=_(
7469 hint=_(
7465 b"see https://mercurial-scm.org/"
7470 b"see https://mercurial-scm.org/"
7466 b"wiki/BundleFeature for more "
7471 b"wiki/BundleFeature for more "
7467 b"information"
7472 b"information"
7468 ),
7473 ),
7469 )
7474 )
7470 modheads = bundle2.combinechangegroupresults(op)
7475 modheads = bundle2.combinechangegroupresults(op)
7471
7476
7472 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
7477 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
7473
7478
7474
7479
7475 @command(
7480 @command(
7476 b'unshelve',
7481 b'unshelve',
7477 [
7482 [
7478 (b'a', b'abort', None, _(b'abort an incomplete unshelve operation')),
7483 (b'a', b'abort', None, _(b'abort an incomplete unshelve operation')),
7479 (
7484 (
7480 b'c',
7485 b'c',
7481 b'continue',
7486 b'continue',
7482 None,
7487 None,
7483 _(b'continue an incomplete unshelve operation'),
7488 _(b'continue an incomplete unshelve operation'),
7484 ),
7489 ),
7485 (b'i', b'interactive', None, _(b'use interactive mode (EXPERIMENTAL)')),
7490 (b'i', b'interactive', None, _(b'use interactive mode (EXPERIMENTAL)')),
7486 (b'k', b'keep', None, _(b'keep shelve after unshelving')),
7491 (b'k', b'keep', None, _(b'keep shelve after unshelving')),
7487 (
7492 (
7488 b'n',
7493 b'n',
7489 b'name',
7494 b'name',
7490 b'',
7495 b'',
7491 _(b'restore shelved change with given name'),
7496 _(b'restore shelved change with given name'),
7492 _(b'NAME'),
7497 _(b'NAME'),
7493 ),
7498 ),
7494 (b't', b'tool', b'', _(b'specify merge tool')),
7499 (b't', b'tool', b'', _(b'specify merge tool')),
7495 (
7500 (
7496 b'',
7501 b'',
7497 b'date',
7502 b'date',
7498 b'',
7503 b'',
7499 _(b'set date for temporary commits (DEPRECATED)'),
7504 _(b'set date for temporary commits (DEPRECATED)'),
7500 _(b'DATE'),
7505 _(b'DATE'),
7501 ),
7506 ),
7502 ],
7507 ],
7503 _(b'hg unshelve [OPTION]... [FILE]... [-n SHELVED]'),
7508 _(b'hg unshelve [OPTION]... [FILE]... [-n SHELVED]'),
7504 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7509 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7505 )
7510 )
7506 def unshelve(ui, repo, *shelved, **opts):
7511 def unshelve(ui, repo, *shelved, **opts):
7507 """restore a shelved change to the working directory
7512 """restore a shelved change to the working directory
7508
7513
7509 This command accepts an optional name of a shelved change to
7514 This command accepts an optional name of a shelved change to
7510 restore. If none is given, the most recent shelved change is used.
7515 restore. If none is given, the most recent shelved change is used.
7511
7516
7512 If a shelved change is applied successfully, the bundle that
7517 If a shelved change is applied successfully, the bundle that
7513 contains the shelved changes is moved to a backup location
7518 contains the shelved changes is moved to a backup location
7514 (.hg/shelve-backup).
7519 (.hg/shelve-backup).
7515
7520
7516 Since you can restore a shelved change on top of an arbitrary
7521 Since you can restore a shelved change on top of an arbitrary
7517 commit, it is possible that unshelving will result in a conflict
7522 commit, it is possible that unshelving will result in a conflict
7518 between your changes and the commits you are unshelving onto. If
7523 between your changes and the commits you are unshelving onto. If
7519 this occurs, you must resolve the conflict, then use
7524 this occurs, you must resolve the conflict, then use
7520 ``--continue`` to complete the unshelve operation. (The bundle
7525 ``--continue`` to complete the unshelve operation. (The bundle
7521 will not be moved until you successfully complete the unshelve.)
7526 will not be moved until you successfully complete the unshelve.)
7522
7527
7523 (Alternatively, you can use ``--abort`` to abandon an unshelve
7528 (Alternatively, you can use ``--abort`` to abandon an unshelve
7524 that causes a conflict. This reverts the unshelved changes, and
7529 that causes a conflict. This reverts the unshelved changes, and
7525 leaves the bundle in place.)
7530 leaves the bundle in place.)
7526
7531
7527 If bare shelved change (when no files are specified, without interactive,
7532 If bare shelved change (when no files are specified, without interactive,
7528 include and exclude option) was done on newly created branch it would
7533 include and exclude option) was done on newly created branch it would
7529 restore branch information to the working directory.
7534 restore branch information to the working directory.
7530
7535
7531 After a successful unshelve, the shelved changes are stored in a
7536 After a successful unshelve, the shelved changes are stored in a
7532 backup directory. Only the N most recent backups are kept. N
7537 backup directory. Only the N most recent backups are kept. N
7533 defaults to 10 but can be overridden using the ``shelve.maxbackups``
7538 defaults to 10 but can be overridden using the ``shelve.maxbackups``
7534 configuration option.
7539 configuration option.
7535
7540
7536 .. container:: verbose
7541 .. container:: verbose
7537
7542
7538 Timestamp in seconds is used to decide order of backups. More
7543 Timestamp in seconds is used to decide order of backups. More
7539 than ``maxbackups`` backups are kept, if same timestamp
7544 than ``maxbackups`` backups are kept, if same timestamp
7540 prevents from deciding exact order of them, for safety.
7545 prevents from deciding exact order of them, for safety.
7541
7546
7542 Selected changes can be unshelved with ``--interactive`` flag.
7547 Selected changes can be unshelved with ``--interactive`` flag.
7543 The working directory is updated with the selected changes, and
7548 The working directory is updated with the selected changes, and
7544 only the unselected changes remain shelved.
7549 only the unselected changes remain shelved.
7545 Note: The whole shelve is applied to working directory first before
7550 Note: The whole shelve is applied to working directory first before
7546 running interactively. So, this will bring up all the conflicts between
7551 running interactively. So, this will bring up all the conflicts between
7547 working directory and the shelve, irrespective of which changes will be
7552 working directory and the shelve, irrespective of which changes will be
7548 unshelved.
7553 unshelved.
7549 """
7554 """
7550 with repo.wlock():
7555 with repo.wlock():
7551 return shelvemod.dounshelve(ui, repo, *shelved, **opts)
7556 return shelvemod.dounshelve(ui, repo, *shelved, **opts)
7552
7557
7553
7558
7554 statemod.addunfinished(
7559 statemod.addunfinished(
7555 b'unshelve',
7560 b'unshelve',
7556 fname=b'shelvedstate',
7561 fname=b'shelvedstate',
7557 continueflag=True,
7562 continueflag=True,
7558 abortfunc=shelvemod.hgabortunshelve,
7563 abortfunc=shelvemod.hgabortunshelve,
7559 continuefunc=shelvemod.hgcontinueunshelve,
7564 continuefunc=shelvemod.hgcontinueunshelve,
7560 cmdmsg=_(b'unshelve already in progress'),
7565 cmdmsg=_(b'unshelve already in progress'),
7561 )
7566 )
7562
7567
7563
7568
7564 @command(
7569 @command(
7565 b'update|up|checkout|co',
7570 b'update|up|checkout|co',
7566 [
7571 [
7567 (b'C', b'clean', None, _(b'discard uncommitted changes (no backup)')),
7572 (b'C', b'clean', None, _(b'discard uncommitted changes (no backup)')),
7568 (b'c', b'check', None, _(b'require clean working directory')),
7573 (b'c', b'check', None, _(b'require clean working directory')),
7569 (b'm', b'merge', None, _(b'merge uncommitted changes')),
7574 (b'm', b'merge', None, _(b'merge uncommitted changes')),
7570 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
7575 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
7571 (b'r', b'rev', b'', _(b'revision'), _(b'REV')),
7576 (b'r', b'rev', b'', _(b'revision'), _(b'REV')),
7572 ]
7577 ]
7573 + mergetoolopts,
7578 + mergetoolopts,
7574 _(b'[-C|-c|-m] [-d DATE] [[-r] REV]'),
7579 _(b'[-C|-c|-m] [-d DATE] [[-r] REV]'),
7575 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7580 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7576 helpbasic=True,
7581 helpbasic=True,
7577 )
7582 )
7578 def update(ui, repo, node=None, **opts):
7583 def update(ui, repo, node=None, **opts):
7579 """update working directory (or switch revisions)
7584 """update working directory (or switch revisions)
7580
7585
7581 Update the repository's working directory to the specified
7586 Update the repository's working directory to the specified
7582 changeset. If no changeset is specified, update to the tip of the
7587 changeset. If no changeset is specified, update to the tip of the
7583 current named branch and move the active bookmark (see :hg:`help
7588 current named branch and move the active bookmark (see :hg:`help
7584 bookmarks`).
7589 bookmarks`).
7585
7590
7586 Update sets the working directory's parent revision to the specified
7591 Update sets the working directory's parent revision to the specified
7587 changeset (see :hg:`help parents`).
7592 changeset (see :hg:`help parents`).
7588
7593
7589 If the changeset is not a descendant or ancestor of the working
7594 If the changeset is not a descendant or ancestor of the working
7590 directory's parent and there are uncommitted changes, the update is
7595 directory's parent and there are uncommitted changes, the update is
7591 aborted. With the -c/--check option, the working directory is checked
7596 aborted. With the -c/--check option, the working directory is checked
7592 for uncommitted changes; if none are found, the working directory is
7597 for uncommitted changes; if none are found, the working directory is
7593 updated to the specified changeset.
7598 updated to the specified changeset.
7594
7599
7595 .. container:: verbose
7600 .. container:: verbose
7596
7601
7597 The -C/--clean, -c/--check, and -m/--merge options control what
7602 The -C/--clean, -c/--check, and -m/--merge options control what
7598 happens if the working directory contains uncommitted changes.
7603 happens if the working directory contains uncommitted changes.
7599 At most of one of them can be specified.
7604 At most of one of them can be specified.
7600
7605
7601 1. If no option is specified, and if
7606 1. If no option is specified, and if
7602 the requested changeset is an ancestor or descendant of
7607 the requested changeset is an ancestor or descendant of
7603 the working directory's parent, the uncommitted changes
7608 the working directory's parent, the uncommitted changes
7604 are merged into the requested changeset and the merged
7609 are merged into the requested changeset and the merged
7605 result is left uncommitted. If the requested changeset is
7610 result is left uncommitted. If the requested changeset is
7606 not an ancestor or descendant (that is, it is on another
7611 not an ancestor or descendant (that is, it is on another
7607 branch), the update is aborted and the uncommitted changes
7612 branch), the update is aborted and the uncommitted changes
7608 are preserved.
7613 are preserved.
7609
7614
7610 2. With the -m/--merge option, the update is allowed even if the
7615 2. With the -m/--merge option, the update is allowed even if the
7611 requested changeset is not an ancestor or descendant of
7616 requested changeset is not an ancestor or descendant of
7612 the working directory's parent.
7617 the working directory's parent.
7613
7618
7614 3. With the -c/--check option, the update is aborted and the
7619 3. With the -c/--check option, the update is aborted and the
7615 uncommitted changes are preserved.
7620 uncommitted changes are preserved.
7616
7621
7617 4. With the -C/--clean option, uncommitted changes are discarded and
7622 4. With the -C/--clean option, uncommitted changes are discarded and
7618 the working directory is updated to the requested changeset.
7623 the working directory is updated to the requested changeset.
7619
7624
7620 To cancel an uncommitted merge (and lose your changes), use
7625 To cancel an uncommitted merge (and lose your changes), use
7621 :hg:`merge --abort`.
7626 :hg:`merge --abort`.
7622
7627
7623 Use null as the changeset to remove the working directory (like
7628 Use null as the changeset to remove the working directory (like
7624 :hg:`clone -U`).
7629 :hg:`clone -U`).
7625
7630
7626 If you want to revert just one file to an older revision, use
7631 If you want to revert just one file to an older revision, use
7627 :hg:`revert [-r REV] NAME`.
7632 :hg:`revert [-r REV] NAME`.
7628
7633
7629 See :hg:`help dates` for a list of formats valid for -d/--date.
7634 See :hg:`help dates` for a list of formats valid for -d/--date.
7630
7635
7631 Returns 0 on success, 1 if there are unresolved files.
7636 Returns 0 on success, 1 if there are unresolved files.
7632 """
7637 """
7633 rev = opts.get(r'rev')
7638 rev = opts.get(r'rev')
7634 date = opts.get(r'date')
7639 date = opts.get(r'date')
7635 clean = opts.get(r'clean')
7640 clean = opts.get(r'clean')
7636 check = opts.get(r'check')
7641 check = opts.get(r'check')
7637 merge = opts.get(r'merge')
7642 merge = opts.get(r'merge')
7638 if rev and node:
7643 if rev and node:
7639 raise error.Abort(_(b"please specify just one revision"))
7644 raise error.Abort(_(b"please specify just one revision"))
7640
7645
7641 if ui.configbool(b'commands', b'update.requiredest'):
7646 if ui.configbool(b'commands', b'update.requiredest'):
7642 if not node and not rev and not date:
7647 if not node and not rev and not date:
7643 raise error.Abort(
7648 raise error.Abort(
7644 _(b'you must specify a destination'),
7649 _(b'you must specify a destination'),
7645 hint=_(b'for example: hg update ".::"'),
7650 hint=_(b'for example: hg update ".::"'),
7646 )
7651 )
7647
7652
7648 if rev is None or rev == b'':
7653 if rev is None or rev == b'':
7649 rev = node
7654 rev = node
7650
7655
7651 if date and rev is not None:
7656 if date and rev is not None:
7652 raise error.Abort(_(b"you can't specify a revision and a date"))
7657 raise error.Abort(_(b"you can't specify a revision and a date"))
7653
7658
7654 if len([x for x in (clean, check, merge) if x]) > 1:
7659 if len([x for x in (clean, check, merge) if x]) > 1:
7655 raise error.Abort(
7660 raise error.Abort(
7656 _(
7661 _(
7657 b"can only specify one of -C/--clean, -c/--check, "
7662 b"can only specify one of -C/--clean, -c/--check, "
7658 b"or -m/--merge"
7663 b"or -m/--merge"
7659 )
7664 )
7660 )
7665 )
7661
7666
7662 updatecheck = None
7667 updatecheck = None
7663 if check:
7668 if check:
7664 updatecheck = b'abort'
7669 updatecheck = b'abort'
7665 elif merge:
7670 elif merge:
7666 updatecheck = b'none'
7671 updatecheck = b'none'
7667
7672
7668 with repo.wlock():
7673 with repo.wlock():
7669 cmdutil.clearunfinished(repo)
7674 cmdutil.clearunfinished(repo)
7670 if date:
7675 if date:
7671 rev = cmdutil.finddate(ui, repo, date)
7676 rev = cmdutil.finddate(ui, repo, date)
7672
7677
7673 # if we defined a bookmark, we have to remember the original name
7678 # if we defined a bookmark, we have to remember the original name
7674 brev = rev
7679 brev = rev
7675 if rev:
7680 if rev:
7676 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
7681 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
7677 ctx = scmutil.revsingle(repo, rev, default=None)
7682 ctx = scmutil.revsingle(repo, rev, default=None)
7678 rev = ctx.rev()
7683 rev = ctx.rev()
7679 hidden = ctx.hidden()
7684 hidden = ctx.hidden()
7680 overrides = {(b'ui', b'forcemerge'): opts.get(r'tool', b'')}
7685 overrides = {(b'ui', b'forcemerge'): opts.get(r'tool', b'')}
7681 with ui.configoverride(overrides, b'update'):
7686 with ui.configoverride(overrides, b'update'):
7682 ret = hg.updatetotally(
7687 ret = hg.updatetotally(
7683 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
7688 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
7684 )
7689 )
7685 if hidden:
7690 if hidden:
7686 ctxstr = ctx.hex()[:12]
7691 ctxstr = ctx.hex()[:12]
7687 ui.warn(_(b"updated to hidden changeset %s\n") % ctxstr)
7692 ui.warn(_(b"updated to hidden changeset %s\n") % ctxstr)
7688
7693
7689 if ctx.obsolete():
7694 if ctx.obsolete():
7690 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
7695 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
7691 ui.warn(b"(%s)\n" % obsfatemsg)
7696 ui.warn(b"(%s)\n" % obsfatemsg)
7692 return ret
7697 return ret
7693
7698
7694
7699
7695 @command(
7700 @command(
7696 b'verify',
7701 b'verify',
7697 [(b'', b'full', False, b'perform more checks (EXPERIMENTAL)')],
7702 [(b'', b'full', False, b'perform more checks (EXPERIMENTAL)')],
7698 helpcategory=command.CATEGORY_MAINTENANCE,
7703 helpcategory=command.CATEGORY_MAINTENANCE,
7699 )
7704 )
7700 def verify(ui, repo, **opts):
7705 def verify(ui, repo, **opts):
7701 """verify the integrity of the repository
7706 """verify the integrity of the repository
7702
7707
7703 Verify the integrity of the current repository.
7708 Verify the integrity of the current repository.
7704
7709
7705 This will perform an extensive check of the repository's
7710 This will perform an extensive check of the repository's
7706 integrity, validating the hashes and checksums of each entry in
7711 integrity, validating the hashes and checksums of each entry in
7707 the changelog, manifest, and tracked files, as well as the
7712 the changelog, manifest, and tracked files, as well as the
7708 integrity of their crosslinks and indices.
7713 integrity of their crosslinks and indices.
7709
7714
7710 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
7715 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
7711 for more information about recovery from corruption of the
7716 for more information about recovery from corruption of the
7712 repository.
7717 repository.
7713
7718
7714 Returns 0 on success, 1 if errors are encountered.
7719 Returns 0 on success, 1 if errors are encountered.
7715 """
7720 """
7716 opts = pycompat.byteskwargs(opts)
7721 opts = pycompat.byteskwargs(opts)
7717
7722
7718 level = None
7723 level = None
7719 if opts[b'full']:
7724 if opts[b'full']:
7720 level = verifymod.VERIFY_FULL
7725 level = verifymod.VERIFY_FULL
7721 return hg.verify(repo, level)
7726 return hg.verify(repo, level)
7722
7727
7723
7728
7724 @command(
7729 @command(
7725 b'version',
7730 b'version',
7726 [] + formatteropts,
7731 [] + formatteropts,
7727 helpcategory=command.CATEGORY_HELP,
7732 helpcategory=command.CATEGORY_HELP,
7728 norepo=True,
7733 norepo=True,
7729 intents={INTENT_READONLY},
7734 intents={INTENT_READONLY},
7730 )
7735 )
7731 def version_(ui, **opts):
7736 def version_(ui, **opts):
7732 """output version and copyright information
7737 """output version and copyright information
7733
7738
7734 .. container:: verbose
7739 .. container:: verbose
7735
7740
7736 Template:
7741 Template:
7737
7742
7738 The following keywords are supported. See also :hg:`help templates`.
7743 The following keywords are supported. See also :hg:`help templates`.
7739
7744
7740 :extensions: List of extensions.
7745 :extensions: List of extensions.
7741 :ver: String. Version number.
7746 :ver: String. Version number.
7742
7747
7743 And each entry of ``{extensions}`` provides the following sub-keywords
7748 And each entry of ``{extensions}`` provides the following sub-keywords
7744 in addition to ``{ver}``.
7749 in addition to ``{ver}``.
7745
7750
7746 :bundled: Boolean. True if included in the release.
7751 :bundled: Boolean. True if included in the release.
7747 :name: String. Extension name.
7752 :name: String. Extension name.
7748 """
7753 """
7749 opts = pycompat.byteskwargs(opts)
7754 opts = pycompat.byteskwargs(opts)
7750 if ui.verbose:
7755 if ui.verbose:
7751 ui.pager(b'version')
7756 ui.pager(b'version')
7752 fm = ui.formatter(b"version", opts)
7757 fm = ui.formatter(b"version", opts)
7753 fm.startitem()
7758 fm.startitem()
7754 fm.write(
7759 fm.write(
7755 b"ver", _(b"Mercurial Distributed SCM (version %s)\n"), util.version()
7760 b"ver", _(b"Mercurial Distributed SCM (version %s)\n"), util.version()
7756 )
7761 )
7757 license = _(
7762 license = _(
7758 b"(see https://mercurial-scm.org for more information)\n"
7763 b"(see https://mercurial-scm.org for more information)\n"
7759 b"\nCopyright (C) 2005-2019 Matt Mackall and others\n"
7764 b"\nCopyright (C) 2005-2019 Matt Mackall and others\n"
7760 b"This is free software; see the source for copying conditions. "
7765 b"This is free software; see the source for copying conditions. "
7761 b"There is NO\nwarranty; "
7766 b"There is NO\nwarranty; "
7762 b"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
7767 b"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
7763 )
7768 )
7764 if not ui.quiet:
7769 if not ui.quiet:
7765 fm.plain(license)
7770 fm.plain(license)
7766
7771
7767 if ui.verbose:
7772 if ui.verbose:
7768 fm.plain(_(b"\nEnabled extensions:\n\n"))
7773 fm.plain(_(b"\nEnabled extensions:\n\n"))
7769 # format names and versions into columns
7774 # format names and versions into columns
7770 names = []
7775 names = []
7771 vers = []
7776 vers = []
7772 isinternals = []
7777 isinternals = []
7773 for name, module in extensions.extensions():
7778 for name, module in extensions.extensions():
7774 names.append(name)
7779 names.append(name)
7775 vers.append(extensions.moduleversion(module) or None)
7780 vers.append(extensions.moduleversion(module) or None)
7776 isinternals.append(extensions.ismoduleinternal(module))
7781 isinternals.append(extensions.ismoduleinternal(module))
7777 fn = fm.nested(b"extensions", tmpl=b'{name}\n')
7782 fn = fm.nested(b"extensions", tmpl=b'{name}\n')
7778 if names:
7783 if names:
7779 namefmt = b" %%-%ds " % max(len(n) for n in names)
7784 namefmt = b" %%-%ds " % max(len(n) for n in names)
7780 places = [_(b"external"), _(b"internal")]
7785 places = [_(b"external"), _(b"internal")]
7781 for n, v, p in zip(names, vers, isinternals):
7786 for n, v, p in zip(names, vers, isinternals):
7782 fn.startitem()
7787 fn.startitem()
7783 fn.condwrite(ui.verbose, b"name", namefmt, n)
7788 fn.condwrite(ui.verbose, b"name", namefmt, n)
7784 if ui.verbose:
7789 if ui.verbose:
7785 fn.plain(b"%s " % places[p])
7790 fn.plain(b"%s " % places[p])
7786 fn.data(bundled=p)
7791 fn.data(bundled=p)
7787 fn.condwrite(ui.verbose and v, b"ver", b"%s", v)
7792 fn.condwrite(ui.verbose and v, b"ver", b"%s", v)
7788 if ui.verbose:
7793 if ui.verbose:
7789 fn.plain(b"\n")
7794 fn.plain(b"\n")
7790 fn.end()
7795 fn.end()
7791 fm.end()
7796 fm.end()
7792
7797
7793
7798
7794 def loadcmdtable(ui, name, cmdtable):
7799 def loadcmdtable(ui, name, cmdtable):
7795 """Load command functions from specified cmdtable
7800 """Load command functions from specified cmdtable
7796 """
7801 """
7797 overrides = [cmd for cmd in cmdtable if cmd in table]
7802 overrides = [cmd for cmd in cmdtable if cmd in table]
7798 if overrides:
7803 if overrides:
7799 ui.warn(
7804 ui.warn(
7800 _(b"extension '%s' overrides commands: %s\n")
7805 _(b"extension '%s' overrides commands: %s\n")
7801 % (name, b" ".join(overrides))
7806 % (name, b" ".join(overrides))
7802 )
7807 )
7803 table.update(cmdtable)
7808 table.update(cmdtable)
@@ -1,562 +1,562 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo a > a
3 $ echo a > a
4 $ hg ci -A -d'1 0' -m a
4 $ hg ci -A -d'1 0' -m a
5 adding a
5 adding a
6
6
7 $ cd ..
7 $ cd ..
8
8
9 $ hg init b
9 $ hg init b
10 $ cd b
10 $ cd b
11 $ echo b > b
11 $ echo b > b
12 $ hg ci -A -d'1 0' -m b
12 $ hg ci -A -d'1 0' -m b
13 adding b
13 adding b
14
14
15 $ cd ..
15 $ cd ..
16
16
17 $ hg clone a c
17 $ hg clone a c
18 updating to branch default
18 updating to branch default
19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 $ cd c
20 $ cd c
21 $ cat >> .hg/hgrc <<EOF
21 $ cat >> .hg/hgrc <<EOF
22 > [paths]
22 > [paths]
23 > relative = ../a
23 > relative = ../a
24 > EOF
24 > EOF
25 $ hg pull -f ../b
25 $ hg pull -f ../b
26 pulling from ../b
26 pulling from ../b
27 searching for changes
27 searching for changes
28 warning: repository is unrelated
28 warning: repository is unrelated
29 requesting all changes
29 requesting all changes
30 adding changesets
30 adding changesets
31 adding manifests
31 adding manifests
32 adding file changes
32 adding file changes
33 added 1 changesets with 1 changes to 1 files (+1 heads)
33 added 1 changesets with 1 changes to 1 files (+1 heads)
34 new changesets b6c483daf290
34 new changesets b6c483daf290
35 (run 'hg heads' to see heads, 'hg merge' to merge)
35 (run 'hg heads' to see heads, 'hg merge' to merge)
36 $ hg merge
36 $ hg merge
37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 (branch merge, don't forget to commit)
38 (branch merge, don't forget to commit)
39
39
40 $ cd ..
40 $ cd ..
41
41
42 Testing -R/--repository:
42 Testing -R/--repository:
43
43
44 $ hg -R a tip
44 $ hg -R a tip
45 changeset: 0:8580ff50825a
45 changeset: 0:8580ff50825a
46 tag: tip
46 tag: tip
47 user: test
47 user: test
48 date: Thu Jan 01 00:00:01 1970 +0000
48 date: Thu Jan 01 00:00:01 1970 +0000
49 summary: a
49 summary: a
50
50
51 $ hg --repository b tip
51 $ hg --repository b tip
52 changeset: 0:b6c483daf290
52 changeset: 0:b6c483daf290
53 tag: tip
53 tag: tip
54 user: test
54 user: test
55 date: Thu Jan 01 00:00:01 1970 +0000
55 date: Thu Jan 01 00:00:01 1970 +0000
56 summary: b
56 summary: b
57
57
58
58
59 -R with a URL:
59 -R with a URL:
60
60
61 $ hg -R file:a identify
61 $ hg -R file:a identify
62 8580ff50825a tip
62 8580ff50825a tip
63 $ hg -R file://localhost/`pwd`/a/ identify
63 $ hg -R file://localhost/`pwd`/a/ identify
64 8580ff50825a tip
64 8580ff50825a tip
65
65
66 -R with path aliases:
66 -R with path aliases:
67
67
68 $ cd c
68 $ cd c
69 $ hg -R default identify
69 $ hg -R default identify
70 8580ff50825a tip
70 8580ff50825a tip
71 $ hg -R relative identify
71 $ hg -R relative identify
72 8580ff50825a tip
72 8580ff50825a tip
73 $ echo '[paths]' >> $HGRCPATH
73 $ echo '[paths]' >> $HGRCPATH
74 $ echo 'relativetohome = a' >> $HGRCPATH
74 $ echo 'relativetohome = a' >> $HGRCPATH
75 $ HOME=`pwd`/../ hg -R relativetohome identify
75 $ HOME=`pwd`/../ hg -R relativetohome identify
76 8580ff50825a tip
76 8580ff50825a tip
77 $ cd ..
77 $ cd ..
78
78
79 #if no-outer-repo
79 #if no-outer-repo
80
80
81 Implicit -R:
81 Implicit -R:
82
82
83 $ hg ann a/a
83 $ hg ann a/a
84 0: a
84 0: a
85 $ hg ann a/a a/a
85 $ hg ann a/a a/a
86 0: a
86 0: a
87 $ hg ann a/a b/b
87 $ hg ann a/a b/b
88 abort: no repository found in '$TESTTMP' (.hg not found)!
88 abort: no repository found in '$TESTTMP' (.hg not found)!
89 [255]
89 [255]
90 $ hg -R b ann a/a
90 $ hg -R b ann a/a
91 abort: a/a not under root '$TESTTMP/b'
91 abort: a/a not under root '$TESTTMP/b'
92 (consider using '--cwd b')
92 (consider using '--cwd b')
93 [255]
93 [255]
94 $ hg log
94 $ hg log
95 abort: no repository found in '$TESTTMP' (.hg not found)!
95 abort: no repository found in '$TESTTMP' (.hg not found)!
96 [255]
96 [255]
97
97
98 #endif
98 #endif
99
99
100 Abbreviation of long option:
100 Abbreviation of long option:
101
101
102 $ hg --repo c tip
102 $ hg --repo c tip
103 changeset: 1:b6c483daf290
103 changeset: 1:b6c483daf290
104 tag: tip
104 tag: tip
105 parent: -1:000000000000
105 parent: -1:000000000000
106 user: test
106 user: test
107 date: Thu Jan 01 00:00:01 1970 +0000
107 date: Thu Jan 01 00:00:01 1970 +0000
108 summary: b
108 summary: b
109
109
110
110
111 earlygetopt with duplicate options (36d23de02da1):
111 earlygetopt with duplicate options (36d23de02da1):
112
112
113 $ hg --cwd a --cwd b --cwd c tip
113 $ hg --cwd a --cwd b --cwd c tip
114 changeset: 1:b6c483daf290
114 changeset: 1:b6c483daf290
115 tag: tip
115 tag: tip
116 parent: -1:000000000000
116 parent: -1:000000000000
117 user: test
117 user: test
118 date: Thu Jan 01 00:00:01 1970 +0000
118 date: Thu Jan 01 00:00:01 1970 +0000
119 summary: b
119 summary: b
120
120
121 $ hg --repo c --repository b -R a tip
121 $ hg --repo c --repository b -R a tip
122 changeset: 0:8580ff50825a
122 changeset: 0:8580ff50825a
123 tag: tip
123 tag: tip
124 user: test
124 user: test
125 date: Thu Jan 01 00:00:01 1970 +0000
125 date: Thu Jan 01 00:00:01 1970 +0000
126 summary: a
126 summary: a
127
127
128
128
129 earlygetopt short option without following space:
129 earlygetopt short option without following space:
130
130
131 $ hg -q -Rb tip
131 $ hg -q -Rb tip
132 0:b6c483daf290
132 0:b6c483daf290
133
133
134 earlygetopt with illegal abbreviations:
134 earlygetopt with illegal abbreviations:
135
135
136 $ hg --confi "foo.bar=baz"
136 $ hg --confi "foo.bar=baz"
137 abort: option --config may not be abbreviated!
137 abort: option --config may not be abbreviated!
138 [255]
138 [255]
139 $ hg --cw a tip
139 $ hg --cw a tip
140 abort: option --cwd may not be abbreviated!
140 abort: option --cwd may not be abbreviated!
141 [255]
141 [255]
142 $ hg --rep a tip
142 $ hg --rep a tip
143 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
143 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
144 [255]
144 [255]
145 $ hg --repositor a tip
145 $ hg --repositor a tip
146 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
146 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
147 [255]
147 [255]
148 $ hg -qR a tip
148 $ hg -qR a tip
149 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
149 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
150 [255]
150 [255]
151 $ hg -qRa tip
151 $ hg -qRa tip
152 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
152 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
153 [255]
153 [255]
154
154
155 Testing --cwd:
155 Testing --cwd:
156
156
157 $ hg --cwd a parents
157 $ hg --cwd a parents
158 changeset: 0:8580ff50825a
158 changeset: 0:8580ff50825a
159 tag: tip
159 tag: tip
160 user: test
160 user: test
161 date: Thu Jan 01 00:00:01 1970 +0000
161 date: Thu Jan 01 00:00:01 1970 +0000
162 summary: a
162 summary: a
163
163
164
164
165 Testing -y/--noninteractive - just be sure it is parsed:
165 Testing -y/--noninteractive - just be sure it is parsed:
166
166
167 $ hg --cwd a tip -q --noninteractive
167 $ hg --cwd a tip -q --noninteractive
168 0:8580ff50825a
168 0:8580ff50825a
169 $ hg --cwd a tip -q -y
169 $ hg --cwd a tip -q -y
170 0:8580ff50825a
170 0:8580ff50825a
171
171
172 Testing -q/--quiet:
172 Testing -q/--quiet:
173
173
174 $ hg -R a -q tip
174 $ hg -R a -q tip
175 0:8580ff50825a
175 0:8580ff50825a
176 $ hg -R b -q tip
176 $ hg -R b -q tip
177 0:b6c483daf290
177 0:b6c483daf290
178 $ hg -R c --quiet parents
178 $ hg -R c --quiet parents
179 0:8580ff50825a
179 0:8580ff50825a
180 1:b6c483daf290
180 1:b6c483daf290
181
181
182 Testing -v/--verbose:
182 Testing -v/--verbose:
183
183
184 $ hg --cwd c head -v
184 $ hg --cwd c head -v
185 changeset: 1:b6c483daf290
185 changeset: 1:b6c483daf290
186 tag: tip
186 tag: tip
187 parent: -1:000000000000
187 parent: -1:000000000000
188 user: test
188 user: test
189 date: Thu Jan 01 00:00:01 1970 +0000
189 date: Thu Jan 01 00:00:01 1970 +0000
190 files: b
190 files: b
191 description:
191 description:
192 b
192 b
193
193
194
194
195 changeset: 0:8580ff50825a
195 changeset: 0:8580ff50825a
196 user: test
196 user: test
197 date: Thu Jan 01 00:00:01 1970 +0000
197 date: Thu Jan 01 00:00:01 1970 +0000
198 files: a
198 files: a
199 description:
199 description:
200 a
200 a
201
201
202
202
203 $ hg --cwd b tip --verbose
203 $ hg --cwd b tip --verbose
204 changeset: 0:b6c483daf290
204 changeset: 0:b6c483daf290
205 tag: tip
205 tag: tip
206 user: test
206 user: test
207 date: Thu Jan 01 00:00:01 1970 +0000
207 date: Thu Jan 01 00:00:01 1970 +0000
208 files: b
208 files: b
209 description:
209 description:
210 b
210 b
211
211
212
212
213
213
214 Testing --config:
214 Testing --config:
215
215
216 $ hg --cwd c --config paths.quuxfoo=bar paths | grep quuxfoo > /dev/null && echo quuxfoo
216 $ hg --cwd c --config paths.quuxfoo=bar paths | grep quuxfoo > /dev/null && echo quuxfoo
217 quuxfoo
217 quuxfoo
218 $ hg --cwd c --config '' tip -q
218 $ hg --cwd c --config '' tip -q
219 abort: malformed --config option: '' (use --config section.name=value)
219 abort: malformed --config option: '' (use --config section.name=value)
220 [255]
220 [255]
221 $ hg --cwd c --config a.b tip -q
221 $ hg --cwd c --config a.b tip -q
222 abort: malformed --config option: 'a.b' (use --config section.name=value)
222 abort: malformed --config option: 'a.b' (use --config section.name=value)
223 [255]
223 [255]
224 $ hg --cwd c --config a tip -q
224 $ hg --cwd c --config a tip -q
225 abort: malformed --config option: 'a' (use --config section.name=value)
225 abort: malformed --config option: 'a' (use --config section.name=value)
226 [255]
226 [255]
227 $ hg --cwd c --config a.= tip -q
227 $ hg --cwd c --config a.= tip -q
228 abort: malformed --config option: 'a.=' (use --config section.name=value)
228 abort: malformed --config option: 'a.=' (use --config section.name=value)
229 [255]
229 [255]
230 $ hg --cwd c --config .b= tip -q
230 $ hg --cwd c --config .b= tip -q
231 abort: malformed --config option: '.b=' (use --config section.name=value)
231 abort: malformed --config option: '.b=' (use --config section.name=value)
232 [255]
232 [255]
233
233
234 Testing --debug:
234 Testing --debug:
235
235
236 $ hg --cwd c log --debug
236 $ hg --cwd c log --debug
237 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
237 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
238 tag: tip
238 tag: tip
239 phase: public
239 phase: public
240 parent: -1:0000000000000000000000000000000000000000
240 parent: -1:0000000000000000000000000000000000000000
241 parent: -1:0000000000000000000000000000000000000000
241 parent: -1:0000000000000000000000000000000000000000
242 manifest: 1:23226e7a252cacdc2d99e4fbdc3653441056de49
242 manifest: 1:23226e7a252cacdc2d99e4fbdc3653441056de49
243 user: test
243 user: test
244 date: Thu Jan 01 00:00:01 1970 +0000
244 date: Thu Jan 01 00:00:01 1970 +0000
245 files+: b
245 files+: b
246 extra: branch=default
246 extra: branch=default
247 description:
247 description:
248 b
248 b
249
249
250
250
251 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
251 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
252 phase: public
252 phase: public
253 parent: -1:0000000000000000000000000000000000000000
253 parent: -1:0000000000000000000000000000000000000000
254 parent: -1:0000000000000000000000000000000000000000
254 parent: -1:0000000000000000000000000000000000000000
255 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
255 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
256 user: test
256 user: test
257 date: Thu Jan 01 00:00:01 1970 +0000
257 date: Thu Jan 01 00:00:01 1970 +0000
258 files+: a
258 files+: a
259 extra: branch=default
259 extra: branch=default
260 description:
260 description:
261 a
261 a
262
262
263
263
264
264
265 Testing --traceback:
265 Testing --traceback:
266
266
267 #if no-chg
267 #if no-chg
268 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
268 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
269 Traceback (most recent call last):
269 Traceback (most recent call last):
270 Traceback (most recent call last): (py3 !)
270 Traceback (most recent call last): (py3 !)
271 #else
271 #else
272 Traceback for '--config' errors not supported with chg.
272 Traceback for '--config' errors not supported with chg.
273 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
273 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
274 [1]
274 [1]
275 #endif
275 #endif
276
276
277 Testing --time:
277 Testing --time:
278
278
279 $ hg --cwd a --time id
279 $ hg --cwd a --time id
280 8580ff50825a tip
280 8580ff50825a tip
281 time: real * (glob)
281 time: real * (glob)
282
282
283 Testing --version:
283 Testing --version:
284
284
285 $ hg --version -q
285 $ hg --version -q
286 Mercurial Distributed SCM * (glob)
286 Mercurial Distributed SCM * (glob)
287
287
288 hide outer repo
288 hide outer repo
289 $ hg init
289 $ hg init
290
290
291 Testing -h/--help:
291 Testing -h/--help:
292
292
293 #if no-extraextensions
293 #if no-extraextensions
294
294
295 $ hg -h
295 $ hg -h
296 Mercurial Distributed SCM
296 Mercurial Distributed SCM
297
297
298 list of commands:
298 list of commands:
299
299
300 Repository creation:
300 Repository creation:
301
301
302 clone make a copy of an existing repository
302 clone make a copy of an existing repository
303 init create a new repository in the given directory
303 init create a new repository in the given directory
304
304
305 Remote repository management:
305 Remote repository management:
306
306
307 incoming show new changesets found in source
307 incoming show new changesets found in source
308 outgoing show changesets not found in the destination
308 outgoing show changesets not found in the destination
309 paths show aliases for remote repositories
309 paths show aliases for remote repositories
310 pull pull changes from the specified source
310 pull pull changes from the specified source
311 push push changes to the specified destination
311 push push changes to the specified destination
312 serve start stand-alone webserver
312 serve start stand-alone webserver
313
313
314 Change creation:
314 Change creation:
315
315
316 commit commit the specified files or all outstanding changes
316 commit commit the specified files or all outstanding changes
317
317
318 Change manipulation:
318 Change manipulation:
319
319
320 backout reverse effect of earlier changeset
320 backout reverse effect of earlier changeset
321 graft copy changes from other branches onto the current branch
321 graft copy changes from other branches onto the current branch
322 merge merge another revision into working directory
322 merge merge another revision into working directory
323
323
324 Change organization:
324 Change organization:
325
325
326 bookmarks create a new bookmark or list existing bookmarks
326 bookmarks create a new bookmark or list existing bookmarks
327 branch set or show the current branch name
327 branch set or show the current branch name
328 branches list repository named branches
328 branches list repository named branches
329 phase set or show the current phase name
329 phase set or show the current phase name
330 tag add one or more tags for the current or given revision
330 tag add one or more tags for the current or given revision
331 tags list repository tags
331 tags list repository tags
332
332
333 File content management:
333 File content management:
334
334
335 annotate show changeset information by line for each file
335 annotate show changeset information by line for each file
336 cat output the current or given revision of files
336 cat output the current or given revision of files
337 copy mark files as copied for the next commit
337 copy mark files as copied for the next commit
338 diff diff repository (or selected files)
338 diff diff repository (or selected files)
339 grep search revision history for a pattern in specified files
339 grep search for a pattern in specified files
340
340
341 Change navigation:
341 Change navigation:
342
342
343 bisect subdivision search of changesets
343 bisect subdivision search of changesets
344 heads show branch heads
344 heads show branch heads
345 identify identify the working directory or specified revision
345 identify identify the working directory or specified revision
346 log show revision history of entire repository or files
346 log show revision history of entire repository or files
347
347
348 Working directory management:
348 Working directory management:
349
349
350 add add the specified files on the next commit
350 add add the specified files on the next commit
351 addremove add all new files, delete all missing files
351 addremove add all new files, delete all missing files
352 files list tracked files
352 files list tracked files
353 forget forget the specified files on the next commit
353 forget forget the specified files on the next commit
354 remove remove the specified files on the next commit
354 remove remove the specified files on the next commit
355 rename rename files; equivalent of copy + remove
355 rename rename files; equivalent of copy + remove
356 resolve redo merges or set/view the merge status of files
356 resolve redo merges or set/view the merge status of files
357 revert restore files to their checkout state
357 revert restore files to their checkout state
358 root print the root (top) of the current working directory
358 root print the root (top) of the current working directory
359 shelve save and set aside changes from the working directory
359 shelve save and set aside changes from the working directory
360 status show changed files in the working directory
360 status show changed files in the working directory
361 summary summarize working directory state
361 summary summarize working directory state
362 unshelve restore a shelved change to the working directory
362 unshelve restore a shelved change to the working directory
363 update update working directory (or switch revisions)
363 update update working directory (or switch revisions)
364
364
365 Change import/export:
365 Change import/export:
366
366
367 archive create an unversioned archive of a repository revision
367 archive create an unversioned archive of a repository revision
368 bundle create a bundle file
368 bundle create a bundle file
369 export dump the header and diffs for one or more changesets
369 export dump the header and diffs for one or more changesets
370 import import an ordered set of patches
370 import import an ordered set of patches
371 unbundle apply one or more bundle files
371 unbundle apply one or more bundle files
372
372
373 Repository maintenance:
373 Repository maintenance:
374
374
375 manifest output the current or given revision of the project manifest
375 manifest output the current or given revision of the project manifest
376 recover roll back an interrupted transaction
376 recover roll back an interrupted transaction
377 verify verify the integrity of the repository
377 verify verify the integrity of the repository
378
378
379 Help:
379 Help:
380
380
381 config show combined config settings from all hgrc files
381 config show combined config settings from all hgrc files
382 help show help for a given topic or a help overview
382 help show help for a given topic or a help overview
383 version output version and copyright information
383 version output version and copyright information
384
384
385 additional help topics:
385 additional help topics:
386
386
387 Mercurial identifiers:
387 Mercurial identifiers:
388
388
389 filesets Specifying File Sets
389 filesets Specifying File Sets
390 hgignore Syntax for Mercurial Ignore Files
390 hgignore Syntax for Mercurial Ignore Files
391 patterns File Name Patterns
391 patterns File Name Patterns
392 revisions Specifying Revisions
392 revisions Specifying Revisions
393 urls URL Paths
393 urls URL Paths
394
394
395 Mercurial output:
395 Mercurial output:
396
396
397 color Colorizing Outputs
397 color Colorizing Outputs
398 dates Date Formats
398 dates Date Formats
399 diffs Diff Formats
399 diffs Diff Formats
400 templating Template Usage
400 templating Template Usage
401
401
402 Mercurial configuration:
402 Mercurial configuration:
403
403
404 config Configuration Files
404 config Configuration Files
405 environment Environment Variables
405 environment Environment Variables
406 extensions Using Additional Features
406 extensions Using Additional Features
407 flags Command-line flags
407 flags Command-line flags
408 hgweb Configuring hgweb
408 hgweb Configuring hgweb
409 merge-tools Merge Tools
409 merge-tools Merge Tools
410 pager Pager Support
410 pager Pager Support
411
411
412 Concepts:
412 Concepts:
413
413
414 bundlespec Bundle File Formats
414 bundlespec Bundle File Formats
415 glossary Glossary
415 glossary Glossary
416 phases Working with Phases
416 phases Working with Phases
417 subrepos Subrepositories
417 subrepos Subrepositories
418
418
419 Miscellaneous:
419 Miscellaneous:
420
420
421 deprecated Deprecated Features
421 deprecated Deprecated Features
422 internals Technical implementation topics
422 internals Technical implementation topics
423 scripting Using Mercurial from scripts and automation
423 scripting Using Mercurial from scripts and automation
424
424
425 (use 'hg help -v' to show built-in aliases and global options)
425 (use 'hg help -v' to show built-in aliases and global options)
426
426
427 $ hg --help
427 $ hg --help
428 Mercurial Distributed SCM
428 Mercurial Distributed SCM
429
429
430 list of commands:
430 list of commands:
431
431
432 Repository creation:
432 Repository creation:
433
433
434 clone make a copy of an existing repository
434 clone make a copy of an existing repository
435 init create a new repository in the given directory
435 init create a new repository in the given directory
436
436
437 Remote repository management:
437 Remote repository management:
438
438
439 incoming show new changesets found in source
439 incoming show new changesets found in source
440 outgoing show changesets not found in the destination
440 outgoing show changesets not found in the destination
441 paths show aliases for remote repositories
441 paths show aliases for remote repositories
442 pull pull changes from the specified source
442 pull pull changes from the specified source
443 push push changes to the specified destination
443 push push changes to the specified destination
444 serve start stand-alone webserver
444 serve start stand-alone webserver
445
445
446 Change creation:
446 Change creation:
447
447
448 commit commit the specified files or all outstanding changes
448 commit commit the specified files or all outstanding changes
449
449
450 Change manipulation:
450 Change manipulation:
451
451
452 backout reverse effect of earlier changeset
452 backout reverse effect of earlier changeset
453 graft copy changes from other branches onto the current branch
453 graft copy changes from other branches onto the current branch
454 merge merge another revision into working directory
454 merge merge another revision into working directory
455
455
456 Change organization:
456 Change organization:
457
457
458 bookmarks create a new bookmark or list existing bookmarks
458 bookmarks create a new bookmark or list existing bookmarks
459 branch set or show the current branch name
459 branch set or show the current branch name
460 branches list repository named branches
460 branches list repository named branches
461 phase set or show the current phase name
461 phase set or show the current phase name
462 tag add one or more tags for the current or given revision
462 tag add one or more tags for the current or given revision
463 tags list repository tags
463 tags list repository tags
464
464
465 File content management:
465 File content management:
466
466
467 annotate show changeset information by line for each file
467 annotate show changeset information by line for each file
468 cat output the current or given revision of files
468 cat output the current or given revision of files
469 copy mark files as copied for the next commit
469 copy mark files as copied for the next commit
470 diff diff repository (or selected files)
470 diff diff repository (or selected files)
471 grep search revision history for a pattern in specified files
471 grep search for a pattern in specified files
472
472
473 Change navigation:
473 Change navigation:
474
474
475 bisect subdivision search of changesets
475 bisect subdivision search of changesets
476 heads show branch heads
476 heads show branch heads
477 identify identify the working directory or specified revision
477 identify identify the working directory or specified revision
478 log show revision history of entire repository or files
478 log show revision history of entire repository or files
479
479
480 Working directory management:
480 Working directory management:
481
481
482 add add the specified files on the next commit
482 add add the specified files on the next commit
483 addremove add all new files, delete all missing files
483 addremove add all new files, delete all missing files
484 files list tracked files
484 files list tracked files
485 forget forget the specified files on the next commit
485 forget forget the specified files on the next commit
486 remove remove the specified files on the next commit
486 remove remove the specified files on the next commit
487 rename rename files; equivalent of copy + remove
487 rename rename files; equivalent of copy + remove
488 resolve redo merges or set/view the merge status of files
488 resolve redo merges or set/view the merge status of files
489 revert restore files to their checkout state
489 revert restore files to their checkout state
490 root print the root (top) of the current working directory
490 root print the root (top) of the current working directory
491 shelve save and set aside changes from the working directory
491 shelve save and set aside changes from the working directory
492 status show changed files in the working directory
492 status show changed files in the working directory
493 summary summarize working directory state
493 summary summarize working directory state
494 unshelve restore a shelved change to the working directory
494 unshelve restore a shelved change to the working directory
495 update update working directory (or switch revisions)
495 update update working directory (or switch revisions)
496
496
497 Change import/export:
497 Change import/export:
498
498
499 archive create an unversioned archive of a repository revision
499 archive create an unversioned archive of a repository revision
500 bundle create a bundle file
500 bundle create a bundle file
501 export dump the header and diffs for one or more changesets
501 export dump the header and diffs for one or more changesets
502 import import an ordered set of patches
502 import import an ordered set of patches
503 unbundle apply one or more bundle files
503 unbundle apply one or more bundle files
504
504
505 Repository maintenance:
505 Repository maintenance:
506
506
507 manifest output the current or given revision of the project manifest
507 manifest output the current or given revision of the project manifest
508 recover roll back an interrupted transaction
508 recover roll back an interrupted transaction
509 verify verify the integrity of the repository
509 verify verify the integrity of the repository
510
510
511 Help:
511 Help:
512
512
513 config show combined config settings from all hgrc files
513 config show combined config settings from all hgrc files
514 help show help for a given topic or a help overview
514 help show help for a given topic or a help overview
515 version output version and copyright information
515 version output version and copyright information
516
516
517 additional help topics:
517 additional help topics:
518
518
519 Mercurial identifiers:
519 Mercurial identifiers:
520
520
521 filesets Specifying File Sets
521 filesets Specifying File Sets
522 hgignore Syntax for Mercurial Ignore Files
522 hgignore Syntax for Mercurial Ignore Files
523 patterns File Name Patterns
523 patterns File Name Patterns
524 revisions Specifying Revisions
524 revisions Specifying Revisions
525 urls URL Paths
525 urls URL Paths
526
526
527 Mercurial output:
527 Mercurial output:
528
528
529 color Colorizing Outputs
529 color Colorizing Outputs
530 dates Date Formats
530 dates Date Formats
531 diffs Diff Formats
531 diffs Diff Formats
532 templating Template Usage
532 templating Template Usage
533
533
534 Mercurial configuration:
534 Mercurial configuration:
535
535
536 config Configuration Files
536 config Configuration Files
537 environment Environment Variables
537 environment Environment Variables
538 extensions Using Additional Features
538 extensions Using Additional Features
539 flags Command-line flags
539 flags Command-line flags
540 hgweb Configuring hgweb
540 hgweb Configuring hgweb
541 merge-tools Merge Tools
541 merge-tools Merge Tools
542 pager Pager Support
542 pager Pager Support
543
543
544 Concepts:
544 Concepts:
545
545
546 bundlespec Bundle File Formats
546 bundlespec Bundle File Formats
547 glossary Glossary
547 glossary Glossary
548 phases Working with Phases
548 phases Working with Phases
549 subrepos Subrepositories
549 subrepos Subrepositories
550
550
551 Miscellaneous:
551 Miscellaneous:
552
552
553 deprecated Deprecated Features
553 deprecated Deprecated Features
554 internals Technical implementation topics
554 internals Technical implementation topics
555 scripting Using Mercurial from scripts and automation
555 scripting Using Mercurial from scripts and automation
556
556
557 (use 'hg help -v' to show built-in aliases and global options)
557 (use 'hg help -v' to show built-in aliases and global options)
558
558
559 #endif
559 #endif
560
560
561 Not tested: --debugger
561 Not tested: --debugger
562
562
@@ -1,259 +1,259 b''
1 Test hiding some commands (which also happens to hide an entire category).
1 Test hiding some commands (which also happens to hide an entire category).
2
2
3 $ hg --config help.hidden-command.clone=true \
3 $ hg --config help.hidden-command.clone=true \
4 > --config help.hidden-command.init=true help
4 > --config help.hidden-command.init=true help
5 Mercurial Distributed SCM
5 Mercurial Distributed SCM
6
6
7 list of commands:
7 list of commands:
8
8
9 Remote repository management:
9 Remote repository management:
10
10
11 incoming show new changesets found in source
11 incoming show new changesets found in source
12 outgoing show changesets not found in the destination
12 outgoing show changesets not found in the destination
13 paths show aliases for remote repositories
13 paths show aliases for remote repositories
14 pull pull changes from the specified source
14 pull pull changes from the specified source
15 push push changes to the specified destination
15 push push changes to the specified destination
16 serve start stand-alone webserver
16 serve start stand-alone webserver
17
17
18 Change creation:
18 Change creation:
19
19
20 commit commit the specified files or all outstanding changes
20 commit commit the specified files or all outstanding changes
21
21
22 Change manipulation:
22 Change manipulation:
23
23
24 backout reverse effect of earlier changeset
24 backout reverse effect of earlier changeset
25 graft copy changes from other branches onto the current branch
25 graft copy changes from other branches onto the current branch
26 merge merge another revision into working directory
26 merge merge another revision into working directory
27
27
28 Change organization:
28 Change organization:
29
29
30 bookmarks create a new bookmark or list existing bookmarks
30 bookmarks create a new bookmark or list existing bookmarks
31 branch set or show the current branch name
31 branch set or show the current branch name
32 branches list repository named branches
32 branches list repository named branches
33 phase set or show the current phase name
33 phase set or show the current phase name
34 tag add one or more tags for the current or given revision
34 tag add one or more tags for the current or given revision
35 tags list repository tags
35 tags list repository tags
36
36
37 File content management:
37 File content management:
38
38
39 annotate show changeset information by line for each file
39 annotate show changeset information by line for each file
40 cat output the current or given revision of files
40 cat output the current or given revision of files
41 copy mark files as copied for the next commit
41 copy mark files as copied for the next commit
42 diff diff repository (or selected files)
42 diff diff repository (or selected files)
43 grep search revision history for a pattern in specified files
43 grep search for a pattern in specified files
44
44
45 Change navigation:
45 Change navigation:
46
46
47 bisect subdivision search of changesets
47 bisect subdivision search of changesets
48 heads show branch heads
48 heads show branch heads
49 identify identify the working directory or specified revision
49 identify identify the working directory or specified revision
50 log show revision history of entire repository or files
50 log show revision history of entire repository or files
51
51
52 Working directory management:
52 Working directory management:
53
53
54 add add the specified files on the next commit
54 add add the specified files on the next commit
55 addremove add all new files, delete all missing files
55 addremove add all new files, delete all missing files
56 files list tracked files
56 files list tracked files
57 forget forget the specified files on the next commit
57 forget forget the specified files on the next commit
58 remove remove the specified files on the next commit
58 remove remove the specified files on the next commit
59 rename rename files; equivalent of copy + remove
59 rename rename files; equivalent of copy + remove
60 resolve redo merges or set/view the merge status of files
60 resolve redo merges or set/view the merge status of files
61 revert restore files to their checkout state
61 revert restore files to their checkout state
62 root print the root (top) of the current working directory
62 root print the root (top) of the current working directory
63 shelve save and set aside changes from the working directory
63 shelve save and set aside changes from the working directory
64 status show changed files in the working directory
64 status show changed files in the working directory
65 summary summarize working directory state
65 summary summarize working directory state
66 unshelve restore a shelved change to the working directory
66 unshelve restore a shelved change to the working directory
67 update update working directory (or switch revisions)
67 update update working directory (or switch revisions)
68
68
69 Change import/export:
69 Change import/export:
70
70
71 archive create an unversioned archive of a repository revision
71 archive create an unversioned archive of a repository revision
72 bundle create a bundle file
72 bundle create a bundle file
73 export dump the header and diffs for one or more changesets
73 export dump the header and diffs for one or more changesets
74 import import an ordered set of patches
74 import import an ordered set of patches
75 unbundle apply one or more bundle files
75 unbundle apply one or more bundle files
76
76
77 Repository maintenance:
77 Repository maintenance:
78
78
79 manifest output the current or given revision of the project manifest
79 manifest output the current or given revision of the project manifest
80 recover roll back an interrupted transaction
80 recover roll back an interrupted transaction
81 verify verify the integrity of the repository
81 verify verify the integrity of the repository
82
82
83 Help:
83 Help:
84
84
85 config show combined config settings from all hgrc files
85 config show combined config settings from all hgrc files
86 help show help for a given topic or a help overview
86 help show help for a given topic or a help overview
87 version output version and copyright information
87 version output version and copyright information
88
88
89 additional help topics:
89 additional help topics:
90
90
91 Mercurial identifiers:
91 Mercurial identifiers:
92
92
93 filesets Specifying File Sets
93 filesets Specifying File Sets
94 hgignore Syntax for Mercurial Ignore Files
94 hgignore Syntax for Mercurial Ignore Files
95 patterns File Name Patterns
95 patterns File Name Patterns
96 revisions Specifying Revisions
96 revisions Specifying Revisions
97 urls URL Paths
97 urls URL Paths
98
98
99 Mercurial output:
99 Mercurial output:
100
100
101 color Colorizing Outputs
101 color Colorizing Outputs
102 dates Date Formats
102 dates Date Formats
103 diffs Diff Formats
103 diffs Diff Formats
104 templating Template Usage
104 templating Template Usage
105
105
106 Mercurial configuration:
106 Mercurial configuration:
107
107
108 config Configuration Files
108 config Configuration Files
109 environment Environment Variables
109 environment Environment Variables
110 extensions Using Additional Features
110 extensions Using Additional Features
111 flags Command-line flags
111 flags Command-line flags
112 hgweb Configuring hgweb
112 hgweb Configuring hgweb
113 merge-tools Merge Tools
113 merge-tools Merge Tools
114 pager Pager Support
114 pager Pager Support
115
115
116 Concepts:
116 Concepts:
117
117
118 bundlespec Bundle File Formats
118 bundlespec Bundle File Formats
119 glossary Glossary
119 glossary Glossary
120 phases Working with Phases
120 phases Working with Phases
121 subrepos Subrepositories
121 subrepos Subrepositories
122
122
123 Miscellaneous:
123 Miscellaneous:
124
124
125 deprecated Deprecated Features
125 deprecated Deprecated Features
126 internals Technical implementation topics
126 internals Technical implementation topics
127 scripting Using Mercurial from scripts and automation
127 scripting Using Mercurial from scripts and automation
128
128
129 (use 'hg help -v' to show built-in aliases and global options)
129 (use 'hg help -v' to show built-in aliases and global options)
130
130
131 Test hiding some topics.
131 Test hiding some topics.
132
132
133 $ hg --config help.hidden-topic.deprecated=true \
133 $ hg --config help.hidden-topic.deprecated=true \
134 > --config help.hidden-topic.internals=true \
134 > --config help.hidden-topic.internals=true \
135 > --config help.hidden-topic.scripting=true help
135 > --config help.hidden-topic.scripting=true help
136 Mercurial Distributed SCM
136 Mercurial Distributed SCM
137
137
138 list of commands:
138 list of commands:
139
139
140 Repository creation:
140 Repository creation:
141
141
142 clone make a copy of an existing repository
142 clone make a copy of an existing repository
143 init create a new repository in the given directory
143 init create a new repository in the given directory
144
144
145 Remote repository management:
145 Remote repository management:
146
146
147 incoming show new changesets found in source
147 incoming show new changesets found in source
148 outgoing show changesets not found in the destination
148 outgoing show changesets not found in the destination
149 paths show aliases for remote repositories
149 paths show aliases for remote repositories
150 pull pull changes from the specified source
150 pull pull changes from the specified source
151 push push changes to the specified destination
151 push push changes to the specified destination
152 serve start stand-alone webserver
152 serve start stand-alone webserver
153
153
154 Change creation:
154 Change creation:
155
155
156 commit commit the specified files or all outstanding changes
156 commit commit the specified files or all outstanding changes
157
157
158 Change manipulation:
158 Change manipulation:
159
159
160 backout reverse effect of earlier changeset
160 backout reverse effect of earlier changeset
161 graft copy changes from other branches onto the current branch
161 graft copy changes from other branches onto the current branch
162 merge merge another revision into working directory
162 merge merge another revision into working directory
163
163
164 Change organization:
164 Change organization:
165
165
166 bookmarks create a new bookmark or list existing bookmarks
166 bookmarks create a new bookmark or list existing bookmarks
167 branch set or show the current branch name
167 branch set or show the current branch name
168 branches list repository named branches
168 branches list repository named branches
169 phase set or show the current phase name
169 phase set or show the current phase name
170 tag add one or more tags for the current or given revision
170 tag add one or more tags for the current or given revision
171 tags list repository tags
171 tags list repository tags
172
172
173 File content management:
173 File content management:
174
174
175 annotate show changeset information by line for each file
175 annotate show changeset information by line for each file
176 cat output the current or given revision of files
176 cat output the current or given revision of files
177 copy mark files as copied for the next commit
177 copy mark files as copied for the next commit
178 diff diff repository (or selected files)
178 diff diff repository (or selected files)
179 grep search revision history for a pattern in specified files
179 grep search for a pattern in specified files
180
180
181 Change navigation:
181 Change navigation:
182
182
183 bisect subdivision search of changesets
183 bisect subdivision search of changesets
184 heads show branch heads
184 heads show branch heads
185 identify identify the working directory or specified revision
185 identify identify the working directory or specified revision
186 log show revision history of entire repository or files
186 log show revision history of entire repository or files
187
187
188 Working directory management:
188 Working directory management:
189
189
190 add add the specified files on the next commit
190 add add the specified files on the next commit
191 addremove add all new files, delete all missing files
191 addremove add all new files, delete all missing files
192 files list tracked files
192 files list tracked files
193 forget forget the specified files on the next commit
193 forget forget the specified files on the next commit
194 remove remove the specified files on the next commit
194 remove remove the specified files on the next commit
195 rename rename files; equivalent of copy + remove
195 rename rename files; equivalent of copy + remove
196 resolve redo merges or set/view the merge status of files
196 resolve redo merges or set/view the merge status of files
197 revert restore files to their checkout state
197 revert restore files to their checkout state
198 root print the root (top) of the current working directory
198 root print the root (top) of the current working directory
199 shelve save and set aside changes from the working directory
199 shelve save and set aside changes from the working directory
200 status show changed files in the working directory
200 status show changed files in the working directory
201 summary summarize working directory state
201 summary summarize working directory state
202 unshelve restore a shelved change to the working directory
202 unshelve restore a shelved change to the working directory
203 update update working directory (or switch revisions)
203 update update working directory (or switch revisions)
204
204
205 Change import/export:
205 Change import/export:
206
206
207 archive create an unversioned archive of a repository revision
207 archive create an unversioned archive of a repository revision
208 bundle create a bundle file
208 bundle create a bundle file
209 export dump the header and diffs for one or more changesets
209 export dump the header and diffs for one or more changesets
210 import import an ordered set of patches
210 import import an ordered set of patches
211 unbundle apply one or more bundle files
211 unbundle apply one or more bundle files
212
212
213 Repository maintenance:
213 Repository maintenance:
214
214
215 manifest output the current or given revision of the project manifest
215 manifest output the current or given revision of the project manifest
216 recover roll back an interrupted transaction
216 recover roll back an interrupted transaction
217 verify verify the integrity of the repository
217 verify verify the integrity of the repository
218
218
219 Help:
219 Help:
220
220
221 config show combined config settings from all hgrc files
221 config show combined config settings from all hgrc files
222 help show help for a given topic or a help overview
222 help show help for a given topic or a help overview
223 version output version and copyright information
223 version output version and copyright information
224
224
225 additional help topics:
225 additional help topics:
226
226
227 Mercurial identifiers:
227 Mercurial identifiers:
228
228
229 filesets Specifying File Sets
229 filesets Specifying File Sets
230 hgignore Syntax for Mercurial Ignore Files
230 hgignore Syntax for Mercurial Ignore Files
231 patterns File Name Patterns
231 patterns File Name Patterns
232 revisions Specifying Revisions
232 revisions Specifying Revisions
233 urls URL Paths
233 urls URL Paths
234
234
235 Mercurial output:
235 Mercurial output:
236
236
237 color Colorizing Outputs
237 color Colorizing Outputs
238 dates Date Formats
238 dates Date Formats
239 diffs Diff Formats
239 diffs Diff Formats
240 templating Template Usage
240 templating Template Usage
241
241
242 Mercurial configuration:
242 Mercurial configuration:
243
243
244 config Configuration Files
244 config Configuration Files
245 environment Environment Variables
245 environment Environment Variables
246 extensions Using Additional Features
246 extensions Using Additional Features
247 flags Command-line flags
247 flags Command-line flags
248 hgweb Configuring hgweb
248 hgweb Configuring hgweb
249 merge-tools Merge Tools
249 merge-tools Merge Tools
250 pager Pager Support
250 pager Pager Support
251
251
252 Concepts:
252 Concepts:
253
253
254 bundlespec Bundle File Formats
254 bundlespec Bundle File Formats
255 glossary Glossary
255 glossary Glossary
256 phases Working with Phases
256 phases Working with Phases
257 subrepos Subrepositories
257 subrepos Subrepositories
258
258
259 (use 'hg help -v' to show built-in aliases and global options)
259 (use 'hg help -v' to show built-in aliases and global options)
@@ -1,3893 +1,3893 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 revision history 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 revision history 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 githelp try mapping git commands to Mercurial commands
367 githelp try mapping git commands to Mercurial commands
368 gpg commands to sign and verify changesets
368 gpg commands to sign and verify changesets
369 hgk browse the repository in a graphical way
369 hgk browse the repository in a graphical way
370 highlight syntax highlighting for hgweb (requires Pygments)
370 highlight syntax highlighting for hgweb (requires Pygments)
371 histedit interactive history editing
371 histedit interactive history editing
372 keyword expand keywords in tracked files
372 keyword expand keywords in tracked files
373 largefiles track large binary files
373 largefiles track large binary files
374 mq manage a stack of patches
374 mq manage a stack of patches
375 notify hooks for sending email push notifications
375 notify hooks for sending email push notifications
376 patchbomb command to send changesets as (a series of) patch emails
376 patchbomb command to send changesets as (a series of) patch emails
377 purge command to delete untracked files from the working
377 purge command to delete untracked files from the working
378 directory
378 directory
379 relink recreates hardlinks between repository clones
379 relink recreates hardlinks between repository clones
380 schemes extend schemes with shortcuts to repository swarms
380 schemes extend schemes with shortcuts to repository swarms
381 share share a common history between several working directories
381 share share a common history between several working directories
382 strip strip changesets and their descendants from history
382 strip strip changesets and their descendants from history
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] | [-r REV1 [-r REV2]]) [FILE]...
632 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r 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 When two revision arguments are given, then changes are shown between
645 When two revision arguments are given, then changes are shown between
646 those revisions. If only one revision is specified then that revision is
646 those revisions. If only one revision is specified then that revision is
647 compared to the working directory, and, when no revisions are specified,
647 compared to the working directory, and, when no revisions are specified,
648 the working directory files are compared to its first parent.
648 the working directory files are compared to its first parent.
649
649
650 Alternatively you can specify -c/--change with a revision to see the
650 Alternatively you can specify -c/--change with a revision to see the
651 changes in that changeset relative to its first parent.
651 changes in that changeset relative to its first parent.
652
652
653 Without the -a/--text option, diff will avoid generating diffs of files it
653 Without the -a/--text option, diff will avoid generating diffs of files it
654 detects as binary. With -a, diff will generate a diff anyway, probably
654 detects as binary. With -a, diff will generate a diff anyway, probably
655 with undesirable results.
655 with undesirable results.
656
656
657 Use the -g/--git option to generate diffs in the git extended diff format.
657 Use the -g/--git option to generate diffs in the git extended diff format.
658 For more information, read 'hg help diffs'.
658 For more information, read 'hg help diffs'.
659
659
660 Returns 0 on success.
660 Returns 0 on success.
661
661
662 options ([+] can be repeated):
662 options ([+] can be repeated):
663
663
664 -r --rev REV [+] revision
664 -r --rev REV [+] revision
665 -c --change REV change made by revision
665 -c --change REV change made by revision
666 -a --text treat all files as text
666 -a --text treat all files as text
667 -g --git use git extended diff format
667 -g --git use git extended diff format
668 --binary generate binary diffs in git mode (default)
668 --binary generate binary diffs in git mode (default)
669 --nodates omit dates from diff headers
669 --nodates omit dates from diff headers
670 --noprefix omit a/ and b/ prefixes from filenames
670 --noprefix omit a/ and b/ prefixes from filenames
671 -p --show-function show which function each change is in
671 -p --show-function show which function each change is in
672 --reverse produce a diff that undoes the changes
672 --reverse produce a diff that undoes the changes
673 -w --ignore-all-space ignore white space when comparing lines
673 -w --ignore-all-space ignore white space when comparing lines
674 -b --ignore-space-change ignore changes in the amount of white space
674 -b --ignore-space-change ignore changes in the amount of white space
675 -B --ignore-blank-lines ignore changes whose lines are all blank
675 -B --ignore-blank-lines ignore changes whose lines are all blank
676 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
676 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
677 -U --unified NUM number of lines of context to show
677 -U --unified NUM number of lines of context to show
678 --stat output diffstat-style summary of changes
678 --stat output diffstat-style summary of changes
679 --root DIR produce diffs relative to subdirectory
679 --root DIR produce diffs relative to subdirectory
680 -I --include PATTERN [+] include names matching the given patterns
680 -I --include PATTERN [+] include names matching the given patterns
681 -X --exclude PATTERN [+] exclude names matching the given patterns
681 -X --exclude PATTERN [+] exclude names matching the given patterns
682 -S --subrepos recurse into subrepositories
682 -S --subrepos recurse into subrepositories
683
683
684 (some details hidden, use --verbose to show complete help)
684 (some details hidden, use --verbose to show complete help)
685
685
686 $ hg help status
686 $ hg help status
687 hg status [OPTION]... [FILE]...
687 hg status [OPTION]... [FILE]...
688
688
689 aliases: st
689 aliases: st
690
690
691 show changed files in the working directory
691 show changed files in the working directory
692
692
693 Show status of files in the repository. If names are given, only files
693 Show status of files in the repository. If names are given, only files
694 that match are shown. Files that are clean or ignored or the source of a
694 that match are shown. Files that are clean or ignored or the source of a
695 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
695 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
696 -C/--copies or -A/--all are given. Unless options described with "show
696 -C/--copies or -A/--all are given. Unless options described with "show
697 only ..." are given, the options -mardu are used.
697 only ..." are given, the options -mardu are used.
698
698
699 Option -q/--quiet hides untracked (unknown and ignored) files unless
699 Option -q/--quiet hides untracked (unknown and ignored) files unless
700 explicitly requested with -u/--unknown or -i/--ignored.
700 explicitly requested with -u/--unknown or -i/--ignored.
701
701
702 Note:
702 Note:
703 'hg status' may appear to disagree with diff if permissions have
703 'hg status' may appear to disagree with diff if permissions have
704 changed or a merge has occurred. The standard diff format does not
704 changed or a merge has occurred. The standard diff format does not
705 report permission changes and diff only reports changes relative to one
705 report permission changes and diff only reports changes relative to one
706 merge parent.
706 merge parent.
707
707
708 If one revision is given, it is used as the base revision. If two
708 If one revision is given, it is used as the base revision. If two
709 revisions are given, the differences between them are shown. The --change
709 revisions are given, the differences between them are shown. The --change
710 option can also be used as a shortcut to list the changed files of a
710 option can also be used as a shortcut to list the changed files of a
711 revision from its first parent.
711 revision from its first parent.
712
712
713 The codes used to show the status of files are:
713 The codes used to show the status of files are:
714
714
715 M = modified
715 M = modified
716 A = added
716 A = added
717 R = removed
717 R = removed
718 C = clean
718 C = clean
719 ! = missing (deleted by non-hg command, but still tracked)
719 ! = missing (deleted by non-hg command, but still tracked)
720 ? = not tracked
720 ? = not tracked
721 I = ignored
721 I = ignored
722 = origin of the previous file (with --copies)
722 = origin of the previous file (with --copies)
723
723
724 Returns 0 on success.
724 Returns 0 on success.
725
725
726 options ([+] can be repeated):
726 options ([+] can be repeated):
727
727
728 -A --all show status of all files
728 -A --all show status of all files
729 -m --modified show only modified files
729 -m --modified show only modified files
730 -a --added show only added files
730 -a --added show only added files
731 -r --removed show only removed files
731 -r --removed show only removed files
732 -d --deleted show only deleted (but tracked) files
732 -d --deleted show only deleted (but tracked) files
733 -c --clean show only files without changes
733 -c --clean show only files without changes
734 -u --unknown show only unknown (not tracked) files
734 -u --unknown show only unknown (not tracked) files
735 -i --ignored show only ignored files
735 -i --ignored show only ignored files
736 -n --no-status hide status prefix
736 -n --no-status hide status prefix
737 -C --copies show source of copied files
737 -C --copies show source of copied files
738 -0 --print0 end filenames with NUL, for use with xargs
738 -0 --print0 end filenames with NUL, for use with xargs
739 --rev REV [+] show difference from revision
739 --rev REV [+] show difference from revision
740 --change REV list the changed files of a revision
740 --change REV list the changed files of a revision
741 -I --include PATTERN [+] include names matching the given patterns
741 -I --include PATTERN [+] include names matching the given patterns
742 -X --exclude PATTERN [+] exclude names matching the given patterns
742 -X --exclude PATTERN [+] exclude names matching the given patterns
743 -S --subrepos recurse into subrepositories
743 -S --subrepos recurse into subrepositories
744 -T --template TEMPLATE display with template
744 -T --template TEMPLATE display with template
745
745
746 (some details hidden, use --verbose to show complete help)
746 (some details hidden, use --verbose to show complete help)
747
747
748 $ hg -q help status
748 $ hg -q help status
749 hg status [OPTION]... [FILE]...
749 hg status [OPTION]... [FILE]...
750
750
751 show changed files in the working directory
751 show changed files in the working directory
752
752
753 $ hg help foo
753 $ hg help foo
754 abort: no such help topic: foo
754 abort: no such help topic: foo
755 (try 'hg help --keyword foo')
755 (try 'hg help --keyword foo')
756 [255]
756 [255]
757
757
758 $ hg skjdfks
758 $ hg skjdfks
759 hg: unknown command 'skjdfks'
759 hg: unknown command 'skjdfks'
760 (use 'hg help' for a list of commands)
760 (use 'hg help' for a list of commands)
761 [255]
761 [255]
762
762
763 Typoed command gives suggestion
763 Typoed command gives suggestion
764 $ hg puls
764 $ hg puls
765 hg: unknown command 'puls'
765 hg: unknown command 'puls'
766 (did you mean one of pull, push?)
766 (did you mean one of pull, push?)
767 [255]
767 [255]
768
768
769 Not enabled extension gets suggested
769 Not enabled extension gets suggested
770
770
771 $ hg rebase
771 $ hg rebase
772 hg: unknown command 'rebase'
772 hg: unknown command 'rebase'
773 'rebase' is provided by the following extension:
773 'rebase' is provided by the following extension:
774
774
775 rebase command to move sets of revisions to a different ancestor
775 rebase command to move sets of revisions to a different ancestor
776
776
777 (use 'hg help extensions' for information on enabling extensions)
777 (use 'hg help extensions' for information on enabling extensions)
778 [255]
778 [255]
779
779
780 Disabled extension gets suggested
780 Disabled extension gets suggested
781 $ hg --config extensions.rebase=! rebase
781 $ hg --config extensions.rebase=! rebase
782 hg: unknown command 'rebase'
782 hg: unknown command 'rebase'
783 'rebase' is provided by the following extension:
783 'rebase' is provided by the following extension:
784
784
785 rebase command to move sets of revisions to a different ancestor
785 rebase command to move sets of revisions to a different ancestor
786
786
787 (use 'hg help extensions' for information on enabling extensions)
787 (use 'hg help extensions' for information on enabling extensions)
788 [255]
788 [255]
789
789
790 Make sure that we don't run afoul of the help system thinking that
790 Make sure that we don't run afoul of the help system thinking that
791 this is a section and erroring out weirdly.
791 this is a section and erroring out weirdly.
792
792
793 $ hg .log
793 $ hg .log
794 hg: unknown command '.log'
794 hg: unknown command '.log'
795 (did you mean log?)
795 (did you mean log?)
796 [255]
796 [255]
797
797
798 $ hg log.
798 $ hg log.
799 hg: unknown command 'log.'
799 hg: unknown command 'log.'
800 (did you mean log?)
800 (did you mean log?)
801 [255]
801 [255]
802 $ hg pu.lh
802 $ hg pu.lh
803 hg: unknown command 'pu.lh'
803 hg: unknown command 'pu.lh'
804 (did you mean one of pull, push?)
804 (did you mean one of pull, push?)
805 [255]
805 [255]
806
806
807 $ cat > helpext.py <<EOF
807 $ cat > helpext.py <<EOF
808 > import os
808 > import os
809 > from mercurial import commands, fancyopts, registrar
809 > from mercurial import commands, fancyopts, registrar
810 >
810 >
811 > def func(arg):
811 > def func(arg):
812 > return '%sfoo' % arg
812 > return '%sfoo' % arg
813 > class customopt(fancyopts.customopt):
813 > class customopt(fancyopts.customopt):
814 > def newstate(self, oldstate, newparam, abort):
814 > def newstate(self, oldstate, newparam, abort):
815 > return '%sbar' % oldstate
815 > return '%sbar' % oldstate
816 > cmdtable = {}
816 > cmdtable = {}
817 > command = registrar.command(cmdtable)
817 > command = registrar.command(cmdtable)
818 >
818 >
819 > @command(b'nohelp',
819 > @command(b'nohelp',
820 > [(b'', b'longdesc', 3, b'x'*67),
820 > [(b'', b'longdesc', 3, b'x'*67),
821 > (b'n', b'', None, b'normal desc'),
821 > (b'n', b'', None, b'normal desc'),
822 > (b'', b'newline', b'', b'line1\nline2'),
822 > (b'', b'newline', b'', b'line1\nline2'),
823 > (b'', b'default-off', False, b'enable X'),
823 > (b'', b'default-off', False, b'enable X'),
824 > (b'', b'default-on', True, b'enable Y'),
824 > (b'', b'default-on', True, b'enable Y'),
825 > (b'', b'callableopt', func, b'adds foo'),
825 > (b'', b'callableopt', func, b'adds foo'),
826 > (b'', b'customopt', customopt(''), b'adds bar'),
826 > (b'', b'customopt', customopt(''), b'adds bar'),
827 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
827 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
828 > b'hg nohelp',
828 > b'hg nohelp',
829 > norepo=True)
829 > norepo=True)
830 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
830 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
831 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
831 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
832 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
832 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
833 > def nohelp(ui, *args, **kwargs):
833 > def nohelp(ui, *args, **kwargs):
834 > pass
834 > pass
835 >
835 >
836 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
836 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
837 > def hashelp(ui, *args, **kwargs):
837 > def hashelp(ui, *args, **kwargs):
838 > """Extension command's help"""
838 > """Extension command's help"""
839 >
839 >
840 > def uisetup(ui):
840 > def uisetup(ui):
841 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
841 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
842 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
842 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
843 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
843 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
844 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
844 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
845 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
845 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
846 >
846 >
847 > EOF
847 > EOF
848 $ echo '[extensions]' >> $HGRCPATH
848 $ echo '[extensions]' >> $HGRCPATH
849 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
849 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
850
850
851 Test for aliases
851 Test for aliases
852
852
853 $ hg help | grep hgalias
853 $ hg help | grep hgalias
854 hgalias My doc
854 hgalias My doc
855
855
856 $ hg help hgalias
856 $ hg help hgalias
857 hg hgalias [--remote]
857 hg hgalias [--remote]
858
858
859 alias for: hg summary
859 alias for: hg summary
860
860
861 My doc
861 My doc
862
862
863 defined by: helpext
863 defined by: helpext
864
864
865 options:
865 options:
866
866
867 --remote check for push and pull
867 --remote check for push and pull
868
868
869 (some details hidden, use --verbose to show complete help)
869 (some details hidden, use --verbose to show complete help)
870 $ hg help hgaliasnodoc
870 $ hg help hgaliasnodoc
871 hg hgaliasnodoc [--remote]
871 hg hgaliasnodoc [--remote]
872
872
873 alias for: hg summary
873 alias for: hg summary
874
874
875 summarize working directory state
875 summarize working directory state
876
876
877 This generates a brief summary of the working directory state, including
877 This generates a brief summary of the working directory state, including
878 parents, branch, commit status, phase and available updates.
878 parents, branch, commit status, phase and available updates.
879
879
880 With the --remote option, this will check the default paths for incoming
880 With the --remote option, this will check the default paths for incoming
881 and outgoing changes. This can be time-consuming.
881 and outgoing changes. This can be time-consuming.
882
882
883 Returns 0 on success.
883 Returns 0 on success.
884
884
885 defined by: helpext
885 defined by: helpext
886
886
887 options:
887 options:
888
888
889 --remote check for push and pull
889 --remote check for push and pull
890
890
891 (some details hidden, use --verbose to show complete help)
891 (some details hidden, use --verbose to show complete help)
892
892
893 $ hg help shellalias
893 $ hg help shellalias
894 hg shellalias
894 hg shellalias
895
895
896 shell alias for: echo hi
896 shell alias for: echo hi
897
897
898 (no help text available)
898 (no help text available)
899
899
900 defined by: helpext
900 defined by: helpext
901
901
902 (some details hidden, use --verbose to show complete help)
902 (some details hidden, use --verbose to show complete help)
903
903
904 Test command with no help text
904 Test command with no help text
905
905
906 $ hg help nohelp
906 $ hg help nohelp
907 hg nohelp
907 hg nohelp
908
908
909 (no help text available)
909 (no help text available)
910
910
911 options:
911 options:
912
912
913 --longdesc VALUE
913 --longdesc VALUE
914 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
914 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
915 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
915 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
916 -n -- normal desc
916 -n -- normal desc
917 --newline VALUE line1 line2
917 --newline VALUE line1 line2
918 --default-off enable X
918 --default-off enable X
919 --[no-]default-on enable Y (default: on)
919 --[no-]default-on enable Y (default: on)
920 --callableopt VALUE adds foo
920 --callableopt VALUE adds foo
921 --customopt VALUE adds bar
921 --customopt VALUE adds bar
922 --customopt-withdefault VALUE adds bar (default: foo)
922 --customopt-withdefault VALUE adds bar (default: foo)
923
923
924 (some details hidden, use --verbose to show complete help)
924 (some details hidden, use --verbose to show complete help)
925
925
926 Test that default list of commands includes extension commands that have help,
926 Test that default list of commands includes extension commands that have help,
927 but not those that don't, except in verbose mode, when a keyword is passed, or
927 but not those that don't, except in verbose mode, when a keyword is passed, or
928 when help about the extension is requested.
928 when help about the extension is requested.
929
929
930 #if no-extraextensions
930 #if no-extraextensions
931
931
932 $ hg help | grep hashelp
932 $ hg help | grep hashelp
933 hashelp Extension command's help
933 hashelp Extension command's help
934 $ hg help | grep nohelp
934 $ hg help | grep nohelp
935 [1]
935 [1]
936 $ hg help -v | grep nohelp
936 $ hg help -v | grep nohelp
937 nohelp (no help text available)
937 nohelp (no help text available)
938
938
939 $ hg help -k nohelp
939 $ hg help -k nohelp
940 Commands:
940 Commands:
941
941
942 nohelp hg nohelp
942 nohelp hg nohelp
943
943
944 Extension Commands:
944 Extension Commands:
945
945
946 nohelp (no help text available)
946 nohelp (no help text available)
947
947
948 $ hg help helpext
948 $ hg help helpext
949 helpext extension - no help text available
949 helpext extension - no help text available
950
950
951 list of commands:
951 list of commands:
952
952
953 hashelp Extension command's help
953 hashelp Extension command's help
954 nohelp (no help text available)
954 nohelp (no help text available)
955
955
956 (use 'hg help -v helpext' to show built-in aliases and global options)
956 (use 'hg help -v helpext' to show built-in aliases and global options)
957
957
958 #endif
958 #endif
959
959
960 Test list of internal help commands
960 Test list of internal help commands
961
961
962 $ hg help debug
962 $ hg help debug
963 debug commands (internal and unsupported):
963 debug commands (internal and unsupported):
964
964
965 debugancestor
965 debugancestor
966 find the ancestor revision of two revisions in a given index
966 find the ancestor revision of two revisions in a given index
967 debugapplystreamclonebundle
967 debugapplystreamclonebundle
968 apply a stream clone bundle file
968 apply a stream clone bundle file
969 debugbuilddag
969 debugbuilddag
970 builds a repo with a given DAG from scratch in the current
970 builds a repo with a given DAG from scratch in the current
971 empty repo
971 empty repo
972 debugbundle lists the contents of a bundle
972 debugbundle lists the contents of a bundle
973 debugcapabilities
973 debugcapabilities
974 lists the capabilities of a remote peer
974 lists the capabilities of a remote peer
975 debugcheckstate
975 debugcheckstate
976 validate the correctness of the current dirstate
976 validate the correctness of the current dirstate
977 debugcolor show available color, effects or style
977 debugcolor show available color, effects or style
978 debugcommands
978 debugcommands
979 list all available commands and options
979 list all available commands and options
980 debugcomplete
980 debugcomplete
981 returns the completion list associated with the given command
981 returns the completion list associated with the given command
982 debugcreatestreamclonebundle
982 debugcreatestreamclonebundle
983 create a stream clone bundle file
983 create a stream clone bundle file
984 debugdag format the changelog or an index DAG as a concise textual
984 debugdag format the changelog or an index DAG as a concise textual
985 description
985 description
986 debugdata dump the contents of a data file revision
986 debugdata dump the contents of a data file revision
987 debugdate parse and display a date
987 debugdate parse and display a date
988 debugdeltachain
988 debugdeltachain
989 dump information about delta chains in a revlog
989 dump information about delta chains in a revlog
990 debugdirstate
990 debugdirstate
991 show the contents of the current dirstate
991 show the contents of the current dirstate
992 debugdiscovery
992 debugdiscovery
993 runs the changeset discovery protocol in isolation
993 runs the changeset discovery protocol in isolation
994 debugdownload
994 debugdownload
995 download a resource using Mercurial logic and config
995 download a resource using Mercurial logic and config
996 debugextensions
996 debugextensions
997 show information about active extensions
997 show information about active extensions
998 debugfileset parse and apply a fileset specification
998 debugfileset parse and apply a fileset specification
999 debugformat display format information about the current repository
999 debugformat display format information about the current repository
1000 debugfsinfo show information detected about current filesystem
1000 debugfsinfo show information detected about current filesystem
1001 debuggetbundle
1001 debuggetbundle
1002 retrieves a bundle from a repo
1002 retrieves a bundle from a repo
1003 debugignore display the combined ignore pattern and information about
1003 debugignore display the combined ignore pattern and information about
1004 ignored files
1004 ignored files
1005 debugindex dump index data for a storage primitive
1005 debugindex dump index data for a storage primitive
1006 debugindexdot
1006 debugindexdot
1007 dump an index DAG as a graphviz dot file
1007 dump an index DAG as a graphviz dot file
1008 debugindexstats
1008 debugindexstats
1009 show stats related to the changelog index
1009 show stats related to the changelog index
1010 debuginstall test Mercurial installation
1010 debuginstall test Mercurial installation
1011 debugknown test whether node ids are known to a repo
1011 debugknown test whether node ids are known to a repo
1012 debuglocks show or modify state of locks
1012 debuglocks show or modify state of locks
1013 debugmanifestfulltextcache
1013 debugmanifestfulltextcache
1014 show, clear or amend the contents of the manifest fulltext
1014 show, clear or amend the contents of the manifest fulltext
1015 cache
1015 cache
1016 debugmergestate
1016 debugmergestate
1017 print merge state
1017 print merge state
1018 debugnamecomplete
1018 debugnamecomplete
1019 complete "names" - tags, open branch names, bookmark names
1019 complete "names" - tags, open branch names, bookmark names
1020 debugobsolete
1020 debugobsolete
1021 create arbitrary obsolete marker
1021 create arbitrary obsolete marker
1022 debugoptADV (no help text available)
1022 debugoptADV (no help text available)
1023 debugoptDEP (no help text available)
1023 debugoptDEP (no help text available)
1024 debugoptEXP (no help text available)
1024 debugoptEXP (no help text available)
1025 debugp1copies
1025 debugp1copies
1026 dump copy information compared to p1
1026 dump copy information compared to p1
1027 debugp2copies
1027 debugp2copies
1028 dump copy information compared to p2
1028 dump copy information compared to p2
1029 debugpathcomplete
1029 debugpathcomplete
1030 complete part or all of a tracked path
1030 complete part or all of a tracked path
1031 debugpathcopies
1031 debugpathcopies
1032 show copies between two revisions
1032 show copies between two revisions
1033 debugpeer establish a connection to a peer repository
1033 debugpeer establish a connection to a peer repository
1034 debugpickmergetool
1034 debugpickmergetool
1035 examine which merge tool is chosen for specified file
1035 examine which merge tool is chosen for specified file
1036 debugpushkey access the pushkey key/value protocol
1036 debugpushkey access the pushkey key/value protocol
1037 debugpvec (no help text available)
1037 debugpvec (no help text available)
1038 debugrebuilddirstate
1038 debugrebuilddirstate
1039 rebuild the dirstate as it would look like for the given
1039 rebuild the dirstate as it would look like for the given
1040 revision
1040 revision
1041 debugrebuildfncache
1041 debugrebuildfncache
1042 rebuild the fncache file
1042 rebuild the fncache file
1043 debugrename dump rename information
1043 debugrename dump rename information
1044 debugrevlog show data and statistics about a revlog
1044 debugrevlog show data and statistics about a revlog
1045 debugrevlogindex
1045 debugrevlogindex
1046 dump the contents of a revlog index
1046 dump the contents of a revlog index
1047 debugrevspec parse and apply a revision specification
1047 debugrevspec parse and apply a revision specification
1048 debugserve run a server with advanced settings
1048 debugserve run a server with advanced settings
1049 debugsetparents
1049 debugsetparents
1050 manually set the parents of the current working directory
1050 manually set the parents of the current working directory
1051 debugsidedata
1051 debugsidedata
1052 dump the side data for a cl/manifest/file revision
1052 dump the side data for a cl/manifest/file revision
1053 debugssl test a secure connection to a server
1053 debugssl test a secure connection to a server
1054 debugsub (no help text available)
1054 debugsub (no help text available)
1055 debugsuccessorssets
1055 debugsuccessorssets
1056 show set of successors for revision
1056 show set of successors for revision
1057 debugtemplate
1057 debugtemplate
1058 parse and apply a template
1058 parse and apply a template
1059 debuguigetpass
1059 debuguigetpass
1060 show prompt to type password
1060 show prompt to type password
1061 debuguiprompt
1061 debuguiprompt
1062 show plain prompt
1062 show plain prompt
1063 debugupdatecaches
1063 debugupdatecaches
1064 warm all known caches in the repository
1064 warm all known caches in the repository
1065 debugupgraderepo
1065 debugupgraderepo
1066 upgrade a repository to use different features
1066 upgrade a repository to use different features
1067 debugwalk show how files match on given patterns
1067 debugwalk show how files match on given patterns
1068 debugwhyunstable
1068 debugwhyunstable
1069 explain instabilities of a changeset
1069 explain instabilities of a changeset
1070 debugwireargs
1070 debugwireargs
1071 (no help text available)
1071 (no help text available)
1072 debugwireproto
1072 debugwireproto
1073 send wire protocol commands to a server
1073 send wire protocol commands to a server
1074
1074
1075 (use 'hg help -v debug' to show built-in aliases and global options)
1075 (use 'hg help -v debug' to show built-in aliases and global options)
1076
1076
1077 internals topic renders index of available sub-topics
1077 internals topic renders index of available sub-topics
1078
1078
1079 $ hg help internals
1079 $ hg help internals
1080 Technical implementation topics
1080 Technical implementation topics
1081 """""""""""""""""""""""""""""""
1081 """""""""""""""""""""""""""""""
1082
1082
1083 To access a subtopic, use "hg help internals.{subtopic-name}"
1083 To access a subtopic, use "hg help internals.{subtopic-name}"
1084
1084
1085 bundle2 Bundle2
1085 bundle2 Bundle2
1086 bundles Bundles
1086 bundles Bundles
1087 cbor CBOR
1087 cbor CBOR
1088 censor Censor
1088 censor Censor
1089 changegroups Changegroups
1089 changegroups Changegroups
1090 config Config Registrar
1090 config Config Registrar
1091 extensions Extension API
1091 extensions Extension API
1092 mergestate Mergestate
1092 mergestate Mergestate
1093 requirements Repository Requirements
1093 requirements Repository Requirements
1094 revlogs Revision Logs
1094 revlogs Revision Logs
1095 wireprotocol Wire Protocol
1095 wireprotocol Wire Protocol
1096 wireprotocolrpc
1096 wireprotocolrpc
1097 Wire Protocol RPC
1097 Wire Protocol RPC
1098 wireprotocolv2
1098 wireprotocolv2
1099 Wire Protocol Version 2
1099 Wire Protocol Version 2
1100
1100
1101 sub-topics can be accessed
1101 sub-topics can be accessed
1102
1102
1103 $ hg help internals.changegroups
1103 $ hg help internals.changegroups
1104 Changegroups
1104 Changegroups
1105 """"""""""""
1105 """"""""""""
1106
1106
1107 Changegroups are representations of repository revlog data, specifically
1107 Changegroups are representations of repository revlog data, specifically
1108 the changelog data, root/flat manifest data, treemanifest data, and
1108 the changelog data, root/flat manifest data, treemanifest data, and
1109 filelogs.
1109 filelogs.
1110
1110
1111 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1111 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1112 level, versions "1" and "2" are almost exactly the same, with the only
1112 level, versions "1" and "2" are almost exactly the same, with the only
1113 difference being an additional item in the *delta header*. Version "3"
1113 difference being an additional item in the *delta header*. Version "3"
1114 adds support for storage flags in the *delta header* and optionally
1114 adds support for storage flags in the *delta header* and optionally
1115 exchanging treemanifests (enabled by setting an option on the
1115 exchanging treemanifests (enabled by setting an option on the
1116 "changegroup" part in the bundle2).
1116 "changegroup" part in the bundle2).
1117
1117
1118 Changegroups when not exchanging treemanifests consist of 3 logical
1118 Changegroups when not exchanging treemanifests consist of 3 logical
1119 segments:
1119 segments:
1120
1120
1121 +---------------------------------+
1121 +---------------------------------+
1122 | | | |
1122 | | | |
1123 | changeset | manifest | filelogs |
1123 | changeset | manifest | filelogs |
1124 | | | |
1124 | | | |
1125 | | | |
1125 | | | |
1126 +---------------------------------+
1126 +---------------------------------+
1127
1127
1128 When exchanging treemanifests, there are 4 logical segments:
1128 When exchanging treemanifests, there are 4 logical segments:
1129
1129
1130 +-------------------------------------------------+
1130 +-------------------------------------------------+
1131 | | | | |
1131 | | | | |
1132 | changeset | root | treemanifests | filelogs |
1132 | changeset | root | treemanifests | filelogs |
1133 | | manifest | | |
1133 | | manifest | | |
1134 | | | | |
1134 | | | | |
1135 +-------------------------------------------------+
1135 +-------------------------------------------------+
1136
1136
1137 The principle building block of each segment is a *chunk*. A *chunk* is a
1137 The principle building block of each segment is a *chunk*. A *chunk* is a
1138 framed piece of data:
1138 framed piece of data:
1139
1139
1140 +---------------------------------------+
1140 +---------------------------------------+
1141 | | |
1141 | | |
1142 | length | data |
1142 | length | data |
1143 | (4 bytes) | (<length - 4> bytes) |
1143 | (4 bytes) | (<length - 4> bytes) |
1144 | | |
1144 | | |
1145 +---------------------------------------+
1145 +---------------------------------------+
1146
1146
1147 All integers are big-endian signed integers. Each chunk starts with a
1147 All integers are big-endian signed integers. Each chunk starts with a
1148 32-bit integer indicating the length of the entire chunk (including the
1148 32-bit integer indicating the length of the entire chunk (including the
1149 length field itself).
1149 length field itself).
1150
1150
1151 There is a special case chunk that has a value of 0 for the length
1151 There is a special case chunk that has a value of 0 for the length
1152 ("0x00000000"). We call this an *empty chunk*.
1152 ("0x00000000"). We call this an *empty chunk*.
1153
1153
1154 Delta Groups
1154 Delta Groups
1155 ============
1155 ============
1156
1156
1157 A *delta group* expresses the content of a revlog as a series of deltas,
1157 A *delta group* expresses the content of a revlog as a series of deltas,
1158 or patches against previous revisions.
1158 or patches against previous revisions.
1159
1159
1160 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1160 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1161 to signal the end of the delta group:
1161 to signal the end of the delta group:
1162
1162
1163 +------------------------------------------------------------------------+
1163 +------------------------------------------------------------------------+
1164 | | | | | |
1164 | | | | | |
1165 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1165 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1166 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1166 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1167 | | | | | |
1167 | | | | | |
1168 +------------------------------------------------------------------------+
1168 +------------------------------------------------------------------------+
1169
1169
1170 Each *chunk*'s data consists of the following:
1170 Each *chunk*'s data consists of the following:
1171
1171
1172 +---------------------------------------+
1172 +---------------------------------------+
1173 | | |
1173 | | |
1174 | delta header | delta data |
1174 | delta header | delta data |
1175 | (various by version) | (various) |
1175 | (various by version) | (various) |
1176 | | |
1176 | | |
1177 +---------------------------------------+
1177 +---------------------------------------+
1178
1178
1179 The *delta data* is a series of *delta*s that describe a diff from an
1179 The *delta data* is a series of *delta*s that describe a diff from an
1180 existing entry (either that the recipient already has, or previously
1180 existing entry (either that the recipient already has, or previously
1181 specified in the bundle/changegroup).
1181 specified in the bundle/changegroup).
1182
1182
1183 The *delta header* is different between versions "1", "2", and "3" of the
1183 The *delta header* is different between versions "1", "2", and "3" of the
1184 changegroup format.
1184 changegroup format.
1185
1185
1186 Version 1 (headerlen=80):
1186 Version 1 (headerlen=80):
1187
1187
1188 +------------------------------------------------------+
1188 +------------------------------------------------------+
1189 | | | | |
1189 | | | | |
1190 | node | p1 node | p2 node | link node |
1190 | node | p1 node | p2 node | link node |
1191 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1191 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1192 | | | | |
1192 | | | | |
1193 +------------------------------------------------------+
1193 +------------------------------------------------------+
1194
1194
1195 Version 2 (headerlen=100):
1195 Version 2 (headerlen=100):
1196
1196
1197 +------------------------------------------------------------------+
1197 +------------------------------------------------------------------+
1198 | | | | | |
1198 | | | | | |
1199 | node | p1 node | p2 node | base node | link node |
1199 | node | p1 node | p2 node | base node | link node |
1200 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1200 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1201 | | | | | |
1201 | | | | | |
1202 +------------------------------------------------------------------+
1202 +------------------------------------------------------------------+
1203
1203
1204 Version 3 (headerlen=102):
1204 Version 3 (headerlen=102):
1205
1205
1206 +------------------------------------------------------------------------------+
1206 +------------------------------------------------------------------------------+
1207 | | | | | | |
1207 | | | | | | |
1208 | node | p1 node | p2 node | base node | link node | flags |
1208 | node | p1 node | p2 node | base node | link node | flags |
1209 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1209 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1210 | | | | | | |
1210 | | | | | | |
1211 +------------------------------------------------------------------------------+
1211 +------------------------------------------------------------------------------+
1212
1212
1213 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1213 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1214 contain a series of *delta*s, densely packed (no separators). These deltas
1214 contain a series of *delta*s, densely packed (no separators). These deltas
1215 describe a diff from an existing entry (either that the recipient already
1215 describe a diff from an existing entry (either that the recipient already
1216 has, or previously specified in the bundle/changegroup). The format is
1216 has, or previously specified in the bundle/changegroup). The format is
1217 described more fully in "hg help internals.bdiff", but briefly:
1217 described more fully in "hg help internals.bdiff", but briefly:
1218
1218
1219 +---------------------------------------------------------------+
1219 +---------------------------------------------------------------+
1220 | | | | |
1220 | | | | |
1221 | start offset | end offset | new length | content |
1221 | start offset | end offset | new length | content |
1222 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1222 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1223 | | | | |
1223 | | | | |
1224 +---------------------------------------------------------------+
1224 +---------------------------------------------------------------+
1225
1225
1226 Please note that the length field in the delta data does *not* include
1226 Please note that the length field in the delta data does *not* include
1227 itself.
1227 itself.
1228
1228
1229 In version 1, the delta is always applied against the previous node from
1229 In version 1, the delta is always applied against the previous node from
1230 the changegroup or the first parent if this is the first entry in the
1230 the changegroup or the first parent if this is the first entry in the
1231 changegroup.
1231 changegroup.
1232
1232
1233 In version 2 and up, the delta base node is encoded in the entry in the
1233 In version 2 and up, the delta base node is encoded in the entry in the
1234 changegroup. This allows the delta to be expressed against any parent,
1234 changegroup. This allows the delta to be expressed against any parent,
1235 which can result in smaller deltas and more efficient encoding of data.
1235 which can result in smaller deltas and more efficient encoding of data.
1236
1236
1237 The *flags* field holds bitwise flags affecting the processing of revision
1237 The *flags* field holds bitwise flags affecting the processing of revision
1238 data. The following flags are defined:
1238 data. The following flags are defined:
1239
1239
1240 32768
1240 32768
1241 Censored revision. The revision's fulltext has been replaced by censor
1241 Censored revision. The revision's fulltext has been replaced by censor
1242 metadata. May only occur on file revisions.
1242 metadata. May only occur on file revisions.
1243
1243
1244 16384
1244 16384
1245 Ellipsis revision. Revision hash does not match data (likely due to
1245 Ellipsis revision. Revision hash does not match data (likely due to
1246 rewritten parents).
1246 rewritten parents).
1247
1247
1248 8192
1248 8192
1249 Externally stored. The revision fulltext contains "key:value" "\n"
1249 Externally stored. The revision fulltext contains "key:value" "\n"
1250 delimited metadata defining an object stored elsewhere. Used by the LFS
1250 delimited metadata defining an object stored elsewhere. Used by the LFS
1251 extension.
1251 extension.
1252
1252
1253 For historical reasons, the integer values are identical to revlog version
1253 For historical reasons, the integer values are identical to revlog version
1254 1 per-revision storage flags and correspond to bits being set in this
1254 1 per-revision storage flags and correspond to bits being set in this
1255 2-byte field. Bits were allocated starting from the most-significant bit,
1255 2-byte field. Bits were allocated starting from the most-significant bit,
1256 hence the reverse ordering and allocation of these flags.
1256 hence the reverse ordering and allocation of these flags.
1257
1257
1258 Changeset Segment
1258 Changeset Segment
1259 =================
1259 =================
1260
1260
1261 The *changeset segment* consists of a single *delta group* holding
1261 The *changeset segment* consists of a single *delta group* holding
1262 changelog data. The *empty chunk* at the end of the *delta group* denotes
1262 changelog data. The *empty chunk* at the end of the *delta group* denotes
1263 the boundary to the *manifest segment*.
1263 the boundary to the *manifest segment*.
1264
1264
1265 Manifest Segment
1265 Manifest Segment
1266 ================
1266 ================
1267
1267
1268 The *manifest segment* consists of a single *delta group* holding manifest
1268 The *manifest segment* consists of a single *delta group* holding manifest
1269 data. If treemanifests are in use, it contains only the manifest for the
1269 data. If treemanifests are in use, it contains only the manifest for the
1270 root directory of the repository. Otherwise, it contains the entire
1270 root directory of the repository. Otherwise, it contains the entire
1271 manifest data. The *empty chunk* at the end of the *delta group* denotes
1271 manifest data. The *empty chunk* at the end of the *delta group* denotes
1272 the boundary to the next segment (either the *treemanifests segment* or
1272 the boundary to the next segment (either the *treemanifests segment* or
1273 the *filelogs segment*, depending on version and the request options).
1273 the *filelogs segment*, depending on version and the request options).
1274
1274
1275 Treemanifests Segment
1275 Treemanifests Segment
1276 ---------------------
1276 ---------------------
1277
1277
1278 The *treemanifests segment* only exists in changegroup version "3", and
1278 The *treemanifests segment* only exists in changegroup version "3", and
1279 only if the 'treemanifest' param is part of the bundle2 changegroup part
1279 only if the 'treemanifest' param is part of the bundle2 changegroup part
1280 (it is not possible to use changegroup version 3 outside of bundle2).
1280 (it is not possible to use changegroup version 3 outside of bundle2).
1281 Aside from the filenames in the *treemanifests segment* containing a
1281 Aside from the filenames in the *treemanifests segment* containing a
1282 trailing "/" character, it behaves identically to the *filelogs segment*
1282 trailing "/" character, it behaves identically to the *filelogs segment*
1283 (see below). The final sub-segment is followed by an *empty chunk*
1283 (see below). The final sub-segment is followed by an *empty chunk*
1284 (logically, a sub-segment with filename size 0). This denotes the boundary
1284 (logically, a sub-segment with filename size 0). This denotes the boundary
1285 to the *filelogs segment*.
1285 to the *filelogs segment*.
1286
1286
1287 Filelogs Segment
1287 Filelogs Segment
1288 ================
1288 ================
1289
1289
1290 The *filelogs segment* consists of multiple sub-segments, each
1290 The *filelogs segment* consists of multiple sub-segments, each
1291 corresponding to an individual file whose data is being described:
1291 corresponding to an individual file whose data is being described:
1292
1292
1293 +--------------------------------------------------+
1293 +--------------------------------------------------+
1294 | | | | | |
1294 | | | | | |
1295 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1295 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1296 | | | | | (4 bytes) |
1296 | | | | | (4 bytes) |
1297 | | | | | |
1297 | | | | | |
1298 +--------------------------------------------------+
1298 +--------------------------------------------------+
1299
1299
1300 The final filelog sub-segment is followed by an *empty chunk* (logically,
1300 The final filelog sub-segment is followed by an *empty chunk* (logically,
1301 a sub-segment with filename size 0). This denotes the end of the segment
1301 a sub-segment with filename size 0). This denotes the end of the segment
1302 and of the overall changegroup.
1302 and of the overall changegroup.
1303
1303
1304 Each filelog sub-segment consists of the following:
1304 Each filelog sub-segment consists of the following:
1305
1305
1306 +------------------------------------------------------+
1306 +------------------------------------------------------+
1307 | | | |
1307 | | | |
1308 | filename length | filename | delta group |
1308 | filename length | filename | delta group |
1309 | (4 bytes) | (<length - 4> bytes) | (various) |
1309 | (4 bytes) | (<length - 4> bytes) | (various) |
1310 | | | |
1310 | | | |
1311 +------------------------------------------------------+
1311 +------------------------------------------------------+
1312
1312
1313 That is, a *chunk* consisting of the filename (not terminated or padded)
1313 That is, a *chunk* consisting of the filename (not terminated or padded)
1314 followed by N chunks constituting the *delta group* for this file. The
1314 followed by N chunks constituting the *delta group* for this file. The
1315 *empty chunk* at the end of each *delta group* denotes the boundary to the
1315 *empty chunk* at the end of each *delta group* denotes the boundary to the
1316 next filelog sub-segment.
1316 next filelog sub-segment.
1317
1317
1318 non-existent subtopics print an error
1318 non-existent subtopics print an error
1319
1319
1320 $ hg help internals.foo
1320 $ hg help internals.foo
1321 abort: no such help topic: internals.foo
1321 abort: no such help topic: internals.foo
1322 (try 'hg help --keyword foo')
1322 (try 'hg help --keyword foo')
1323 [255]
1323 [255]
1324
1324
1325 test advanced, deprecated and experimental options are hidden in command help
1325 test advanced, deprecated and experimental options are hidden in command help
1326 $ hg help debugoptADV
1326 $ hg help debugoptADV
1327 hg debugoptADV
1327 hg debugoptADV
1328
1328
1329 (no help text available)
1329 (no help text available)
1330
1330
1331 options:
1331 options:
1332
1332
1333 (some details hidden, use --verbose to show complete help)
1333 (some details hidden, use --verbose to show complete help)
1334 $ hg help debugoptDEP
1334 $ hg help debugoptDEP
1335 hg debugoptDEP
1335 hg debugoptDEP
1336
1336
1337 (no help text available)
1337 (no help text available)
1338
1338
1339 options:
1339 options:
1340
1340
1341 (some details hidden, use --verbose to show complete help)
1341 (some details hidden, use --verbose to show complete help)
1342
1342
1343 $ hg help debugoptEXP
1343 $ hg help debugoptEXP
1344 hg debugoptEXP
1344 hg debugoptEXP
1345
1345
1346 (no help text available)
1346 (no help text available)
1347
1347
1348 options:
1348 options:
1349
1349
1350 (some details hidden, use --verbose to show complete help)
1350 (some details hidden, use --verbose to show complete help)
1351
1351
1352 test advanced, deprecated and experimental options are shown with -v
1352 test advanced, deprecated and experimental options are shown with -v
1353 $ hg help -v debugoptADV | grep aopt
1353 $ hg help -v debugoptADV | grep aopt
1354 --aopt option is (ADVANCED)
1354 --aopt option is (ADVANCED)
1355 $ hg help -v debugoptDEP | grep dopt
1355 $ hg help -v debugoptDEP | grep dopt
1356 --dopt option is (DEPRECATED)
1356 --dopt option is (DEPRECATED)
1357 $ hg help -v debugoptEXP | grep eopt
1357 $ hg help -v debugoptEXP | grep eopt
1358 --eopt option is (EXPERIMENTAL)
1358 --eopt option is (EXPERIMENTAL)
1359
1359
1360 #if gettext
1360 #if gettext
1361 test deprecated option is hidden with translation with untranslated description
1361 test deprecated option is hidden with translation with untranslated description
1362 (use many globy for not failing on changed transaction)
1362 (use many globy for not failing on changed transaction)
1363 $ LANGUAGE=sv hg help debugoptDEP
1363 $ LANGUAGE=sv hg help debugoptDEP
1364 hg debugoptDEP
1364 hg debugoptDEP
1365
1365
1366 (*) (glob)
1366 (*) (glob)
1367
1367
1368 options:
1368 options:
1369
1369
1370 (some details hidden, use --verbose to show complete help)
1370 (some details hidden, use --verbose to show complete help)
1371 #endif
1371 #endif
1372
1372
1373 Test commands that collide with topics (issue4240)
1373 Test commands that collide with topics (issue4240)
1374
1374
1375 $ hg config -hq
1375 $ hg config -hq
1376 hg config [-u] [NAME]...
1376 hg config [-u] [NAME]...
1377
1377
1378 show combined config settings from all hgrc files
1378 show combined config settings from all hgrc files
1379 $ hg showconfig -hq
1379 $ hg showconfig -hq
1380 hg config [-u] [NAME]...
1380 hg config [-u] [NAME]...
1381
1381
1382 show combined config settings from all hgrc files
1382 show combined config settings from all hgrc files
1383
1383
1384 Test a help topic
1384 Test a help topic
1385
1385
1386 $ hg help dates
1386 $ hg help dates
1387 Date Formats
1387 Date Formats
1388 """"""""""""
1388 """"""""""""
1389
1389
1390 Some commands allow the user to specify a date, e.g.:
1390 Some commands allow the user to specify a date, e.g.:
1391
1391
1392 - backout, commit, import, tag: Specify the commit date.
1392 - backout, commit, import, tag: Specify the commit date.
1393 - log, revert, update: Select revision(s) by date.
1393 - log, revert, update: Select revision(s) by date.
1394
1394
1395 Many date formats are valid. Here are some examples:
1395 Many date formats are valid. Here are some examples:
1396
1396
1397 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1397 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1398 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1398 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1399 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1399 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1400 - "Dec 6" (midnight)
1400 - "Dec 6" (midnight)
1401 - "13:18" (today assumed)
1401 - "13:18" (today assumed)
1402 - "3:39" (3:39AM assumed)
1402 - "3:39" (3:39AM assumed)
1403 - "3:39pm" (15:39)
1403 - "3:39pm" (15:39)
1404 - "2006-12-06 13:18:29" (ISO 8601 format)
1404 - "2006-12-06 13:18:29" (ISO 8601 format)
1405 - "2006-12-6 13:18"
1405 - "2006-12-6 13:18"
1406 - "2006-12-6"
1406 - "2006-12-6"
1407 - "12-6"
1407 - "12-6"
1408 - "12/6"
1408 - "12/6"
1409 - "12/6/6" (Dec 6 2006)
1409 - "12/6/6" (Dec 6 2006)
1410 - "today" (midnight)
1410 - "today" (midnight)
1411 - "yesterday" (midnight)
1411 - "yesterday" (midnight)
1412 - "now" - right now
1412 - "now" - right now
1413
1413
1414 Lastly, there is Mercurial's internal format:
1414 Lastly, there is Mercurial's internal format:
1415
1415
1416 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1416 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1417
1417
1418 This is the internal representation format for dates. The first number is
1418 This is the internal representation format for dates. The first number is
1419 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1419 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1420 is the offset of the local timezone, in seconds west of UTC (negative if
1420 is the offset of the local timezone, in seconds west of UTC (negative if
1421 the timezone is east of UTC).
1421 the timezone is east of UTC).
1422
1422
1423 The log command also accepts date ranges:
1423 The log command also accepts date ranges:
1424
1424
1425 - "<DATE" - at or before a given date/time
1425 - "<DATE" - at or before a given date/time
1426 - ">DATE" - on or after a given date/time
1426 - ">DATE" - on or after a given date/time
1427 - "DATE to DATE" - a date range, inclusive
1427 - "DATE to DATE" - a date range, inclusive
1428 - "-DAYS" - within a given number of days of today
1428 - "-DAYS" - within a given number of days of today
1429
1429
1430 Test repeated config section name
1430 Test repeated config section name
1431
1431
1432 $ hg help config.host
1432 $ hg help config.host
1433 "http_proxy.host"
1433 "http_proxy.host"
1434 Host name and (optional) port of the proxy server, for example
1434 Host name and (optional) port of the proxy server, for example
1435 "myproxy:8000".
1435 "myproxy:8000".
1436
1436
1437 "smtp.host"
1437 "smtp.host"
1438 Host name of mail server, e.g. "mail.example.com".
1438 Host name of mail server, e.g. "mail.example.com".
1439
1439
1440
1440
1441 Test section name with dot
1441 Test section name with dot
1442
1442
1443 $ hg help config.ui.username
1443 $ hg help config.ui.username
1444 "ui.username"
1444 "ui.username"
1445 The committer of a changeset created when running "commit". Typically
1445 The committer of a changeset created when running "commit". Typically
1446 a person's name and email address, e.g. "Fred Widget
1446 a person's name and email address, e.g. "Fred Widget
1447 <fred@example.com>". Environment variables in the username are
1447 <fred@example.com>". Environment variables in the username are
1448 expanded.
1448 expanded.
1449
1449
1450 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1450 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1451 empty, e.g. if the system admin set "username =" in the system hgrc,
1451 empty, e.g. if the system admin set "username =" in the system hgrc,
1452 it has to be specified manually or in a different hgrc file)
1452 it has to be specified manually or in a different hgrc file)
1453
1453
1454
1454
1455 $ hg help config.annotate.git
1455 $ hg help config.annotate.git
1456 abort: help section not found: config.annotate.git
1456 abort: help section not found: config.annotate.git
1457 [255]
1457 [255]
1458
1458
1459 $ hg help config.update.check
1459 $ hg help config.update.check
1460 "commands.update.check"
1460 "commands.update.check"
1461 Determines what level of checking 'hg update' will perform before
1461 Determines what level of checking 'hg update' will perform before
1462 moving to a destination revision. Valid values are "abort", "none",
1462 moving to a destination revision. Valid values are "abort", "none",
1463 "linear", and "noconflict". "abort" always fails if the working
1463 "linear", and "noconflict". "abort" always fails if the working
1464 directory has uncommitted changes. "none" performs no checking, and
1464 directory has uncommitted changes. "none" performs no checking, and
1465 may result in a merge with uncommitted changes. "linear" allows any
1465 may result in a merge with uncommitted changes. "linear" allows any
1466 update as long as it follows a straight line in the revision history,
1466 update as long as it follows a straight line in the revision history,
1467 and may trigger a merge with uncommitted changes. "noconflict" will
1467 and may trigger a merge with uncommitted changes. "noconflict" will
1468 allow any update which would not trigger a merge with uncommitted
1468 allow any update which would not trigger a merge with uncommitted
1469 changes, if any are present. (default: "linear")
1469 changes, if any are present. (default: "linear")
1470
1470
1471
1471
1472 $ hg help config.commands.update.check
1472 $ hg help config.commands.update.check
1473 "commands.update.check"
1473 "commands.update.check"
1474 Determines what level of checking 'hg update' will perform before
1474 Determines what level of checking 'hg update' will perform before
1475 moving to a destination revision. Valid values are "abort", "none",
1475 moving to a destination revision. Valid values are "abort", "none",
1476 "linear", and "noconflict". "abort" always fails if the working
1476 "linear", and "noconflict". "abort" always fails if the working
1477 directory has uncommitted changes. "none" performs no checking, and
1477 directory has uncommitted changes. "none" performs no checking, and
1478 may result in a merge with uncommitted changes. "linear" allows any
1478 may result in a merge with uncommitted changes. "linear" allows any
1479 update as long as it follows a straight line in the revision history,
1479 update as long as it follows a straight line in the revision history,
1480 and may trigger a merge with uncommitted changes. "noconflict" will
1480 and may trigger a merge with uncommitted changes. "noconflict" will
1481 allow any update which would not trigger a merge with uncommitted
1481 allow any update which would not trigger a merge with uncommitted
1482 changes, if any are present. (default: "linear")
1482 changes, if any are present. (default: "linear")
1483
1483
1484
1484
1485 $ hg help config.ommands.update.check
1485 $ hg help config.ommands.update.check
1486 abort: help section not found: config.ommands.update.check
1486 abort: help section not found: config.ommands.update.check
1487 [255]
1487 [255]
1488
1488
1489 Unrelated trailing paragraphs shouldn't be included
1489 Unrelated trailing paragraphs shouldn't be included
1490
1490
1491 $ hg help config.extramsg | grep '^$'
1491 $ hg help config.extramsg | grep '^$'
1492
1492
1493
1493
1494 Test capitalized section name
1494 Test capitalized section name
1495
1495
1496 $ hg help scripting.HGPLAIN > /dev/null
1496 $ hg help scripting.HGPLAIN > /dev/null
1497
1497
1498 Help subsection:
1498 Help subsection:
1499
1499
1500 $ hg help config.charsets |grep "Email example:" > /dev/null
1500 $ hg help config.charsets |grep "Email example:" > /dev/null
1501 [1]
1501 [1]
1502
1502
1503 Show nested definitions
1503 Show nested definitions
1504 ("profiling.type"[break]"ls"[break]"stat"[break])
1504 ("profiling.type"[break]"ls"[break]"stat"[break])
1505
1505
1506 $ hg help config.type | egrep '^$'|wc -l
1506 $ hg help config.type | egrep '^$'|wc -l
1507 \s*3 (re)
1507 \s*3 (re)
1508
1508
1509 $ hg help config.profiling.type.ls
1509 $ hg help config.profiling.type.ls
1510 "profiling.type.ls"
1510 "profiling.type.ls"
1511 Use Python's built-in instrumenting profiler. This profiler works on
1511 Use Python's built-in instrumenting profiler. This profiler works on
1512 all platforms, but each line number it reports is the first line of
1512 all platforms, but each line number it reports is the first line of
1513 a function. This restriction makes it difficult to identify the
1513 a function. This restriction makes it difficult to identify the
1514 expensive parts of a non-trivial function.
1514 expensive parts of a non-trivial function.
1515
1515
1516
1516
1517 Separate sections from subsections
1517 Separate sections from subsections
1518
1518
1519 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1519 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1520 "format"
1520 "format"
1521 --------
1521 --------
1522
1522
1523 "usegeneraldelta"
1523 "usegeneraldelta"
1524
1524
1525 "dotencode"
1525 "dotencode"
1526
1526
1527 "usefncache"
1527 "usefncache"
1528
1528
1529 "usestore"
1529 "usestore"
1530
1530
1531 "sparse-revlog"
1531 "sparse-revlog"
1532
1532
1533 "revlog-compression"
1533 "revlog-compression"
1534
1534
1535 "bookmarks-in-store"
1535 "bookmarks-in-store"
1536
1536
1537 "profiling"
1537 "profiling"
1538 -----------
1538 -----------
1539
1539
1540 "format"
1540 "format"
1541
1541
1542 "progress"
1542 "progress"
1543 ----------
1543 ----------
1544
1544
1545 "format"
1545 "format"
1546
1546
1547
1547
1548 Last item in help config.*:
1548 Last item in help config.*:
1549
1549
1550 $ hg help config.`hg help config|grep '^ "'| \
1550 $ hg help config.`hg help config|grep '^ "'| \
1551 > tail -1|sed 's![ "]*!!g'`| \
1551 > tail -1|sed 's![ "]*!!g'`| \
1552 > grep 'hg help -c config' > /dev/null
1552 > grep 'hg help -c config' > /dev/null
1553 [1]
1553 [1]
1554
1554
1555 note to use help -c for general hg help config:
1555 note to use help -c for general hg help config:
1556
1556
1557 $ hg help config |grep 'hg help -c config' > /dev/null
1557 $ hg help config |grep 'hg help -c config' > /dev/null
1558
1558
1559 Test templating help
1559 Test templating help
1560
1560
1561 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1561 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1562 desc String. The text of the changeset description.
1562 desc String. The text of the changeset description.
1563 diffstat String. Statistics of changes with the following format:
1563 diffstat String. Statistics of changes with the following format:
1564 firstline Any text. Returns the first line of text.
1564 firstline Any text. Returns the first line of text.
1565 nonempty Any text. Returns '(none)' if the string is empty.
1565 nonempty Any text. Returns '(none)' if the string is empty.
1566
1566
1567 Test deprecated items
1567 Test deprecated items
1568
1568
1569 $ hg help -v templating | grep currentbookmark
1569 $ hg help -v templating | grep currentbookmark
1570 currentbookmark
1570 currentbookmark
1571 $ hg help templating | (grep currentbookmark || true)
1571 $ hg help templating | (grep currentbookmark || true)
1572
1572
1573 Test help hooks
1573 Test help hooks
1574
1574
1575 $ cat > helphook1.py <<EOF
1575 $ cat > helphook1.py <<EOF
1576 > from mercurial import help
1576 > from mercurial import help
1577 >
1577 >
1578 > def rewrite(ui, topic, doc):
1578 > def rewrite(ui, topic, doc):
1579 > return doc + b'\nhelphook1\n'
1579 > return doc + b'\nhelphook1\n'
1580 >
1580 >
1581 > def extsetup(ui):
1581 > def extsetup(ui):
1582 > help.addtopichook(b'revisions', rewrite)
1582 > help.addtopichook(b'revisions', rewrite)
1583 > EOF
1583 > EOF
1584 $ cat > helphook2.py <<EOF
1584 $ cat > helphook2.py <<EOF
1585 > from mercurial import help
1585 > from mercurial import help
1586 >
1586 >
1587 > def rewrite(ui, topic, doc):
1587 > def rewrite(ui, topic, doc):
1588 > return doc + b'\nhelphook2\n'
1588 > return doc + b'\nhelphook2\n'
1589 >
1589 >
1590 > def extsetup(ui):
1590 > def extsetup(ui):
1591 > help.addtopichook(b'revisions', rewrite)
1591 > help.addtopichook(b'revisions', rewrite)
1592 > EOF
1592 > EOF
1593 $ echo '[extensions]' >> $HGRCPATH
1593 $ echo '[extensions]' >> $HGRCPATH
1594 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1594 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1595 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1595 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1596 $ hg help revsets | grep helphook
1596 $ hg help revsets | grep helphook
1597 helphook1
1597 helphook1
1598 helphook2
1598 helphook2
1599
1599
1600 help -c should only show debug --debug
1600 help -c should only show debug --debug
1601
1601
1602 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1602 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1603 [1]
1603 [1]
1604
1604
1605 help -c should only show deprecated for -v
1605 help -c should only show deprecated for -v
1606
1606
1607 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1607 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1608 [1]
1608 [1]
1609
1609
1610 Test -s / --system
1610 Test -s / --system
1611
1611
1612 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1612 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1613 > wc -l | sed -e 's/ //g'
1613 > wc -l | sed -e 's/ //g'
1614 0
1614 0
1615 $ hg help config.files --system unix | grep 'USER' | \
1615 $ hg help config.files --system unix | grep 'USER' | \
1616 > wc -l | sed -e 's/ //g'
1616 > wc -l | sed -e 's/ //g'
1617 0
1617 0
1618
1618
1619 Test -e / -c / -k combinations
1619 Test -e / -c / -k combinations
1620
1620
1621 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1621 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1622 Commands:
1622 Commands:
1623 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1623 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1624 Extensions:
1624 Extensions:
1625 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1625 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1626 Topics:
1626 Topics:
1627 Commands:
1627 Commands:
1628 Extensions:
1628 Extensions:
1629 Extension Commands:
1629 Extension Commands:
1630 $ hg help -c schemes
1630 $ hg help -c schemes
1631 abort: no such help topic: schemes
1631 abort: no such help topic: schemes
1632 (try 'hg help --keyword schemes')
1632 (try 'hg help --keyword schemes')
1633 [255]
1633 [255]
1634 $ hg help -e schemes |head -1
1634 $ hg help -e schemes |head -1
1635 schemes extension - extend schemes with shortcuts to repository swarms
1635 schemes extension - extend schemes with shortcuts to repository swarms
1636 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1636 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1637 Commands:
1637 Commands:
1638 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1638 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1639 Extensions:
1639 Extensions:
1640 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1640 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1641 Extensions:
1641 Extensions:
1642 Commands:
1642 Commands:
1643 $ hg help -c commit > /dev/null
1643 $ hg help -c commit > /dev/null
1644 $ hg help -e -c commit > /dev/null
1644 $ hg help -e -c commit > /dev/null
1645 $ hg help -e commit
1645 $ hg help -e commit
1646 abort: no such help topic: commit
1646 abort: no such help topic: commit
1647 (try 'hg help --keyword commit')
1647 (try 'hg help --keyword commit')
1648 [255]
1648 [255]
1649
1649
1650 Test keyword search help
1650 Test keyword search help
1651
1651
1652 $ cat > prefixedname.py <<EOF
1652 $ cat > prefixedname.py <<EOF
1653 > '''matched against word "clone"
1653 > '''matched against word "clone"
1654 > '''
1654 > '''
1655 > EOF
1655 > EOF
1656 $ echo '[extensions]' >> $HGRCPATH
1656 $ echo '[extensions]' >> $HGRCPATH
1657 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1657 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1658 $ hg help -k clone
1658 $ hg help -k clone
1659 Topics:
1659 Topics:
1660
1660
1661 config Configuration Files
1661 config Configuration Files
1662 extensions Using Additional Features
1662 extensions Using Additional Features
1663 glossary Glossary
1663 glossary Glossary
1664 phases Working with Phases
1664 phases Working with Phases
1665 subrepos Subrepositories
1665 subrepos Subrepositories
1666 urls URL Paths
1666 urls URL Paths
1667
1667
1668 Commands:
1668 Commands:
1669
1669
1670 bookmarks create a new bookmark or list existing bookmarks
1670 bookmarks create a new bookmark or list existing bookmarks
1671 clone make a copy of an existing repository
1671 clone make a copy of an existing repository
1672 paths show aliases for remote repositories
1672 paths show aliases for remote repositories
1673 pull pull changes from the specified source
1673 pull pull changes from the specified source
1674 update update working directory (or switch revisions)
1674 update update working directory (or switch revisions)
1675
1675
1676 Extensions:
1676 Extensions:
1677
1677
1678 clonebundles advertise pre-generated bundles to seed clones
1678 clonebundles advertise pre-generated bundles to seed clones
1679 narrow create clones which fetch history data for subset of files
1679 narrow create clones which fetch history data for subset of files
1680 (EXPERIMENTAL)
1680 (EXPERIMENTAL)
1681 prefixedname matched against word "clone"
1681 prefixedname matched against word "clone"
1682 relink recreates hardlinks between repository clones
1682 relink recreates hardlinks between repository clones
1683
1683
1684 Extension Commands:
1684 Extension Commands:
1685
1685
1686 qclone clone main and patch repository at same time
1686 qclone clone main and patch repository at same time
1687
1687
1688 Test unfound topic
1688 Test unfound topic
1689
1689
1690 $ hg help nonexistingtopicthatwillneverexisteverever
1690 $ hg help nonexistingtopicthatwillneverexisteverever
1691 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1691 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1692 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1692 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1693 [255]
1693 [255]
1694
1694
1695 Test unfound keyword
1695 Test unfound keyword
1696
1696
1697 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1697 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1698 abort: no matches
1698 abort: no matches
1699 (try 'hg help' for a list of topics)
1699 (try 'hg help' for a list of topics)
1700 [255]
1700 [255]
1701
1701
1702 Test omit indicating for help
1702 Test omit indicating for help
1703
1703
1704 $ cat > addverboseitems.py <<EOF
1704 $ cat > addverboseitems.py <<EOF
1705 > r'''extension to test omit indicating.
1705 > r'''extension to test omit indicating.
1706 >
1706 >
1707 > This paragraph is never omitted (for extension)
1707 > This paragraph is never omitted (for extension)
1708 >
1708 >
1709 > .. container:: verbose
1709 > .. container:: verbose
1710 >
1710 >
1711 > This paragraph is omitted,
1711 > This paragraph is omitted,
1712 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1712 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1713 >
1713 >
1714 > This paragraph is never omitted, too (for extension)
1714 > This paragraph is never omitted, too (for extension)
1715 > '''
1715 > '''
1716 > from __future__ import absolute_import
1716 > from __future__ import absolute_import
1717 > from mercurial import commands, help
1717 > from mercurial import commands, help
1718 > testtopic = br"""This paragraph is never omitted (for topic).
1718 > testtopic = br"""This paragraph is never omitted (for topic).
1719 >
1719 >
1720 > .. container:: verbose
1720 > .. container:: verbose
1721 >
1721 >
1722 > This paragraph is omitted,
1722 > This paragraph is omitted,
1723 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1723 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1724 >
1724 >
1725 > This paragraph is never omitted, too (for topic)
1725 > This paragraph is never omitted, too (for topic)
1726 > """
1726 > """
1727 > def extsetup(ui):
1727 > def extsetup(ui):
1728 > help.helptable.append(([b"topic-containing-verbose"],
1728 > help.helptable.append(([b"topic-containing-verbose"],
1729 > b"This is the topic to test omit indicating.",
1729 > b"This is the topic to test omit indicating.",
1730 > lambda ui: testtopic))
1730 > lambda ui: testtopic))
1731 > EOF
1731 > EOF
1732 $ echo '[extensions]' >> $HGRCPATH
1732 $ echo '[extensions]' >> $HGRCPATH
1733 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1733 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1734 $ hg help addverboseitems
1734 $ hg help addverboseitems
1735 addverboseitems extension - extension to test omit indicating.
1735 addverboseitems extension - extension to test omit indicating.
1736
1736
1737 This paragraph is never omitted (for extension)
1737 This paragraph is never omitted (for extension)
1738
1738
1739 This paragraph is never omitted, too (for extension)
1739 This paragraph is never omitted, too (for extension)
1740
1740
1741 (some details hidden, use --verbose to show complete help)
1741 (some details hidden, use --verbose to show complete help)
1742
1742
1743 no commands defined
1743 no commands defined
1744 $ hg help -v addverboseitems
1744 $ hg help -v addverboseitems
1745 addverboseitems extension - extension to test omit indicating.
1745 addverboseitems extension - extension to test omit indicating.
1746
1746
1747 This paragraph is never omitted (for extension)
1747 This paragraph is never omitted (for extension)
1748
1748
1749 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1749 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1750 extension)
1750 extension)
1751
1751
1752 This paragraph is never omitted, too (for extension)
1752 This paragraph is never omitted, too (for extension)
1753
1753
1754 no commands defined
1754 no commands defined
1755 $ hg help topic-containing-verbose
1755 $ hg help topic-containing-verbose
1756 This is the topic to test omit indicating.
1756 This is the topic to test omit indicating.
1757 """"""""""""""""""""""""""""""""""""""""""
1757 """"""""""""""""""""""""""""""""""""""""""
1758
1758
1759 This paragraph is never omitted (for topic).
1759 This paragraph is never omitted (for topic).
1760
1760
1761 This paragraph is never omitted, too (for topic)
1761 This paragraph is never omitted, too (for topic)
1762
1762
1763 (some details hidden, use --verbose to show complete help)
1763 (some details hidden, use --verbose to show complete help)
1764 $ hg help -v topic-containing-verbose
1764 $ hg help -v topic-containing-verbose
1765 This is the topic to test omit indicating.
1765 This is the topic to test omit indicating.
1766 """"""""""""""""""""""""""""""""""""""""""
1766 """"""""""""""""""""""""""""""""""""""""""
1767
1767
1768 This paragraph is never omitted (for topic).
1768 This paragraph is never omitted (for topic).
1769
1769
1770 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1770 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1771 topic)
1771 topic)
1772
1772
1773 This paragraph is never omitted, too (for topic)
1773 This paragraph is never omitted, too (for topic)
1774
1774
1775 Test section lookup
1775 Test section lookup
1776
1776
1777 $ hg help revset.merge
1777 $ hg help revset.merge
1778 "merge()"
1778 "merge()"
1779 Changeset is a merge changeset.
1779 Changeset is a merge changeset.
1780
1780
1781 $ hg help glossary.dag
1781 $ hg help glossary.dag
1782 DAG
1782 DAG
1783 The repository of changesets of a distributed version control system
1783 The repository of changesets of a distributed version control system
1784 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1784 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1785 of nodes and edges, where nodes correspond to changesets and edges
1785 of nodes and edges, where nodes correspond to changesets and edges
1786 imply a parent -> child relation. This graph can be visualized by
1786 imply a parent -> child relation. This graph can be visualized by
1787 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1787 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1788 limited by the requirement for children to have at most two parents.
1788 limited by the requirement for children to have at most two parents.
1789
1789
1790
1790
1791 $ hg help hgrc.paths
1791 $ hg help hgrc.paths
1792 "paths"
1792 "paths"
1793 -------
1793 -------
1794
1794
1795 Assigns symbolic names and behavior to repositories.
1795 Assigns symbolic names and behavior to repositories.
1796
1796
1797 Options are symbolic names defining the URL or directory that is the
1797 Options are symbolic names defining the URL or directory that is the
1798 location of the repository. Example:
1798 location of the repository. Example:
1799
1799
1800 [paths]
1800 [paths]
1801 my_server = https://example.com/my_repo
1801 my_server = https://example.com/my_repo
1802 local_path = /home/me/repo
1802 local_path = /home/me/repo
1803
1803
1804 These symbolic names can be used from the command line. To pull from
1804 These symbolic names can be used from the command line. To pull from
1805 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1805 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1806 local_path'.
1806 local_path'.
1807
1807
1808 Options containing colons (":") denote sub-options that can influence
1808 Options containing colons (":") denote sub-options that can influence
1809 behavior for that specific path. Example:
1809 behavior for that specific path. Example:
1810
1810
1811 [paths]
1811 [paths]
1812 my_server = https://example.com/my_path
1812 my_server = https://example.com/my_path
1813 my_server:pushurl = ssh://example.com/my_path
1813 my_server:pushurl = ssh://example.com/my_path
1814
1814
1815 The following sub-options can be defined:
1815 The following sub-options can be defined:
1816
1816
1817 "pushurl"
1817 "pushurl"
1818 The URL to use for push operations. If not defined, the location
1818 The URL to use for push operations. If not defined, the location
1819 defined by the path's main entry is used.
1819 defined by the path's main entry is used.
1820
1820
1821 "pushrev"
1821 "pushrev"
1822 A revset defining which revisions to push by default.
1822 A revset defining which revisions to push by default.
1823
1823
1824 When 'hg push' is executed without a "-r" argument, the revset defined
1824 When 'hg push' is executed without a "-r" argument, the revset defined
1825 by this sub-option is evaluated to determine what to push.
1825 by this sub-option is evaluated to determine what to push.
1826
1826
1827 For example, a value of "." will push the working directory's revision
1827 For example, a value of "." will push the working directory's revision
1828 by default.
1828 by default.
1829
1829
1830 Revsets specifying bookmarks will not result in the bookmark being
1830 Revsets specifying bookmarks will not result in the bookmark being
1831 pushed.
1831 pushed.
1832
1832
1833 The following special named paths exist:
1833 The following special named paths exist:
1834
1834
1835 "default"
1835 "default"
1836 The URL or directory to use when no source or remote is specified.
1836 The URL or directory to use when no source or remote is specified.
1837
1837
1838 'hg clone' will automatically define this path to the location the
1838 'hg clone' will automatically define this path to the location the
1839 repository was cloned from.
1839 repository was cloned from.
1840
1840
1841 "default-push"
1841 "default-push"
1842 (deprecated) The URL or directory for the default 'hg push' location.
1842 (deprecated) The URL or directory for the default 'hg push' location.
1843 "default:pushurl" should be used instead.
1843 "default:pushurl" should be used instead.
1844
1844
1845 $ hg help glossary.mcguffin
1845 $ hg help glossary.mcguffin
1846 abort: help section not found: glossary.mcguffin
1846 abort: help section not found: glossary.mcguffin
1847 [255]
1847 [255]
1848
1848
1849 $ hg help glossary.mc.guffin
1849 $ hg help glossary.mc.guffin
1850 abort: help section not found: glossary.mc.guffin
1850 abort: help section not found: glossary.mc.guffin
1851 [255]
1851 [255]
1852
1852
1853 $ hg help template.files
1853 $ hg help template.files
1854 files List of strings. All files modified, added, or removed by
1854 files List of strings. All files modified, added, or removed by
1855 this changeset.
1855 this changeset.
1856 files(pattern)
1856 files(pattern)
1857 All files of the current changeset matching the pattern. See
1857 All files of the current changeset matching the pattern. See
1858 'hg help patterns'.
1858 'hg help patterns'.
1859
1859
1860 Test section lookup by translated message
1860 Test section lookup by translated message
1861
1861
1862 str.lower() instead of encoding.lower(str) on translated message might
1862 str.lower() instead of encoding.lower(str) on translated message might
1863 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1863 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1864 as the second or later byte of multi-byte character.
1864 as the second or later byte of multi-byte character.
1865
1865
1866 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1866 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1867 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1867 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1868 replacement makes message meaningless.
1868 replacement makes message meaningless.
1869
1869
1870 This tests that section lookup by translated string isn't broken by
1870 This tests that section lookup by translated string isn't broken by
1871 such str.lower().
1871 such str.lower().
1872
1872
1873 $ "$PYTHON" <<EOF
1873 $ "$PYTHON" <<EOF
1874 > def escape(s):
1874 > def escape(s):
1875 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1875 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1876 > # translation of "record" in ja_JP.cp932
1876 > # translation of "record" in ja_JP.cp932
1877 > upper = b"\x8bL\x98^"
1877 > upper = b"\x8bL\x98^"
1878 > # str.lower()-ed section name should be treated as different one
1878 > # str.lower()-ed section name should be treated as different one
1879 > lower = b"\x8bl\x98^"
1879 > lower = b"\x8bl\x98^"
1880 > with open('ambiguous.py', 'wb') as fp:
1880 > with open('ambiguous.py', 'wb') as fp:
1881 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1881 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1882 > u'''summary of extension
1882 > u'''summary of extension
1883 >
1883 >
1884 > %s
1884 > %s
1885 > ----
1885 > ----
1886 >
1886 >
1887 > Upper name should show only this message
1887 > Upper name should show only this message
1888 >
1888 >
1889 > %s
1889 > %s
1890 > ----
1890 > ----
1891 >
1891 >
1892 > Lower name should show only this message
1892 > Lower name should show only this message
1893 >
1893 >
1894 > subsequent section
1894 > subsequent section
1895 > ------------------
1895 > ------------------
1896 >
1896 >
1897 > This should be hidden at 'hg help ambiguous' with section name.
1897 > This should be hidden at 'hg help ambiguous' with section name.
1898 > '''
1898 > '''
1899 > """ % (escape(upper), escape(lower)))
1899 > """ % (escape(upper), escape(lower)))
1900 > EOF
1900 > EOF
1901
1901
1902 $ cat >> $HGRCPATH <<EOF
1902 $ cat >> $HGRCPATH <<EOF
1903 > [extensions]
1903 > [extensions]
1904 > ambiguous = ./ambiguous.py
1904 > ambiguous = ./ambiguous.py
1905 > EOF
1905 > EOF
1906
1906
1907 $ "$PYTHON" <<EOF | sh
1907 $ "$PYTHON" <<EOF | sh
1908 > from mercurial import pycompat
1908 > from mercurial import pycompat
1909 > upper = b"\x8bL\x98^"
1909 > upper = b"\x8bL\x98^"
1910 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1910 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1911 > EOF
1911 > EOF
1912 \x8bL\x98^ (esc)
1912 \x8bL\x98^ (esc)
1913 ----
1913 ----
1914
1914
1915 Upper name should show only this message
1915 Upper name should show only this message
1916
1916
1917
1917
1918 $ "$PYTHON" <<EOF | sh
1918 $ "$PYTHON" <<EOF | sh
1919 > from mercurial import pycompat
1919 > from mercurial import pycompat
1920 > lower = b"\x8bl\x98^"
1920 > lower = b"\x8bl\x98^"
1921 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1921 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1922 > EOF
1922 > EOF
1923 \x8bl\x98^ (esc)
1923 \x8bl\x98^ (esc)
1924 ----
1924 ----
1925
1925
1926 Lower name should show only this message
1926 Lower name should show only this message
1927
1927
1928
1928
1929 $ cat >> $HGRCPATH <<EOF
1929 $ cat >> $HGRCPATH <<EOF
1930 > [extensions]
1930 > [extensions]
1931 > ambiguous = !
1931 > ambiguous = !
1932 > EOF
1932 > EOF
1933
1933
1934 Show help content of disabled extensions
1934 Show help content of disabled extensions
1935
1935
1936 $ cat >> $HGRCPATH <<EOF
1936 $ cat >> $HGRCPATH <<EOF
1937 > [extensions]
1937 > [extensions]
1938 > ambiguous = !./ambiguous.py
1938 > ambiguous = !./ambiguous.py
1939 > EOF
1939 > EOF
1940 $ hg help -e ambiguous
1940 $ hg help -e ambiguous
1941 ambiguous extension - (no help text available)
1941 ambiguous extension - (no help text available)
1942
1942
1943 (use 'hg help extensions' for information on enabling extensions)
1943 (use 'hg help extensions' for information on enabling extensions)
1944
1944
1945 Test dynamic list of merge tools only shows up once
1945 Test dynamic list of merge tools only shows up once
1946 $ hg help merge-tools
1946 $ hg help merge-tools
1947 Merge Tools
1947 Merge Tools
1948 """""""""""
1948 """""""""""
1949
1949
1950 To merge files Mercurial uses merge tools.
1950 To merge files Mercurial uses merge tools.
1951
1951
1952 A merge tool combines two different versions of a file into a merged file.
1952 A merge tool combines two different versions of a file into a merged file.
1953 Merge tools are given the two files and the greatest common ancestor of
1953 Merge tools are given the two files and the greatest common ancestor of
1954 the two file versions, so they can determine the changes made on both
1954 the two file versions, so they can determine the changes made on both
1955 branches.
1955 branches.
1956
1956
1957 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1957 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1958 backout' and in several extensions.
1958 backout' and in several extensions.
1959
1959
1960 Usually, the merge tool tries to automatically reconcile the files by
1960 Usually, the merge tool tries to automatically reconcile the files by
1961 combining all non-overlapping changes that occurred separately in the two
1961 combining all non-overlapping changes that occurred separately in the two
1962 different evolutions of the same initial base file. Furthermore, some
1962 different evolutions of the same initial base file. Furthermore, some
1963 interactive merge programs make it easier to manually resolve conflicting
1963 interactive merge programs make it easier to manually resolve conflicting
1964 merges, either in a graphical way, or by inserting some conflict markers.
1964 merges, either in a graphical way, or by inserting some conflict markers.
1965 Mercurial does not include any interactive merge programs but relies on
1965 Mercurial does not include any interactive merge programs but relies on
1966 external tools for that.
1966 external tools for that.
1967
1967
1968 Available merge tools
1968 Available merge tools
1969 =====================
1969 =====================
1970
1970
1971 External merge tools and their properties are configured in the merge-
1971 External merge tools and their properties are configured in the merge-
1972 tools configuration section - see hgrc(5) - but they can often just be
1972 tools configuration section - see hgrc(5) - but they can often just be
1973 named by their executable.
1973 named by their executable.
1974
1974
1975 A merge tool is generally usable if its executable can be found on the
1975 A merge tool is generally usable if its executable can be found on the
1976 system and if it can handle the merge. The executable is found if it is an
1976 system and if it can handle the merge. The executable is found if it is an
1977 absolute or relative executable path or the name of an application in the
1977 absolute or relative executable path or the name of an application in the
1978 executable search path. The tool is assumed to be able to handle the merge
1978 executable search path. The tool is assumed to be able to handle the merge
1979 if it can handle symlinks if the file is a symlink, if it can handle
1979 if it can handle symlinks if the file is a symlink, if it can handle
1980 binary files if the file is binary, and if a GUI is available if the tool
1980 binary files if the file is binary, and if a GUI is available if the tool
1981 requires a GUI.
1981 requires a GUI.
1982
1982
1983 There are some internal merge tools which can be used. The internal merge
1983 There are some internal merge tools which can be used. The internal merge
1984 tools are:
1984 tools are:
1985
1985
1986 ":dump"
1986 ":dump"
1987 Creates three versions of the files to merge, containing the contents of
1987 Creates three versions of the files to merge, containing the contents of
1988 local, other and base. These files can then be used to perform a merge
1988 local, other and base. These files can then be used to perform a merge
1989 manually. If the file to be merged is named "a.txt", these files will
1989 manually. If the file to be merged is named "a.txt", these files will
1990 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1990 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1991 they will be placed in the same directory as "a.txt".
1991 they will be placed in the same directory as "a.txt".
1992
1992
1993 This implies premerge. Therefore, files aren't dumped, if premerge runs
1993 This implies premerge. Therefore, files aren't dumped, if premerge runs
1994 successfully. Use :forcedump to forcibly write files out.
1994 successfully. Use :forcedump to forcibly write files out.
1995
1995
1996 (actual capabilities: binary, symlink)
1996 (actual capabilities: binary, symlink)
1997
1997
1998 ":fail"
1998 ":fail"
1999 Rather than attempting to merge files that were modified on both
1999 Rather than attempting to merge files that were modified on both
2000 branches, it marks them as unresolved. The resolve command must be used
2000 branches, it marks them as unresolved. The resolve command must be used
2001 to resolve these conflicts.
2001 to resolve these conflicts.
2002
2002
2003 (actual capabilities: binary, symlink)
2003 (actual capabilities: binary, symlink)
2004
2004
2005 ":forcedump"
2005 ":forcedump"
2006 Creates three versions of the files as same as :dump, but omits
2006 Creates three versions of the files as same as :dump, but omits
2007 premerge.
2007 premerge.
2008
2008
2009 (actual capabilities: binary, symlink)
2009 (actual capabilities: binary, symlink)
2010
2010
2011 ":local"
2011 ":local"
2012 Uses the local 'p1()' version of files as the merged version.
2012 Uses the local 'p1()' version of files as the merged version.
2013
2013
2014 (actual capabilities: binary, symlink)
2014 (actual capabilities: binary, symlink)
2015
2015
2016 ":merge"
2016 ":merge"
2017 Uses the internal non-interactive simple merge algorithm for merging
2017 Uses the internal non-interactive simple merge algorithm for merging
2018 files. It will fail if there are any conflicts and leave markers in the
2018 files. It will fail if there are any conflicts and leave markers in the
2019 partially merged file. Markers will have two sections, one for each side
2019 partially merged file. Markers will have two sections, one for each side
2020 of merge.
2020 of merge.
2021
2021
2022 ":merge-local"
2022 ":merge-local"
2023 Like :merge, but resolve all conflicts non-interactively in favor of the
2023 Like :merge, but resolve all conflicts non-interactively in favor of the
2024 local 'p1()' changes.
2024 local 'p1()' changes.
2025
2025
2026 ":merge-other"
2026 ":merge-other"
2027 Like :merge, but resolve all conflicts non-interactively in favor of the
2027 Like :merge, but resolve all conflicts non-interactively in favor of the
2028 other 'p2()' changes.
2028 other 'p2()' changes.
2029
2029
2030 ":merge3"
2030 ":merge3"
2031 Uses the internal non-interactive simple merge algorithm for merging
2031 Uses the internal non-interactive simple merge algorithm for merging
2032 files. It will fail if there are any conflicts and leave markers in the
2032 files. It will fail if there are any conflicts and leave markers in the
2033 partially merged file. Marker will have three sections, one from each
2033 partially merged file. Marker will have three sections, one from each
2034 side of the merge and one for the base content.
2034 side of the merge and one for the base content.
2035
2035
2036 ":other"
2036 ":other"
2037 Uses the other 'p2()' version of files as the merged version.
2037 Uses the other 'p2()' version of files as the merged version.
2038
2038
2039 (actual capabilities: binary, symlink)
2039 (actual capabilities: binary, symlink)
2040
2040
2041 ":prompt"
2041 ":prompt"
2042 Asks the user which of the local 'p1()' or the other 'p2()' version to
2042 Asks the user which of the local 'p1()' or the other 'p2()' version to
2043 keep as the merged version.
2043 keep as the merged version.
2044
2044
2045 (actual capabilities: binary, symlink)
2045 (actual capabilities: binary, symlink)
2046
2046
2047 ":tagmerge"
2047 ":tagmerge"
2048 Uses the internal tag merge algorithm (experimental).
2048 Uses the internal tag merge algorithm (experimental).
2049
2049
2050 ":union"
2050 ":union"
2051 Uses the internal non-interactive simple merge algorithm for merging
2051 Uses the internal non-interactive simple merge algorithm for merging
2052 files. It will use both left and right sides for conflict regions. No
2052 files. It will use both left and right sides for conflict regions. No
2053 markers are inserted.
2053 markers are inserted.
2054
2054
2055 Internal tools are always available and do not require a GUI but will by
2055 Internal tools are always available and do not require a GUI but will by
2056 default not handle symlinks or binary files. See next section for detail
2056 default not handle symlinks or binary files. See next section for detail
2057 about "actual capabilities" described above.
2057 about "actual capabilities" described above.
2058
2058
2059 Choosing a merge tool
2059 Choosing a merge tool
2060 =====================
2060 =====================
2061
2061
2062 Mercurial uses these rules when deciding which merge tool to use:
2062 Mercurial uses these rules when deciding which merge tool to use:
2063
2063
2064 1. If a tool has been specified with the --tool option to merge or
2064 1. If a tool has been specified with the --tool option to merge or
2065 resolve, it is used. If it is the name of a tool in the merge-tools
2065 resolve, it is used. If it is the name of a tool in the merge-tools
2066 configuration, its configuration is used. Otherwise the specified tool
2066 configuration, its configuration is used. Otherwise the specified tool
2067 must be executable by the shell.
2067 must be executable by the shell.
2068 2. If the "HGMERGE" environment variable is present, its value is used and
2068 2. If the "HGMERGE" environment variable is present, its value is used and
2069 must be executable by the shell.
2069 must be executable by the shell.
2070 3. If the filename of the file to be merged matches any of the patterns in
2070 3. If the filename of the file to be merged matches any of the patterns in
2071 the merge-patterns configuration section, the first usable merge tool
2071 the merge-patterns configuration section, the first usable merge tool
2072 corresponding to a matching pattern is used.
2072 corresponding to a matching pattern is used.
2073 4. If ui.merge is set it will be considered next. If the value is not the
2073 4. If ui.merge is set it will be considered next. If the value is not the
2074 name of a configured tool, the specified value is used and must be
2074 name of a configured tool, the specified value is used and must be
2075 executable by the shell. Otherwise the named tool is used if it is
2075 executable by the shell. Otherwise the named tool is used if it is
2076 usable.
2076 usable.
2077 5. If any usable merge tools are present in the merge-tools configuration
2077 5. If any usable merge tools are present in the merge-tools configuration
2078 section, the one with the highest priority is used.
2078 section, the one with the highest priority is used.
2079 6. If a program named "hgmerge" can be found on the system, it is used -
2079 6. If a program named "hgmerge" can be found on the system, it is used -
2080 but it will by default not be used for symlinks and binary files.
2080 but it will by default not be used for symlinks and binary files.
2081 7. If the file to be merged is not binary and is not a symlink, then
2081 7. If the file to be merged is not binary and is not a symlink, then
2082 internal ":merge" is used.
2082 internal ":merge" is used.
2083 8. Otherwise, ":prompt" is used.
2083 8. Otherwise, ":prompt" is used.
2084
2084
2085 For historical reason, Mercurial treats merge tools as below while
2085 For historical reason, Mercurial treats merge tools as below while
2086 examining rules above.
2086 examining rules above.
2087
2087
2088 step specified via binary symlink
2088 step specified via binary symlink
2089 ----------------------------------
2089 ----------------------------------
2090 1. --tool o/o o/o
2090 1. --tool o/o o/o
2091 2. HGMERGE o/o o/o
2091 2. HGMERGE o/o o/o
2092 3. merge-patterns o/o(*) x/?(*)
2092 3. merge-patterns o/o(*) x/?(*)
2093 4. ui.merge x/?(*) x/?(*)
2093 4. ui.merge x/?(*) x/?(*)
2094
2094
2095 Each capability column indicates Mercurial behavior for internal/external
2095 Each capability column indicates Mercurial behavior for internal/external
2096 merge tools at examining each rule.
2096 merge tools at examining each rule.
2097
2097
2098 - "o": "assume that a tool has capability"
2098 - "o": "assume that a tool has capability"
2099 - "x": "assume that a tool does not have capability"
2099 - "x": "assume that a tool does not have capability"
2100 - "?": "check actual capability of a tool"
2100 - "?": "check actual capability of a tool"
2101
2101
2102 If "merge.strict-capability-check" configuration is true, Mercurial checks
2102 If "merge.strict-capability-check" configuration is true, Mercurial checks
2103 capabilities of merge tools strictly in (*) cases above (= each capability
2103 capabilities of merge tools strictly in (*) cases above (= each capability
2104 column becomes "?/?"). It is false by default for backward compatibility.
2104 column becomes "?/?"). It is false by default for backward compatibility.
2105
2105
2106 Note:
2106 Note:
2107 After selecting a merge program, Mercurial will by default attempt to
2107 After selecting a merge program, Mercurial will by default attempt to
2108 merge the files using a simple merge algorithm first. Only if it
2108 merge the files using a simple merge algorithm first. Only if it
2109 doesn't succeed because of conflicting changes will Mercurial actually
2109 doesn't succeed because of conflicting changes will Mercurial actually
2110 execute the merge program. Whether to use the simple merge algorithm
2110 execute the merge program. Whether to use the simple merge algorithm
2111 first can be controlled by the premerge setting of the merge tool.
2111 first can be controlled by the premerge setting of the merge tool.
2112 Premerge is enabled by default unless the file is binary or a symlink.
2112 Premerge is enabled by default unless the file is binary or a symlink.
2113
2113
2114 See the merge-tools and ui sections of hgrc(5) for details on the
2114 See the merge-tools and ui sections of hgrc(5) for details on the
2115 configuration of merge tools.
2115 configuration of merge tools.
2116
2116
2117 Compression engines listed in `hg help bundlespec`
2117 Compression engines listed in `hg help bundlespec`
2118
2118
2119 $ hg help bundlespec | grep gzip
2119 $ hg help bundlespec | grep gzip
2120 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2120 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2121 An algorithm that produces smaller bundles than "gzip".
2121 An algorithm that produces smaller bundles than "gzip".
2122 This engine will likely produce smaller bundles than "gzip" but will be
2122 This engine will likely produce smaller bundles than "gzip" but will be
2123 "gzip"
2123 "gzip"
2124 better compression than "gzip". It also frequently yields better (?)
2124 better compression than "gzip". It also frequently yields better (?)
2125
2125
2126 Test usage of section marks in help documents
2126 Test usage of section marks in help documents
2127
2127
2128 $ cd "$TESTDIR"/../doc
2128 $ cd "$TESTDIR"/../doc
2129 $ "$PYTHON" check-seclevel.py
2129 $ "$PYTHON" check-seclevel.py
2130 $ cd $TESTTMP
2130 $ cd $TESTTMP
2131
2131
2132 #if serve
2132 #if serve
2133
2133
2134 Test the help pages in hgweb.
2134 Test the help pages in hgweb.
2135
2135
2136 Dish up an empty repo; serve it cold.
2136 Dish up an empty repo; serve it cold.
2137
2137
2138 $ hg init "$TESTTMP/test"
2138 $ hg init "$TESTTMP/test"
2139 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2139 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2140 $ cat hg.pid >> $DAEMON_PIDS
2140 $ cat hg.pid >> $DAEMON_PIDS
2141
2141
2142 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2142 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2143 200 Script output follows
2143 200 Script output follows
2144
2144
2145 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2145 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2146 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2146 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2147 <head>
2147 <head>
2148 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2148 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2149 <meta name="robots" content="index, nofollow" />
2149 <meta name="robots" content="index, nofollow" />
2150 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2150 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2151 <script type="text/javascript" src="/static/mercurial.js"></script>
2151 <script type="text/javascript" src="/static/mercurial.js"></script>
2152
2152
2153 <title>Help: Index</title>
2153 <title>Help: Index</title>
2154 </head>
2154 </head>
2155 <body>
2155 <body>
2156
2156
2157 <div class="container">
2157 <div class="container">
2158 <div class="menu">
2158 <div class="menu">
2159 <div class="logo">
2159 <div class="logo">
2160 <a href="https://mercurial-scm.org/">
2160 <a href="https://mercurial-scm.org/">
2161 <img src="/static/hglogo.png" alt="mercurial" /></a>
2161 <img src="/static/hglogo.png" alt="mercurial" /></a>
2162 </div>
2162 </div>
2163 <ul>
2163 <ul>
2164 <li><a href="/shortlog">log</a></li>
2164 <li><a href="/shortlog">log</a></li>
2165 <li><a href="/graph">graph</a></li>
2165 <li><a href="/graph">graph</a></li>
2166 <li><a href="/tags">tags</a></li>
2166 <li><a href="/tags">tags</a></li>
2167 <li><a href="/bookmarks">bookmarks</a></li>
2167 <li><a href="/bookmarks">bookmarks</a></li>
2168 <li><a href="/branches">branches</a></li>
2168 <li><a href="/branches">branches</a></li>
2169 </ul>
2169 </ul>
2170 <ul>
2170 <ul>
2171 <li class="active">help</li>
2171 <li class="active">help</li>
2172 </ul>
2172 </ul>
2173 </div>
2173 </div>
2174
2174
2175 <div class="main">
2175 <div class="main">
2176 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2176 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2177
2177
2178 <form class="search" action="/log">
2178 <form class="search" action="/log">
2179
2179
2180 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2180 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2181 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2181 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2182 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2182 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2183 </form>
2183 </form>
2184 <table class="bigtable">
2184 <table class="bigtable">
2185 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2185 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2186
2186
2187 <tr><td>
2187 <tr><td>
2188 <a href="/help/bundlespec">
2188 <a href="/help/bundlespec">
2189 bundlespec
2189 bundlespec
2190 </a>
2190 </a>
2191 </td><td>
2191 </td><td>
2192 Bundle File Formats
2192 Bundle File Formats
2193 </td></tr>
2193 </td></tr>
2194 <tr><td>
2194 <tr><td>
2195 <a href="/help/color">
2195 <a href="/help/color">
2196 color
2196 color
2197 </a>
2197 </a>
2198 </td><td>
2198 </td><td>
2199 Colorizing Outputs
2199 Colorizing Outputs
2200 </td></tr>
2200 </td></tr>
2201 <tr><td>
2201 <tr><td>
2202 <a href="/help/config">
2202 <a href="/help/config">
2203 config
2203 config
2204 </a>
2204 </a>
2205 </td><td>
2205 </td><td>
2206 Configuration Files
2206 Configuration Files
2207 </td></tr>
2207 </td></tr>
2208 <tr><td>
2208 <tr><td>
2209 <a href="/help/dates">
2209 <a href="/help/dates">
2210 dates
2210 dates
2211 </a>
2211 </a>
2212 </td><td>
2212 </td><td>
2213 Date Formats
2213 Date Formats
2214 </td></tr>
2214 </td></tr>
2215 <tr><td>
2215 <tr><td>
2216 <a href="/help/deprecated">
2216 <a href="/help/deprecated">
2217 deprecated
2217 deprecated
2218 </a>
2218 </a>
2219 </td><td>
2219 </td><td>
2220 Deprecated Features
2220 Deprecated Features
2221 </td></tr>
2221 </td></tr>
2222 <tr><td>
2222 <tr><td>
2223 <a href="/help/diffs">
2223 <a href="/help/diffs">
2224 diffs
2224 diffs
2225 </a>
2225 </a>
2226 </td><td>
2226 </td><td>
2227 Diff Formats
2227 Diff Formats
2228 </td></tr>
2228 </td></tr>
2229 <tr><td>
2229 <tr><td>
2230 <a href="/help/environment">
2230 <a href="/help/environment">
2231 environment
2231 environment
2232 </a>
2232 </a>
2233 </td><td>
2233 </td><td>
2234 Environment Variables
2234 Environment Variables
2235 </td></tr>
2235 </td></tr>
2236 <tr><td>
2236 <tr><td>
2237 <a href="/help/extensions">
2237 <a href="/help/extensions">
2238 extensions
2238 extensions
2239 </a>
2239 </a>
2240 </td><td>
2240 </td><td>
2241 Using Additional Features
2241 Using Additional Features
2242 </td></tr>
2242 </td></tr>
2243 <tr><td>
2243 <tr><td>
2244 <a href="/help/filesets">
2244 <a href="/help/filesets">
2245 filesets
2245 filesets
2246 </a>
2246 </a>
2247 </td><td>
2247 </td><td>
2248 Specifying File Sets
2248 Specifying File Sets
2249 </td></tr>
2249 </td></tr>
2250 <tr><td>
2250 <tr><td>
2251 <a href="/help/flags">
2251 <a href="/help/flags">
2252 flags
2252 flags
2253 </a>
2253 </a>
2254 </td><td>
2254 </td><td>
2255 Command-line flags
2255 Command-line flags
2256 </td></tr>
2256 </td></tr>
2257 <tr><td>
2257 <tr><td>
2258 <a href="/help/glossary">
2258 <a href="/help/glossary">
2259 glossary
2259 glossary
2260 </a>
2260 </a>
2261 </td><td>
2261 </td><td>
2262 Glossary
2262 Glossary
2263 </td></tr>
2263 </td></tr>
2264 <tr><td>
2264 <tr><td>
2265 <a href="/help/hgignore">
2265 <a href="/help/hgignore">
2266 hgignore
2266 hgignore
2267 </a>
2267 </a>
2268 </td><td>
2268 </td><td>
2269 Syntax for Mercurial Ignore Files
2269 Syntax for Mercurial Ignore Files
2270 </td></tr>
2270 </td></tr>
2271 <tr><td>
2271 <tr><td>
2272 <a href="/help/hgweb">
2272 <a href="/help/hgweb">
2273 hgweb
2273 hgweb
2274 </a>
2274 </a>
2275 </td><td>
2275 </td><td>
2276 Configuring hgweb
2276 Configuring hgweb
2277 </td></tr>
2277 </td></tr>
2278 <tr><td>
2278 <tr><td>
2279 <a href="/help/internals">
2279 <a href="/help/internals">
2280 internals
2280 internals
2281 </a>
2281 </a>
2282 </td><td>
2282 </td><td>
2283 Technical implementation topics
2283 Technical implementation topics
2284 </td></tr>
2284 </td></tr>
2285 <tr><td>
2285 <tr><td>
2286 <a href="/help/merge-tools">
2286 <a href="/help/merge-tools">
2287 merge-tools
2287 merge-tools
2288 </a>
2288 </a>
2289 </td><td>
2289 </td><td>
2290 Merge Tools
2290 Merge Tools
2291 </td></tr>
2291 </td></tr>
2292 <tr><td>
2292 <tr><td>
2293 <a href="/help/pager">
2293 <a href="/help/pager">
2294 pager
2294 pager
2295 </a>
2295 </a>
2296 </td><td>
2296 </td><td>
2297 Pager Support
2297 Pager Support
2298 </td></tr>
2298 </td></tr>
2299 <tr><td>
2299 <tr><td>
2300 <a href="/help/patterns">
2300 <a href="/help/patterns">
2301 patterns
2301 patterns
2302 </a>
2302 </a>
2303 </td><td>
2303 </td><td>
2304 File Name Patterns
2304 File Name Patterns
2305 </td></tr>
2305 </td></tr>
2306 <tr><td>
2306 <tr><td>
2307 <a href="/help/phases">
2307 <a href="/help/phases">
2308 phases
2308 phases
2309 </a>
2309 </a>
2310 </td><td>
2310 </td><td>
2311 Working with Phases
2311 Working with Phases
2312 </td></tr>
2312 </td></tr>
2313 <tr><td>
2313 <tr><td>
2314 <a href="/help/revisions">
2314 <a href="/help/revisions">
2315 revisions
2315 revisions
2316 </a>
2316 </a>
2317 </td><td>
2317 </td><td>
2318 Specifying Revisions
2318 Specifying Revisions
2319 </td></tr>
2319 </td></tr>
2320 <tr><td>
2320 <tr><td>
2321 <a href="/help/scripting">
2321 <a href="/help/scripting">
2322 scripting
2322 scripting
2323 </a>
2323 </a>
2324 </td><td>
2324 </td><td>
2325 Using Mercurial from scripts and automation
2325 Using Mercurial from scripts and automation
2326 </td></tr>
2326 </td></tr>
2327 <tr><td>
2327 <tr><td>
2328 <a href="/help/subrepos">
2328 <a href="/help/subrepos">
2329 subrepos
2329 subrepos
2330 </a>
2330 </a>
2331 </td><td>
2331 </td><td>
2332 Subrepositories
2332 Subrepositories
2333 </td></tr>
2333 </td></tr>
2334 <tr><td>
2334 <tr><td>
2335 <a href="/help/templating">
2335 <a href="/help/templating">
2336 templating
2336 templating
2337 </a>
2337 </a>
2338 </td><td>
2338 </td><td>
2339 Template Usage
2339 Template Usage
2340 </td></tr>
2340 </td></tr>
2341 <tr><td>
2341 <tr><td>
2342 <a href="/help/urls">
2342 <a href="/help/urls">
2343 urls
2343 urls
2344 </a>
2344 </a>
2345 </td><td>
2345 </td><td>
2346 URL Paths
2346 URL Paths
2347 </td></tr>
2347 </td></tr>
2348 <tr><td>
2348 <tr><td>
2349 <a href="/help/topic-containing-verbose">
2349 <a href="/help/topic-containing-verbose">
2350 topic-containing-verbose
2350 topic-containing-verbose
2351 </a>
2351 </a>
2352 </td><td>
2352 </td><td>
2353 This is the topic to test omit indicating.
2353 This is the topic to test omit indicating.
2354 </td></tr>
2354 </td></tr>
2355
2355
2356
2356
2357 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2357 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2358
2358
2359 <tr><td>
2359 <tr><td>
2360 <a href="/help/abort">
2360 <a href="/help/abort">
2361 abort
2361 abort
2362 </a>
2362 </a>
2363 </td><td>
2363 </td><td>
2364 abort an unfinished operation (EXPERIMENTAL)
2364 abort an unfinished operation (EXPERIMENTAL)
2365 </td></tr>
2365 </td></tr>
2366 <tr><td>
2366 <tr><td>
2367 <a href="/help/add">
2367 <a href="/help/add">
2368 add
2368 add
2369 </a>
2369 </a>
2370 </td><td>
2370 </td><td>
2371 add the specified files on the next commit
2371 add the specified files on the next commit
2372 </td></tr>
2372 </td></tr>
2373 <tr><td>
2373 <tr><td>
2374 <a href="/help/annotate">
2374 <a href="/help/annotate">
2375 annotate
2375 annotate
2376 </a>
2376 </a>
2377 </td><td>
2377 </td><td>
2378 show changeset information by line for each file
2378 show changeset information by line for each file
2379 </td></tr>
2379 </td></tr>
2380 <tr><td>
2380 <tr><td>
2381 <a href="/help/clone">
2381 <a href="/help/clone">
2382 clone
2382 clone
2383 </a>
2383 </a>
2384 </td><td>
2384 </td><td>
2385 make a copy of an existing repository
2385 make a copy of an existing repository
2386 </td></tr>
2386 </td></tr>
2387 <tr><td>
2387 <tr><td>
2388 <a href="/help/commit">
2388 <a href="/help/commit">
2389 commit
2389 commit
2390 </a>
2390 </a>
2391 </td><td>
2391 </td><td>
2392 commit the specified files or all outstanding changes
2392 commit the specified files or all outstanding changes
2393 </td></tr>
2393 </td></tr>
2394 <tr><td>
2394 <tr><td>
2395 <a href="/help/continue">
2395 <a href="/help/continue">
2396 continue
2396 continue
2397 </a>
2397 </a>
2398 </td><td>
2398 </td><td>
2399 resumes an interrupted operation (EXPERIMENTAL)
2399 resumes an interrupted operation (EXPERIMENTAL)
2400 </td></tr>
2400 </td></tr>
2401 <tr><td>
2401 <tr><td>
2402 <a href="/help/diff">
2402 <a href="/help/diff">
2403 diff
2403 diff
2404 </a>
2404 </a>
2405 </td><td>
2405 </td><td>
2406 diff repository (or selected files)
2406 diff repository (or selected files)
2407 </td></tr>
2407 </td></tr>
2408 <tr><td>
2408 <tr><td>
2409 <a href="/help/export">
2409 <a href="/help/export">
2410 export
2410 export
2411 </a>
2411 </a>
2412 </td><td>
2412 </td><td>
2413 dump the header and diffs for one or more changesets
2413 dump the header and diffs for one or more changesets
2414 </td></tr>
2414 </td></tr>
2415 <tr><td>
2415 <tr><td>
2416 <a href="/help/forget">
2416 <a href="/help/forget">
2417 forget
2417 forget
2418 </a>
2418 </a>
2419 </td><td>
2419 </td><td>
2420 forget the specified files on the next commit
2420 forget the specified files on the next commit
2421 </td></tr>
2421 </td></tr>
2422 <tr><td>
2422 <tr><td>
2423 <a href="/help/init">
2423 <a href="/help/init">
2424 init
2424 init
2425 </a>
2425 </a>
2426 </td><td>
2426 </td><td>
2427 create a new repository in the given directory
2427 create a new repository in the given directory
2428 </td></tr>
2428 </td></tr>
2429 <tr><td>
2429 <tr><td>
2430 <a href="/help/log">
2430 <a href="/help/log">
2431 log
2431 log
2432 </a>
2432 </a>
2433 </td><td>
2433 </td><td>
2434 show revision history of entire repository or files
2434 show revision history of entire repository or files
2435 </td></tr>
2435 </td></tr>
2436 <tr><td>
2436 <tr><td>
2437 <a href="/help/merge">
2437 <a href="/help/merge">
2438 merge
2438 merge
2439 </a>
2439 </a>
2440 </td><td>
2440 </td><td>
2441 merge another revision into working directory
2441 merge another revision into working directory
2442 </td></tr>
2442 </td></tr>
2443 <tr><td>
2443 <tr><td>
2444 <a href="/help/pull">
2444 <a href="/help/pull">
2445 pull
2445 pull
2446 </a>
2446 </a>
2447 </td><td>
2447 </td><td>
2448 pull changes from the specified source
2448 pull changes from the specified source
2449 </td></tr>
2449 </td></tr>
2450 <tr><td>
2450 <tr><td>
2451 <a href="/help/push">
2451 <a href="/help/push">
2452 push
2452 push
2453 </a>
2453 </a>
2454 </td><td>
2454 </td><td>
2455 push changes to the specified destination
2455 push changes to the specified destination
2456 </td></tr>
2456 </td></tr>
2457 <tr><td>
2457 <tr><td>
2458 <a href="/help/remove">
2458 <a href="/help/remove">
2459 remove
2459 remove
2460 </a>
2460 </a>
2461 </td><td>
2461 </td><td>
2462 remove the specified files on the next commit
2462 remove the specified files on the next commit
2463 </td></tr>
2463 </td></tr>
2464 <tr><td>
2464 <tr><td>
2465 <a href="/help/serve">
2465 <a href="/help/serve">
2466 serve
2466 serve
2467 </a>
2467 </a>
2468 </td><td>
2468 </td><td>
2469 start stand-alone webserver
2469 start stand-alone webserver
2470 </td></tr>
2470 </td></tr>
2471 <tr><td>
2471 <tr><td>
2472 <a href="/help/status">
2472 <a href="/help/status">
2473 status
2473 status
2474 </a>
2474 </a>
2475 </td><td>
2475 </td><td>
2476 show changed files in the working directory
2476 show changed files in the working directory
2477 </td></tr>
2477 </td></tr>
2478 <tr><td>
2478 <tr><td>
2479 <a href="/help/summary">
2479 <a href="/help/summary">
2480 summary
2480 summary
2481 </a>
2481 </a>
2482 </td><td>
2482 </td><td>
2483 summarize working directory state
2483 summarize working directory state
2484 </td></tr>
2484 </td></tr>
2485 <tr><td>
2485 <tr><td>
2486 <a href="/help/update">
2486 <a href="/help/update">
2487 update
2487 update
2488 </a>
2488 </a>
2489 </td><td>
2489 </td><td>
2490 update working directory (or switch revisions)
2490 update working directory (or switch revisions)
2491 </td></tr>
2491 </td></tr>
2492
2492
2493
2493
2494
2494
2495 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2495 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2496
2496
2497 <tr><td>
2497 <tr><td>
2498 <a href="/help/addremove">
2498 <a href="/help/addremove">
2499 addremove
2499 addremove
2500 </a>
2500 </a>
2501 </td><td>
2501 </td><td>
2502 add all new files, delete all missing files
2502 add all new files, delete all missing files
2503 </td></tr>
2503 </td></tr>
2504 <tr><td>
2504 <tr><td>
2505 <a href="/help/archive">
2505 <a href="/help/archive">
2506 archive
2506 archive
2507 </a>
2507 </a>
2508 </td><td>
2508 </td><td>
2509 create an unversioned archive of a repository revision
2509 create an unversioned archive of a repository revision
2510 </td></tr>
2510 </td></tr>
2511 <tr><td>
2511 <tr><td>
2512 <a href="/help/backout">
2512 <a href="/help/backout">
2513 backout
2513 backout
2514 </a>
2514 </a>
2515 </td><td>
2515 </td><td>
2516 reverse effect of earlier changeset
2516 reverse effect of earlier changeset
2517 </td></tr>
2517 </td></tr>
2518 <tr><td>
2518 <tr><td>
2519 <a href="/help/bisect">
2519 <a href="/help/bisect">
2520 bisect
2520 bisect
2521 </a>
2521 </a>
2522 </td><td>
2522 </td><td>
2523 subdivision search of changesets
2523 subdivision search of changesets
2524 </td></tr>
2524 </td></tr>
2525 <tr><td>
2525 <tr><td>
2526 <a href="/help/bookmarks">
2526 <a href="/help/bookmarks">
2527 bookmarks
2527 bookmarks
2528 </a>
2528 </a>
2529 </td><td>
2529 </td><td>
2530 create a new bookmark or list existing bookmarks
2530 create a new bookmark or list existing bookmarks
2531 </td></tr>
2531 </td></tr>
2532 <tr><td>
2532 <tr><td>
2533 <a href="/help/branch">
2533 <a href="/help/branch">
2534 branch
2534 branch
2535 </a>
2535 </a>
2536 </td><td>
2536 </td><td>
2537 set or show the current branch name
2537 set or show the current branch name
2538 </td></tr>
2538 </td></tr>
2539 <tr><td>
2539 <tr><td>
2540 <a href="/help/branches">
2540 <a href="/help/branches">
2541 branches
2541 branches
2542 </a>
2542 </a>
2543 </td><td>
2543 </td><td>
2544 list repository named branches
2544 list repository named branches
2545 </td></tr>
2545 </td></tr>
2546 <tr><td>
2546 <tr><td>
2547 <a href="/help/bundle">
2547 <a href="/help/bundle">
2548 bundle
2548 bundle
2549 </a>
2549 </a>
2550 </td><td>
2550 </td><td>
2551 create a bundle file
2551 create a bundle file
2552 </td></tr>
2552 </td></tr>
2553 <tr><td>
2553 <tr><td>
2554 <a href="/help/cat">
2554 <a href="/help/cat">
2555 cat
2555 cat
2556 </a>
2556 </a>
2557 </td><td>
2557 </td><td>
2558 output the current or given revision of files
2558 output the current or given revision of files
2559 </td></tr>
2559 </td></tr>
2560 <tr><td>
2560 <tr><td>
2561 <a href="/help/config">
2561 <a href="/help/config">
2562 config
2562 config
2563 </a>
2563 </a>
2564 </td><td>
2564 </td><td>
2565 show combined config settings from all hgrc files
2565 show combined config settings from all hgrc files
2566 </td></tr>
2566 </td></tr>
2567 <tr><td>
2567 <tr><td>
2568 <a href="/help/copy">
2568 <a href="/help/copy">
2569 copy
2569 copy
2570 </a>
2570 </a>
2571 </td><td>
2571 </td><td>
2572 mark files as copied for the next commit
2572 mark files as copied for the next commit
2573 </td></tr>
2573 </td></tr>
2574 <tr><td>
2574 <tr><td>
2575 <a href="/help/files">
2575 <a href="/help/files">
2576 files
2576 files
2577 </a>
2577 </a>
2578 </td><td>
2578 </td><td>
2579 list tracked files
2579 list tracked files
2580 </td></tr>
2580 </td></tr>
2581 <tr><td>
2581 <tr><td>
2582 <a href="/help/graft">
2582 <a href="/help/graft">
2583 graft
2583 graft
2584 </a>
2584 </a>
2585 </td><td>
2585 </td><td>
2586 copy changes from other branches onto the current branch
2586 copy changes from other branches onto the current branch
2587 </td></tr>
2587 </td></tr>
2588 <tr><td>
2588 <tr><td>
2589 <a href="/help/grep">
2589 <a href="/help/grep">
2590 grep
2590 grep
2591 </a>
2591 </a>
2592 </td><td>
2592 </td><td>
2593 search revision history for a pattern in specified files
2593 search for a pattern in specified files
2594 </td></tr>
2594 </td></tr>
2595 <tr><td>
2595 <tr><td>
2596 <a href="/help/hashelp">
2596 <a href="/help/hashelp">
2597 hashelp
2597 hashelp
2598 </a>
2598 </a>
2599 </td><td>
2599 </td><td>
2600 Extension command's help
2600 Extension command's help
2601 </td></tr>
2601 </td></tr>
2602 <tr><td>
2602 <tr><td>
2603 <a href="/help/heads">
2603 <a href="/help/heads">
2604 heads
2604 heads
2605 </a>
2605 </a>
2606 </td><td>
2606 </td><td>
2607 show branch heads
2607 show branch heads
2608 </td></tr>
2608 </td></tr>
2609 <tr><td>
2609 <tr><td>
2610 <a href="/help/help">
2610 <a href="/help/help">
2611 help
2611 help
2612 </a>
2612 </a>
2613 </td><td>
2613 </td><td>
2614 show help for a given topic or a help overview
2614 show help for a given topic or a help overview
2615 </td></tr>
2615 </td></tr>
2616 <tr><td>
2616 <tr><td>
2617 <a href="/help/hgalias">
2617 <a href="/help/hgalias">
2618 hgalias
2618 hgalias
2619 </a>
2619 </a>
2620 </td><td>
2620 </td><td>
2621 My doc
2621 My doc
2622 </td></tr>
2622 </td></tr>
2623 <tr><td>
2623 <tr><td>
2624 <a href="/help/hgaliasnodoc">
2624 <a href="/help/hgaliasnodoc">
2625 hgaliasnodoc
2625 hgaliasnodoc
2626 </a>
2626 </a>
2627 </td><td>
2627 </td><td>
2628 summarize working directory state
2628 summarize working directory state
2629 </td></tr>
2629 </td></tr>
2630 <tr><td>
2630 <tr><td>
2631 <a href="/help/identify">
2631 <a href="/help/identify">
2632 identify
2632 identify
2633 </a>
2633 </a>
2634 </td><td>
2634 </td><td>
2635 identify the working directory or specified revision
2635 identify the working directory or specified revision
2636 </td></tr>
2636 </td></tr>
2637 <tr><td>
2637 <tr><td>
2638 <a href="/help/import">
2638 <a href="/help/import">
2639 import
2639 import
2640 </a>
2640 </a>
2641 </td><td>
2641 </td><td>
2642 import an ordered set of patches
2642 import an ordered set of patches
2643 </td></tr>
2643 </td></tr>
2644 <tr><td>
2644 <tr><td>
2645 <a href="/help/incoming">
2645 <a href="/help/incoming">
2646 incoming
2646 incoming
2647 </a>
2647 </a>
2648 </td><td>
2648 </td><td>
2649 show new changesets found in source
2649 show new changesets found in source
2650 </td></tr>
2650 </td></tr>
2651 <tr><td>
2651 <tr><td>
2652 <a href="/help/manifest">
2652 <a href="/help/manifest">
2653 manifest
2653 manifest
2654 </a>
2654 </a>
2655 </td><td>
2655 </td><td>
2656 output the current or given revision of the project manifest
2656 output the current or given revision of the project manifest
2657 </td></tr>
2657 </td></tr>
2658 <tr><td>
2658 <tr><td>
2659 <a href="/help/nohelp">
2659 <a href="/help/nohelp">
2660 nohelp
2660 nohelp
2661 </a>
2661 </a>
2662 </td><td>
2662 </td><td>
2663 (no help text available)
2663 (no help text available)
2664 </td></tr>
2664 </td></tr>
2665 <tr><td>
2665 <tr><td>
2666 <a href="/help/outgoing">
2666 <a href="/help/outgoing">
2667 outgoing
2667 outgoing
2668 </a>
2668 </a>
2669 </td><td>
2669 </td><td>
2670 show changesets not found in the destination
2670 show changesets not found in the destination
2671 </td></tr>
2671 </td></tr>
2672 <tr><td>
2672 <tr><td>
2673 <a href="/help/paths">
2673 <a href="/help/paths">
2674 paths
2674 paths
2675 </a>
2675 </a>
2676 </td><td>
2676 </td><td>
2677 show aliases for remote repositories
2677 show aliases for remote repositories
2678 </td></tr>
2678 </td></tr>
2679 <tr><td>
2679 <tr><td>
2680 <a href="/help/phase">
2680 <a href="/help/phase">
2681 phase
2681 phase
2682 </a>
2682 </a>
2683 </td><td>
2683 </td><td>
2684 set or show the current phase name
2684 set or show the current phase name
2685 </td></tr>
2685 </td></tr>
2686 <tr><td>
2686 <tr><td>
2687 <a href="/help/recover">
2687 <a href="/help/recover">
2688 recover
2688 recover
2689 </a>
2689 </a>
2690 </td><td>
2690 </td><td>
2691 roll back an interrupted transaction
2691 roll back an interrupted transaction
2692 </td></tr>
2692 </td></tr>
2693 <tr><td>
2693 <tr><td>
2694 <a href="/help/rename">
2694 <a href="/help/rename">
2695 rename
2695 rename
2696 </a>
2696 </a>
2697 </td><td>
2697 </td><td>
2698 rename files; equivalent of copy + remove
2698 rename files; equivalent of copy + remove
2699 </td></tr>
2699 </td></tr>
2700 <tr><td>
2700 <tr><td>
2701 <a href="/help/resolve">
2701 <a href="/help/resolve">
2702 resolve
2702 resolve
2703 </a>
2703 </a>
2704 </td><td>
2704 </td><td>
2705 redo merges or set/view the merge status of files
2705 redo merges or set/view the merge status of files
2706 </td></tr>
2706 </td></tr>
2707 <tr><td>
2707 <tr><td>
2708 <a href="/help/revert">
2708 <a href="/help/revert">
2709 revert
2709 revert
2710 </a>
2710 </a>
2711 </td><td>
2711 </td><td>
2712 restore files to their checkout state
2712 restore files to their checkout state
2713 </td></tr>
2713 </td></tr>
2714 <tr><td>
2714 <tr><td>
2715 <a href="/help/root">
2715 <a href="/help/root">
2716 root
2716 root
2717 </a>
2717 </a>
2718 </td><td>
2718 </td><td>
2719 print the root (top) of the current working directory
2719 print the root (top) of the current working directory
2720 </td></tr>
2720 </td></tr>
2721 <tr><td>
2721 <tr><td>
2722 <a href="/help/shellalias">
2722 <a href="/help/shellalias">
2723 shellalias
2723 shellalias
2724 </a>
2724 </a>
2725 </td><td>
2725 </td><td>
2726 (no help text available)
2726 (no help text available)
2727 </td></tr>
2727 </td></tr>
2728 <tr><td>
2728 <tr><td>
2729 <a href="/help/shelve">
2729 <a href="/help/shelve">
2730 shelve
2730 shelve
2731 </a>
2731 </a>
2732 </td><td>
2732 </td><td>
2733 save and set aside changes from the working directory
2733 save and set aside changes from the working directory
2734 </td></tr>
2734 </td></tr>
2735 <tr><td>
2735 <tr><td>
2736 <a href="/help/tag">
2736 <a href="/help/tag">
2737 tag
2737 tag
2738 </a>
2738 </a>
2739 </td><td>
2739 </td><td>
2740 add one or more tags for the current or given revision
2740 add one or more tags for the current or given revision
2741 </td></tr>
2741 </td></tr>
2742 <tr><td>
2742 <tr><td>
2743 <a href="/help/tags">
2743 <a href="/help/tags">
2744 tags
2744 tags
2745 </a>
2745 </a>
2746 </td><td>
2746 </td><td>
2747 list repository tags
2747 list repository tags
2748 </td></tr>
2748 </td></tr>
2749 <tr><td>
2749 <tr><td>
2750 <a href="/help/unbundle">
2750 <a href="/help/unbundle">
2751 unbundle
2751 unbundle
2752 </a>
2752 </a>
2753 </td><td>
2753 </td><td>
2754 apply one or more bundle files
2754 apply one or more bundle files
2755 </td></tr>
2755 </td></tr>
2756 <tr><td>
2756 <tr><td>
2757 <a href="/help/unshelve">
2757 <a href="/help/unshelve">
2758 unshelve
2758 unshelve
2759 </a>
2759 </a>
2760 </td><td>
2760 </td><td>
2761 restore a shelved change to the working directory
2761 restore a shelved change to the working directory
2762 </td></tr>
2762 </td></tr>
2763 <tr><td>
2763 <tr><td>
2764 <a href="/help/verify">
2764 <a href="/help/verify">
2765 verify
2765 verify
2766 </a>
2766 </a>
2767 </td><td>
2767 </td><td>
2768 verify the integrity of the repository
2768 verify the integrity of the repository
2769 </td></tr>
2769 </td></tr>
2770 <tr><td>
2770 <tr><td>
2771 <a href="/help/version">
2771 <a href="/help/version">
2772 version
2772 version
2773 </a>
2773 </a>
2774 </td><td>
2774 </td><td>
2775 output version and copyright information
2775 output version and copyright information
2776 </td></tr>
2776 </td></tr>
2777
2777
2778
2778
2779 </table>
2779 </table>
2780 </div>
2780 </div>
2781 </div>
2781 </div>
2782
2782
2783
2783
2784
2784
2785 </body>
2785 </body>
2786 </html>
2786 </html>
2787
2787
2788
2788
2789 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2789 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2790 200 Script output follows
2790 200 Script output follows
2791
2791
2792 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2792 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2793 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2793 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2794 <head>
2794 <head>
2795 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2795 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2796 <meta name="robots" content="index, nofollow" />
2796 <meta name="robots" content="index, nofollow" />
2797 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2797 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2798 <script type="text/javascript" src="/static/mercurial.js"></script>
2798 <script type="text/javascript" src="/static/mercurial.js"></script>
2799
2799
2800 <title>Help: add</title>
2800 <title>Help: add</title>
2801 </head>
2801 </head>
2802 <body>
2802 <body>
2803
2803
2804 <div class="container">
2804 <div class="container">
2805 <div class="menu">
2805 <div class="menu">
2806 <div class="logo">
2806 <div class="logo">
2807 <a href="https://mercurial-scm.org/">
2807 <a href="https://mercurial-scm.org/">
2808 <img src="/static/hglogo.png" alt="mercurial" /></a>
2808 <img src="/static/hglogo.png" alt="mercurial" /></a>
2809 </div>
2809 </div>
2810 <ul>
2810 <ul>
2811 <li><a href="/shortlog">log</a></li>
2811 <li><a href="/shortlog">log</a></li>
2812 <li><a href="/graph">graph</a></li>
2812 <li><a href="/graph">graph</a></li>
2813 <li><a href="/tags">tags</a></li>
2813 <li><a href="/tags">tags</a></li>
2814 <li><a href="/bookmarks">bookmarks</a></li>
2814 <li><a href="/bookmarks">bookmarks</a></li>
2815 <li><a href="/branches">branches</a></li>
2815 <li><a href="/branches">branches</a></li>
2816 </ul>
2816 </ul>
2817 <ul>
2817 <ul>
2818 <li class="active"><a href="/help">help</a></li>
2818 <li class="active"><a href="/help">help</a></li>
2819 </ul>
2819 </ul>
2820 </div>
2820 </div>
2821
2821
2822 <div class="main">
2822 <div class="main">
2823 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2823 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2824 <h3>Help: add</h3>
2824 <h3>Help: add</h3>
2825
2825
2826 <form class="search" action="/log">
2826 <form class="search" action="/log">
2827
2827
2828 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2828 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2829 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2829 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2830 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2830 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2831 </form>
2831 </form>
2832 <div id="doc">
2832 <div id="doc">
2833 <p>
2833 <p>
2834 hg add [OPTION]... [FILE]...
2834 hg add [OPTION]... [FILE]...
2835 </p>
2835 </p>
2836 <p>
2836 <p>
2837 add the specified files on the next commit
2837 add the specified files on the next commit
2838 </p>
2838 </p>
2839 <p>
2839 <p>
2840 Schedule files to be version controlled and added to the
2840 Schedule files to be version controlled and added to the
2841 repository.
2841 repository.
2842 </p>
2842 </p>
2843 <p>
2843 <p>
2844 The files will be added to the repository at the next commit. To
2844 The files will be added to the repository at the next commit. To
2845 undo an add before that, see 'hg forget'.
2845 undo an add before that, see 'hg forget'.
2846 </p>
2846 </p>
2847 <p>
2847 <p>
2848 If no names are given, add all files to the repository (except
2848 If no names are given, add all files to the repository (except
2849 files matching &quot;.hgignore&quot;).
2849 files matching &quot;.hgignore&quot;).
2850 </p>
2850 </p>
2851 <p>
2851 <p>
2852 Examples:
2852 Examples:
2853 </p>
2853 </p>
2854 <ul>
2854 <ul>
2855 <li> New (unknown) files are added automatically by 'hg add':
2855 <li> New (unknown) files are added automatically by 'hg add':
2856 <pre>
2856 <pre>
2857 \$ ls (re)
2857 \$ ls (re)
2858 foo.c
2858 foo.c
2859 \$ hg status (re)
2859 \$ hg status (re)
2860 ? foo.c
2860 ? foo.c
2861 \$ hg add (re)
2861 \$ hg add (re)
2862 adding foo.c
2862 adding foo.c
2863 \$ hg status (re)
2863 \$ hg status (re)
2864 A foo.c
2864 A foo.c
2865 </pre>
2865 </pre>
2866 <li> Specific files to be added can be specified:
2866 <li> Specific files to be added can be specified:
2867 <pre>
2867 <pre>
2868 \$ ls (re)
2868 \$ ls (re)
2869 bar.c foo.c
2869 bar.c foo.c
2870 \$ hg status (re)
2870 \$ hg status (re)
2871 ? bar.c
2871 ? bar.c
2872 ? foo.c
2872 ? foo.c
2873 \$ hg add bar.c (re)
2873 \$ hg add bar.c (re)
2874 \$ hg status (re)
2874 \$ hg status (re)
2875 A bar.c
2875 A bar.c
2876 ? foo.c
2876 ? foo.c
2877 </pre>
2877 </pre>
2878 </ul>
2878 </ul>
2879 <p>
2879 <p>
2880 Returns 0 if all files are successfully added.
2880 Returns 0 if all files are successfully added.
2881 </p>
2881 </p>
2882 <p>
2882 <p>
2883 options ([+] can be repeated):
2883 options ([+] can be repeated):
2884 </p>
2884 </p>
2885 <table>
2885 <table>
2886 <tr><td>-I</td>
2886 <tr><td>-I</td>
2887 <td>--include PATTERN [+]</td>
2887 <td>--include PATTERN [+]</td>
2888 <td>include names matching the given patterns</td></tr>
2888 <td>include names matching the given patterns</td></tr>
2889 <tr><td>-X</td>
2889 <tr><td>-X</td>
2890 <td>--exclude PATTERN [+]</td>
2890 <td>--exclude PATTERN [+]</td>
2891 <td>exclude names matching the given patterns</td></tr>
2891 <td>exclude names matching the given patterns</td></tr>
2892 <tr><td>-S</td>
2892 <tr><td>-S</td>
2893 <td>--subrepos</td>
2893 <td>--subrepos</td>
2894 <td>recurse into subrepositories</td></tr>
2894 <td>recurse into subrepositories</td></tr>
2895 <tr><td>-n</td>
2895 <tr><td>-n</td>
2896 <td>--dry-run</td>
2896 <td>--dry-run</td>
2897 <td>do not perform actions, just print output</td></tr>
2897 <td>do not perform actions, just print output</td></tr>
2898 </table>
2898 </table>
2899 <p>
2899 <p>
2900 global options ([+] can be repeated):
2900 global options ([+] can be repeated):
2901 </p>
2901 </p>
2902 <table>
2902 <table>
2903 <tr><td>-R</td>
2903 <tr><td>-R</td>
2904 <td>--repository REPO</td>
2904 <td>--repository REPO</td>
2905 <td>repository root directory or name of overlay bundle file</td></tr>
2905 <td>repository root directory or name of overlay bundle file</td></tr>
2906 <tr><td></td>
2906 <tr><td></td>
2907 <td>--cwd DIR</td>
2907 <td>--cwd DIR</td>
2908 <td>change working directory</td></tr>
2908 <td>change working directory</td></tr>
2909 <tr><td>-y</td>
2909 <tr><td>-y</td>
2910 <td>--noninteractive</td>
2910 <td>--noninteractive</td>
2911 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2911 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2912 <tr><td>-q</td>
2912 <tr><td>-q</td>
2913 <td>--quiet</td>
2913 <td>--quiet</td>
2914 <td>suppress output</td></tr>
2914 <td>suppress output</td></tr>
2915 <tr><td>-v</td>
2915 <tr><td>-v</td>
2916 <td>--verbose</td>
2916 <td>--verbose</td>
2917 <td>enable additional output</td></tr>
2917 <td>enable additional output</td></tr>
2918 <tr><td></td>
2918 <tr><td></td>
2919 <td>--color TYPE</td>
2919 <td>--color TYPE</td>
2920 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2920 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2921 <tr><td></td>
2921 <tr><td></td>
2922 <td>--config CONFIG [+]</td>
2922 <td>--config CONFIG [+]</td>
2923 <td>set/override config option (use 'section.name=value')</td></tr>
2923 <td>set/override config option (use 'section.name=value')</td></tr>
2924 <tr><td></td>
2924 <tr><td></td>
2925 <td>--debug</td>
2925 <td>--debug</td>
2926 <td>enable debugging output</td></tr>
2926 <td>enable debugging output</td></tr>
2927 <tr><td></td>
2927 <tr><td></td>
2928 <td>--debugger</td>
2928 <td>--debugger</td>
2929 <td>start debugger</td></tr>
2929 <td>start debugger</td></tr>
2930 <tr><td></td>
2930 <tr><td></td>
2931 <td>--encoding ENCODE</td>
2931 <td>--encoding ENCODE</td>
2932 <td>set the charset encoding (default: ascii)</td></tr>
2932 <td>set the charset encoding (default: ascii)</td></tr>
2933 <tr><td></td>
2933 <tr><td></td>
2934 <td>--encodingmode MODE</td>
2934 <td>--encodingmode MODE</td>
2935 <td>set the charset encoding mode (default: strict)</td></tr>
2935 <td>set the charset encoding mode (default: strict)</td></tr>
2936 <tr><td></td>
2936 <tr><td></td>
2937 <td>--traceback</td>
2937 <td>--traceback</td>
2938 <td>always print a traceback on exception</td></tr>
2938 <td>always print a traceback on exception</td></tr>
2939 <tr><td></td>
2939 <tr><td></td>
2940 <td>--time</td>
2940 <td>--time</td>
2941 <td>time how long the command takes</td></tr>
2941 <td>time how long the command takes</td></tr>
2942 <tr><td></td>
2942 <tr><td></td>
2943 <td>--profile</td>
2943 <td>--profile</td>
2944 <td>print command execution profile</td></tr>
2944 <td>print command execution profile</td></tr>
2945 <tr><td></td>
2945 <tr><td></td>
2946 <td>--version</td>
2946 <td>--version</td>
2947 <td>output version information and exit</td></tr>
2947 <td>output version information and exit</td></tr>
2948 <tr><td>-h</td>
2948 <tr><td>-h</td>
2949 <td>--help</td>
2949 <td>--help</td>
2950 <td>display help and exit</td></tr>
2950 <td>display help and exit</td></tr>
2951 <tr><td></td>
2951 <tr><td></td>
2952 <td>--hidden</td>
2952 <td>--hidden</td>
2953 <td>consider hidden changesets</td></tr>
2953 <td>consider hidden changesets</td></tr>
2954 <tr><td></td>
2954 <tr><td></td>
2955 <td>--pager TYPE</td>
2955 <td>--pager TYPE</td>
2956 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2956 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2957 </table>
2957 </table>
2958
2958
2959 </div>
2959 </div>
2960 </div>
2960 </div>
2961 </div>
2961 </div>
2962
2962
2963
2963
2964
2964
2965 </body>
2965 </body>
2966 </html>
2966 </html>
2967
2967
2968
2968
2969 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2969 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2970 200 Script output follows
2970 200 Script output follows
2971
2971
2972 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2972 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2973 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2973 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2974 <head>
2974 <head>
2975 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2975 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2976 <meta name="robots" content="index, nofollow" />
2976 <meta name="robots" content="index, nofollow" />
2977 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2977 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2978 <script type="text/javascript" src="/static/mercurial.js"></script>
2978 <script type="text/javascript" src="/static/mercurial.js"></script>
2979
2979
2980 <title>Help: remove</title>
2980 <title>Help: remove</title>
2981 </head>
2981 </head>
2982 <body>
2982 <body>
2983
2983
2984 <div class="container">
2984 <div class="container">
2985 <div class="menu">
2985 <div class="menu">
2986 <div class="logo">
2986 <div class="logo">
2987 <a href="https://mercurial-scm.org/">
2987 <a href="https://mercurial-scm.org/">
2988 <img src="/static/hglogo.png" alt="mercurial" /></a>
2988 <img src="/static/hglogo.png" alt="mercurial" /></a>
2989 </div>
2989 </div>
2990 <ul>
2990 <ul>
2991 <li><a href="/shortlog">log</a></li>
2991 <li><a href="/shortlog">log</a></li>
2992 <li><a href="/graph">graph</a></li>
2992 <li><a href="/graph">graph</a></li>
2993 <li><a href="/tags">tags</a></li>
2993 <li><a href="/tags">tags</a></li>
2994 <li><a href="/bookmarks">bookmarks</a></li>
2994 <li><a href="/bookmarks">bookmarks</a></li>
2995 <li><a href="/branches">branches</a></li>
2995 <li><a href="/branches">branches</a></li>
2996 </ul>
2996 </ul>
2997 <ul>
2997 <ul>
2998 <li class="active"><a href="/help">help</a></li>
2998 <li class="active"><a href="/help">help</a></li>
2999 </ul>
2999 </ul>
3000 </div>
3000 </div>
3001
3001
3002 <div class="main">
3002 <div class="main">
3003 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3003 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3004 <h3>Help: remove</h3>
3004 <h3>Help: remove</h3>
3005
3005
3006 <form class="search" action="/log">
3006 <form class="search" action="/log">
3007
3007
3008 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3008 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3009 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3009 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3010 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3010 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3011 </form>
3011 </form>
3012 <div id="doc">
3012 <div id="doc">
3013 <p>
3013 <p>
3014 hg remove [OPTION]... FILE...
3014 hg remove [OPTION]... FILE...
3015 </p>
3015 </p>
3016 <p>
3016 <p>
3017 aliases: rm
3017 aliases: rm
3018 </p>
3018 </p>
3019 <p>
3019 <p>
3020 remove the specified files on the next commit
3020 remove the specified files on the next commit
3021 </p>
3021 </p>
3022 <p>
3022 <p>
3023 Schedule the indicated files for removal from the current branch.
3023 Schedule the indicated files for removal from the current branch.
3024 </p>
3024 </p>
3025 <p>
3025 <p>
3026 This command schedules the files to be removed at the next commit.
3026 This command schedules the files to be removed at the next commit.
3027 To undo a remove before that, see 'hg revert'. To undo added
3027 To undo a remove before that, see 'hg revert'. To undo added
3028 files, see 'hg forget'.
3028 files, see 'hg forget'.
3029 </p>
3029 </p>
3030 <p>
3030 <p>
3031 -A/--after can be used to remove only files that have already
3031 -A/--after can be used to remove only files that have already
3032 been deleted, -f/--force can be used to force deletion, and -Af
3032 been deleted, -f/--force can be used to force deletion, and -Af
3033 can be used to remove files from the next revision without
3033 can be used to remove files from the next revision without
3034 deleting them from the working directory.
3034 deleting them from the working directory.
3035 </p>
3035 </p>
3036 <p>
3036 <p>
3037 The following table details the behavior of remove for different
3037 The following table details the behavior of remove for different
3038 file states (columns) and option combinations (rows). The file
3038 file states (columns) and option combinations (rows). The file
3039 states are Added [A], Clean [C], Modified [M] and Missing [!]
3039 states are Added [A], Clean [C], Modified [M] and Missing [!]
3040 (as reported by 'hg status'). The actions are Warn, Remove
3040 (as reported by 'hg status'). The actions are Warn, Remove
3041 (from branch) and Delete (from disk):
3041 (from branch) and Delete (from disk):
3042 </p>
3042 </p>
3043 <table>
3043 <table>
3044 <tr><td>opt/state</td>
3044 <tr><td>opt/state</td>
3045 <td>A</td>
3045 <td>A</td>
3046 <td>C</td>
3046 <td>C</td>
3047 <td>M</td>
3047 <td>M</td>
3048 <td>!</td></tr>
3048 <td>!</td></tr>
3049 <tr><td>none</td>
3049 <tr><td>none</td>
3050 <td>W</td>
3050 <td>W</td>
3051 <td>RD</td>
3051 <td>RD</td>
3052 <td>W</td>
3052 <td>W</td>
3053 <td>R</td></tr>
3053 <td>R</td></tr>
3054 <tr><td>-f</td>
3054 <tr><td>-f</td>
3055 <td>R</td>
3055 <td>R</td>
3056 <td>RD</td>
3056 <td>RD</td>
3057 <td>RD</td>
3057 <td>RD</td>
3058 <td>R</td></tr>
3058 <td>R</td></tr>
3059 <tr><td>-A</td>
3059 <tr><td>-A</td>
3060 <td>W</td>
3060 <td>W</td>
3061 <td>W</td>
3061 <td>W</td>
3062 <td>W</td>
3062 <td>W</td>
3063 <td>R</td></tr>
3063 <td>R</td></tr>
3064 <tr><td>-Af</td>
3064 <tr><td>-Af</td>
3065 <td>R</td>
3065 <td>R</td>
3066 <td>R</td>
3066 <td>R</td>
3067 <td>R</td>
3067 <td>R</td>
3068 <td>R</td></tr>
3068 <td>R</td></tr>
3069 </table>
3069 </table>
3070 <p>
3070 <p>
3071 <b>Note:</b>
3071 <b>Note:</b>
3072 </p>
3072 </p>
3073 <p>
3073 <p>
3074 'hg remove' never deletes files in Added [A] state from the
3074 'hg remove' never deletes files in Added [A] state from the
3075 working directory, not even if &quot;--force&quot; is specified.
3075 working directory, not even if &quot;--force&quot; is specified.
3076 </p>
3076 </p>
3077 <p>
3077 <p>
3078 Returns 0 on success, 1 if any warnings encountered.
3078 Returns 0 on success, 1 if any warnings encountered.
3079 </p>
3079 </p>
3080 <p>
3080 <p>
3081 options ([+] can be repeated):
3081 options ([+] can be repeated):
3082 </p>
3082 </p>
3083 <table>
3083 <table>
3084 <tr><td>-A</td>
3084 <tr><td>-A</td>
3085 <td>--after</td>
3085 <td>--after</td>
3086 <td>record delete for missing files</td></tr>
3086 <td>record delete for missing files</td></tr>
3087 <tr><td>-f</td>
3087 <tr><td>-f</td>
3088 <td>--force</td>
3088 <td>--force</td>
3089 <td>forget added files, delete modified files</td></tr>
3089 <td>forget added files, delete modified files</td></tr>
3090 <tr><td>-S</td>
3090 <tr><td>-S</td>
3091 <td>--subrepos</td>
3091 <td>--subrepos</td>
3092 <td>recurse into subrepositories</td></tr>
3092 <td>recurse into subrepositories</td></tr>
3093 <tr><td>-I</td>
3093 <tr><td>-I</td>
3094 <td>--include PATTERN [+]</td>
3094 <td>--include PATTERN [+]</td>
3095 <td>include names matching the given patterns</td></tr>
3095 <td>include names matching the given patterns</td></tr>
3096 <tr><td>-X</td>
3096 <tr><td>-X</td>
3097 <td>--exclude PATTERN [+]</td>
3097 <td>--exclude PATTERN [+]</td>
3098 <td>exclude names matching the given patterns</td></tr>
3098 <td>exclude names matching the given patterns</td></tr>
3099 <tr><td>-n</td>
3099 <tr><td>-n</td>
3100 <td>--dry-run</td>
3100 <td>--dry-run</td>
3101 <td>do not perform actions, just print output</td></tr>
3101 <td>do not perform actions, just print output</td></tr>
3102 </table>
3102 </table>
3103 <p>
3103 <p>
3104 global options ([+] can be repeated):
3104 global options ([+] can be repeated):
3105 </p>
3105 </p>
3106 <table>
3106 <table>
3107 <tr><td>-R</td>
3107 <tr><td>-R</td>
3108 <td>--repository REPO</td>
3108 <td>--repository REPO</td>
3109 <td>repository root directory or name of overlay bundle file</td></tr>
3109 <td>repository root directory or name of overlay bundle file</td></tr>
3110 <tr><td></td>
3110 <tr><td></td>
3111 <td>--cwd DIR</td>
3111 <td>--cwd DIR</td>
3112 <td>change working directory</td></tr>
3112 <td>change working directory</td></tr>
3113 <tr><td>-y</td>
3113 <tr><td>-y</td>
3114 <td>--noninteractive</td>
3114 <td>--noninteractive</td>
3115 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3115 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3116 <tr><td>-q</td>
3116 <tr><td>-q</td>
3117 <td>--quiet</td>
3117 <td>--quiet</td>
3118 <td>suppress output</td></tr>
3118 <td>suppress output</td></tr>
3119 <tr><td>-v</td>
3119 <tr><td>-v</td>
3120 <td>--verbose</td>
3120 <td>--verbose</td>
3121 <td>enable additional output</td></tr>
3121 <td>enable additional output</td></tr>
3122 <tr><td></td>
3122 <tr><td></td>
3123 <td>--color TYPE</td>
3123 <td>--color TYPE</td>
3124 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3124 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3125 <tr><td></td>
3125 <tr><td></td>
3126 <td>--config CONFIG [+]</td>
3126 <td>--config CONFIG [+]</td>
3127 <td>set/override config option (use 'section.name=value')</td></tr>
3127 <td>set/override config option (use 'section.name=value')</td></tr>
3128 <tr><td></td>
3128 <tr><td></td>
3129 <td>--debug</td>
3129 <td>--debug</td>
3130 <td>enable debugging output</td></tr>
3130 <td>enable debugging output</td></tr>
3131 <tr><td></td>
3131 <tr><td></td>
3132 <td>--debugger</td>
3132 <td>--debugger</td>
3133 <td>start debugger</td></tr>
3133 <td>start debugger</td></tr>
3134 <tr><td></td>
3134 <tr><td></td>
3135 <td>--encoding ENCODE</td>
3135 <td>--encoding ENCODE</td>
3136 <td>set the charset encoding (default: ascii)</td></tr>
3136 <td>set the charset encoding (default: ascii)</td></tr>
3137 <tr><td></td>
3137 <tr><td></td>
3138 <td>--encodingmode MODE</td>
3138 <td>--encodingmode MODE</td>
3139 <td>set the charset encoding mode (default: strict)</td></tr>
3139 <td>set the charset encoding mode (default: strict)</td></tr>
3140 <tr><td></td>
3140 <tr><td></td>
3141 <td>--traceback</td>
3141 <td>--traceback</td>
3142 <td>always print a traceback on exception</td></tr>
3142 <td>always print a traceback on exception</td></tr>
3143 <tr><td></td>
3143 <tr><td></td>
3144 <td>--time</td>
3144 <td>--time</td>
3145 <td>time how long the command takes</td></tr>
3145 <td>time how long the command takes</td></tr>
3146 <tr><td></td>
3146 <tr><td></td>
3147 <td>--profile</td>
3147 <td>--profile</td>
3148 <td>print command execution profile</td></tr>
3148 <td>print command execution profile</td></tr>
3149 <tr><td></td>
3149 <tr><td></td>
3150 <td>--version</td>
3150 <td>--version</td>
3151 <td>output version information and exit</td></tr>
3151 <td>output version information and exit</td></tr>
3152 <tr><td>-h</td>
3152 <tr><td>-h</td>
3153 <td>--help</td>
3153 <td>--help</td>
3154 <td>display help and exit</td></tr>
3154 <td>display help and exit</td></tr>
3155 <tr><td></td>
3155 <tr><td></td>
3156 <td>--hidden</td>
3156 <td>--hidden</td>
3157 <td>consider hidden changesets</td></tr>
3157 <td>consider hidden changesets</td></tr>
3158 <tr><td></td>
3158 <tr><td></td>
3159 <td>--pager TYPE</td>
3159 <td>--pager TYPE</td>
3160 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3160 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3161 </table>
3161 </table>
3162
3162
3163 </div>
3163 </div>
3164 </div>
3164 </div>
3165 </div>
3165 </div>
3166
3166
3167
3167
3168
3168
3169 </body>
3169 </body>
3170 </html>
3170 </html>
3171
3171
3172
3172
3173 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3173 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3174 200 Script output follows
3174 200 Script output follows
3175
3175
3176 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3176 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3177 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3177 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3178 <head>
3178 <head>
3179 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3179 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3180 <meta name="robots" content="index, nofollow" />
3180 <meta name="robots" content="index, nofollow" />
3181 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3181 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3182 <script type="text/javascript" src="/static/mercurial.js"></script>
3182 <script type="text/javascript" src="/static/mercurial.js"></script>
3183
3183
3184 <title>Help: dates</title>
3184 <title>Help: dates</title>
3185 </head>
3185 </head>
3186 <body>
3186 <body>
3187
3187
3188 <div class="container">
3188 <div class="container">
3189 <div class="menu">
3189 <div class="menu">
3190 <div class="logo">
3190 <div class="logo">
3191 <a href="https://mercurial-scm.org/">
3191 <a href="https://mercurial-scm.org/">
3192 <img src="/static/hglogo.png" alt="mercurial" /></a>
3192 <img src="/static/hglogo.png" alt="mercurial" /></a>
3193 </div>
3193 </div>
3194 <ul>
3194 <ul>
3195 <li><a href="/shortlog">log</a></li>
3195 <li><a href="/shortlog">log</a></li>
3196 <li><a href="/graph">graph</a></li>
3196 <li><a href="/graph">graph</a></li>
3197 <li><a href="/tags">tags</a></li>
3197 <li><a href="/tags">tags</a></li>
3198 <li><a href="/bookmarks">bookmarks</a></li>
3198 <li><a href="/bookmarks">bookmarks</a></li>
3199 <li><a href="/branches">branches</a></li>
3199 <li><a href="/branches">branches</a></li>
3200 </ul>
3200 </ul>
3201 <ul>
3201 <ul>
3202 <li class="active"><a href="/help">help</a></li>
3202 <li class="active"><a href="/help">help</a></li>
3203 </ul>
3203 </ul>
3204 </div>
3204 </div>
3205
3205
3206 <div class="main">
3206 <div class="main">
3207 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3207 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3208 <h3>Help: dates</h3>
3208 <h3>Help: dates</h3>
3209
3209
3210 <form class="search" action="/log">
3210 <form class="search" action="/log">
3211
3211
3212 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3212 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3213 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3213 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3214 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3214 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3215 </form>
3215 </form>
3216 <div id="doc">
3216 <div id="doc">
3217 <h1>Date Formats</h1>
3217 <h1>Date Formats</h1>
3218 <p>
3218 <p>
3219 Some commands allow the user to specify a date, e.g.:
3219 Some commands allow the user to specify a date, e.g.:
3220 </p>
3220 </p>
3221 <ul>
3221 <ul>
3222 <li> backout, commit, import, tag: Specify the commit date.
3222 <li> backout, commit, import, tag: Specify the commit date.
3223 <li> log, revert, update: Select revision(s) by date.
3223 <li> log, revert, update: Select revision(s) by date.
3224 </ul>
3224 </ul>
3225 <p>
3225 <p>
3226 Many date formats are valid. Here are some examples:
3226 Many date formats are valid. Here are some examples:
3227 </p>
3227 </p>
3228 <ul>
3228 <ul>
3229 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3229 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3230 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3230 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3231 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3231 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3232 <li> &quot;Dec 6&quot; (midnight)
3232 <li> &quot;Dec 6&quot; (midnight)
3233 <li> &quot;13:18&quot; (today assumed)
3233 <li> &quot;13:18&quot; (today assumed)
3234 <li> &quot;3:39&quot; (3:39AM assumed)
3234 <li> &quot;3:39&quot; (3:39AM assumed)
3235 <li> &quot;3:39pm&quot; (15:39)
3235 <li> &quot;3:39pm&quot; (15:39)
3236 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3236 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3237 <li> &quot;2006-12-6 13:18&quot;
3237 <li> &quot;2006-12-6 13:18&quot;
3238 <li> &quot;2006-12-6&quot;
3238 <li> &quot;2006-12-6&quot;
3239 <li> &quot;12-6&quot;
3239 <li> &quot;12-6&quot;
3240 <li> &quot;12/6&quot;
3240 <li> &quot;12/6&quot;
3241 <li> &quot;12/6/6&quot; (Dec 6 2006)
3241 <li> &quot;12/6/6&quot; (Dec 6 2006)
3242 <li> &quot;today&quot; (midnight)
3242 <li> &quot;today&quot; (midnight)
3243 <li> &quot;yesterday&quot; (midnight)
3243 <li> &quot;yesterday&quot; (midnight)
3244 <li> &quot;now&quot; - right now
3244 <li> &quot;now&quot; - right now
3245 </ul>
3245 </ul>
3246 <p>
3246 <p>
3247 Lastly, there is Mercurial's internal format:
3247 Lastly, there is Mercurial's internal format:
3248 </p>
3248 </p>
3249 <ul>
3249 <ul>
3250 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3250 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3251 </ul>
3251 </ul>
3252 <p>
3252 <p>
3253 This is the internal representation format for dates. The first number
3253 This is the internal representation format for dates. The first number
3254 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3254 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3255 second is the offset of the local timezone, in seconds west of UTC
3255 second is the offset of the local timezone, in seconds west of UTC
3256 (negative if the timezone is east of UTC).
3256 (negative if the timezone is east of UTC).
3257 </p>
3257 </p>
3258 <p>
3258 <p>
3259 The log command also accepts date ranges:
3259 The log command also accepts date ranges:
3260 </p>
3260 </p>
3261 <ul>
3261 <ul>
3262 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3262 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3263 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3263 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3264 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3264 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3265 <li> &quot;-DAYS&quot; - within a given number of days of today
3265 <li> &quot;-DAYS&quot; - within a given number of days of today
3266 </ul>
3266 </ul>
3267
3267
3268 </div>
3268 </div>
3269 </div>
3269 </div>
3270 </div>
3270 </div>
3271
3271
3272
3272
3273
3273
3274 </body>
3274 </body>
3275 </html>
3275 </html>
3276
3276
3277
3277
3278 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3278 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3279 200 Script output follows
3279 200 Script output follows
3280
3280
3281 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3281 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3282 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3282 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3283 <head>
3283 <head>
3284 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3284 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3285 <meta name="robots" content="index, nofollow" />
3285 <meta name="robots" content="index, nofollow" />
3286 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3286 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3287 <script type="text/javascript" src="/static/mercurial.js"></script>
3287 <script type="text/javascript" src="/static/mercurial.js"></script>
3288
3288
3289 <title>Help: pager</title>
3289 <title>Help: pager</title>
3290 </head>
3290 </head>
3291 <body>
3291 <body>
3292
3292
3293 <div class="container">
3293 <div class="container">
3294 <div class="menu">
3294 <div class="menu">
3295 <div class="logo">
3295 <div class="logo">
3296 <a href="https://mercurial-scm.org/">
3296 <a href="https://mercurial-scm.org/">
3297 <img src="/static/hglogo.png" alt="mercurial" /></a>
3297 <img src="/static/hglogo.png" alt="mercurial" /></a>
3298 </div>
3298 </div>
3299 <ul>
3299 <ul>
3300 <li><a href="/shortlog">log</a></li>
3300 <li><a href="/shortlog">log</a></li>
3301 <li><a href="/graph">graph</a></li>
3301 <li><a href="/graph">graph</a></li>
3302 <li><a href="/tags">tags</a></li>
3302 <li><a href="/tags">tags</a></li>
3303 <li><a href="/bookmarks">bookmarks</a></li>
3303 <li><a href="/bookmarks">bookmarks</a></li>
3304 <li><a href="/branches">branches</a></li>
3304 <li><a href="/branches">branches</a></li>
3305 </ul>
3305 </ul>
3306 <ul>
3306 <ul>
3307 <li class="active"><a href="/help">help</a></li>
3307 <li class="active"><a href="/help">help</a></li>
3308 </ul>
3308 </ul>
3309 </div>
3309 </div>
3310
3310
3311 <div class="main">
3311 <div class="main">
3312 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3312 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3313 <h3>Help: pager</h3>
3313 <h3>Help: pager</h3>
3314
3314
3315 <form class="search" action="/log">
3315 <form class="search" action="/log">
3316
3316
3317 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3317 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3318 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3318 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3319 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3319 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3320 </form>
3320 </form>
3321 <div id="doc">
3321 <div id="doc">
3322 <h1>Pager Support</h1>
3322 <h1>Pager Support</h1>
3323 <p>
3323 <p>
3324 Some Mercurial commands can produce a lot of output, and Mercurial will
3324 Some Mercurial commands can produce a lot of output, and Mercurial will
3325 attempt to use a pager to make those commands more pleasant.
3325 attempt to use a pager to make those commands more pleasant.
3326 </p>
3326 </p>
3327 <p>
3327 <p>
3328 To set the pager that should be used, set the application variable:
3328 To set the pager that should be used, set the application variable:
3329 </p>
3329 </p>
3330 <pre>
3330 <pre>
3331 [pager]
3331 [pager]
3332 pager = less -FRX
3332 pager = less -FRX
3333 </pre>
3333 </pre>
3334 <p>
3334 <p>
3335 If no pager is set in the user or repository configuration, Mercurial uses the
3335 If no pager is set in the user or repository configuration, Mercurial uses the
3336 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3336 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3337 or system configuration is used. If none of these are set, a default pager will
3337 or system configuration is used. If none of these are set, a default pager will
3338 be used, typically 'less' on Unix and 'more' on Windows.
3338 be used, typically 'less' on Unix and 'more' on Windows.
3339 </p>
3339 </p>
3340 <p>
3340 <p>
3341 You can disable the pager for certain commands by adding them to the
3341 You can disable the pager for certain commands by adding them to the
3342 pager.ignore list:
3342 pager.ignore list:
3343 </p>
3343 </p>
3344 <pre>
3344 <pre>
3345 [pager]
3345 [pager]
3346 ignore = version, help, update
3346 ignore = version, help, update
3347 </pre>
3347 </pre>
3348 <p>
3348 <p>
3349 To ignore global commands like 'hg version' or 'hg help', you have
3349 To ignore global commands like 'hg version' or 'hg help', you have
3350 to specify them in your user configuration file.
3350 to specify them in your user configuration file.
3351 </p>
3351 </p>
3352 <p>
3352 <p>
3353 To control whether the pager is used at all for an individual command,
3353 To control whether the pager is used at all for an individual command,
3354 you can use --pager=&lt;value&gt;:
3354 you can use --pager=&lt;value&gt;:
3355 </p>
3355 </p>
3356 <ul>
3356 <ul>
3357 <li> use as needed: 'auto'.
3357 <li> use as needed: 'auto'.
3358 <li> require the pager: 'yes' or 'on'.
3358 <li> require the pager: 'yes' or 'on'.
3359 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3359 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3360 </ul>
3360 </ul>
3361 <p>
3361 <p>
3362 To globally turn off all attempts to use a pager, set:
3362 To globally turn off all attempts to use a pager, set:
3363 </p>
3363 </p>
3364 <pre>
3364 <pre>
3365 [ui]
3365 [ui]
3366 paginate = never
3366 paginate = never
3367 </pre>
3367 </pre>
3368 <p>
3368 <p>
3369 which will prevent the pager from running.
3369 which will prevent the pager from running.
3370 </p>
3370 </p>
3371
3371
3372 </div>
3372 </div>
3373 </div>
3373 </div>
3374 </div>
3374 </div>
3375
3375
3376
3376
3377
3377
3378 </body>
3378 </body>
3379 </html>
3379 </html>
3380
3380
3381
3381
3382 Sub-topic indexes rendered properly
3382 Sub-topic indexes rendered properly
3383
3383
3384 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3384 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3385 200 Script output follows
3385 200 Script output follows
3386
3386
3387 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3387 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3388 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3388 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3389 <head>
3389 <head>
3390 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3390 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3391 <meta name="robots" content="index, nofollow" />
3391 <meta name="robots" content="index, nofollow" />
3392 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3392 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3393 <script type="text/javascript" src="/static/mercurial.js"></script>
3393 <script type="text/javascript" src="/static/mercurial.js"></script>
3394
3394
3395 <title>Help: internals</title>
3395 <title>Help: internals</title>
3396 </head>
3396 </head>
3397 <body>
3397 <body>
3398
3398
3399 <div class="container">
3399 <div class="container">
3400 <div class="menu">
3400 <div class="menu">
3401 <div class="logo">
3401 <div class="logo">
3402 <a href="https://mercurial-scm.org/">
3402 <a href="https://mercurial-scm.org/">
3403 <img src="/static/hglogo.png" alt="mercurial" /></a>
3403 <img src="/static/hglogo.png" alt="mercurial" /></a>
3404 </div>
3404 </div>
3405 <ul>
3405 <ul>
3406 <li><a href="/shortlog">log</a></li>
3406 <li><a href="/shortlog">log</a></li>
3407 <li><a href="/graph">graph</a></li>
3407 <li><a href="/graph">graph</a></li>
3408 <li><a href="/tags">tags</a></li>
3408 <li><a href="/tags">tags</a></li>
3409 <li><a href="/bookmarks">bookmarks</a></li>
3409 <li><a href="/bookmarks">bookmarks</a></li>
3410 <li><a href="/branches">branches</a></li>
3410 <li><a href="/branches">branches</a></li>
3411 </ul>
3411 </ul>
3412 <ul>
3412 <ul>
3413 <li><a href="/help">help</a></li>
3413 <li><a href="/help">help</a></li>
3414 </ul>
3414 </ul>
3415 </div>
3415 </div>
3416
3416
3417 <div class="main">
3417 <div class="main">
3418 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3418 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3419
3419
3420 <form class="search" action="/log">
3420 <form class="search" action="/log">
3421
3421
3422 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3422 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3423 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3423 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3424 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3424 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3425 </form>
3425 </form>
3426 <table class="bigtable">
3426 <table class="bigtable">
3427 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3427 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3428
3428
3429 <tr><td>
3429 <tr><td>
3430 <a href="/help/internals.bundle2">
3430 <a href="/help/internals.bundle2">
3431 bundle2
3431 bundle2
3432 </a>
3432 </a>
3433 </td><td>
3433 </td><td>
3434 Bundle2
3434 Bundle2
3435 </td></tr>
3435 </td></tr>
3436 <tr><td>
3436 <tr><td>
3437 <a href="/help/internals.bundles">
3437 <a href="/help/internals.bundles">
3438 bundles
3438 bundles
3439 </a>
3439 </a>
3440 </td><td>
3440 </td><td>
3441 Bundles
3441 Bundles
3442 </td></tr>
3442 </td></tr>
3443 <tr><td>
3443 <tr><td>
3444 <a href="/help/internals.cbor">
3444 <a href="/help/internals.cbor">
3445 cbor
3445 cbor
3446 </a>
3446 </a>
3447 </td><td>
3447 </td><td>
3448 CBOR
3448 CBOR
3449 </td></tr>
3449 </td></tr>
3450 <tr><td>
3450 <tr><td>
3451 <a href="/help/internals.censor">
3451 <a href="/help/internals.censor">
3452 censor
3452 censor
3453 </a>
3453 </a>
3454 </td><td>
3454 </td><td>
3455 Censor
3455 Censor
3456 </td></tr>
3456 </td></tr>
3457 <tr><td>
3457 <tr><td>
3458 <a href="/help/internals.changegroups">
3458 <a href="/help/internals.changegroups">
3459 changegroups
3459 changegroups
3460 </a>
3460 </a>
3461 </td><td>
3461 </td><td>
3462 Changegroups
3462 Changegroups
3463 </td></tr>
3463 </td></tr>
3464 <tr><td>
3464 <tr><td>
3465 <a href="/help/internals.config">
3465 <a href="/help/internals.config">
3466 config
3466 config
3467 </a>
3467 </a>
3468 </td><td>
3468 </td><td>
3469 Config Registrar
3469 Config Registrar
3470 </td></tr>
3470 </td></tr>
3471 <tr><td>
3471 <tr><td>
3472 <a href="/help/internals.extensions">
3472 <a href="/help/internals.extensions">
3473 extensions
3473 extensions
3474 </a>
3474 </a>
3475 </td><td>
3475 </td><td>
3476 Extension API
3476 Extension API
3477 </td></tr>
3477 </td></tr>
3478 <tr><td>
3478 <tr><td>
3479 <a href="/help/internals.mergestate">
3479 <a href="/help/internals.mergestate">
3480 mergestate
3480 mergestate
3481 </a>
3481 </a>
3482 </td><td>
3482 </td><td>
3483 Mergestate
3483 Mergestate
3484 </td></tr>
3484 </td></tr>
3485 <tr><td>
3485 <tr><td>
3486 <a href="/help/internals.requirements">
3486 <a href="/help/internals.requirements">
3487 requirements
3487 requirements
3488 </a>
3488 </a>
3489 </td><td>
3489 </td><td>
3490 Repository Requirements
3490 Repository Requirements
3491 </td></tr>
3491 </td></tr>
3492 <tr><td>
3492 <tr><td>
3493 <a href="/help/internals.revlogs">
3493 <a href="/help/internals.revlogs">
3494 revlogs
3494 revlogs
3495 </a>
3495 </a>
3496 </td><td>
3496 </td><td>
3497 Revision Logs
3497 Revision Logs
3498 </td></tr>
3498 </td></tr>
3499 <tr><td>
3499 <tr><td>
3500 <a href="/help/internals.wireprotocol">
3500 <a href="/help/internals.wireprotocol">
3501 wireprotocol
3501 wireprotocol
3502 </a>
3502 </a>
3503 </td><td>
3503 </td><td>
3504 Wire Protocol
3504 Wire Protocol
3505 </td></tr>
3505 </td></tr>
3506 <tr><td>
3506 <tr><td>
3507 <a href="/help/internals.wireprotocolrpc">
3507 <a href="/help/internals.wireprotocolrpc">
3508 wireprotocolrpc
3508 wireprotocolrpc
3509 </a>
3509 </a>
3510 </td><td>
3510 </td><td>
3511 Wire Protocol RPC
3511 Wire Protocol RPC
3512 </td></tr>
3512 </td></tr>
3513 <tr><td>
3513 <tr><td>
3514 <a href="/help/internals.wireprotocolv2">
3514 <a href="/help/internals.wireprotocolv2">
3515 wireprotocolv2
3515 wireprotocolv2
3516 </a>
3516 </a>
3517 </td><td>
3517 </td><td>
3518 Wire Protocol Version 2
3518 Wire Protocol Version 2
3519 </td></tr>
3519 </td></tr>
3520
3520
3521
3521
3522
3522
3523
3523
3524
3524
3525 </table>
3525 </table>
3526 </div>
3526 </div>
3527 </div>
3527 </div>
3528
3528
3529
3529
3530
3530
3531 </body>
3531 </body>
3532 </html>
3532 </html>
3533
3533
3534
3534
3535 Sub-topic topics rendered properly
3535 Sub-topic topics rendered properly
3536
3536
3537 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3537 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3538 200 Script output follows
3538 200 Script output follows
3539
3539
3540 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3540 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3541 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3541 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3542 <head>
3542 <head>
3543 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3543 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3544 <meta name="robots" content="index, nofollow" />
3544 <meta name="robots" content="index, nofollow" />
3545 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3545 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3546 <script type="text/javascript" src="/static/mercurial.js"></script>
3546 <script type="text/javascript" src="/static/mercurial.js"></script>
3547
3547
3548 <title>Help: internals.changegroups</title>
3548 <title>Help: internals.changegroups</title>
3549 </head>
3549 </head>
3550 <body>
3550 <body>
3551
3551
3552 <div class="container">
3552 <div class="container">
3553 <div class="menu">
3553 <div class="menu">
3554 <div class="logo">
3554 <div class="logo">
3555 <a href="https://mercurial-scm.org/">
3555 <a href="https://mercurial-scm.org/">
3556 <img src="/static/hglogo.png" alt="mercurial" /></a>
3556 <img src="/static/hglogo.png" alt="mercurial" /></a>
3557 </div>
3557 </div>
3558 <ul>
3558 <ul>
3559 <li><a href="/shortlog">log</a></li>
3559 <li><a href="/shortlog">log</a></li>
3560 <li><a href="/graph">graph</a></li>
3560 <li><a href="/graph">graph</a></li>
3561 <li><a href="/tags">tags</a></li>
3561 <li><a href="/tags">tags</a></li>
3562 <li><a href="/bookmarks">bookmarks</a></li>
3562 <li><a href="/bookmarks">bookmarks</a></li>
3563 <li><a href="/branches">branches</a></li>
3563 <li><a href="/branches">branches</a></li>
3564 </ul>
3564 </ul>
3565 <ul>
3565 <ul>
3566 <li class="active"><a href="/help">help</a></li>
3566 <li class="active"><a href="/help">help</a></li>
3567 </ul>
3567 </ul>
3568 </div>
3568 </div>
3569
3569
3570 <div class="main">
3570 <div class="main">
3571 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3571 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3572 <h3>Help: internals.changegroups</h3>
3572 <h3>Help: internals.changegroups</h3>
3573
3573
3574 <form class="search" action="/log">
3574 <form class="search" action="/log">
3575
3575
3576 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3576 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3577 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3577 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3578 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3578 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3579 </form>
3579 </form>
3580 <div id="doc">
3580 <div id="doc">
3581 <h1>Changegroups</h1>
3581 <h1>Changegroups</h1>
3582 <p>
3582 <p>
3583 Changegroups are representations of repository revlog data, specifically
3583 Changegroups are representations of repository revlog data, specifically
3584 the changelog data, root/flat manifest data, treemanifest data, and
3584 the changelog data, root/flat manifest data, treemanifest data, and
3585 filelogs.
3585 filelogs.
3586 </p>
3586 </p>
3587 <p>
3587 <p>
3588 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3588 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3589 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3589 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3590 only difference being an additional item in the *delta header*. Version
3590 only difference being an additional item in the *delta header*. Version
3591 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3591 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3592 exchanging treemanifests (enabled by setting an option on the
3592 exchanging treemanifests (enabled by setting an option on the
3593 &quot;changegroup&quot; part in the bundle2).
3593 &quot;changegroup&quot; part in the bundle2).
3594 </p>
3594 </p>
3595 <p>
3595 <p>
3596 Changegroups when not exchanging treemanifests consist of 3 logical
3596 Changegroups when not exchanging treemanifests consist of 3 logical
3597 segments:
3597 segments:
3598 </p>
3598 </p>
3599 <pre>
3599 <pre>
3600 +---------------------------------+
3600 +---------------------------------+
3601 | | | |
3601 | | | |
3602 | changeset | manifest | filelogs |
3602 | changeset | manifest | filelogs |
3603 | | | |
3603 | | | |
3604 | | | |
3604 | | | |
3605 +---------------------------------+
3605 +---------------------------------+
3606 </pre>
3606 </pre>
3607 <p>
3607 <p>
3608 When exchanging treemanifests, there are 4 logical segments:
3608 When exchanging treemanifests, there are 4 logical segments:
3609 </p>
3609 </p>
3610 <pre>
3610 <pre>
3611 +-------------------------------------------------+
3611 +-------------------------------------------------+
3612 | | | | |
3612 | | | | |
3613 | changeset | root | treemanifests | filelogs |
3613 | changeset | root | treemanifests | filelogs |
3614 | | manifest | | |
3614 | | manifest | | |
3615 | | | | |
3615 | | | | |
3616 +-------------------------------------------------+
3616 +-------------------------------------------------+
3617 </pre>
3617 </pre>
3618 <p>
3618 <p>
3619 The principle building block of each segment is a *chunk*. A *chunk*
3619 The principle building block of each segment is a *chunk*. A *chunk*
3620 is a framed piece of data:
3620 is a framed piece of data:
3621 </p>
3621 </p>
3622 <pre>
3622 <pre>
3623 +---------------------------------------+
3623 +---------------------------------------+
3624 | | |
3624 | | |
3625 | length | data |
3625 | length | data |
3626 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3626 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3627 | | |
3627 | | |
3628 +---------------------------------------+
3628 +---------------------------------------+
3629 </pre>
3629 </pre>
3630 <p>
3630 <p>
3631 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3631 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3632 integer indicating the length of the entire chunk (including the length field
3632 integer indicating the length of the entire chunk (including the length field
3633 itself).
3633 itself).
3634 </p>
3634 </p>
3635 <p>
3635 <p>
3636 There is a special case chunk that has a value of 0 for the length
3636 There is a special case chunk that has a value of 0 for the length
3637 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3637 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3638 </p>
3638 </p>
3639 <h2>Delta Groups</h2>
3639 <h2>Delta Groups</h2>
3640 <p>
3640 <p>
3641 A *delta group* expresses the content of a revlog as a series of deltas,
3641 A *delta group* expresses the content of a revlog as a series of deltas,
3642 or patches against previous revisions.
3642 or patches against previous revisions.
3643 </p>
3643 </p>
3644 <p>
3644 <p>
3645 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3645 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3646 to signal the end of the delta group:
3646 to signal the end of the delta group:
3647 </p>
3647 </p>
3648 <pre>
3648 <pre>
3649 +------------------------------------------------------------------------+
3649 +------------------------------------------------------------------------+
3650 | | | | | |
3650 | | | | | |
3651 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3651 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3652 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3652 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3653 | | | | | |
3653 | | | | | |
3654 +------------------------------------------------------------------------+
3654 +------------------------------------------------------------------------+
3655 </pre>
3655 </pre>
3656 <p>
3656 <p>
3657 Each *chunk*'s data consists of the following:
3657 Each *chunk*'s data consists of the following:
3658 </p>
3658 </p>
3659 <pre>
3659 <pre>
3660 +---------------------------------------+
3660 +---------------------------------------+
3661 | | |
3661 | | |
3662 | delta header | delta data |
3662 | delta header | delta data |
3663 | (various by version) | (various) |
3663 | (various by version) | (various) |
3664 | | |
3664 | | |
3665 +---------------------------------------+
3665 +---------------------------------------+
3666 </pre>
3666 </pre>
3667 <p>
3667 <p>
3668 The *delta data* is a series of *delta*s that describe a diff from an existing
3668 The *delta data* is a series of *delta*s that describe a diff from an existing
3669 entry (either that the recipient already has, or previously specified in the
3669 entry (either that the recipient already has, or previously specified in the
3670 bundle/changegroup).
3670 bundle/changegroup).
3671 </p>
3671 </p>
3672 <p>
3672 <p>
3673 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3673 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3674 &quot;3&quot; of the changegroup format.
3674 &quot;3&quot; of the changegroup format.
3675 </p>
3675 </p>
3676 <p>
3676 <p>
3677 Version 1 (headerlen=80):
3677 Version 1 (headerlen=80):
3678 </p>
3678 </p>
3679 <pre>
3679 <pre>
3680 +------------------------------------------------------+
3680 +------------------------------------------------------+
3681 | | | | |
3681 | | | | |
3682 | node | p1 node | p2 node | link node |
3682 | node | p1 node | p2 node | link node |
3683 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3683 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3684 | | | | |
3684 | | | | |
3685 +------------------------------------------------------+
3685 +------------------------------------------------------+
3686 </pre>
3686 </pre>
3687 <p>
3687 <p>
3688 Version 2 (headerlen=100):
3688 Version 2 (headerlen=100):
3689 </p>
3689 </p>
3690 <pre>
3690 <pre>
3691 +------------------------------------------------------------------+
3691 +------------------------------------------------------------------+
3692 | | | | | |
3692 | | | | | |
3693 | node | p1 node | p2 node | base node | link node |
3693 | node | p1 node | p2 node | base node | link node |
3694 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3694 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3695 | | | | | |
3695 | | | | | |
3696 +------------------------------------------------------------------+
3696 +------------------------------------------------------------------+
3697 </pre>
3697 </pre>
3698 <p>
3698 <p>
3699 Version 3 (headerlen=102):
3699 Version 3 (headerlen=102):
3700 </p>
3700 </p>
3701 <pre>
3701 <pre>
3702 +------------------------------------------------------------------------------+
3702 +------------------------------------------------------------------------------+
3703 | | | | | | |
3703 | | | | | | |
3704 | node | p1 node | p2 node | base node | link node | flags |
3704 | node | p1 node | p2 node | base node | link node | flags |
3705 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3705 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3706 | | | | | | |
3706 | | | | | | |
3707 +------------------------------------------------------------------------------+
3707 +------------------------------------------------------------------------------+
3708 </pre>
3708 </pre>
3709 <p>
3709 <p>
3710 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3710 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3711 series of *delta*s, densely packed (no separators). These deltas describe a diff
3711 series of *delta*s, densely packed (no separators). These deltas describe a diff
3712 from an existing entry (either that the recipient already has, or previously
3712 from an existing entry (either that the recipient already has, or previously
3713 specified in the bundle/changegroup). The format is described more fully in
3713 specified in the bundle/changegroup). The format is described more fully in
3714 &quot;hg help internals.bdiff&quot;, but briefly:
3714 &quot;hg help internals.bdiff&quot;, but briefly:
3715 </p>
3715 </p>
3716 <pre>
3716 <pre>
3717 +---------------------------------------------------------------+
3717 +---------------------------------------------------------------+
3718 | | | | |
3718 | | | | |
3719 | start offset | end offset | new length | content |
3719 | start offset | end offset | new length | content |
3720 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3720 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3721 | | | | |
3721 | | | | |
3722 +---------------------------------------------------------------+
3722 +---------------------------------------------------------------+
3723 </pre>
3723 </pre>
3724 <p>
3724 <p>
3725 Please note that the length field in the delta data does *not* include itself.
3725 Please note that the length field in the delta data does *not* include itself.
3726 </p>
3726 </p>
3727 <p>
3727 <p>
3728 In version 1, the delta is always applied against the previous node from
3728 In version 1, the delta is always applied against the previous node from
3729 the changegroup or the first parent if this is the first entry in the
3729 the changegroup or the first parent if this is the first entry in the
3730 changegroup.
3730 changegroup.
3731 </p>
3731 </p>
3732 <p>
3732 <p>
3733 In version 2 and up, the delta base node is encoded in the entry in the
3733 In version 2 and up, the delta base node is encoded in the entry in the
3734 changegroup. This allows the delta to be expressed against any parent,
3734 changegroup. This allows the delta to be expressed against any parent,
3735 which can result in smaller deltas and more efficient encoding of data.
3735 which can result in smaller deltas and more efficient encoding of data.
3736 </p>
3736 </p>
3737 <p>
3737 <p>
3738 The *flags* field holds bitwise flags affecting the processing of revision
3738 The *flags* field holds bitwise flags affecting the processing of revision
3739 data. The following flags are defined:
3739 data. The following flags are defined:
3740 </p>
3740 </p>
3741 <dl>
3741 <dl>
3742 <dt>32768
3742 <dt>32768
3743 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3743 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3744 <dt>16384
3744 <dt>16384
3745 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3745 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3746 <dt>8192
3746 <dt>8192
3747 <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.
3747 <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.
3748 </dl>
3748 </dl>
3749 <p>
3749 <p>
3750 For historical reasons, the integer values are identical to revlog version 1
3750 For historical reasons, the integer values are identical to revlog version 1
3751 per-revision storage flags and correspond to bits being set in this 2-byte
3751 per-revision storage flags and correspond to bits being set in this 2-byte
3752 field. Bits were allocated starting from the most-significant bit, hence the
3752 field. Bits were allocated starting from the most-significant bit, hence the
3753 reverse ordering and allocation of these flags.
3753 reverse ordering and allocation of these flags.
3754 </p>
3754 </p>
3755 <h2>Changeset Segment</h2>
3755 <h2>Changeset Segment</h2>
3756 <p>
3756 <p>
3757 The *changeset segment* consists of a single *delta group* holding
3757 The *changeset segment* consists of a single *delta group* holding
3758 changelog data. The *empty chunk* at the end of the *delta group* denotes
3758 changelog data. The *empty chunk* at the end of the *delta group* denotes
3759 the boundary to the *manifest segment*.
3759 the boundary to the *manifest segment*.
3760 </p>
3760 </p>
3761 <h2>Manifest Segment</h2>
3761 <h2>Manifest Segment</h2>
3762 <p>
3762 <p>
3763 The *manifest segment* consists of a single *delta group* holding manifest
3763 The *manifest segment* consists of a single *delta group* holding manifest
3764 data. If treemanifests are in use, it contains only the manifest for the
3764 data. If treemanifests are in use, it contains only the manifest for the
3765 root directory of the repository. Otherwise, it contains the entire
3765 root directory of the repository. Otherwise, it contains the entire
3766 manifest data. The *empty chunk* at the end of the *delta group* denotes
3766 manifest data. The *empty chunk* at the end of the *delta group* denotes
3767 the boundary to the next segment (either the *treemanifests segment* or the
3767 the boundary to the next segment (either the *treemanifests segment* or the
3768 *filelogs segment*, depending on version and the request options).
3768 *filelogs segment*, depending on version and the request options).
3769 </p>
3769 </p>
3770 <h3>Treemanifests Segment</h3>
3770 <h3>Treemanifests Segment</h3>
3771 <p>
3771 <p>
3772 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3772 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3773 only if the 'treemanifest' param is part of the bundle2 changegroup part
3773 only if the 'treemanifest' param is part of the bundle2 changegroup part
3774 (it is not possible to use changegroup version 3 outside of bundle2).
3774 (it is not possible to use changegroup version 3 outside of bundle2).
3775 Aside from the filenames in the *treemanifests segment* containing a
3775 Aside from the filenames in the *treemanifests segment* containing a
3776 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3776 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3777 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3777 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3778 a sub-segment with filename size 0). This denotes the boundary to the
3778 a sub-segment with filename size 0). This denotes the boundary to the
3779 *filelogs segment*.
3779 *filelogs segment*.
3780 </p>
3780 </p>
3781 <h2>Filelogs Segment</h2>
3781 <h2>Filelogs Segment</h2>
3782 <p>
3782 <p>
3783 The *filelogs segment* consists of multiple sub-segments, each
3783 The *filelogs segment* consists of multiple sub-segments, each
3784 corresponding to an individual file whose data is being described:
3784 corresponding to an individual file whose data is being described:
3785 </p>
3785 </p>
3786 <pre>
3786 <pre>
3787 +--------------------------------------------------+
3787 +--------------------------------------------------+
3788 | | | | | |
3788 | | | | | |
3789 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3789 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3790 | | | | | (4 bytes) |
3790 | | | | | (4 bytes) |
3791 | | | | | |
3791 | | | | | |
3792 +--------------------------------------------------+
3792 +--------------------------------------------------+
3793 </pre>
3793 </pre>
3794 <p>
3794 <p>
3795 The final filelog sub-segment is followed by an *empty chunk* (logically,
3795 The final filelog sub-segment is followed by an *empty chunk* (logically,
3796 a sub-segment with filename size 0). This denotes the end of the segment
3796 a sub-segment with filename size 0). This denotes the end of the segment
3797 and of the overall changegroup.
3797 and of the overall changegroup.
3798 </p>
3798 </p>
3799 <p>
3799 <p>
3800 Each filelog sub-segment consists of the following:
3800 Each filelog sub-segment consists of the following:
3801 </p>
3801 </p>
3802 <pre>
3802 <pre>
3803 +------------------------------------------------------+
3803 +------------------------------------------------------+
3804 | | | |
3804 | | | |
3805 | filename length | filename | delta group |
3805 | filename length | filename | delta group |
3806 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3806 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3807 | | | |
3807 | | | |
3808 +------------------------------------------------------+
3808 +------------------------------------------------------+
3809 </pre>
3809 </pre>
3810 <p>
3810 <p>
3811 That is, a *chunk* consisting of the filename (not terminated or padded)
3811 That is, a *chunk* consisting of the filename (not terminated or padded)
3812 followed by N chunks constituting the *delta group* for this file. The
3812 followed by N chunks constituting the *delta group* for this file. The
3813 *empty chunk* at the end of each *delta group* denotes the boundary to the
3813 *empty chunk* at the end of each *delta group* denotes the boundary to the
3814 next filelog sub-segment.
3814 next filelog sub-segment.
3815 </p>
3815 </p>
3816
3816
3817 </div>
3817 </div>
3818 </div>
3818 </div>
3819 </div>
3819 </div>
3820
3820
3821
3821
3822
3822
3823 </body>
3823 </body>
3824 </html>
3824 </html>
3825
3825
3826
3826
3827 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3827 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3828 404 Not Found
3828 404 Not Found
3829
3829
3830 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3830 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3831 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3831 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3832 <head>
3832 <head>
3833 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3833 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3834 <meta name="robots" content="index, nofollow" />
3834 <meta name="robots" content="index, nofollow" />
3835 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3835 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3836 <script type="text/javascript" src="/static/mercurial.js"></script>
3836 <script type="text/javascript" src="/static/mercurial.js"></script>
3837
3837
3838 <title>test: error</title>
3838 <title>test: error</title>
3839 </head>
3839 </head>
3840 <body>
3840 <body>
3841
3841
3842 <div class="container">
3842 <div class="container">
3843 <div class="menu">
3843 <div class="menu">
3844 <div class="logo">
3844 <div class="logo">
3845 <a href="https://mercurial-scm.org/">
3845 <a href="https://mercurial-scm.org/">
3846 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3846 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3847 </div>
3847 </div>
3848 <ul>
3848 <ul>
3849 <li><a href="/shortlog">log</a></li>
3849 <li><a href="/shortlog">log</a></li>
3850 <li><a href="/graph">graph</a></li>
3850 <li><a href="/graph">graph</a></li>
3851 <li><a href="/tags">tags</a></li>
3851 <li><a href="/tags">tags</a></li>
3852 <li><a href="/bookmarks">bookmarks</a></li>
3852 <li><a href="/bookmarks">bookmarks</a></li>
3853 <li><a href="/branches">branches</a></li>
3853 <li><a href="/branches">branches</a></li>
3854 </ul>
3854 </ul>
3855 <ul>
3855 <ul>
3856 <li><a href="/help">help</a></li>
3856 <li><a href="/help">help</a></li>
3857 </ul>
3857 </ul>
3858 </div>
3858 </div>
3859
3859
3860 <div class="main">
3860 <div class="main">
3861
3861
3862 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3862 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3863 <h3>error</h3>
3863 <h3>error</h3>
3864
3864
3865
3865
3866 <form class="search" action="/log">
3866 <form class="search" action="/log">
3867
3867
3868 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3868 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3869 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3869 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3870 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3870 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3871 </form>
3871 </form>
3872
3872
3873 <div class="description">
3873 <div class="description">
3874 <p>
3874 <p>
3875 An error occurred while processing your request:
3875 An error occurred while processing your request:
3876 </p>
3876 </p>
3877 <p>
3877 <p>
3878 Not Found
3878 Not Found
3879 </p>
3879 </p>
3880 </div>
3880 </div>
3881 </div>
3881 </div>
3882 </div>
3882 </div>
3883
3883
3884
3884
3885
3885
3886 </body>
3886 </body>
3887 </html>
3887 </html>
3888
3888
3889 [1]
3889 [1]
3890
3890
3891 $ killdaemons.py
3891 $ killdaemons.py
3892
3892
3893 #endif
3893 #endif
@@ -1,2236 +1,2236 b''
1 #require serve
1 #require serve
2
2
3 $ request() {
3 $ request() {
4 > get-with-headers.py --json localhost:$HGPORT "$1"
4 > get-with-headers.py --json localhost:$HGPORT "$1"
5 > }
5 > }
6
6
7 $ hg init test
7 $ hg init test
8 $ cd test
8 $ cd test
9 $ mkdir da
9 $ mkdir da
10 $ echo foo > da/foo
10 $ echo foo > da/foo
11 $ echo foo > foo
11 $ echo foo > foo
12 $ hg -q ci -A -m initial
12 $ hg -q ci -A -m initial
13 $ echo bar > foo
13 $ echo bar > foo
14 $ hg ci -m 'modify foo'
14 $ hg ci -m 'modify foo'
15 $ echo bar > da/foo
15 $ echo bar > da/foo
16 $ hg ci -m 'modify da/foo'
16 $ hg ci -m 'modify da/foo'
17 $ hg bookmark bookmark1
17 $ hg bookmark bookmark1
18 $ hg up default
18 $ hg up default
19 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
19 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 (leaving bookmark bookmark1)
20 (leaving bookmark bookmark1)
21 $ hg mv foo foo-new
21 $ hg mv foo foo-new
22 $ hg commit -m 'move foo'
22 $ hg commit -m 'move foo'
23 $ hg tag -m 'create tag' tag1
23 $ hg tag -m 'create tag' tag1
24 $ hg phase --public -r .
24 $ hg phase --public -r .
25 $ echo baz > da/foo
25 $ echo baz > da/foo
26 $ hg commit -m 'another commit to da/foo'
26 $ hg commit -m 'another commit to da/foo'
27 $ hg tag -m 'create tag2' tag2
27 $ hg tag -m 'create tag2' tag2
28 $ hg bookmark bookmark2
28 $ hg bookmark bookmark2
29 $ hg -q up -r 0
29 $ hg -q up -r 0
30 $ hg -q branch test-branch
30 $ hg -q branch test-branch
31 $ echo branch > foo
31 $ echo branch > foo
32 $ hg commit -m 'create test branch'
32 $ hg commit -m 'create test branch'
33 $ echo branch_commit_2 > foo
33 $ echo branch_commit_2 > foo
34 $ hg commit -m 'another commit in test-branch'
34 $ hg commit -m 'another commit in test-branch'
35 $ hg -q up default
35 $ hg -q up default
36 $ hg merge --tool :local test-branch
36 $ hg merge --tool :local test-branch
37 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
37 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
38 (branch merge, don't forget to commit)
38 (branch merge, don't forget to commit)
39 $ hg commit -m 'merge test-branch into default'
39 $ hg commit -m 'merge test-branch into default'
40
40
41 $ hg log -G
41 $ hg log -G
42 @ changeset: 9:cc725e08502a
42 @ changeset: 9:cc725e08502a
43 |\ tag: tip
43 |\ tag: tip
44 | | parent: 6:ceed296fe500
44 | | parent: 6:ceed296fe500
45 | | parent: 8:ed66c30e87eb
45 | | parent: 8:ed66c30e87eb
46 | | user: test
46 | | user: test
47 | | date: Thu Jan 01 00:00:00 1970 +0000
47 | | date: Thu Jan 01 00:00:00 1970 +0000
48 | | summary: merge test-branch into default
48 | | summary: merge test-branch into default
49 | |
49 | |
50 | o changeset: 8:ed66c30e87eb
50 | o changeset: 8:ed66c30e87eb
51 | | branch: test-branch
51 | | branch: test-branch
52 | | user: test
52 | | user: test
53 | | date: Thu Jan 01 00:00:00 1970 +0000
53 | | date: Thu Jan 01 00:00:00 1970 +0000
54 | | summary: another commit in test-branch
54 | | summary: another commit in test-branch
55 | |
55 | |
56 | o changeset: 7:6ab967a8ab34
56 | o changeset: 7:6ab967a8ab34
57 | | branch: test-branch
57 | | branch: test-branch
58 | | parent: 0:06e557f3edf6
58 | | parent: 0:06e557f3edf6
59 | | user: test
59 | | user: test
60 | | date: Thu Jan 01 00:00:00 1970 +0000
60 | | date: Thu Jan 01 00:00:00 1970 +0000
61 | | summary: create test branch
61 | | summary: create test branch
62 | |
62 | |
63 o | changeset: 6:ceed296fe500
63 o | changeset: 6:ceed296fe500
64 | | bookmark: bookmark2
64 | | bookmark: bookmark2
65 | | user: test
65 | | user: test
66 | | date: Thu Jan 01 00:00:00 1970 +0000
66 | | date: Thu Jan 01 00:00:00 1970 +0000
67 | | summary: create tag2
67 | | summary: create tag2
68 | |
68 | |
69 o | changeset: 5:f2890a05fea4
69 o | changeset: 5:f2890a05fea4
70 | | tag: tag2
70 | | tag: tag2
71 | | user: test
71 | | user: test
72 | | date: Thu Jan 01 00:00:00 1970 +0000
72 | | date: Thu Jan 01 00:00:00 1970 +0000
73 | | summary: another commit to da/foo
73 | | summary: another commit to da/foo
74 | |
74 | |
75 o | changeset: 4:93a8ce14f891
75 o | changeset: 4:93a8ce14f891
76 | | user: test
76 | | user: test
77 | | date: Thu Jan 01 00:00:00 1970 +0000
77 | | date: Thu Jan 01 00:00:00 1970 +0000
78 | | summary: create tag
78 | | summary: create tag
79 | |
79 | |
80 o | changeset: 3:78896eb0e102
80 o | changeset: 3:78896eb0e102
81 | | tag: tag1
81 | | tag: tag1
82 | | user: test
82 | | user: test
83 | | date: Thu Jan 01 00:00:00 1970 +0000
83 | | date: Thu Jan 01 00:00:00 1970 +0000
84 | | summary: move foo
84 | | summary: move foo
85 | |
85 | |
86 o | changeset: 2:8d7c456572ac
86 o | changeset: 2:8d7c456572ac
87 | | bookmark: bookmark1
87 | | bookmark: bookmark1
88 | | user: test
88 | | user: test
89 | | date: Thu Jan 01 00:00:00 1970 +0000
89 | | date: Thu Jan 01 00:00:00 1970 +0000
90 | | summary: modify da/foo
90 | | summary: modify da/foo
91 | |
91 | |
92 o | changeset: 1:f8bbb9024b10
92 o | changeset: 1:f8bbb9024b10
93 |/ user: test
93 |/ user: test
94 | date: Thu Jan 01 00:00:00 1970 +0000
94 | date: Thu Jan 01 00:00:00 1970 +0000
95 | summary: modify foo
95 | summary: modify foo
96 |
96 |
97 o changeset: 0:06e557f3edf6
97 o changeset: 0:06e557f3edf6
98 user: test
98 user: test
99 date: Thu Jan 01 00:00:00 1970 +0000
99 date: Thu Jan 01 00:00:00 1970 +0000
100 summary: initial
100 summary: initial
101
101
102
102
103 $ echo '[web]' >> .hg/hgrc
103 $ echo '[web]' >> .hg/hgrc
104 $ echo 'allow-archive = bz2' >> .hg/hgrc
104 $ echo 'allow-archive = bz2' >> .hg/hgrc
105 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E error.log
105 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E error.log
106 $ cat hg.pid >> $DAEMON_PIDS
106 $ cat hg.pid >> $DAEMON_PIDS
107
107
108 (Try to keep these in roughly the order they are defined in webcommands.py)
108 (Try to keep these in roughly the order they are defined in webcommands.py)
109
109
110 (log is handled by filelog/ and changelog/ - ignore it)
110 (log is handled by filelog/ and changelog/ - ignore it)
111
111
112 (rawfile/ doesn't use templating - nothing to test)
112 (rawfile/ doesn't use templating - nothing to test)
113
113
114 file/{revision}/{path} shows file revision
114 file/{revision}/{path} shows file revision
115
115
116 $ request json-file/78896eb0e102/foo-new
116 $ request json-file/78896eb0e102/foo-new
117 200 Script output follows
117 200 Script output follows
118
118
119 {
119 {
120 "bookmarks": [],
120 "bookmarks": [],
121 "branch": "default",
121 "branch": "default",
122 "date": [
122 "date": [
123 0.0,
123 0.0,
124 0
124 0
125 ],
125 ],
126 "desc": "move foo",
126 "desc": "move foo",
127 "lines": [
127 "lines": [
128 {
128 {
129 "line": "bar\n"
129 "line": "bar\n"
130 }
130 }
131 ],
131 ],
132 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
132 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
133 "parents": [
133 "parents": [
134 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
134 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
135 ],
135 ],
136 "path": "foo-new",
136 "path": "foo-new",
137 "phase": "public",
137 "phase": "public",
138 "tags": [
138 "tags": [
139 "tag1"
139 "tag1"
140 ],
140 ],
141 "user": "test"
141 "user": "test"
142 }
142 }
143
143
144 file/{revision} shows root directory info
144 file/{revision} shows root directory info
145
145
146 $ request json-file/cc725e08502a
146 $ request json-file/cc725e08502a
147 200 Script output follows
147 200 Script output follows
148
148
149 {
149 {
150 "abspath": "/",
150 "abspath": "/",
151 "bookmarks": [],
151 "bookmarks": [],
152 "directories": [
152 "directories": [
153 {
153 {
154 "abspath": "/da",
154 "abspath": "/da",
155 "basename": "da",
155 "basename": "da",
156 "emptydirs": ""
156 "emptydirs": ""
157 }
157 }
158 ],
158 ],
159 "files": [
159 "files": [
160 {
160 {
161 "abspath": ".hgtags",
161 "abspath": ".hgtags",
162 "basename": ".hgtags",
162 "basename": ".hgtags",
163 "date": [
163 "date": [
164 0.0,
164 0.0,
165 0
165 0
166 ],
166 ],
167 "flags": "",
167 "flags": "",
168 "size": 92
168 "size": 92
169 },
169 },
170 {
170 {
171 "abspath": "foo-new",
171 "abspath": "foo-new",
172 "basename": "foo-new",
172 "basename": "foo-new",
173 "date": [
173 "date": [
174 0.0,
174 0.0,
175 0
175 0
176 ],
176 ],
177 "flags": "",
177 "flags": "",
178 "size": 4
178 "size": 4
179 }
179 }
180 ],
180 ],
181 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
181 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
182 "tags": [
182 "tags": [
183 "tip"
183 "tip"
184 ]
184 ]
185 }
185 }
186
186
187 changelog/ shows information about several changesets
187 changelog/ shows information about several changesets
188
188
189 $ request json-changelog
189 $ request json-changelog
190 200 Script output follows
190 200 Script output follows
191
191
192 {
192 {
193 "changeset_count": 10,
193 "changeset_count": 10,
194 "changesets": [
194 "changesets": [
195 {
195 {
196 "bookmarks": [],
196 "bookmarks": [],
197 "branch": "default",
197 "branch": "default",
198 "date": [
198 "date": [
199 0.0,
199 0.0,
200 0
200 0
201 ],
201 ],
202 "desc": "merge test-branch into default",
202 "desc": "merge test-branch into default",
203 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
203 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
204 "parents": [
204 "parents": [
205 "ceed296fe500c3fac9541e31dad860cb49c89e45",
205 "ceed296fe500c3fac9541e31dad860cb49c89e45",
206 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
206 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
207 ],
207 ],
208 "phase": "draft",
208 "phase": "draft",
209 "tags": [
209 "tags": [
210 "tip"
210 "tip"
211 ],
211 ],
212 "user": "test"
212 "user": "test"
213 },
213 },
214 {
214 {
215 "bookmarks": [],
215 "bookmarks": [],
216 "branch": "test-branch",
216 "branch": "test-branch",
217 "date": [
217 "date": [
218 0.0,
218 0.0,
219 0
219 0
220 ],
220 ],
221 "desc": "another commit in test-branch",
221 "desc": "another commit in test-branch",
222 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
222 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
223 "parents": [
223 "parents": [
224 "6ab967a8ab3489227a83f80e920faa039a71819f"
224 "6ab967a8ab3489227a83f80e920faa039a71819f"
225 ],
225 ],
226 "phase": "draft",
226 "phase": "draft",
227 "tags": [],
227 "tags": [],
228 "user": "test"
228 "user": "test"
229 },
229 },
230 {
230 {
231 "bookmarks": [],
231 "bookmarks": [],
232 "branch": "test-branch",
232 "branch": "test-branch",
233 "date": [
233 "date": [
234 0.0,
234 0.0,
235 0
235 0
236 ],
236 ],
237 "desc": "create test branch",
237 "desc": "create test branch",
238 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
238 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
239 "parents": [
239 "parents": [
240 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
240 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
241 ],
241 ],
242 "phase": "draft",
242 "phase": "draft",
243 "tags": [],
243 "tags": [],
244 "user": "test"
244 "user": "test"
245 },
245 },
246 {
246 {
247 "bookmarks": [
247 "bookmarks": [
248 "bookmark2"
248 "bookmark2"
249 ],
249 ],
250 "branch": "default",
250 "branch": "default",
251 "date": [
251 "date": [
252 0.0,
252 0.0,
253 0
253 0
254 ],
254 ],
255 "desc": "create tag2",
255 "desc": "create tag2",
256 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
256 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
257 "parents": [
257 "parents": [
258 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
258 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
259 ],
259 ],
260 "phase": "draft",
260 "phase": "draft",
261 "tags": [],
261 "tags": [],
262 "user": "test"
262 "user": "test"
263 },
263 },
264 {
264 {
265 "bookmarks": [],
265 "bookmarks": [],
266 "branch": "default",
266 "branch": "default",
267 "date": [
267 "date": [
268 0.0,
268 0.0,
269 0
269 0
270 ],
270 ],
271 "desc": "another commit to da/foo",
271 "desc": "another commit to da/foo",
272 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
272 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
273 "parents": [
273 "parents": [
274 "93a8ce14f89156426b7fa981af8042da53f03aa0"
274 "93a8ce14f89156426b7fa981af8042da53f03aa0"
275 ],
275 ],
276 "phase": "draft",
276 "phase": "draft",
277 "tags": [
277 "tags": [
278 "tag2"
278 "tag2"
279 ],
279 ],
280 "user": "test"
280 "user": "test"
281 },
281 },
282 {
282 {
283 "bookmarks": [],
283 "bookmarks": [],
284 "branch": "default",
284 "branch": "default",
285 "date": [
285 "date": [
286 0.0,
286 0.0,
287 0
287 0
288 ],
288 ],
289 "desc": "create tag",
289 "desc": "create tag",
290 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
290 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
291 "parents": [
291 "parents": [
292 "78896eb0e102174ce9278438a95e12543e4367a7"
292 "78896eb0e102174ce9278438a95e12543e4367a7"
293 ],
293 ],
294 "phase": "public",
294 "phase": "public",
295 "tags": [],
295 "tags": [],
296 "user": "test"
296 "user": "test"
297 },
297 },
298 {
298 {
299 "bookmarks": [],
299 "bookmarks": [],
300 "branch": "default",
300 "branch": "default",
301 "date": [
301 "date": [
302 0.0,
302 0.0,
303 0
303 0
304 ],
304 ],
305 "desc": "move foo",
305 "desc": "move foo",
306 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
306 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
307 "parents": [
307 "parents": [
308 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
308 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
309 ],
309 ],
310 "phase": "public",
310 "phase": "public",
311 "tags": [
311 "tags": [
312 "tag1"
312 "tag1"
313 ],
313 ],
314 "user": "test"
314 "user": "test"
315 },
315 },
316 {
316 {
317 "bookmarks": [
317 "bookmarks": [
318 "bookmark1"
318 "bookmark1"
319 ],
319 ],
320 "branch": "default",
320 "branch": "default",
321 "date": [
321 "date": [
322 0.0,
322 0.0,
323 0
323 0
324 ],
324 ],
325 "desc": "modify da/foo",
325 "desc": "modify da/foo",
326 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
326 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
327 "parents": [
327 "parents": [
328 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
328 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
329 ],
329 ],
330 "phase": "public",
330 "phase": "public",
331 "tags": [],
331 "tags": [],
332 "user": "test"
332 "user": "test"
333 },
333 },
334 {
334 {
335 "bookmarks": [],
335 "bookmarks": [],
336 "branch": "default",
336 "branch": "default",
337 "date": [
337 "date": [
338 0.0,
338 0.0,
339 0
339 0
340 ],
340 ],
341 "desc": "modify foo",
341 "desc": "modify foo",
342 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
342 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
343 "parents": [
343 "parents": [
344 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
344 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
345 ],
345 ],
346 "phase": "public",
346 "phase": "public",
347 "tags": [],
347 "tags": [],
348 "user": "test"
348 "user": "test"
349 },
349 },
350 {
350 {
351 "bookmarks": [],
351 "bookmarks": [],
352 "branch": "default",
352 "branch": "default",
353 "date": [
353 "date": [
354 0.0,
354 0.0,
355 0
355 0
356 ],
356 ],
357 "desc": "initial",
357 "desc": "initial",
358 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
358 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
359 "parents": [],
359 "parents": [],
360 "phase": "public",
360 "phase": "public",
361 "tags": [],
361 "tags": [],
362 "user": "test"
362 "user": "test"
363 }
363 }
364 ],
364 ],
365 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7"
365 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7"
366 }
366 }
367
367
368 changelog/{revision} shows information starting at a specific changeset
368 changelog/{revision} shows information starting at a specific changeset
369
369
370 $ request json-changelog/f8bbb9024b10
370 $ request json-changelog/f8bbb9024b10
371 200 Script output follows
371 200 Script output follows
372
372
373 {
373 {
374 "changeset_count": 10,
374 "changeset_count": 10,
375 "changesets": [
375 "changesets": [
376 {
376 {
377 "bookmarks": [],
377 "bookmarks": [],
378 "branch": "default",
378 "branch": "default",
379 "date": [
379 "date": [
380 0.0,
380 0.0,
381 0
381 0
382 ],
382 ],
383 "desc": "modify foo",
383 "desc": "modify foo",
384 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
384 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
385 "parents": [
385 "parents": [
386 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
386 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
387 ],
387 ],
388 "phase": "public",
388 "phase": "public",
389 "tags": [],
389 "tags": [],
390 "user": "test"
390 "user": "test"
391 },
391 },
392 {
392 {
393 "bookmarks": [],
393 "bookmarks": [],
394 "branch": "default",
394 "branch": "default",
395 "date": [
395 "date": [
396 0.0,
396 0.0,
397 0
397 0
398 ],
398 ],
399 "desc": "initial",
399 "desc": "initial",
400 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
400 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
401 "parents": [],
401 "parents": [],
402 "phase": "public",
402 "phase": "public",
403 "tags": [],
403 "tags": [],
404 "user": "test"
404 "user": "test"
405 }
405 }
406 ],
406 ],
407 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8"
407 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8"
408 }
408 }
409
409
410 shortlog/ shows information about a set of changesets
410 shortlog/ shows information about a set of changesets
411
411
412 $ request json-shortlog
412 $ request json-shortlog
413 200 Script output follows
413 200 Script output follows
414
414
415 {
415 {
416 "changeset_count": 10,
416 "changeset_count": 10,
417 "changesets": [
417 "changesets": [
418 {
418 {
419 "bookmarks": [],
419 "bookmarks": [],
420 "branch": "default",
420 "branch": "default",
421 "date": [
421 "date": [
422 0.0,
422 0.0,
423 0
423 0
424 ],
424 ],
425 "desc": "merge test-branch into default",
425 "desc": "merge test-branch into default",
426 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
426 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
427 "parents": [
427 "parents": [
428 "ceed296fe500c3fac9541e31dad860cb49c89e45",
428 "ceed296fe500c3fac9541e31dad860cb49c89e45",
429 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
429 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
430 ],
430 ],
431 "phase": "draft",
431 "phase": "draft",
432 "tags": [
432 "tags": [
433 "tip"
433 "tip"
434 ],
434 ],
435 "user": "test"
435 "user": "test"
436 },
436 },
437 {
437 {
438 "bookmarks": [],
438 "bookmarks": [],
439 "branch": "test-branch",
439 "branch": "test-branch",
440 "date": [
440 "date": [
441 0.0,
441 0.0,
442 0
442 0
443 ],
443 ],
444 "desc": "another commit in test-branch",
444 "desc": "another commit in test-branch",
445 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
445 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
446 "parents": [
446 "parents": [
447 "6ab967a8ab3489227a83f80e920faa039a71819f"
447 "6ab967a8ab3489227a83f80e920faa039a71819f"
448 ],
448 ],
449 "phase": "draft",
449 "phase": "draft",
450 "tags": [],
450 "tags": [],
451 "user": "test"
451 "user": "test"
452 },
452 },
453 {
453 {
454 "bookmarks": [],
454 "bookmarks": [],
455 "branch": "test-branch",
455 "branch": "test-branch",
456 "date": [
456 "date": [
457 0.0,
457 0.0,
458 0
458 0
459 ],
459 ],
460 "desc": "create test branch",
460 "desc": "create test branch",
461 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
461 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
462 "parents": [
462 "parents": [
463 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
463 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
464 ],
464 ],
465 "phase": "draft",
465 "phase": "draft",
466 "tags": [],
466 "tags": [],
467 "user": "test"
467 "user": "test"
468 },
468 },
469 {
469 {
470 "bookmarks": [
470 "bookmarks": [
471 "bookmark2"
471 "bookmark2"
472 ],
472 ],
473 "branch": "default",
473 "branch": "default",
474 "date": [
474 "date": [
475 0.0,
475 0.0,
476 0
476 0
477 ],
477 ],
478 "desc": "create tag2",
478 "desc": "create tag2",
479 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
479 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
480 "parents": [
480 "parents": [
481 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
481 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
482 ],
482 ],
483 "phase": "draft",
483 "phase": "draft",
484 "tags": [],
484 "tags": [],
485 "user": "test"
485 "user": "test"
486 },
486 },
487 {
487 {
488 "bookmarks": [],
488 "bookmarks": [],
489 "branch": "default",
489 "branch": "default",
490 "date": [
490 "date": [
491 0.0,
491 0.0,
492 0
492 0
493 ],
493 ],
494 "desc": "another commit to da/foo",
494 "desc": "another commit to da/foo",
495 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
495 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
496 "parents": [
496 "parents": [
497 "93a8ce14f89156426b7fa981af8042da53f03aa0"
497 "93a8ce14f89156426b7fa981af8042da53f03aa0"
498 ],
498 ],
499 "phase": "draft",
499 "phase": "draft",
500 "tags": [
500 "tags": [
501 "tag2"
501 "tag2"
502 ],
502 ],
503 "user": "test"
503 "user": "test"
504 },
504 },
505 {
505 {
506 "bookmarks": [],
506 "bookmarks": [],
507 "branch": "default",
507 "branch": "default",
508 "date": [
508 "date": [
509 0.0,
509 0.0,
510 0
510 0
511 ],
511 ],
512 "desc": "create tag",
512 "desc": "create tag",
513 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
513 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
514 "parents": [
514 "parents": [
515 "78896eb0e102174ce9278438a95e12543e4367a7"
515 "78896eb0e102174ce9278438a95e12543e4367a7"
516 ],
516 ],
517 "phase": "public",
517 "phase": "public",
518 "tags": [],
518 "tags": [],
519 "user": "test"
519 "user": "test"
520 },
520 },
521 {
521 {
522 "bookmarks": [],
522 "bookmarks": [],
523 "branch": "default",
523 "branch": "default",
524 "date": [
524 "date": [
525 0.0,
525 0.0,
526 0
526 0
527 ],
527 ],
528 "desc": "move foo",
528 "desc": "move foo",
529 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
529 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
530 "parents": [
530 "parents": [
531 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
531 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
532 ],
532 ],
533 "phase": "public",
533 "phase": "public",
534 "tags": [
534 "tags": [
535 "tag1"
535 "tag1"
536 ],
536 ],
537 "user": "test"
537 "user": "test"
538 },
538 },
539 {
539 {
540 "bookmarks": [
540 "bookmarks": [
541 "bookmark1"
541 "bookmark1"
542 ],
542 ],
543 "branch": "default",
543 "branch": "default",
544 "date": [
544 "date": [
545 0.0,
545 0.0,
546 0
546 0
547 ],
547 ],
548 "desc": "modify da/foo",
548 "desc": "modify da/foo",
549 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
549 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
550 "parents": [
550 "parents": [
551 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
551 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
552 ],
552 ],
553 "phase": "public",
553 "phase": "public",
554 "tags": [],
554 "tags": [],
555 "user": "test"
555 "user": "test"
556 },
556 },
557 {
557 {
558 "bookmarks": [],
558 "bookmarks": [],
559 "branch": "default",
559 "branch": "default",
560 "date": [
560 "date": [
561 0.0,
561 0.0,
562 0
562 0
563 ],
563 ],
564 "desc": "modify foo",
564 "desc": "modify foo",
565 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
565 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
566 "parents": [
566 "parents": [
567 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
567 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
568 ],
568 ],
569 "phase": "public",
569 "phase": "public",
570 "tags": [],
570 "tags": [],
571 "user": "test"
571 "user": "test"
572 },
572 },
573 {
573 {
574 "bookmarks": [],
574 "bookmarks": [],
575 "branch": "default",
575 "branch": "default",
576 "date": [
576 "date": [
577 0.0,
577 0.0,
578 0
578 0
579 ],
579 ],
580 "desc": "initial",
580 "desc": "initial",
581 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
581 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
582 "parents": [],
582 "parents": [],
583 "phase": "public",
583 "phase": "public",
584 "tags": [],
584 "tags": [],
585 "user": "test"
585 "user": "test"
586 }
586 }
587 ],
587 ],
588 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7"
588 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7"
589 }
589 }
590
590
591 shortlog is displayed by default (issue5978)
591 shortlog is displayed by default (issue5978)
592
592
593 $ request '?style=json'
593 $ request '?style=json'
594 200 Script output follows
594 200 Script output follows
595
595
596 {
596 {
597 "changeset_count": 10,
597 "changeset_count": 10,
598 "changesets": [
598 "changesets": [
599 {
599 {
600 "bookmarks": [],
600 "bookmarks": [],
601 "branch": "default",
601 "branch": "default",
602 "date": [
602 "date": [
603 0.0,
603 0.0,
604 0
604 0
605 ],
605 ],
606 "desc": "merge test-branch into default",
606 "desc": "merge test-branch into default",
607 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
607 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
608 "parents": [
608 "parents": [
609 "ceed296fe500c3fac9541e31dad860cb49c89e45",
609 "ceed296fe500c3fac9541e31dad860cb49c89e45",
610 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
610 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
611 ],
611 ],
612 "phase": "draft",
612 "phase": "draft",
613 "tags": [
613 "tags": [
614 "tip"
614 "tip"
615 ],
615 ],
616 "user": "test"
616 "user": "test"
617 },
617 },
618 {
618 {
619 "bookmarks": [],
619 "bookmarks": [],
620 "branch": "test-branch",
620 "branch": "test-branch",
621 "date": [
621 "date": [
622 0.0,
622 0.0,
623 0
623 0
624 ],
624 ],
625 "desc": "another commit in test-branch",
625 "desc": "another commit in test-branch",
626 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
626 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
627 "parents": [
627 "parents": [
628 "6ab967a8ab3489227a83f80e920faa039a71819f"
628 "6ab967a8ab3489227a83f80e920faa039a71819f"
629 ],
629 ],
630 "phase": "draft",
630 "phase": "draft",
631 "tags": [],
631 "tags": [],
632 "user": "test"
632 "user": "test"
633 },
633 },
634 {
634 {
635 "bookmarks": [],
635 "bookmarks": [],
636 "branch": "test-branch",
636 "branch": "test-branch",
637 "date": [
637 "date": [
638 0.0,
638 0.0,
639 0
639 0
640 ],
640 ],
641 "desc": "create test branch",
641 "desc": "create test branch",
642 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
642 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
643 "parents": [
643 "parents": [
644 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
644 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
645 ],
645 ],
646 "phase": "draft",
646 "phase": "draft",
647 "tags": [],
647 "tags": [],
648 "user": "test"
648 "user": "test"
649 },
649 },
650 {
650 {
651 "bookmarks": [
651 "bookmarks": [
652 "bookmark2"
652 "bookmark2"
653 ],
653 ],
654 "branch": "default",
654 "branch": "default",
655 "date": [
655 "date": [
656 0.0,
656 0.0,
657 0
657 0
658 ],
658 ],
659 "desc": "create tag2",
659 "desc": "create tag2",
660 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
660 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
661 "parents": [
661 "parents": [
662 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
662 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
663 ],
663 ],
664 "phase": "draft",
664 "phase": "draft",
665 "tags": [],
665 "tags": [],
666 "user": "test"
666 "user": "test"
667 },
667 },
668 {
668 {
669 "bookmarks": [],
669 "bookmarks": [],
670 "branch": "default",
670 "branch": "default",
671 "date": [
671 "date": [
672 0.0,
672 0.0,
673 0
673 0
674 ],
674 ],
675 "desc": "another commit to da/foo",
675 "desc": "another commit to da/foo",
676 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
676 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
677 "parents": [
677 "parents": [
678 "93a8ce14f89156426b7fa981af8042da53f03aa0"
678 "93a8ce14f89156426b7fa981af8042da53f03aa0"
679 ],
679 ],
680 "phase": "draft",
680 "phase": "draft",
681 "tags": [
681 "tags": [
682 "tag2"
682 "tag2"
683 ],
683 ],
684 "user": "test"
684 "user": "test"
685 },
685 },
686 {
686 {
687 "bookmarks": [],
687 "bookmarks": [],
688 "branch": "default",
688 "branch": "default",
689 "date": [
689 "date": [
690 0.0,
690 0.0,
691 0
691 0
692 ],
692 ],
693 "desc": "create tag",
693 "desc": "create tag",
694 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
694 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
695 "parents": [
695 "parents": [
696 "78896eb0e102174ce9278438a95e12543e4367a7"
696 "78896eb0e102174ce9278438a95e12543e4367a7"
697 ],
697 ],
698 "phase": "public",
698 "phase": "public",
699 "tags": [],
699 "tags": [],
700 "user": "test"
700 "user": "test"
701 },
701 },
702 {
702 {
703 "bookmarks": [],
703 "bookmarks": [],
704 "branch": "default",
704 "branch": "default",
705 "date": [
705 "date": [
706 0.0,
706 0.0,
707 0
707 0
708 ],
708 ],
709 "desc": "move foo",
709 "desc": "move foo",
710 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
710 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
711 "parents": [
711 "parents": [
712 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
712 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
713 ],
713 ],
714 "phase": "public",
714 "phase": "public",
715 "tags": [
715 "tags": [
716 "tag1"
716 "tag1"
717 ],
717 ],
718 "user": "test"
718 "user": "test"
719 },
719 },
720 {
720 {
721 "bookmarks": [
721 "bookmarks": [
722 "bookmark1"
722 "bookmark1"
723 ],
723 ],
724 "branch": "default",
724 "branch": "default",
725 "date": [
725 "date": [
726 0.0,
726 0.0,
727 0
727 0
728 ],
728 ],
729 "desc": "modify da/foo",
729 "desc": "modify da/foo",
730 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
730 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
731 "parents": [
731 "parents": [
732 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
732 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
733 ],
733 ],
734 "phase": "public",
734 "phase": "public",
735 "tags": [],
735 "tags": [],
736 "user": "test"
736 "user": "test"
737 },
737 },
738 {
738 {
739 "bookmarks": [],
739 "bookmarks": [],
740 "branch": "default",
740 "branch": "default",
741 "date": [
741 "date": [
742 0.0,
742 0.0,
743 0
743 0
744 ],
744 ],
745 "desc": "modify foo",
745 "desc": "modify foo",
746 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
746 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
747 "parents": [
747 "parents": [
748 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
748 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
749 ],
749 ],
750 "phase": "public",
750 "phase": "public",
751 "tags": [],
751 "tags": [],
752 "user": "test"
752 "user": "test"
753 },
753 },
754 {
754 {
755 "bookmarks": [],
755 "bookmarks": [],
756 "branch": "default",
756 "branch": "default",
757 "date": [
757 "date": [
758 0.0,
758 0.0,
759 0
759 0
760 ],
760 ],
761 "desc": "initial",
761 "desc": "initial",
762 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
762 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
763 "parents": [],
763 "parents": [],
764 "phase": "public",
764 "phase": "public",
765 "tags": [],
765 "tags": [],
766 "user": "test"
766 "user": "test"
767 }
767 }
768 ],
768 ],
769 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7"
769 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7"
770 }
770 }
771
771
772 changeset/ renders the tip changeset
772 changeset/ renders the tip changeset
773
773
774 $ request json-rev
774 $ request json-rev
775 200 Script output follows
775 200 Script output follows
776
776
777 {
777 {
778 "bookmarks": [],
778 "bookmarks": [],
779 "branch": "default",
779 "branch": "default",
780 "date": [
780 "date": [
781 0.0,
781 0.0,
782 0
782 0
783 ],
783 ],
784 "desc": "merge test-branch into default",
784 "desc": "merge test-branch into default",
785 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
785 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
786 "parents": [
786 "parents": [
787 "ceed296fe500c3fac9541e31dad860cb49c89e45",
787 "ceed296fe500c3fac9541e31dad860cb49c89e45",
788 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
788 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
789 ],
789 ],
790 "phase": "draft",
790 "phase": "draft",
791 "tags": [
791 "tags": [
792 "tip"
792 "tip"
793 ],
793 ],
794 "user": "test"
794 "user": "test"
795 }
795 }
796
796
797 changeset/{revision} shows tags
797 changeset/{revision} shows tags
798
798
799 $ request json-rev/78896eb0e102
799 $ request json-rev/78896eb0e102
800 200 Script output follows
800 200 Script output follows
801
801
802 {
802 {
803 "bookmarks": [],
803 "bookmarks": [],
804 "branch": "default",
804 "branch": "default",
805 "date": [
805 "date": [
806 0.0,
806 0.0,
807 0
807 0
808 ],
808 ],
809 "desc": "move foo",
809 "desc": "move foo",
810 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
810 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
811 "parents": [
811 "parents": [
812 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
812 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
813 ],
813 ],
814 "phase": "public",
814 "phase": "public",
815 "tags": [
815 "tags": [
816 "tag1"
816 "tag1"
817 ],
817 ],
818 "user": "test"
818 "user": "test"
819 }
819 }
820
820
821 changeset/{revision} shows bookmarks
821 changeset/{revision} shows bookmarks
822
822
823 $ request json-rev/8d7c456572ac
823 $ request json-rev/8d7c456572ac
824 200 Script output follows
824 200 Script output follows
825
825
826 {
826 {
827 "bookmarks": [
827 "bookmarks": [
828 "bookmark1"
828 "bookmark1"
829 ],
829 ],
830 "branch": "default",
830 "branch": "default",
831 "date": [
831 "date": [
832 0.0,
832 0.0,
833 0
833 0
834 ],
834 ],
835 "desc": "modify da/foo",
835 "desc": "modify da/foo",
836 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
836 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
837 "parents": [
837 "parents": [
838 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
838 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
839 ],
839 ],
840 "phase": "public",
840 "phase": "public",
841 "tags": [],
841 "tags": [],
842 "user": "test"
842 "user": "test"
843 }
843 }
844
844
845 changeset/{revision} shows branches
845 changeset/{revision} shows branches
846
846
847 $ request json-rev/6ab967a8ab34
847 $ request json-rev/6ab967a8ab34
848 200 Script output follows
848 200 Script output follows
849
849
850 {
850 {
851 "bookmarks": [],
851 "bookmarks": [],
852 "branch": "test-branch",
852 "branch": "test-branch",
853 "date": [
853 "date": [
854 0.0,
854 0.0,
855 0
855 0
856 ],
856 ],
857 "desc": "create test branch",
857 "desc": "create test branch",
858 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
858 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
859 "parents": [
859 "parents": [
860 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
860 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
861 ],
861 ],
862 "phase": "draft",
862 "phase": "draft",
863 "tags": [],
863 "tags": [],
864 "user": "test"
864 "user": "test"
865 }
865 }
866
866
867 manifest/{revision}/{path} shows info about a directory at a revision
867 manifest/{revision}/{path} shows info about a directory at a revision
868
868
869 $ request json-manifest/06e557f3edf6/
869 $ request json-manifest/06e557f3edf6/
870 200 Script output follows
870 200 Script output follows
871
871
872 {
872 {
873 "abspath": "/",
873 "abspath": "/",
874 "bookmarks": [],
874 "bookmarks": [],
875 "directories": [
875 "directories": [
876 {
876 {
877 "abspath": "/da",
877 "abspath": "/da",
878 "basename": "da",
878 "basename": "da",
879 "emptydirs": ""
879 "emptydirs": ""
880 }
880 }
881 ],
881 ],
882 "files": [
882 "files": [
883 {
883 {
884 "abspath": "foo",
884 "abspath": "foo",
885 "basename": "foo",
885 "basename": "foo",
886 "date": [
886 "date": [
887 0.0,
887 0.0,
888 0
888 0
889 ],
889 ],
890 "flags": "",
890 "flags": "",
891 "size": 4
891 "size": 4
892 }
892 }
893 ],
893 ],
894 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
894 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
895 "tags": []
895 "tags": []
896 }
896 }
897
897
898 tags/ shows tags info
898 tags/ shows tags info
899
899
900 $ request json-tags
900 $ request json-tags
901 200 Script output follows
901 200 Script output follows
902
902
903 {
903 {
904 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
904 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
905 "tags": [
905 "tags": [
906 {
906 {
907 "date": [
907 "date": [
908 0.0,
908 0.0,
909 0
909 0
910 ],
910 ],
911 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
911 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
912 "tag": "tag2"
912 "tag": "tag2"
913 },
913 },
914 {
914 {
915 "date": [
915 "date": [
916 0.0,
916 0.0,
917 0
917 0
918 ],
918 ],
919 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
919 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
920 "tag": "tag1"
920 "tag": "tag1"
921 }
921 }
922 ]
922 ]
923 }
923 }
924
924
925 bookmarks/ shows bookmarks info
925 bookmarks/ shows bookmarks info
926
926
927 $ request json-bookmarks
927 $ request json-bookmarks
928 200 Script output follows
928 200 Script output follows
929
929
930 {
930 {
931 "bookmarks": [
931 "bookmarks": [
932 {
932 {
933 "bookmark": "bookmark2",
933 "bookmark": "bookmark2",
934 "date": [
934 "date": [
935 0.0,
935 0.0,
936 0
936 0
937 ],
937 ],
938 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45"
938 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45"
939 },
939 },
940 {
940 {
941 "bookmark": "bookmark1",
941 "bookmark": "bookmark1",
942 "date": [
942 "date": [
943 0.0,
943 0.0,
944 0
944 0
945 ],
945 ],
946 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5"
946 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5"
947 }
947 }
948 ],
948 ],
949 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7"
949 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7"
950 }
950 }
951
951
952 branches/ shows branches info
952 branches/ shows branches info
953
953
954 $ request json-branches
954 $ request json-branches
955 200 Script output follows
955 200 Script output follows
956
956
957 {
957 {
958 "branches": [
958 "branches": [
959 {
959 {
960 "branch": "default",
960 "branch": "default",
961 "date": [
961 "date": [
962 0.0,
962 0.0,
963 0
963 0
964 ],
964 ],
965 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
965 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
966 "status": "open"
966 "status": "open"
967 },
967 },
968 {
968 {
969 "branch": "test-branch",
969 "branch": "test-branch",
970 "date": [
970 "date": [
971 0.0,
971 0.0,
972 0
972 0
973 ],
973 ],
974 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
974 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
975 "status": "inactive"
975 "status": "inactive"
976 }
976 }
977 ]
977 ]
978 }
978 }
979
979
980 summary/ shows a summary of repository state
980 summary/ shows a summary of repository state
981
981
982 $ request json-summary
982 $ request json-summary
983 200 Script output follows
983 200 Script output follows
984
984
985 {
985 {
986 "archives": [
986 "archives": [
987 {
987 {
988 "extension": ".tar.bz2",
988 "extension": ".tar.bz2",
989 "node": "tip",
989 "node": "tip",
990 "type": "bz2",
990 "type": "bz2",
991 "url": "http://*:$HGPORT/archive/tip.tar.bz2" (glob)
991 "url": "http://*:$HGPORT/archive/tip.tar.bz2" (glob)
992 }
992 }
993 ],
993 ],
994 "bookmarks": [
994 "bookmarks": [
995 {
995 {
996 "bookmark": "bookmark2",
996 "bookmark": "bookmark2",
997 "date": [
997 "date": [
998 0.0,
998 0.0,
999 0
999 0
1000 ],
1000 ],
1001 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45"
1001 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45"
1002 },
1002 },
1003 {
1003 {
1004 "bookmark": "bookmark1",
1004 "bookmark": "bookmark1",
1005 "date": [
1005 "date": [
1006 0.0,
1006 0.0,
1007 0
1007 0
1008 ],
1008 ],
1009 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5"
1009 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5"
1010 }
1010 }
1011 ],
1011 ],
1012 "branches": [
1012 "branches": [
1013 {
1013 {
1014 "branch": "default",
1014 "branch": "default",
1015 "date": [
1015 "date": [
1016 0.0,
1016 0.0,
1017 0
1017 0
1018 ],
1018 ],
1019 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
1019 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
1020 "status": "open"
1020 "status": "open"
1021 },
1021 },
1022 {
1022 {
1023 "branch": "test-branch",
1023 "branch": "test-branch",
1024 "date": [
1024 "date": [
1025 0.0,
1025 0.0,
1026 0
1026 0
1027 ],
1027 ],
1028 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
1028 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
1029 "status": "inactive"
1029 "status": "inactive"
1030 }
1030 }
1031 ],
1031 ],
1032 "labels": [],
1032 "labels": [],
1033 "lastchange": [
1033 "lastchange": [
1034 0.0,
1034 0.0,
1035 0
1035 0
1036 ],
1036 ],
1037 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
1037 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
1038 "shortlog": [
1038 "shortlog": [
1039 {
1039 {
1040 "bookmarks": [],
1040 "bookmarks": [],
1041 "branch": "default",
1041 "branch": "default",
1042 "date": [
1042 "date": [
1043 0.0,
1043 0.0,
1044 0
1044 0
1045 ],
1045 ],
1046 "desc": "merge test-branch into default",
1046 "desc": "merge test-branch into default",
1047 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
1047 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
1048 "parents": [
1048 "parents": [
1049 "ceed296fe500c3fac9541e31dad860cb49c89e45",
1049 "ceed296fe500c3fac9541e31dad860cb49c89e45",
1050 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
1050 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
1051 ],
1051 ],
1052 "phase": "draft",
1052 "phase": "draft",
1053 "tags": [
1053 "tags": [
1054 "tip"
1054 "tip"
1055 ],
1055 ],
1056 "user": "test"
1056 "user": "test"
1057 },
1057 },
1058 {
1058 {
1059 "bookmarks": [],
1059 "bookmarks": [],
1060 "branch": "test-branch",
1060 "branch": "test-branch",
1061 "date": [
1061 "date": [
1062 0.0,
1062 0.0,
1063 0
1063 0
1064 ],
1064 ],
1065 "desc": "another commit in test-branch",
1065 "desc": "another commit in test-branch",
1066 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
1066 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
1067 "parents": [
1067 "parents": [
1068 "6ab967a8ab3489227a83f80e920faa039a71819f"
1068 "6ab967a8ab3489227a83f80e920faa039a71819f"
1069 ],
1069 ],
1070 "phase": "draft",
1070 "phase": "draft",
1071 "tags": [],
1071 "tags": [],
1072 "user": "test"
1072 "user": "test"
1073 },
1073 },
1074 {
1074 {
1075 "bookmarks": [],
1075 "bookmarks": [],
1076 "branch": "test-branch",
1076 "branch": "test-branch",
1077 "date": [
1077 "date": [
1078 0.0,
1078 0.0,
1079 0
1079 0
1080 ],
1080 ],
1081 "desc": "create test branch",
1081 "desc": "create test branch",
1082 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
1082 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
1083 "parents": [
1083 "parents": [
1084 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1084 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1085 ],
1085 ],
1086 "phase": "draft",
1086 "phase": "draft",
1087 "tags": [],
1087 "tags": [],
1088 "user": "test"
1088 "user": "test"
1089 },
1089 },
1090 {
1090 {
1091 "bookmarks": [
1091 "bookmarks": [
1092 "bookmark2"
1092 "bookmark2"
1093 ],
1093 ],
1094 "branch": "default",
1094 "branch": "default",
1095 "date": [
1095 "date": [
1096 0.0,
1096 0.0,
1097 0
1097 0
1098 ],
1098 ],
1099 "desc": "create tag2",
1099 "desc": "create tag2",
1100 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
1100 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
1101 "parents": [
1101 "parents": [
1102 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
1102 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
1103 ],
1103 ],
1104 "phase": "draft",
1104 "phase": "draft",
1105 "tags": [],
1105 "tags": [],
1106 "user": "test"
1106 "user": "test"
1107 },
1107 },
1108 {
1108 {
1109 "bookmarks": [],
1109 "bookmarks": [],
1110 "branch": "default",
1110 "branch": "default",
1111 "date": [
1111 "date": [
1112 0.0,
1112 0.0,
1113 0
1113 0
1114 ],
1114 ],
1115 "desc": "another commit to da/foo",
1115 "desc": "another commit to da/foo",
1116 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
1116 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
1117 "parents": [
1117 "parents": [
1118 "93a8ce14f89156426b7fa981af8042da53f03aa0"
1118 "93a8ce14f89156426b7fa981af8042da53f03aa0"
1119 ],
1119 ],
1120 "phase": "draft",
1120 "phase": "draft",
1121 "tags": [
1121 "tags": [
1122 "tag2"
1122 "tag2"
1123 ],
1123 ],
1124 "user": "test"
1124 "user": "test"
1125 },
1125 },
1126 {
1126 {
1127 "bookmarks": [],
1127 "bookmarks": [],
1128 "branch": "default",
1128 "branch": "default",
1129 "date": [
1129 "date": [
1130 0.0,
1130 0.0,
1131 0
1131 0
1132 ],
1132 ],
1133 "desc": "create tag",
1133 "desc": "create tag",
1134 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
1134 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
1135 "parents": [
1135 "parents": [
1136 "78896eb0e102174ce9278438a95e12543e4367a7"
1136 "78896eb0e102174ce9278438a95e12543e4367a7"
1137 ],
1137 ],
1138 "phase": "public",
1138 "phase": "public",
1139 "tags": [],
1139 "tags": [],
1140 "user": "test"
1140 "user": "test"
1141 },
1141 },
1142 {
1142 {
1143 "bookmarks": [],
1143 "bookmarks": [],
1144 "branch": "default",
1144 "branch": "default",
1145 "date": [
1145 "date": [
1146 0.0,
1146 0.0,
1147 0
1147 0
1148 ],
1148 ],
1149 "desc": "move foo",
1149 "desc": "move foo",
1150 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
1150 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
1151 "parents": [
1151 "parents": [
1152 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
1152 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
1153 ],
1153 ],
1154 "phase": "public",
1154 "phase": "public",
1155 "tags": [
1155 "tags": [
1156 "tag1"
1156 "tag1"
1157 ],
1157 ],
1158 "user": "test"
1158 "user": "test"
1159 },
1159 },
1160 {
1160 {
1161 "bookmarks": [
1161 "bookmarks": [
1162 "bookmark1"
1162 "bookmark1"
1163 ],
1163 ],
1164 "branch": "default",
1164 "branch": "default",
1165 "date": [
1165 "date": [
1166 0.0,
1166 0.0,
1167 0
1167 0
1168 ],
1168 ],
1169 "desc": "modify da/foo",
1169 "desc": "modify da/foo",
1170 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
1170 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
1171 "parents": [
1171 "parents": [
1172 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
1172 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
1173 ],
1173 ],
1174 "phase": "public",
1174 "phase": "public",
1175 "tags": [],
1175 "tags": [],
1176 "user": "test"
1176 "user": "test"
1177 },
1177 },
1178 {
1178 {
1179 "bookmarks": [],
1179 "bookmarks": [],
1180 "branch": "default",
1180 "branch": "default",
1181 "date": [
1181 "date": [
1182 0.0,
1182 0.0,
1183 0
1183 0
1184 ],
1184 ],
1185 "desc": "modify foo",
1185 "desc": "modify foo",
1186 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1186 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1187 "parents": [
1187 "parents": [
1188 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1188 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1189 ],
1189 ],
1190 "phase": "public",
1190 "phase": "public",
1191 "tags": [],
1191 "tags": [],
1192 "user": "test"
1192 "user": "test"
1193 },
1193 },
1194 {
1194 {
1195 "bookmarks": [],
1195 "bookmarks": [],
1196 "branch": "default",
1196 "branch": "default",
1197 "date": [
1197 "date": [
1198 0.0,
1198 0.0,
1199 0
1199 0
1200 ],
1200 ],
1201 "desc": "initial",
1201 "desc": "initial",
1202 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
1202 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
1203 "parents": [],
1203 "parents": [],
1204 "phase": "public",
1204 "phase": "public",
1205 "tags": [],
1205 "tags": [],
1206 "user": "test"
1206 "user": "test"
1207 }
1207 }
1208 ],
1208 ],
1209 "tags": [
1209 "tags": [
1210 {
1210 {
1211 "date": [
1211 "date": [
1212 0.0,
1212 0.0,
1213 0
1213 0
1214 ],
1214 ],
1215 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
1215 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
1216 "tag": "tag2"
1216 "tag": "tag2"
1217 },
1217 },
1218 {
1218 {
1219 "date": [
1219 "date": [
1220 0.0,
1220 0.0,
1221 0
1221 0
1222 ],
1222 ],
1223 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
1223 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
1224 "tag": "tag1"
1224 "tag": "tag1"
1225 }
1225 }
1226 ]
1226 ]
1227 }
1227 }
1228
1228
1229 $ request json-changelog?rev=create
1229 $ request json-changelog?rev=create
1230 200 Script output follows
1230 200 Script output follows
1231
1231
1232 {
1232 {
1233 "entries": [
1233 "entries": [
1234 {
1234 {
1235 "bookmarks": [],
1235 "bookmarks": [],
1236 "branch": "test-branch",
1236 "branch": "test-branch",
1237 "date": [
1237 "date": [
1238 0.0,
1238 0.0,
1239 0
1239 0
1240 ],
1240 ],
1241 "desc": "create test branch",
1241 "desc": "create test branch",
1242 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
1242 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
1243 "parents": [
1243 "parents": [
1244 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1244 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1245 ],
1245 ],
1246 "phase": "draft",
1246 "phase": "draft",
1247 "tags": [],
1247 "tags": [],
1248 "user": "test"
1248 "user": "test"
1249 },
1249 },
1250 {
1250 {
1251 "bookmarks": [
1251 "bookmarks": [
1252 "bookmark2"
1252 "bookmark2"
1253 ],
1253 ],
1254 "branch": "default",
1254 "branch": "default",
1255 "date": [
1255 "date": [
1256 0.0,
1256 0.0,
1257 0
1257 0
1258 ],
1258 ],
1259 "desc": "create tag2",
1259 "desc": "create tag2",
1260 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
1260 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
1261 "parents": [
1261 "parents": [
1262 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
1262 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
1263 ],
1263 ],
1264 "phase": "draft",
1264 "phase": "draft",
1265 "tags": [],
1265 "tags": [],
1266 "user": "test"
1266 "user": "test"
1267 },
1267 },
1268 {
1268 {
1269 "bookmarks": [],
1269 "bookmarks": [],
1270 "branch": "default",
1270 "branch": "default",
1271 "date": [
1271 "date": [
1272 0.0,
1272 0.0,
1273 0
1273 0
1274 ],
1274 ],
1275 "desc": "create tag",
1275 "desc": "create tag",
1276 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
1276 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
1277 "parents": [
1277 "parents": [
1278 "78896eb0e102174ce9278438a95e12543e4367a7"
1278 "78896eb0e102174ce9278438a95e12543e4367a7"
1279 ],
1279 ],
1280 "phase": "public",
1280 "phase": "public",
1281 "tags": [],
1281 "tags": [],
1282 "user": "test"
1282 "user": "test"
1283 }
1283 }
1284 ],
1284 ],
1285 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
1285 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
1286 "query": "create"
1286 "query": "create"
1287 }
1287 }
1288
1288
1289 filediff/{revision}/{path} shows changes to a file in a revision
1289 filediff/{revision}/{path} shows changes to a file in a revision
1290
1290
1291 $ request json-diff/f8bbb9024b10/foo
1291 $ request json-diff/f8bbb9024b10/foo
1292 200 Script output follows
1292 200 Script output follows
1293
1293
1294 {
1294 {
1295 "author": "test",
1295 "author": "test",
1296 "children": [],
1296 "children": [],
1297 "date": [
1297 "date": [
1298 0.0,
1298 0.0,
1299 0
1299 0
1300 ],
1300 ],
1301 "desc": "modify foo",
1301 "desc": "modify foo",
1302 "diff": [
1302 "diff": [
1303 {
1303 {
1304 "blockno": 1,
1304 "blockno": 1,
1305 "lines": [
1305 "lines": [
1306 {
1306 {
1307 "l": "--- a/foo\tThu Jan 01 00:00:00 1970 +0000\n",
1307 "l": "--- a/foo\tThu Jan 01 00:00:00 1970 +0000\n",
1308 "n": 1,
1308 "n": 1,
1309 "t": "-"
1309 "t": "-"
1310 },
1310 },
1311 {
1311 {
1312 "l": "+++ b/foo\tThu Jan 01 00:00:00 1970 +0000\n",
1312 "l": "+++ b/foo\tThu Jan 01 00:00:00 1970 +0000\n",
1313 "n": 2,
1313 "n": 2,
1314 "t": "+"
1314 "t": "+"
1315 },
1315 },
1316 {
1316 {
1317 "l": "@@ -1,1 +1,1 @@\n",
1317 "l": "@@ -1,1 +1,1 @@\n",
1318 "n": 3,
1318 "n": 3,
1319 "t": "@"
1319 "t": "@"
1320 },
1320 },
1321 {
1321 {
1322 "l": "-foo\n",
1322 "l": "-foo\n",
1323 "n": 4,
1323 "n": 4,
1324 "t": "-"
1324 "t": "-"
1325 },
1325 },
1326 {
1326 {
1327 "l": "+bar\n",
1327 "l": "+bar\n",
1328 "n": 5,
1328 "n": 5,
1329 "t": "+"
1329 "t": "+"
1330 }
1330 }
1331 ]
1331 ]
1332 }
1332 }
1333 ],
1333 ],
1334 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1334 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1335 "parents": [
1335 "parents": [
1336 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1336 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1337 ],
1337 ],
1338 "path": "foo"
1338 "path": "foo"
1339 }
1339 }
1340
1340
1341 comparison/{revision}/{path} shows information about before and after for a file
1341 comparison/{revision}/{path} shows information about before and after for a file
1342
1342
1343 $ request json-comparison/f8bbb9024b10/foo
1343 $ request json-comparison/f8bbb9024b10/foo
1344 200 Script output follows
1344 200 Script output follows
1345
1345
1346 {
1346 {
1347 "author": "test",
1347 "author": "test",
1348 "children": [],
1348 "children": [],
1349 "comparison": [
1349 "comparison": [
1350 {
1350 {
1351 "lines": [
1351 "lines": [
1352 {
1352 {
1353 "ll": "foo",
1353 "ll": "foo",
1354 "ln": 1,
1354 "ln": 1,
1355 "rl": "bar",
1355 "rl": "bar",
1356 "rn": 1,
1356 "rn": 1,
1357 "t": "replace"
1357 "t": "replace"
1358 }
1358 }
1359 ]
1359 ]
1360 }
1360 }
1361 ],
1361 ],
1362 "date": [
1362 "date": [
1363 0.0,
1363 0.0,
1364 0
1364 0
1365 ],
1365 ],
1366 "desc": "modify foo",
1366 "desc": "modify foo",
1367 "leftnode": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
1367 "leftnode": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
1368 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1368 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1369 "parents": [
1369 "parents": [
1370 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1370 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1371 ],
1371 ],
1372 "path": "foo",
1372 "path": "foo",
1373 "rightnode": "f8bbb9024b10f93cdbb8d940337398291d40dea8"
1373 "rightnode": "f8bbb9024b10f93cdbb8d940337398291d40dea8"
1374 }
1374 }
1375
1375
1376 annotate/{revision}/{path} shows annotations for each line
1376 annotate/{revision}/{path} shows annotations for each line
1377
1377
1378 $ request json-annotate/f8bbb9024b10/foo
1378 $ request json-annotate/f8bbb9024b10/foo
1379 200 Script output follows
1379 200 Script output follows
1380
1380
1381 {
1381 {
1382 "abspath": "foo",
1382 "abspath": "foo",
1383 "annotate": [
1383 "annotate": [
1384 {
1384 {
1385 "abspath": "foo",
1385 "abspath": "foo",
1386 "author": "test",
1386 "author": "test",
1387 "desc": "modify foo",
1387 "desc": "modify foo",
1388 "line": "bar\n",
1388 "line": "bar\n",
1389 "lineno": 1,
1389 "lineno": 1,
1390 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1390 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1391 "revdate": [
1391 "revdate": [
1392 0.0,
1392 0.0,
1393 0
1393 0
1394 ],
1394 ],
1395 "targetline": 1
1395 "targetline": 1
1396 }
1396 }
1397 ],
1397 ],
1398 "author": "test",
1398 "author": "test",
1399 "children": [],
1399 "children": [],
1400 "date": [
1400 "date": [
1401 0.0,
1401 0.0,
1402 0
1402 0
1403 ],
1403 ],
1404 "desc": "modify foo",
1404 "desc": "modify foo",
1405 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1405 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1406 "parents": [
1406 "parents": [
1407 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1407 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1408 ],
1408 ],
1409 "permissions": ""
1409 "permissions": ""
1410 }
1410 }
1411
1411
1412 filelog/{revision}/{path} shows history of a single file
1412 filelog/{revision}/{path} shows history of a single file
1413
1413
1414 $ request json-filelog/f8bbb9024b10/foo
1414 $ request json-filelog/f8bbb9024b10/foo
1415 200 Script output follows
1415 200 Script output follows
1416
1416
1417 {
1417 {
1418 "entries": [
1418 "entries": [
1419 {
1419 {
1420 "bookmarks": [],
1420 "bookmarks": [],
1421 "branch": "default",
1421 "branch": "default",
1422 "date": [
1422 "date": [
1423 0.0,
1423 0.0,
1424 0
1424 0
1425 ],
1425 ],
1426 "desc": "modify foo",
1426 "desc": "modify foo",
1427 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1427 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1428 "parents": [
1428 "parents": [
1429 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1429 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1430 ],
1430 ],
1431 "phase": "public",
1431 "phase": "public",
1432 "tags": [],
1432 "tags": [],
1433 "user": "test"
1433 "user": "test"
1434 },
1434 },
1435 {
1435 {
1436 "bookmarks": [],
1436 "bookmarks": [],
1437 "branch": "default",
1437 "branch": "default",
1438 "date": [
1438 "date": [
1439 0.0,
1439 0.0,
1440 0
1440 0
1441 ],
1441 ],
1442 "desc": "initial",
1442 "desc": "initial",
1443 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
1443 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
1444 "parents": [],
1444 "parents": [],
1445 "phase": "public",
1445 "phase": "public",
1446 "tags": [],
1446 "tags": [],
1447 "user": "test"
1447 "user": "test"
1448 }
1448 }
1449 ]
1449 ]
1450 }
1450 }
1451
1451
1452 $ request json-filelog/cc725e08502a/da/foo
1452 $ request json-filelog/cc725e08502a/da/foo
1453 200 Script output follows
1453 200 Script output follows
1454
1454
1455 {
1455 {
1456 "entries": [
1456 "entries": [
1457 {
1457 {
1458 "bookmarks": [],
1458 "bookmarks": [],
1459 "branch": "default",
1459 "branch": "default",
1460 "date": [
1460 "date": [
1461 0.0,
1461 0.0,
1462 0
1462 0
1463 ],
1463 ],
1464 "desc": "another commit to da/foo",
1464 "desc": "another commit to da/foo",
1465 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
1465 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
1466 "parents": [
1466 "parents": [
1467 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
1467 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
1468 ],
1468 ],
1469 "phase": "draft",
1469 "phase": "draft",
1470 "tags": [
1470 "tags": [
1471 "tag2"
1471 "tag2"
1472 ],
1472 ],
1473 "user": "test"
1473 "user": "test"
1474 },
1474 },
1475 {
1475 {
1476 "bookmarks": [
1476 "bookmarks": [
1477 "bookmark1"
1477 "bookmark1"
1478 ],
1478 ],
1479 "branch": "default",
1479 "branch": "default",
1480 "date": [
1480 "date": [
1481 0.0,
1481 0.0,
1482 0
1482 0
1483 ],
1483 ],
1484 "desc": "modify da/foo",
1484 "desc": "modify da/foo",
1485 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
1485 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
1486 "parents": [
1486 "parents": [
1487 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1487 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1488 ],
1488 ],
1489 "phase": "public",
1489 "phase": "public",
1490 "tags": [],
1490 "tags": [],
1491 "user": "test"
1491 "user": "test"
1492 },
1492 },
1493 {
1493 {
1494 "bookmarks": [],
1494 "bookmarks": [],
1495 "branch": "default",
1495 "branch": "default",
1496 "date": [
1496 "date": [
1497 0.0,
1497 0.0,
1498 0
1498 0
1499 ],
1499 ],
1500 "desc": "initial",
1500 "desc": "initial",
1501 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
1501 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
1502 "parents": [],
1502 "parents": [],
1503 "phase": "public",
1503 "phase": "public",
1504 "tags": [],
1504 "tags": [],
1505 "user": "test"
1505 "user": "test"
1506 }
1506 }
1507 ]
1507 ]
1508 }
1508 }
1509
1509
1510 (archive/ doesn't use templating, so ignore it)
1510 (archive/ doesn't use templating, so ignore it)
1511
1511
1512 (static/ doesn't use templating, so ignore it)
1512 (static/ doesn't use templating, so ignore it)
1513
1513
1514 graph/ shows information that can be used to render a graph of the DAG
1514 graph/ shows information that can be used to render a graph of the DAG
1515
1515
1516 $ request json-graph
1516 $ request json-graph
1517 200 Script output follows
1517 200 Script output follows
1518
1518
1519 {
1519 {
1520 "changeset_count": 10,
1520 "changeset_count": 10,
1521 "changesets": [
1521 "changesets": [
1522 {
1522 {
1523 "bookmarks": [],
1523 "bookmarks": [],
1524 "branch": "default",
1524 "branch": "default",
1525 "col": 0,
1525 "col": 0,
1526 "color": 1,
1526 "color": 1,
1527 "date": [
1527 "date": [
1528 0.0,
1528 0.0,
1529 0
1529 0
1530 ],
1530 ],
1531 "desc": "merge test-branch into default",
1531 "desc": "merge test-branch into default",
1532 "edges": [
1532 "edges": [
1533 {
1533 {
1534 "bcolor": "",
1534 "bcolor": "",
1535 "col": 0,
1535 "col": 0,
1536 "color": 1,
1536 "color": 1,
1537 "nextcol": 0,
1537 "nextcol": 0,
1538 "width": -1
1538 "width": -1
1539 },
1539 },
1540 {
1540 {
1541 "bcolor": "",
1541 "bcolor": "",
1542 "col": 0,
1542 "col": 0,
1543 "color": 1,
1543 "color": 1,
1544 "nextcol": 1,
1544 "nextcol": 1,
1545 "width": -1
1545 "width": -1
1546 }
1546 }
1547 ],
1547 ],
1548 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
1548 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7",
1549 "parents": [
1549 "parents": [
1550 "ceed296fe500c3fac9541e31dad860cb49c89e45",
1550 "ceed296fe500c3fac9541e31dad860cb49c89e45",
1551 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
1551 "ed66c30e87eb65337c05a4229efaa5f1d5285a90"
1552 ],
1552 ],
1553 "phase": "draft",
1553 "phase": "draft",
1554 "row": 0,
1554 "row": 0,
1555 "tags": [
1555 "tags": [
1556 "tip"
1556 "tip"
1557 ],
1557 ],
1558 "user": "test"
1558 "user": "test"
1559 },
1559 },
1560 {
1560 {
1561 "bookmarks": [],
1561 "bookmarks": [],
1562 "branch": "test-branch",
1562 "branch": "test-branch",
1563 "col": 1,
1563 "col": 1,
1564 "color": 2,
1564 "color": 2,
1565 "date": [
1565 "date": [
1566 0.0,
1566 0.0,
1567 0
1567 0
1568 ],
1568 ],
1569 "desc": "another commit in test-branch",
1569 "desc": "another commit in test-branch",
1570 "edges": [
1570 "edges": [
1571 {
1571 {
1572 "bcolor": "",
1572 "bcolor": "",
1573 "col": 0,
1573 "col": 0,
1574 "color": 1,
1574 "color": 1,
1575 "nextcol": 0,
1575 "nextcol": 0,
1576 "width": -1
1576 "width": -1
1577 },
1577 },
1578 {
1578 {
1579 "bcolor": "",
1579 "bcolor": "",
1580 "col": 1,
1580 "col": 1,
1581 "color": 2,
1581 "color": 2,
1582 "nextcol": 1,
1582 "nextcol": 1,
1583 "width": -1
1583 "width": -1
1584 }
1584 }
1585 ],
1585 ],
1586 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
1586 "node": "ed66c30e87eb65337c05a4229efaa5f1d5285a90",
1587 "parents": [
1587 "parents": [
1588 "6ab967a8ab3489227a83f80e920faa039a71819f"
1588 "6ab967a8ab3489227a83f80e920faa039a71819f"
1589 ],
1589 ],
1590 "phase": "draft",
1590 "phase": "draft",
1591 "row": 1,
1591 "row": 1,
1592 "tags": [],
1592 "tags": [],
1593 "user": "test"
1593 "user": "test"
1594 },
1594 },
1595 {
1595 {
1596 "bookmarks": [],
1596 "bookmarks": [],
1597 "branch": "test-branch",
1597 "branch": "test-branch",
1598 "col": 1,
1598 "col": 1,
1599 "color": 2,
1599 "color": 2,
1600 "date": [
1600 "date": [
1601 0.0,
1601 0.0,
1602 0
1602 0
1603 ],
1603 ],
1604 "desc": "create test branch",
1604 "desc": "create test branch",
1605 "edges": [
1605 "edges": [
1606 {
1606 {
1607 "bcolor": "",
1607 "bcolor": "",
1608 "col": 0,
1608 "col": 0,
1609 "color": 1,
1609 "color": 1,
1610 "nextcol": 0,
1610 "nextcol": 0,
1611 "width": -1
1611 "width": -1
1612 },
1612 },
1613 {
1613 {
1614 "bcolor": "",
1614 "bcolor": "",
1615 "col": 1,
1615 "col": 1,
1616 "color": 2,
1616 "color": 2,
1617 "nextcol": 1,
1617 "nextcol": 1,
1618 "width": -1
1618 "width": -1
1619 }
1619 }
1620 ],
1620 ],
1621 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
1621 "node": "6ab967a8ab3489227a83f80e920faa039a71819f",
1622 "parents": [
1622 "parents": [
1623 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1623 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1624 ],
1624 ],
1625 "phase": "draft",
1625 "phase": "draft",
1626 "row": 2,
1626 "row": 2,
1627 "tags": [],
1627 "tags": [],
1628 "user": "test"
1628 "user": "test"
1629 },
1629 },
1630 {
1630 {
1631 "bookmarks": [
1631 "bookmarks": [
1632 "bookmark2"
1632 "bookmark2"
1633 ],
1633 ],
1634 "branch": "default",
1634 "branch": "default",
1635 "col": 0,
1635 "col": 0,
1636 "color": 1,
1636 "color": 1,
1637 "date": [
1637 "date": [
1638 0.0,
1638 0.0,
1639 0
1639 0
1640 ],
1640 ],
1641 "desc": "create tag2",
1641 "desc": "create tag2",
1642 "edges": [
1642 "edges": [
1643 {
1643 {
1644 "bcolor": "",
1644 "bcolor": "",
1645 "col": 0,
1645 "col": 0,
1646 "color": 1,
1646 "color": 1,
1647 "nextcol": 0,
1647 "nextcol": 0,
1648 "width": -1
1648 "width": -1
1649 },
1649 },
1650 {
1650 {
1651 "bcolor": "",
1651 "bcolor": "",
1652 "col": 1,
1652 "col": 1,
1653 "color": 2,
1653 "color": 2,
1654 "nextcol": 1,
1654 "nextcol": 1,
1655 "width": -1
1655 "width": -1
1656 }
1656 }
1657 ],
1657 ],
1658 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
1658 "node": "ceed296fe500c3fac9541e31dad860cb49c89e45",
1659 "parents": [
1659 "parents": [
1660 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
1660 "f2890a05fea49bfaf9fb27ed5490894eba32da78"
1661 ],
1661 ],
1662 "phase": "draft",
1662 "phase": "draft",
1663 "row": 3,
1663 "row": 3,
1664 "tags": [],
1664 "tags": [],
1665 "user": "test"
1665 "user": "test"
1666 },
1666 },
1667 {
1667 {
1668 "bookmarks": [],
1668 "bookmarks": [],
1669 "branch": "default",
1669 "branch": "default",
1670 "col": 0,
1670 "col": 0,
1671 "color": 1,
1671 "color": 1,
1672 "date": [
1672 "date": [
1673 0.0,
1673 0.0,
1674 0
1674 0
1675 ],
1675 ],
1676 "desc": "another commit to da/foo",
1676 "desc": "another commit to da/foo",
1677 "edges": [
1677 "edges": [
1678 {
1678 {
1679 "bcolor": "",
1679 "bcolor": "",
1680 "col": 0,
1680 "col": 0,
1681 "color": 1,
1681 "color": 1,
1682 "nextcol": 0,
1682 "nextcol": 0,
1683 "width": -1
1683 "width": -1
1684 },
1684 },
1685 {
1685 {
1686 "bcolor": "",
1686 "bcolor": "",
1687 "col": 1,
1687 "col": 1,
1688 "color": 2,
1688 "color": 2,
1689 "nextcol": 1,
1689 "nextcol": 1,
1690 "width": -1
1690 "width": -1
1691 }
1691 }
1692 ],
1692 ],
1693 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
1693 "node": "f2890a05fea49bfaf9fb27ed5490894eba32da78",
1694 "parents": [
1694 "parents": [
1695 "93a8ce14f89156426b7fa981af8042da53f03aa0"
1695 "93a8ce14f89156426b7fa981af8042da53f03aa0"
1696 ],
1696 ],
1697 "phase": "draft",
1697 "phase": "draft",
1698 "row": 4,
1698 "row": 4,
1699 "tags": [
1699 "tags": [
1700 "tag2"
1700 "tag2"
1701 ],
1701 ],
1702 "user": "test"
1702 "user": "test"
1703 },
1703 },
1704 {
1704 {
1705 "bookmarks": [],
1705 "bookmarks": [],
1706 "branch": "default",
1706 "branch": "default",
1707 "col": 0,
1707 "col": 0,
1708 "color": 1,
1708 "color": 1,
1709 "date": [
1709 "date": [
1710 0.0,
1710 0.0,
1711 0
1711 0
1712 ],
1712 ],
1713 "desc": "create tag",
1713 "desc": "create tag",
1714 "edges": [
1714 "edges": [
1715 {
1715 {
1716 "bcolor": "",
1716 "bcolor": "",
1717 "col": 0,
1717 "col": 0,
1718 "color": 1,
1718 "color": 1,
1719 "nextcol": 0,
1719 "nextcol": 0,
1720 "width": -1
1720 "width": -1
1721 },
1721 },
1722 {
1722 {
1723 "bcolor": "",
1723 "bcolor": "",
1724 "col": 1,
1724 "col": 1,
1725 "color": 2,
1725 "color": 2,
1726 "nextcol": 1,
1726 "nextcol": 1,
1727 "width": -1
1727 "width": -1
1728 }
1728 }
1729 ],
1729 ],
1730 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
1730 "node": "93a8ce14f89156426b7fa981af8042da53f03aa0",
1731 "parents": [
1731 "parents": [
1732 "78896eb0e102174ce9278438a95e12543e4367a7"
1732 "78896eb0e102174ce9278438a95e12543e4367a7"
1733 ],
1733 ],
1734 "phase": "public",
1734 "phase": "public",
1735 "row": 5,
1735 "row": 5,
1736 "tags": [],
1736 "tags": [],
1737 "user": "test"
1737 "user": "test"
1738 },
1738 },
1739 {
1739 {
1740 "bookmarks": [],
1740 "bookmarks": [],
1741 "branch": "default",
1741 "branch": "default",
1742 "col": 0,
1742 "col": 0,
1743 "color": 1,
1743 "color": 1,
1744 "date": [
1744 "date": [
1745 0.0,
1745 0.0,
1746 0
1746 0
1747 ],
1747 ],
1748 "desc": "move foo",
1748 "desc": "move foo",
1749 "edges": [
1749 "edges": [
1750 {
1750 {
1751 "bcolor": "",
1751 "bcolor": "",
1752 "col": 0,
1752 "col": 0,
1753 "color": 1,
1753 "color": 1,
1754 "nextcol": 0,
1754 "nextcol": 0,
1755 "width": -1
1755 "width": -1
1756 },
1756 },
1757 {
1757 {
1758 "bcolor": "",
1758 "bcolor": "",
1759 "col": 1,
1759 "col": 1,
1760 "color": 2,
1760 "color": 2,
1761 "nextcol": 1,
1761 "nextcol": 1,
1762 "width": -1
1762 "width": -1
1763 }
1763 }
1764 ],
1764 ],
1765 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
1765 "node": "78896eb0e102174ce9278438a95e12543e4367a7",
1766 "parents": [
1766 "parents": [
1767 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
1767 "8d7c456572acf3557e8ed8a07286b10c408bcec5"
1768 ],
1768 ],
1769 "phase": "public",
1769 "phase": "public",
1770 "row": 6,
1770 "row": 6,
1771 "tags": [
1771 "tags": [
1772 "tag1"
1772 "tag1"
1773 ],
1773 ],
1774 "user": "test"
1774 "user": "test"
1775 },
1775 },
1776 {
1776 {
1777 "bookmarks": [
1777 "bookmarks": [
1778 "bookmark1"
1778 "bookmark1"
1779 ],
1779 ],
1780 "branch": "default",
1780 "branch": "default",
1781 "col": 0,
1781 "col": 0,
1782 "color": 1,
1782 "color": 1,
1783 "date": [
1783 "date": [
1784 0.0,
1784 0.0,
1785 0
1785 0
1786 ],
1786 ],
1787 "desc": "modify da/foo",
1787 "desc": "modify da/foo",
1788 "edges": [
1788 "edges": [
1789 {
1789 {
1790 "bcolor": "",
1790 "bcolor": "",
1791 "col": 0,
1791 "col": 0,
1792 "color": 1,
1792 "color": 1,
1793 "nextcol": 0,
1793 "nextcol": 0,
1794 "width": -1
1794 "width": -1
1795 },
1795 },
1796 {
1796 {
1797 "bcolor": "",
1797 "bcolor": "",
1798 "col": 1,
1798 "col": 1,
1799 "color": 2,
1799 "color": 2,
1800 "nextcol": 1,
1800 "nextcol": 1,
1801 "width": -1
1801 "width": -1
1802 }
1802 }
1803 ],
1803 ],
1804 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
1804 "node": "8d7c456572acf3557e8ed8a07286b10c408bcec5",
1805 "parents": [
1805 "parents": [
1806 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
1806 "f8bbb9024b10f93cdbb8d940337398291d40dea8"
1807 ],
1807 ],
1808 "phase": "public",
1808 "phase": "public",
1809 "row": 7,
1809 "row": 7,
1810 "tags": [],
1810 "tags": [],
1811 "user": "test"
1811 "user": "test"
1812 },
1812 },
1813 {
1813 {
1814 "bookmarks": [],
1814 "bookmarks": [],
1815 "branch": "default",
1815 "branch": "default",
1816 "col": 0,
1816 "col": 0,
1817 "color": 1,
1817 "color": 1,
1818 "date": [
1818 "date": [
1819 0.0,
1819 0.0,
1820 0
1820 0
1821 ],
1821 ],
1822 "desc": "modify foo",
1822 "desc": "modify foo",
1823 "edges": [
1823 "edges": [
1824 {
1824 {
1825 "bcolor": "",
1825 "bcolor": "",
1826 "col": 0,
1826 "col": 0,
1827 "color": 1,
1827 "color": 1,
1828 "nextcol": 0,
1828 "nextcol": 0,
1829 "width": -1
1829 "width": -1
1830 },
1830 },
1831 {
1831 {
1832 "bcolor": "",
1832 "bcolor": "",
1833 "col": 1,
1833 "col": 1,
1834 "color": 2,
1834 "color": 2,
1835 "nextcol": 0,
1835 "nextcol": 0,
1836 "width": -1
1836 "width": -1
1837 }
1837 }
1838 ],
1838 ],
1839 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1839 "node": "f8bbb9024b10f93cdbb8d940337398291d40dea8",
1840 "parents": [
1840 "parents": [
1841 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1841 "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e"
1842 ],
1842 ],
1843 "phase": "public",
1843 "phase": "public",
1844 "row": 8,
1844 "row": 8,
1845 "tags": [],
1845 "tags": [],
1846 "user": "test"
1846 "user": "test"
1847 },
1847 },
1848 {
1848 {
1849 "bookmarks": [],
1849 "bookmarks": [],
1850 "branch": "default",
1850 "branch": "default",
1851 "col": 0,
1851 "col": 0,
1852 "color": 2,
1852 "color": 2,
1853 "date": [
1853 "date": [
1854 0.0,
1854 0.0,
1855 0
1855 0
1856 ],
1856 ],
1857 "desc": "initial",
1857 "desc": "initial",
1858 "edges": [],
1858 "edges": [],
1859 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
1859 "node": "06e557f3edf66faa1ccaba5dd8c203c21cc79f1e",
1860 "parents": [],
1860 "parents": [],
1861 "phase": "public",
1861 "phase": "public",
1862 "row": 9,
1862 "row": 9,
1863 "tags": [],
1863 "tags": [],
1864 "user": "test"
1864 "user": "test"
1865 }
1865 }
1866 ],
1866 ],
1867 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7"
1867 "node": "cc725e08502a79dd1eda913760fbe06ed7a9abc7"
1868 }
1868 }
1869
1869
1870 help/ shows help topics
1870 help/ shows help topics
1871
1871
1872 $ request json-help
1872 $ request json-help
1873 200 Script output follows
1873 200 Script output follows
1874
1874
1875 {
1875 {
1876 "earlycommands": [
1876 "earlycommands": [
1877 {
1877 {
1878 "summary": "abort an unfinished operation (EXPERIMENTAL)",
1878 "summary": "abort an unfinished operation (EXPERIMENTAL)",
1879 "topic": "abort"
1879 "topic": "abort"
1880 },
1880 },
1881 {
1881 {
1882 "summary": "add the specified files on the next commit",
1882 "summary": "add the specified files on the next commit",
1883 "topic": "add"
1883 "topic": "add"
1884 },
1884 },
1885 {
1885 {
1886 "summary": "show changeset information by line for each file",
1886 "summary": "show changeset information by line for each file",
1887 "topic": "annotate"
1887 "topic": "annotate"
1888 },
1888 },
1889 {
1889 {
1890 "summary": "make a copy of an existing repository",
1890 "summary": "make a copy of an existing repository",
1891 "topic": "clone"
1891 "topic": "clone"
1892 },
1892 },
1893 {
1893 {
1894 "summary": "commit the specified files or all outstanding changes",
1894 "summary": "commit the specified files or all outstanding changes",
1895 "topic": "commit"
1895 "topic": "commit"
1896 },
1896 },
1897 {
1897 {
1898 "summary": "resumes an interrupted operation (EXPERIMENTAL)",
1898 "summary": "resumes an interrupted operation (EXPERIMENTAL)",
1899 "topic": "continue"
1899 "topic": "continue"
1900 },
1900 },
1901 {
1901 {
1902 "summary": "diff repository (or selected files)",
1902 "summary": "diff repository (or selected files)",
1903 "topic": "diff"
1903 "topic": "diff"
1904 },
1904 },
1905 {
1905 {
1906 "summary": "dump the header and diffs for one or more changesets",
1906 "summary": "dump the header and diffs for one or more changesets",
1907 "topic": "export"
1907 "topic": "export"
1908 },
1908 },
1909 {
1909 {
1910 "summary": "forget the specified files on the next commit",
1910 "summary": "forget the specified files on the next commit",
1911 "topic": "forget"
1911 "topic": "forget"
1912 },
1912 },
1913 {
1913 {
1914 "summary": "create a new repository in the given directory",
1914 "summary": "create a new repository in the given directory",
1915 "topic": "init"
1915 "topic": "init"
1916 },
1916 },
1917 {
1917 {
1918 "summary": "show revision history of entire repository or files",
1918 "summary": "show revision history of entire repository or files",
1919 "topic": "log"
1919 "topic": "log"
1920 },
1920 },
1921 {
1921 {
1922 "summary": "merge another revision into working directory",
1922 "summary": "merge another revision into working directory",
1923 "topic": "merge"
1923 "topic": "merge"
1924 },
1924 },
1925 {
1925 {
1926 "summary": "pull changes from the specified source",
1926 "summary": "pull changes from the specified source",
1927 "topic": "pull"
1927 "topic": "pull"
1928 },
1928 },
1929 {
1929 {
1930 "summary": "push changes to the specified destination",
1930 "summary": "push changes to the specified destination",
1931 "topic": "push"
1931 "topic": "push"
1932 },
1932 },
1933 {
1933 {
1934 "summary": "remove the specified files on the next commit",
1934 "summary": "remove the specified files on the next commit",
1935 "topic": "remove"
1935 "topic": "remove"
1936 },
1936 },
1937 {
1937 {
1938 "summary": "start stand-alone webserver",
1938 "summary": "start stand-alone webserver",
1939 "topic": "serve"
1939 "topic": "serve"
1940 },
1940 },
1941 {
1941 {
1942 "summary": "show changed files in the working directory",
1942 "summary": "show changed files in the working directory",
1943 "topic": "status"
1943 "topic": "status"
1944 },
1944 },
1945 {
1945 {
1946 "summary": "summarize working directory state",
1946 "summary": "summarize working directory state",
1947 "topic": "summary"
1947 "topic": "summary"
1948 },
1948 },
1949 {
1949 {
1950 "summary": "update working directory (or switch revisions)",
1950 "summary": "update working directory (or switch revisions)",
1951 "topic": "update"
1951 "topic": "update"
1952 }
1952 }
1953 ],
1953 ],
1954 "othercommands": [
1954 "othercommands": [
1955 {
1955 {
1956 "summary": "add all new files, delete all missing files",
1956 "summary": "add all new files, delete all missing files",
1957 "topic": "addremove"
1957 "topic": "addremove"
1958 },
1958 },
1959 {
1959 {
1960 "summary": "create an unversioned archive of a repository revision",
1960 "summary": "create an unversioned archive of a repository revision",
1961 "topic": "archive"
1961 "topic": "archive"
1962 },
1962 },
1963 {
1963 {
1964 "summary": "reverse effect of earlier changeset",
1964 "summary": "reverse effect of earlier changeset",
1965 "topic": "backout"
1965 "topic": "backout"
1966 },
1966 },
1967 {
1967 {
1968 "summary": "subdivision search of changesets",
1968 "summary": "subdivision search of changesets",
1969 "topic": "bisect"
1969 "topic": "bisect"
1970 },
1970 },
1971 {
1971 {
1972 "summary": "create a new bookmark or list existing bookmarks",
1972 "summary": "create a new bookmark or list existing bookmarks",
1973 "topic": "bookmarks"
1973 "topic": "bookmarks"
1974 },
1974 },
1975 {
1975 {
1976 "summary": "set or show the current branch name",
1976 "summary": "set or show the current branch name",
1977 "topic": "branch"
1977 "topic": "branch"
1978 },
1978 },
1979 {
1979 {
1980 "summary": "list repository named branches",
1980 "summary": "list repository named branches",
1981 "topic": "branches"
1981 "topic": "branches"
1982 },
1982 },
1983 {
1983 {
1984 "summary": "create a bundle file",
1984 "summary": "create a bundle file",
1985 "topic": "bundle"
1985 "topic": "bundle"
1986 },
1986 },
1987 {
1987 {
1988 "summary": "output the current or given revision of files",
1988 "summary": "output the current or given revision of files",
1989 "topic": "cat"
1989 "topic": "cat"
1990 },
1990 },
1991 {
1991 {
1992 "summary": "show combined config settings from all hgrc files",
1992 "summary": "show combined config settings from all hgrc files",
1993 "topic": "config"
1993 "topic": "config"
1994 },
1994 },
1995 {
1995 {
1996 "summary": "mark files as copied for the next commit",
1996 "summary": "mark files as copied for the next commit",
1997 "topic": "copy"
1997 "topic": "copy"
1998 },
1998 },
1999 {
1999 {
2000 "summary": "list tracked files",
2000 "summary": "list tracked files",
2001 "topic": "files"
2001 "topic": "files"
2002 },
2002 },
2003 {
2003 {
2004 "summary": "copy changes from other branches onto the current branch",
2004 "summary": "copy changes from other branches onto the current branch",
2005 "topic": "graft"
2005 "topic": "graft"
2006 },
2006 },
2007 {
2007 {
2008 "summary": "search revision history for a pattern in specified files",
2008 "summary": "search for a pattern in specified files",
2009 "topic": "grep"
2009 "topic": "grep"
2010 },
2010 },
2011 {
2011 {
2012 "summary": "show branch heads",
2012 "summary": "show branch heads",
2013 "topic": "heads"
2013 "topic": "heads"
2014 },
2014 },
2015 {
2015 {
2016 "summary": "show help for a given topic or a help overview",
2016 "summary": "show help for a given topic or a help overview",
2017 "topic": "help"
2017 "topic": "help"
2018 },
2018 },
2019 {
2019 {
2020 "summary": "identify the working directory or specified revision",
2020 "summary": "identify the working directory or specified revision",
2021 "topic": "identify"
2021 "topic": "identify"
2022 },
2022 },
2023 {
2023 {
2024 "summary": "import an ordered set of patches",
2024 "summary": "import an ordered set of patches",
2025 "topic": "import"
2025 "topic": "import"
2026 },
2026 },
2027 {
2027 {
2028 "summary": "show new changesets found in source",
2028 "summary": "show new changesets found in source",
2029 "topic": "incoming"
2029 "topic": "incoming"
2030 },
2030 },
2031 {
2031 {
2032 "summary": "output the current or given revision of the project manifest",
2032 "summary": "output the current or given revision of the project manifest",
2033 "topic": "manifest"
2033 "topic": "manifest"
2034 },
2034 },
2035 {
2035 {
2036 "summary": "show changesets not found in the destination",
2036 "summary": "show changesets not found in the destination",
2037 "topic": "outgoing"
2037 "topic": "outgoing"
2038 },
2038 },
2039 {
2039 {
2040 "summary": "show aliases for remote repositories",
2040 "summary": "show aliases for remote repositories",
2041 "topic": "paths"
2041 "topic": "paths"
2042 },
2042 },
2043 {
2043 {
2044 "summary": "set or show the current phase name",
2044 "summary": "set or show the current phase name",
2045 "topic": "phase"
2045 "topic": "phase"
2046 },
2046 },
2047 {
2047 {
2048 "summary": "roll back an interrupted transaction",
2048 "summary": "roll back an interrupted transaction",
2049 "topic": "recover"
2049 "topic": "recover"
2050 },
2050 },
2051 {
2051 {
2052 "summary": "rename files; equivalent of copy + remove",
2052 "summary": "rename files; equivalent of copy + remove",
2053 "topic": "rename"
2053 "topic": "rename"
2054 },
2054 },
2055 {
2055 {
2056 "summary": "redo merges or set/view the merge status of files",
2056 "summary": "redo merges or set/view the merge status of files",
2057 "topic": "resolve"
2057 "topic": "resolve"
2058 },
2058 },
2059 {
2059 {
2060 "summary": "restore files to their checkout state",
2060 "summary": "restore files to their checkout state",
2061 "topic": "revert"
2061 "topic": "revert"
2062 },
2062 },
2063 {
2063 {
2064 "summary": "print the root (top) of the current working directory",
2064 "summary": "print the root (top) of the current working directory",
2065 "topic": "root"
2065 "topic": "root"
2066 },
2066 },
2067 {
2067 {
2068 "summary": "save and set aside changes from the working directory",
2068 "summary": "save and set aside changes from the working directory",
2069 "topic": "shelve"
2069 "topic": "shelve"
2070 },
2070 },
2071 {
2071 {
2072 "summary": "add one or more tags for the current or given revision",
2072 "summary": "add one or more tags for the current or given revision",
2073 "topic": "tag"
2073 "topic": "tag"
2074 },
2074 },
2075 {
2075 {
2076 "summary": "list repository tags",
2076 "summary": "list repository tags",
2077 "topic": "tags"
2077 "topic": "tags"
2078 },
2078 },
2079 {
2079 {
2080 "summary": "apply one or more bundle files",
2080 "summary": "apply one or more bundle files",
2081 "topic": "unbundle"
2081 "topic": "unbundle"
2082 },
2082 },
2083 {
2083 {
2084 "summary": "restore a shelved change to the working directory",
2084 "summary": "restore a shelved change to the working directory",
2085 "topic": "unshelve"
2085 "topic": "unshelve"
2086 },
2086 },
2087 {
2087 {
2088 "summary": "verify the integrity of the repository",
2088 "summary": "verify the integrity of the repository",
2089 "topic": "verify"
2089 "topic": "verify"
2090 },
2090 },
2091 {
2091 {
2092 "summary": "output version and copyright information",
2092 "summary": "output version and copyright information",
2093 "topic": "version"
2093 "topic": "version"
2094 }
2094 }
2095 ],
2095 ],
2096 "topics": [
2096 "topics": [
2097 {
2097 {
2098 "summary": "Bundle File Formats",
2098 "summary": "Bundle File Formats",
2099 "topic": "bundlespec"
2099 "topic": "bundlespec"
2100 },
2100 },
2101 {
2101 {
2102 "summary": "Colorizing Outputs",
2102 "summary": "Colorizing Outputs",
2103 "topic": "color"
2103 "topic": "color"
2104 },
2104 },
2105 {
2105 {
2106 "summary": "Configuration Files",
2106 "summary": "Configuration Files",
2107 "topic": "config"
2107 "topic": "config"
2108 },
2108 },
2109 {
2109 {
2110 "summary": "Date Formats",
2110 "summary": "Date Formats",
2111 "topic": "dates"
2111 "topic": "dates"
2112 },
2112 },
2113 {
2113 {
2114 "summary": "Deprecated Features",
2114 "summary": "Deprecated Features",
2115 "topic": "deprecated"
2115 "topic": "deprecated"
2116 },
2116 },
2117 {
2117 {
2118 "summary": "Diff Formats",
2118 "summary": "Diff Formats",
2119 "topic": "diffs"
2119 "topic": "diffs"
2120 },
2120 },
2121 {
2121 {
2122 "summary": "Environment Variables",
2122 "summary": "Environment Variables",
2123 "topic": "environment"
2123 "topic": "environment"
2124 },
2124 },
2125 {
2125 {
2126 "summary": "Using Additional Features",
2126 "summary": "Using Additional Features",
2127 "topic": "extensions"
2127 "topic": "extensions"
2128 },
2128 },
2129 {
2129 {
2130 "summary": "Specifying File Sets",
2130 "summary": "Specifying File Sets",
2131 "topic": "filesets"
2131 "topic": "filesets"
2132 },
2132 },
2133 {
2133 {
2134 "summary": "Command-line flags",
2134 "summary": "Command-line flags",
2135 "topic": "flags"
2135 "topic": "flags"
2136 },
2136 },
2137 {
2137 {
2138 "summary": "Glossary",
2138 "summary": "Glossary",
2139 "topic": "glossary"
2139 "topic": "glossary"
2140 },
2140 },
2141 {
2141 {
2142 "summary": "Syntax for Mercurial Ignore Files",
2142 "summary": "Syntax for Mercurial Ignore Files",
2143 "topic": "hgignore"
2143 "topic": "hgignore"
2144 },
2144 },
2145 {
2145 {
2146 "summary": "Configuring hgweb",
2146 "summary": "Configuring hgweb",
2147 "topic": "hgweb"
2147 "topic": "hgweb"
2148 },
2148 },
2149 {
2149 {
2150 "summary": "Technical implementation topics",
2150 "summary": "Technical implementation topics",
2151 "topic": "internals"
2151 "topic": "internals"
2152 },
2152 },
2153 {
2153 {
2154 "summary": "Merge Tools",
2154 "summary": "Merge Tools",
2155 "topic": "merge-tools"
2155 "topic": "merge-tools"
2156 },
2156 },
2157 {
2157 {
2158 "summary": "Pager Support",
2158 "summary": "Pager Support",
2159 "topic": "pager"
2159 "topic": "pager"
2160 },
2160 },
2161 {
2161 {
2162 "summary": "File Name Patterns",
2162 "summary": "File Name Patterns",
2163 "topic": "patterns"
2163 "topic": "patterns"
2164 },
2164 },
2165 {
2165 {
2166 "summary": "Working with Phases",
2166 "summary": "Working with Phases",
2167 "topic": "phases"
2167 "topic": "phases"
2168 },
2168 },
2169 {
2169 {
2170 "summary": "Specifying Revisions",
2170 "summary": "Specifying Revisions",
2171 "topic": "revisions"
2171 "topic": "revisions"
2172 },
2172 },
2173 {
2173 {
2174 "summary": "Using Mercurial from scripts and automation",
2174 "summary": "Using Mercurial from scripts and automation",
2175 "topic": "scripting"
2175 "topic": "scripting"
2176 },
2176 },
2177 {
2177 {
2178 "summary": "Subrepositories",
2178 "summary": "Subrepositories",
2179 "topic": "subrepos"
2179 "topic": "subrepos"
2180 },
2180 },
2181 {
2181 {
2182 "summary": "Template Usage",
2182 "summary": "Template Usage",
2183 "topic": "templating"
2183 "topic": "templating"
2184 },
2184 },
2185 {
2185 {
2186 "summary": "URL Paths",
2186 "summary": "URL Paths",
2187 "topic": "urls"
2187 "topic": "urls"
2188 }
2188 }
2189 ]
2189 ]
2190 }
2190 }
2191
2191
2192 help/{topic} shows an individual help topic
2192 help/{topic} shows an individual help topic
2193
2193
2194 $ request json-help/phases
2194 $ request json-help/phases
2195 200 Script output follows
2195 200 Script output follows
2196
2196
2197 {
2197 {
2198 "rawdoc": "Working with Phases\n*", (glob)
2198 "rawdoc": "Working with Phases\n*", (glob)
2199 "topic": "phases"
2199 "topic": "phases"
2200 }
2200 }
2201
2201
2202 Error page shouldn't crash
2202 Error page shouldn't crash
2203
2203
2204 $ request json-changeset/deadbeef
2204 $ request json-changeset/deadbeef
2205 404 Not Found
2205 404 Not Found
2206
2206
2207 {
2207 {
2208 "error": "unknown revision 'deadbeef'"
2208 "error": "unknown revision 'deadbeef'"
2209 }
2209 }
2210 [1]
2210 [1]
2211
2211
2212 Commit message with Japanese Kanji 'Noh', which ends with '\x5c'
2212 Commit message with Japanese Kanji 'Noh', which ends with '\x5c'
2213
2213
2214 $ echo foo >> da/foo
2214 $ echo foo >> da/foo
2215 >>> open('msg', 'wb').write(b'\x94\x5c\x0a') and None
2215 >>> open('msg', 'wb').write(b'\x94\x5c\x0a') and None
2216 $ HGENCODING=cp932 hg ci -l msg
2216 $ HGENCODING=cp932 hg ci -l msg
2217
2217
2218 Commit message with null character
2218 Commit message with null character
2219
2219
2220 $ echo foo >> da/foo
2220 $ echo foo >> da/foo
2221 >>> open('msg', 'wb').write(b'commit with null character: \0\n') and None
2221 >>> open('msg', 'wb').write(b'commit with null character: \0\n') and None
2222 $ hg ci -l msg
2222 $ hg ci -l msg
2223 $ rm msg
2223 $ rm msg
2224
2224
2225 Stop and restart with HGENCODING=cp932
2225 Stop and restart with HGENCODING=cp932
2226
2226
2227 $ killdaemons.py
2227 $ killdaemons.py
2228 $ HGENCODING=cp932 hg serve -p $HGPORT -d --pid-file=hg.pid \
2228 $ HGENCODING=cp932 hg serve -p $HGPORT -d --pid-file=hg.pid \
2229 > -A access.log -E error.log
2229 > -A access.log -E error.log
2230 $ cat hg.pid >> $DAEMON_PIDS
2230 $ cat hg.pid >> $DAEMON_PIDS
2231
2231
2232 Test json escape of multibyte characters
2232 Test json escape of multibyte characters
2233
2233
2234 $ request json-filelog/tip/da/foo?revcount=2 | grep '"desc":'
2234 $ request json-filelog/tip/da/foo?revcount=2 | grep '"desc":'
2235 "desc": "commit with null character: \u0000",
2235 "desc": "commit with null character: \u0000",
2236 "desc": "\u80fd",
2236 "desc": "\u80fd",
General Comments 0
You need to be logged in to leave comments. Login now