##// END OF EJS Templates
continue: added logic for hg continue...
Taapas Agrawal -
r42831:3c16b9c0 default
parent child Browse files
Show More
@@ -1,6415 +1,6441 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 . import (
25 from . import (
26 archival,
26 archival,
27 bookmarks,
27 bookmarks,
28 bundle2,
28 bundle2,
29 changegroup,
29 changegroup,
30 cmdutil,
30 cmdutil,
31 copies,
31 copies,
32 debugcommands as debugcommandsmod,
32 debugcommands as debugcommandsmod,
33 destutil,
33 destutil,
34 dirstateguard,
34 dirstateguard,
35 discovery,
35 discovery,
36 encoding,
36 encoding,
37 error,
37 error,
38 exchange,
38 exchange,
39 extensions,
39 extensions,
40 filemerge,
40 filemerge,
41 formatter,
41 formatter,
42 graphmod,
42 graphmod,
43 hbisect,
43 hbisect,
44 help,
44 help,
45 hg,
45 hg,
46 logcmdutil,
46 logcmdutil,
47 merge as mergemod,
47 merge as mergemod,
48 narrowspec,
48 narrowspec,
49 obsolete,
49 obsolete,
50 obsutil,
50 obsutil,
51 patch,
51 patch,
52 phases,
52 phases,
53 pycompat,
53 pycompat,
54 rcutil,
54 rcutil,
55 registrar,
55 registrar,
56 revsetlang,
56 revsetlang,
57 rewriteutil,
57 rewriteutil,
58 scmutil,
58 scmutil,
59 server,
59 server,
60 shelve as shelvemod,
60 shelve as shelvemod,
61 state as statemod,
61 state as statemod,
62 streamclone,
62 streamclone,
63 tags as tagsmod,
63 tags as tagsmod,
64 ui as uimod,
64 ui as uimod,
65 util,
65 util,
66 verify as verifymod,
66 verify as verifymod,
67 wireprotoserver,
67 wireprotoserver,
68 )
68 )
69 from .utils import (
69 from .utils import (
70 dateutil,
70 dateutil,
71 stringutil,
71 stringutil,
72 )
72 )
73
73
74 table = {}
74 table = {}
75 table.update(debugcommandsmod.command._table)
75 table.update(debugcommandsmod.command._table)
76
76
77 command = registrar.command(table)
77 command = registrar.command(table)
78 INTENT_READONLY = registrar.INTENT_READONLY
78 INTENT_READONLY = registrar.INTENT_READONLY
79
79
80 # common command options
80 # common command options
81
81
82 globalopts = [
82 globalopts = [
83 ('R', 'repository', '',
83 ('R', 'repository', '',
84 _('repository root directory or name of overlay bundle file'),
84 _('repository root directory or name of overlay bundle file'),
85 _('REPO')),
85 _('REPO')),
86 ('', 'cwd', '',
86 ('', 'cwd', '',
87 _('change working directory'), _('DIR')),
87 _('change working directory'), _('DIR')),
88 ('y', 'noninteractive', None,
88 ('y', 'noninteractive', None,
89 _('do not prompt, automatically pick the first choice for all prompts')),
89 _('do not prompt, automatically pick the first choice for all prompts')),
90 ('q', 'quiet', None, _('suppress output')),
90 ('q', 'quiet', None, _('suppress output')),
91 ('v', 'verbose', None, _('enable additional output')),
91 ('v', 'verbose', None, _('enable additional output')),
92 ('', 'color', '',
92 ('', 'color', '',
93 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
93 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
94 # and should not be translated
94 # and should not be translated
95 _("when to colorize (boolean, always, auto, never, or debug)"),
95 _("when to colorize (boolean, always, auto, never, or debug)"),
96 _('TYPE')),
96 _('TYPE')),
97 ('', 'config', [],
97 ('', 'config', [],
98 _('set/override config option (use \'section.name=value\')'),
98 _('set/override config option (use \'section.name=value\')'),
99 _('CONFIG')),
99 _('CONFIG')),
100 ('', 'debug', None, _('enable debugging output')),
100 ('', 'debug', None, _('enable debugging output')),
101 ('', 'debugger', None, _('start debugger')),
101 ('', 'debugger', None, _('start debugger')),
102 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
102 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
103 _('ENCODE')),
103 _('ENCODE')),
104 ('', 'encodingmode', encoding.encodingmode,
104 ('', 'encodingmode', encoding.encodingmode,
105 _('set the charset encoding mode'), _('MODE')),
105 _('set the charset encoding mode'), _('MODE')),
106 ('', 'traceback', None, _('always print a traceback on exception')),
106 ('', 'traceback', None, _('always print a traceback on exception')),
107 ('', 'time', None, _('time how long the command takes')),
107 ('', 'time', None, _('time how long the command takes')),
108 ('', 'profile', None, _('print command execution profile')),
108 ('', 'profile', None, _('print command execution profile')),
109 ('', 'version', None, _('output version information and exit')),
109 ('', 'version', None, _('output version information and exit')),
110 ('h', 'help', None, _('display help and exit')),
110 ('h', 'help', None, _('display help and exit')),
111 ('', 'hidden', False, _('consider hidden changesets')),
111 ('', 'hidden', False, _('consider hidden changesets')),
112 ('', 'pager', 'auto',
112 ('', 'pager', 'auto',
113 _("when to paginate (boolean, always, auto, or never)"), _('TYPE')),
113 _("when to paginate (boolean, always, auto, or never)"), _('TYPE')),
114 ]
114 ]
115
115
116 dryrunopts = cmdutil.dryrunopts
116 dryrunopts = cmdutil.dryrunopts
117 remoteopts = cmdutil.remoteopts
117 remoteopts = cmdutil.remoteopts
118 walkopts = cmdutil.walkopts
118 walkopts = cmdutil.walkopts
119 commitopts = cmdutil.commitopts
119 commitopts = cmdutil.commitopts
120 commitopts2 = cmdutil.commitopts2
120 commitopts2 = cmdutil.commitopts2
121 formatteropts = cmdutil.formatteropts
121 formatteropts = cmdutil.formatteropts
122 templateopts = cmdutil.templateopts
122 templateopts = cmdutil.templateopts
123 logopts = cmdutil.logopts
123 logopts = cmdutil.logopts
124 diffopts = cmdutil.diffopts
124 diffopts = cmdutil.diffopts
125 diffwsopts = cmdutil.diffwsopts
125 diffwsopts = cmdutil.diffwsopts
126 diffopts2 = cmdutil.diffopts2
126 diffopts2 = cmdutil.diffopts2
127 mergetoolopts = cmdutil.mergetoolopts
127 mergetoolopts = cmdutil.mergetoolopts
128 similarityopts = cmdutil.similarityopts
128 similarityopts = cmdutil.similarityopts
129 subrepoopts = cmdutil.subrepoopts
129 subrepoopts = cmdutil.subrepoopts
130 debugrevlogopts = cmdutil.debugrevlogopts
130 debugrevlogopts = cmdutil.debugrevlogopts
131
131
132 # Commands start here, listed alphabetically
132 # Commands start here, listed alphabetically
133
133
134 @command('abort',
134 @command('abort',
135 dryrunopts, helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
135 dryrunopts, helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
136 helpbasic=True)
136 helpbasic=True)
137 def abort(ui, repo, **opts):
137 def abort(ui, repo, **opts):
138 """abort an unfinished operation (EXPERIMENTAL)
138 """abort an unfinished operation (EXPERIMENTAL)
139
139
140 Aborts a multistep operation like graft, histedit, rebase, merge,
140 Aborts a multistep operation like graft, histedit, rebase, merge,
141 and unshelve if they are in an unfinished state.
141 and unshelve if they are in an unfinished state.
142
142
143 use --dry-run/-n to dry run the command.
143 use --dry-run/-n to dry run the command.
144 A new operation can be added to this by registering the operation and
144 A new operation can be added to this by registering the operation and
145 abort logic in the unfinishedstates list under statemod.
145 abort logic in the unfinishedstates list under statemod.
146 """
146 """
147 dryrun = opts.get(r'dry_run')
147 dryrun = opts.get(r'dry_run')
148 abortstate = cmdutil.getunfinishedstate(repo)
148 abortstate = cmdutil.getunfinishedstate(repo)
149 if not abortstate:
149 if not abortstate:
150 raise error.Abort(_('no operation in progress'))
150 raise error.Abort(_('no operation in progress'))
151 if not abortstate.abortfunc:
151 if not abortstate.abortfunc:
152 raise error.Abort((_("%s in progress but does not support 'hg abort'") %
152 raise error.Abort((_("%s in progress but does not support 'hg abort'") %
153 (abortstate._opname)), hint=abortstate.hint())
153 (abortstate._opname)), hint=abortstate.hint())
154 if dryrun:
154 if dryrun:
155 ui.status(_('%s in progress, will be aborted\n') % (abortstate._opname))
155 ui.status(_('%s in progress, will be aborted\n') % (abortstate._opname))
156 return
156 return
157 return abortstate.abortfunc(ui, repo)
157 return abortstate.abortfunc(ui, repo)
158
158
159 @command('add',
159 @command('add',
160 walkopts + subrepoopts + dryrunopts,
160 walkopts + subrepoopts + dryrunopts,
161 _('[OPTION]... [FILE]...'),
161 _('[OPTION]... [FILE]...'),
162 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
162 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
163 helpbasic=True, inferrepo=True)
163 helpbasic=True, inferrepo=True)
164 def add(ui, repo, *pats, **opts):
164 def add(ui, repo, *pats, **opts):
165 """add the specified files on the next commit
165 """add the specified files on the next commit
166
166
167 Schedule files to be version controlled and added to the
167 Schedule files to be version controlled and added to the
168 repository.
168 repository.
169
169
170 The files will be added to the repository at the next commit. To
170 The files will be added to the repository at the next commit. To
171 undo an add before that, see :hg:`forget`.
171 undo an add before that, see :hg:`forget`.
172
172
173 If no names are given, add all files to the repository (except
173 If no names are given, add all files to the repository (except
174 files matching ``.hgignore``).
174 files matching ``.hgignore``).
175
175
176 .. container:: verbose
176 .. container:: verbose
177
177
178 Examples:
178 Examples:
179
179
180 - New (unknown) files are added
180 - New (unknown) files are added
181 automatically by :hg:`add`::
181 automatically by :hg:`add`::
182
182
183 $ ls
183 $ ls
184 foo.c
184 foo.c
185 $ hg status
185 $ hg status
186 ? foo.c
186 ? foo.c
187 $ hg add
187 $ hg add
188 adding foo.c
188 adding foo.c
189 $ hg status
189 $ hg status
190 A foo.c
190 A foo.c
191
191
192 - Specific files to be added can be specified::
192 - Specific files to be added can be specified::
193
193
194 $ ls
194 $ ls
195 bar.c foo.c
195 bar.c foo.c
196 $ hg status
196 $ hg status
197 ? bar.c
197 ? bar.c
198 ? foo.c
198 ? foo.c
199 $ hg add bar.c
199 $ hg add bar.c
200 $ hg status
200 $ hg status
201 A bar.c
201 A bar.c
202 ? foo.c
202 ? foo.c
203
203
204 Returns 0 if all files are successfully added.
204 Returns 0 if all files are successfully added.
205 """
205 """
206
206
207 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
207 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
208 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
208 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
209 rejected = cmdutil.add(ui, repo, m, "", uipathfn, False, **opts)
209 rejected = cmdutil.add(ui, repo, m, "", uipathfn, False, **opts)
210 return rejected and 1 or 0
210 return rejected and 1 or 0
211
211
212 @command('addremove',
212 @command('addremove',
213 similarityopts + subrepoopts + walkopts + dryrunopts,
213 similarityopts + subrepoopts + walkopts + dryrunopts,
214 _('[OPTION]... [FILE]...'),
214 _('[OPTION]... [FILE]...'),
215 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
215 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
216 inferrepo=True)
216 inferrepo=True)
217 def addremove(ui, repo, *pats, **opts):
217 def addremove(ui, repo, *pats, **opts):
218 """add all new files, delete all missing files
218 """add all new files, delete all missing files
219
219
220 Add all new files and remove all missing files from the
220 Add all new files and remove all missing files from the
221 repository.
221 repository.
222
222
223 Unless names are given, new files are ignored if they match any of
223 Unless names are given, new files are ignored if they match any of
224 the patterns in ``.hgignore``. As with add, these changes take
224 the patterns in ``.hgignore``. As with add, these changes take
225 effect at the next commit.
225 effect at the next commit.
226
226
227 Use the -s/--similarity option to detect renamed files. This
227 Use the -s/--similarity option to detect renamed files. This
228 option takes a percentage between 0 (disabled) and 100 (files must
228 option takes a percentage between 0 (disabled) and 100 (files must
229 be identical) as its parameter. With a parameter greater than 0,
229 be identical) as its parameter. With a parameter greater than 0,
230 this compares every removed file with every added file and records
230 this compares every removed file with every added file and records
231 those similar enough as renames. Detecting renamed files this way
231 those similar enough as renames. Detecting renamed files this way
232 can be expensive. After using this option, :hg:`status -C` can be
232 can be expensive. After using this option, :hg:`status -C` can be
233 used to check which files were identified as moved or renamed. If
233 used to check which files were identified as moved or renamed. If
234 not specified, -s/--similarity defaults to 100 and only renames of
234 not specified, -s/--similarity defaults to 100 and only renames of
235 identical files are detected.
235 identical files are detected.
236
236
237 .. container:: verbose
237 .. container:: verbose
238
238
239 Examples:
239 Examples:
240
240
241 - A number of files (bar.c and foo.c) are new,
241 - A number of files (bar.c and foo.c) are new,
242 while foobar.c has been removed (without using :hg:`remove`)
242 while foobar.c has been removed (without using :hg:`remove`)
243 from the repository::
243 from the repository::
244
244
245 $ ls
245 $ ls
246 bar.c foo.c
246 bar.c foo.c
247 $ hg status
247 $ hg status
248 ! foobar.c
248 ! foobar.c
249 ? bar.c
249 ? bar.c
250 ? foo.c
250 ? foo.c
251 $ hg addremove
251 $ hg addremove
252 adding bar.c
252 adding bar.c
253 adding foo.c
253 adding foo.c
254 removing foobar.c
254 removing foobar.c
255 $ hg status
255 $ hg status
256 A bar.c
256 A bar.c
257 A foo.c
257 A foo.c
258 R foobar.c
258 R foobar.c
259
259
260 - A file foobar.c was moved to foo.c without using :hg:`rename`.
260 - A file foobar.c was moved to foo.c without using :hg:`rename`.
261 Afterwards, it was edited slightly::
261 Afterwards, it was edited slightly::
262
262
263 $ ls
263 $ ls
264 foo.c
264 foo.c
265 $ hg status
265 $ hg status
266 ! foobar.c
266 ! foobar.c
267 ? foo.c
267 ? foo.c
268 $ hg addremove --similarity 90
268 $ hg addremove --similarity 90
269 removing foobar.c
269 removing foobar.c
270 adding foo.c
270 adding foo.c
271 recording removal of foobar.c as rename to foo.c (94% similar)
271 recording removal of foobar.c as rename to foo.c (94% similar)
272 $ hg status -C
272 $ hg status -C
273 A foo.c
273 A foo.c
274 foobar.c
274 foobar.c
275 R foobar.c
275 R foobar.c
276
276
277 Returns 0 if all files are successfully added.
277 Returns 0 if all files are successfully added.
278 """
278 """
279 opts = pycompat.byteskwargs(opts)
279 opts = pycompat.byteskwargs(opts)
280 if not opts.get('similarity'):
280 if not opts.get('similarity'):
281 opts['similarity'] = '100'
281 opts['similarity'] = '100'
282 matcher = scmutil.match(repo[None], pats, opts)
282 matcher = scmutil.match(repo[None], pats, opts)
283 relative = scmutil.anypats(pats, opts)
283 relative = scmutil.anypats(pats, opts)
284 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
284 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
285 return scmutil.addremove(repo, matcher, "", uipathfn, opts)
285 return scmutil.addremove(repo, matcher, "", uipathfn, opts)
286
286
287 @command('annotate|blame',
287 @command('annotate|blame',
288 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
288 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
289 ('', 'follow', None,
289 ('', 'follow', None,
290 _('follow copies/renames and list the filename (DEPRECATED)')),
290 _('follow copies/renames and list the filename (DEPRECATED)')),
291 ('', 'no-follow', None, _("don't follow copies and renames")),
291 ('', 'no-follow', None, _("don't follow copies and renames")),
292 ('a', 'text', None, _('treat all files as text')),
292 ('a', 'text', None, _('treat all files as text')),
293 ('u', 'user', None, _('list the author (long with -v)')),
293 ('u', 'user', None, _('list the author (long with -v)')),
294 ('f', 'file', None, _('list the filename')),
294 ('f', 'file', None, _('list the filename')),
295 ('d', 'date', None, _('list the date (short with -q)')),
295 ('d', 'date', None, _('list the date (short with -q)')),
296 ('n', 'number', None, _('list the revision number (default)')),
296 ('n', 'number', None, _('list the revision number (default)')),
297 ('c', 'changeset', None, _('list the changeset')),
297 ('c', 'changeset', None, _('list the changeset')),
298 ('l', 'line-number', None, _('show line number at the first appearance')),
298 ('l', 'line-number', None, _('show line number at the first appearance')),
299 ('', 'skip', [], _('revision to not display (EXPERIMENTAL)'), _('REV')),
299 ('', 'skip', [], _('revision to not display (EXPERIMENTAL)'), _('REV')),
300 ] + diffwsopts + walkopts + formatteropts,
300 ] + diffwsopts + walkopts + formatteropts,
301 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
301 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
302 helpcategory=command.CATEGORY_FILE_CONTENTS,
302 helpcategory=command.CATEGORY_FILE_CONTENTS,
303 helpbasic=True, inferrepo=True)
303 helpbasic=True, inferrepo=True)
304 def annotate(ui, repo, *pats, **opts):
304 def annotate(ui, repo, *pats, **opts):
305 """show changeset information by line for each file
305 """show changeset information by line for each file
306
306
307 List changes in files, showing the revision id responsible for
307 List changes in files, showing the revision id responsible for
308 each line.
308 each line.
309
309
310 This command is useful for discovering when a change was made and
310 This command is useful for discovering when a change was made and
311 by whom.
311 by whom.
312
312
313 If you include --file, --user, or --date, the revision number is
313 If you include --file, --user, or --date, the revision number is
314 suppressed unless you also include --number.
314 suppressed unless you also include --number.
315
315
316 Without the -a/--text option, annotate will avoid processing files
316 Without the -a/--text option, annotate will avoid processing files
317 it detects as binary. With -a, annotate will annotate the file
317 it detects as binary. With -a, annotate will annotate the file
318 anyway, although the results will probably be neither useful
318 anyway, although the results will probably be neither useful
319 nor desirable.
319 nor desirable.
320
320
321 .. container:: verbose
321 .. container:: verbose
322
322
323 Template:
323 Template:
324
324
325 The following keywords are supported in addition to the common template
325 The following keywords are supported in addition to the common template
326 keywords and functions. See also :hg:`help templates`.
326 keywords and functions. See also :hg:`help templates`.
327
327
328 :lines: List of lines with annotation data.
328 :lines: List of lines with annotation data.
329 :path: String. Repository-absolute path of the specified file.
329 :path: String. Repository-absolute path of the specified file.
330
330
331 And each entry of ``{lines}`` provides the following sub-keywords in
331 And each entry of ``{lines}`` provides the following sub-keywords in
332 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
332 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
333
333
334 :line: String. Line content.
334 :line: String. Line content.
335 :lineno: Integer. Line number at that revision.
335 :lineno: Integer. Line number at that revision.
336 :path: String. Repository-absolute path of the file at that revision.
336 :path: String. Repository-absolute path of the file at that revision.
337
337
338 See :hg:`help templates.operators` for the list expansion syntax.
338 See :hg:`help templates.operators` for the list expansion syntax.
339
339
340 Returns 0 on success.
340 Returns 0 on success.
341 """
341 """
342 opts = pycompat.byteskwargs(opts)
342 opts = pycompat.byteskwargs(opts)
343 if not pats:
343 if not pats:
344 raise error.Abort(_('at least one filename or pattern is required'))
344 raise error.Abort(_('at least one filename or pattern is required'))
345
345
346 if opts.get('follow'):
346 if opts.get('follow'):
347 # --follow is deprecated and now just an alias for -f/--file
347 # --follow is deprecated and now just an alias for -f/--file
348 # to mimic the behavior of Mercurial before version 1.5
348 # to mimic the behavior of Mercurial before version 1.5
349 opts['file'] = True
349 opts['file'] = True
350
350
351 if (not opts.get('user') and not opts.get('changeset')
351 if (not opts.get('user') and not opts.get('changeset')
352 and not opts.get('date') and not opts.get('file')):
352 and not opts.get('date') and not opts.get('file')):
353 opts['number'] = True
353 opts['number'] = True
354
354
355 linenumber = opts.get('line_number') is not None
355 linenumber = opts.get('line_number') is not None
356 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
356 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
357 raise error.Abort(_('at least one of -n/-c is required for -l'))
357 raise error.Abort(_('at least one of -n/-c is required for -l'))
358
358
359 rev = opts.get('rev')
359 rev = opts.get('rev')
360 if rev:
360 if rev:
361 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
361 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
362 ctx = scmutil.revsingle(repo, rev)
362 ctx = scmutil.revsingle(repo, rev)
363
363
364 ui.pager('annotate')
364 ui.pager('annotate')
365 rootfm = ui.formatter('annotate', opts)
365 rootfm = ui.formatter('annotate', opts)
366 if ui.debugflag:
366 if ui.debugflag:
367 shorthex = pycompat.identity
367 shorthex = pycompat.identity
368 else:
368 else:
369 def shorthex(h):
369 def shorthex(h):
370 return h[:12]
370 return h[:12]
371 if ui.quiet:
371 if ui.quiet:
372 datefunc = dateutil.shortdate
372 datefunc = dateutil.shortdate
373 else:
373 else:
374 datefunc = dateutil.datestr
374 datefunc = dateutil.datestr
375 if ctx.rev() is None:
375 if ctx.rev() is None:
376 if opts.get('changeset'):
376 if opts.get('changeset'):
377 # omit "+" suffix which is appended to node hex
377 # omit "+" suffix which is appended to node hex
378 def formatrev(rev):
378 def formatrev(rev):
379 if rev == wdirrev:
379 if rev == wdirrev:
380 return '%d' % ctx.p1().rev()
380 return '%d' % ctx.p1().rev()
381 else:
381 else:
382 return '%d' % rev
382 return '%d' % rev
383 else:
383 else:
384 def formatrev(rev):
384 def formatrev(rev):
385 if rev == wdirrev:
385 if rev == wdirrev:
386 return '%d+' % ctx.p1().rev()
386 return '%d+' % ctx.p1().rev()
387 else:
387 else:
388 return '%d ' % rev
388 return '%d ' % rev
389 def formathex(h):
389 def formathex(h):
390 if h == wdirhex:
390 if h == wdirhex:
391 return '%s+' % shorthex(hex(ctx.p1().node()))
391 return '%s+' % shorthex(hex(ctx.p1().node()))
392 else:
392 else:
393 return '%s ' % shorthex(h)
393 return '%s ' % shorthex(h)
394 else:
394 else:
395 formatrev = b'%d'.__mod__
395 formatrev = b'%d'.__mod__
396 formathex = shorthex
396 formathex = shorthex
397
397
398 opmap = [
398 opmap = [
399 ('user', ' ', lambda x: x.fctx.user(), ui.shortuser),
399 ('user', ' ', lambda x: x.fctx.user(), ui.shortuser),
400 ('rev', ' ', lambda x: scmutil.intrev(x.fctx), formatrev),
400 ('rev', ' ', lambda x: scmutil.intrev(x.fctx), formatrev),
401 ('node', ' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
401 ('node', ' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
402 ('date', ' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
402 ('date', ' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
403 ('path', ' ', lambda x: x.fctx.path(), pycompat.bytestr),
403 ('path', ' ', lambda x: x.fctx.path(), pycompat.bytestr),
404 ('lineno', ':', lambda x: x.lineno, pycompat.bytestr),
404 ('lineno', ':', lambda x: x.lineno, pycompat.bytestr),
405 ]
405 ]
406 opnamemap = {
406 opnamemap = {
407 'rev': 'number',
407 'rev': 'number',
408 'node': 'changeset',
408 'node': 'changeset',
409 'path': 'file',
409 'path': 'file',
410 'lineno': 'line_number',
410 'lineno': 'line_number',
411 }
411 }
412
412
413 if rootfm.isplain():
413 if rootfm.isplain():
414 def makefunc(get, fmt):
414 def makefunc(get, fmt):
415 return lambda x: fmt(get(x))
415 return lambda x: fmt(get(x))
416 else:
416 else:
417 def makefunc(get, fmt):
417 def makefunc(get, fmt):
418 return get
418 return get
419 datahint = rootfm.datahint()
419 datahint = rootfm.datahint()
420 funcmap = [(makefunc(get, fmt), sep) for fn, sep, get, fmt in opmap
420 funcmap = [(makefunc(get, fmt), sep) for fn, sep, get, fmt in opmap
421 if opts.get(opnamemap.get(fn, fn)) or fn in datahint]
421 if opts.get(opnamemap.get(fn, fn)) or fn in datahint]
422 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
422 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
423 fields = ' '.join(fn for fn, sep, get, fmt in opmap
423 fields = ' '.join(fn for fn, sep, get, fmt in opmap
424 if opts.get(opnamemap.get(fn, fn)) or fn in datahint)
424 if opts.get(opnamemap.get(fn, fn)) or fn in datahint)
425
425
426 def bad(x, y):
426 def bad(x, y):
427 raise error.Abort("%s: %s" % (x, y))
427 raise error.Abort("%s: %s" % (x, y))
428
428
429 m = scmutil.match(ctx, pats, opts, badfn=bad)
429 m = scmutil.match(ctx, pats, opts, badfn=bad)
430
430
431 follow = not opts.get('no_follow')
431 follow = not opts.get('no_follow')
432 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
432 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
433 whitespace=True)
433 whitespace=True)
434 skiprevs = opts.get('skip')
434 skiprevs = opts.get('skip')
435 if skiprevs:
435 if skiprevs:
436 skiprevs = scmutil.revrange(repo, skiprevs)
436 skiprevs = scmutil.revrange(repo, skiprevs)
437
437
438 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
438 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
439 for abs in ctx.walk(m):
439 for abs in ctx.walk(m):
440 fctx = ctx[abs]
440 fctx = ctx[abs]
441 rootfm.startitem()
441 rootfm.startitem()
442 rootfm.data(path=abs)
442 rootfm.data(path=abs)
443 if not opts.get('text') and fctx.isbinary():
443 if not opts.get('text') and fctx.isbinary():
444 rootfm.plain(_("%s: binary file\n") % uipathfn(abs))
444 rootfm.plain(_("%s: binary file\n") % uipathfn(abs))
445 continue
445 continue
446
446
447 fm = rootfm.nested('lines', tmpl='{rev}: {line}')
447 fm = rootfm.nested('lines', tmpl='{rev}: {line}')
448 lines = fctx.annotate(follow=follow, skiprevs=skiprevs,
448 lines = fctx.annotate(follow=follow, skiprevs=skiprevs,
449 diffopts=diffopts)
449 diffopts=diffopts)
450 if not lines:
450 if not lines:
451 fm.end()
451 fm.end()
452 continue
452 continue
453 formats = []
453 formats = []
454 pieces = []
454 pieces = []
455
455
456 for f, sep in funcmap:
456 for f, sep in funcmap:
457 l = [f(n) for n in lines]
457 l = [f(n) for n in lines]
458 if fm.isplain():
458 if fm.isplain():
459 sizes = [encoding.colwidth(x) for x in l]
459 sizes = [encoding.colwidth(x) for x in l]
460 ml = max(sizes)
460 ml = max(sizes)
461 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
461 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
462 else:
462 else:
463 formats.append(['%s' for x in l])
463 formats.append(['%s' for x in l])
464 pieces.append(l)
464 pieces.append(l)
465
465
466 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
466 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
467 fm.startitem()
467 fm.startitem()
468 fm.context(fctx=n.fctx)
468 fm.context(fctx=n.fctx)
469 fm.write(fields, "".join(f), *p)
469 fm.write(fields, "".join(f), *p)
470 if n.skip:
470 if n.skip:
471 fmt = "* %s"
471 fmt = "* %s"
472 else:
472 else:
473 fmt = ": %s"
473 fmt = ": %s"
474 fm.write('line', fmt, n.text)
474 fm.write('line', fmt, n.text)
475
475
476 if not lines[-1].text.endswith('\n'):
476 if not lines[-1].text.endswith('\n'):
477 fm.plain('\n')
477 fm.plain('\n')
478 fm.end()
478 fm.end()
479
479
480 rootfm.end()
480 rootfm.end()
481
481
482 @command('archive',
482 @command('archive',
483 [('', 'no-decode', None, _('do not pass files through decoders')),
483 [('', 'no-decode', None, _('do not pass files through decoders')),
484 ('p', 'prefix', '', _('directory prefix for files in archive'),
484 ('p', 'prefix', '', _('directory prefix for files in archive'),
485 _('PREFIX')),
485 _('PREFIX')),
486 ('r', 'rev', '', _('revision to distribute'), _('REV')),
486 ('r', 'rev', '', _('revision to distribute'), _('REV')),
487 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
487 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
488 ] + subrepoopts + walkopts,
488 ] + subrepoopts + walkopts,
489 _('[OPTION]... DEST'),
489 _('[OPTION]... DEST'),
490 helpcategory=command.CATEGORY_IMPORT_EXPORT)
490 helpcategory=command.CATEGORY_IMPORT_EXPORT)
491 def archive(ui, repo, dest, **opts):
491 def archive(ui, repo, dest, **opts):
492 '''create an unversioned archive of a repository revision
492 '''create an unversioned archive of a repository revision
493
493
494 By default, the revision used is the parent of the working
494 By default, the revision used is the parent of the working
495 directory; use -r/--rev to specify a different revision.
495 directory; use -r/--rev to specify a different revision.
496
496
497 The archive type is automatically detected based on file
497 The archive type is automatically detected based on file
498 extension (to override, use -t/--type).
498 extension (to override, use -t/--type).
499
499
500 .. container:: verbose
500 .. container:: verbose
501
501
502 Examples:
502 Examples:
503
503
504 - create a zip file containing the 1.0 release::
504 - create a zip file containing the 1.0 release::
505
505
506 hg archive -r 1.0 project-1.0.zip
506 hg archive -r 1.0 project-1.0.zip
507
507
508 - create a tarball excluding .hg files::
508 - create a tarball excluding .hg files::
509
509
510 hg archive project.tar.gz -X ".hg*"
510 hg archive project.tar.gz -X ".hg*"
511
511
512 Valid types are:
512 Valid types are:
513
513
514 :``files``: a directory full of files (default)
514 :``files``: a directory full of files (default)
515 :``tar``: tar archive, uncompressed
515 :``tar``: tar archive, uncompressed
516 :``tbz2``: tar archive, compressed using bzip2
516 :``tbz2``: tar archive, compressed using bzip2
517 :``tgz``: tar archive, compressed using gzip
517 :``tgz``: tar archive, compressed using gzip
518 :``uzip``: zip archive, uncompressed
518 :``uzip``: zip archive, uncompressed
519 :``zip``: zip archive, compressed using deflate
519 :``zip``: zip archive, compressed using deflate
520
520
521 The exact name of the destination archive or directory is given
521 The exact name of the destination archive or directory is given
522 using a format string; see :hg:`help export` for details.
522 using a format string; see :hg:`help export` for details.
523
523
524 Each member added to an archive file has a directory prefix
524 Each member added to an archive file has a directory prefix
525 prepended. Use -p/--prefix to specify a format string for the
525 prepended. Use -p/--prefix to specify a format string for the
526 prefix. The default is the basename of the archive, with suffixes
526 prefix. The default is the basename of the archive, with suffixes
527 removed.
527 removed.
528
528
529 Returns 0 on success.
529 Returns 0 on success.
530 '''
530 '''
531
531
532 opts = pycompat.byteskwargs(opts)
532 opts = pycompat.byteskwargs(opts)
533 rev = opts.get('rev')
533 rev = opts.get('rev')
534 if rev:
534 if rev:
535 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
535 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
536 ctx = scmutil.revsingle(repo, rev)
536 ctx = scmutil.revsingle(repo, rev)
537 if not ctx:
537 if not ctx:
538 raise error.Abort(_('no working directory: please specify a revision'))
538 raise error.Abort(_('no working directory: please specify a revision'))
539 node = ctx.node()
539 node = ctx.node()
540 dest = cmdutil.makefilename(ctx, dest)
540 dest = cmdutil.makefilename(ctx, dest)
541 if os.path.realpath(dest) == repo.root:
541 if os.path.realpath(dest) == repo.root:
542 raise error.Abort(_('repository root cannot be destination'))
542 raise error.Abort(_('repository root cannot be destination'))
543
543
544 kind = opts.get('type') or archival.guesskind(dest) or 'files'
544 kind = opts.get('type') or archival.guesskind(dest) or 'files'
545 prefix = opts.get('prefix')
545 prefix = opts.get('prefix')
546
546
547 if dest == '-':
547 if dest == '-':
548 if kind == 'files':
548 if kind == 'files':
549 raise error.Abort(_('cannot archive plain files to stdout'))
549 raise error.Abort(_('cannot archive plain files to stdout'))
550 dest = cmdutil.makefileobj(ctx, dest)
550 dest = cmdutil.makefileobj(ctx, dest)
551 if not prefix:
551 if not prefix:
552 prefix = os.path.basename(repo.root) + '-%h'
552 prefix = os.path.basename(repo.root) + '-%h'
553
553
554 prefix = cmdutil.makefilename(ctx, prefix)
554 prefix = cmdutil.makefilename(ctx, prefix)
555 match = scmutil.match(ctx, [], opts)
555 match = scmutil.match(ctx, [], opts)
556 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
556 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
557 match, prefix, subrepos=opts.get('subrepos'))
557 match, prefix, subrepos=opts.get('subrepos'))
558
558
559 @command('backout',
559 @command('backout',
560 [('', 'merge', None, _('merge with old dirstate parent after backout')),
560 [('', 'merge', None, _('merge with old dirstate parent after backout')),
561 ('', 'commit', None,
561 ('', 'commit', None,
562 _('commit if no conflicts were encountered (DEPRECATED)')),
562 _('commit if no conflicts were encountered (DEPRECATED)')),
563 ('', 'no-commit', None, _('do not commit')),
563 ('', 'no-commit', None, _('do not commit')),
564 ('', 'parent', '',
564 ('', 'parent', '',
565 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
565 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
566 ('r', 'rev', '', _('revision to backout'), _('REV')),
566 ('r', 'rev', '', _('revision to backout'), _('REV')),
567 ('e', 'edit', False, _('invoke editor on commit messages')),
567 ('e', 'edit', False, _('invoke editor on commit messages')),
568 ] + mergetoolopts + walkopts + commitopts + commitopts2,
568 ] + mergetoolopts + walkopts + commitopts + commitopts2,
569 _('[OPTION]... [-r] REV'),
569 _('[OPTION]... [-r] REV'),
570 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
570 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
571 def backout(ui, repo, node=None, rev=None, **opts):
571 def backout(ui, repo, node=None, rev=None, **opts):
572 '''reverse effect of earlier changeset
572 '''reverse effect of earlier changeset
573
573
574 Prepare a new changeset with the effect of REV undone in the
574 Prepare a new changeset with the effect of REV undone in the
575 current working directory. If no conflicts were encountered,
575 current working directory. If no conflicts were encountered,
576 it will be committed immediately.
576 it will be committed immediately.
577
577
578 If REV is the parent of the working directory, then this new changeset
578 If REV is the parent of the working directory, then this new changeset
579 is committed automatically (unless --no-commit is specified).
579 is committed automatically (unless --no-commit is specified).
580
580
581 .. note::
581 .. note::
582
582
583 :hg:`backout` cannot be used to fix either an unwanted or
583 :hg:`backout` cannot be used to fix either an unwanted or
584 incorrect merge.
584 incorrect merge.
585
585
586 .. container:: verbose
586 .. container:: verbose
587
587
588 Examples:
588 Examples:
589
589
590 - Reverse the effect of the parent of the working directory.
590 - Reverse the effect of the parent of the working directory.
591 This backout will be committed immediately::
591 This backout will be committed immediately::
592
592
593 hg backout -r .
593 hg backout -r .
594
594
595 - Reverse the effect of previous bad revision 23::
595 - Reverse the effect of previous bad revision 23::
596
596
597 hg backout -r 23
597 hg backout -r 23
598
598
599 - Reverse the effect of previous bad revision 23 and
599 - Reverse the effect of previous bad revision 23 and
600 leave changes uncommitted::
600 leave changes uncommitted::
601
601
602 hg backout -r 23 --no-commit
602 hg backout -r 23 --no-commit
603 hg commit -m "Backout revision 23"
603 hg commit -m "Backout revision 23"
604
604
605 By default, the pending changeset will have one parent,
605 By default, the pending changeset will have one parent,
606 maintaining a linear history. With --merge, the pending
606 maintaining a linear history. With --merge, the pending
607 changeset will instead have two parents: the old parent of the
607 changeset will instead have two parents: the old parent of the
608 working directory and a new child of REV that simply undoes REV.
608 working directory and a new child of REV that simply undoes REV.
609
609
610 Before version 1.7, the behavior without --merge was equivalent
610 Before version 1.7, the behavior without --merge was equivalent
611 to specifying --merge followed by :hg:`update --clean .` to
611 to specifying --merge followed by :hg:`update --clean .` to
612 cancel the merge and leave the child of REV as a head to be
612 cancel the merge and leave the child of REV as a head to be
613 merged separately.
613 merged separately.
614
614
615 See :hg:`help dates` for a list of formats valid for -d/--date.
615 See :hg:`help dates` for a list of formats valid for -d/--date.
616
616
617 See :hg:`help revert` for a way to restore files to the state
617 See :hg:`help revert` for a way to restore files to the state
618 of another revision.
618 of another revision.
619
619
620 Returns 0 on success, 1 if nothing to backout or there are unresolved
620 Returns 0 on success, 1 if nothing to backout or there are unresolved
621 files.
621 files.
622 '''
622 '''
623 with repo.wlock(), repo.lock():
623 with repo.wlock(), repo.lock():
624 return _dobackout(ui, repo, node, rev, **opts)
624 return _dobackout(ui, repo, node, rev, **opts)
625
625
626 def _dobackout(ui, repo, node=None, rev=None, **opts):
626 def _dobackout(ui, repo, node=None, rev=None, **opts):
627 opts = pycompat.byteskwargs(opts)
627 opts = pycompat.byteskwargs(opts)
628 if opts.get('commit') and opts.get('no_commit'):
628 if opts.get('commit') and opts.get('no_commit'):
629 raise error.Abort(_("cannot use --commit with --no-commit"))
629 raise error.Abort(_("cannot use --commit with --no-commit"))
630 if opts.get('merge') and opts.get('no_commit'):
630 if opts.get('merge') and opts.get('no_commit'):
631 raise error.Abort(_("cannot use --merge with --no-commit"))
631 raise error.Abort(_("cannot use --merge with --no-commit"))
632
632
633 if rev and node:
633 if rev and node:
634 raise error.Abort(_("please specify just one revision"))
634 raise error.Abort(_("please specify just one revision"))
635
635
636 if not rev:
636 if not rev:
637 rev = node
637 rev = node
638
638
639 if not rev:
639 if not rev:
640 raise error.Abort(_("please specify a revision to backout"))
640 raise error.Abort(_("please specify a revision to backout"))
641
641
642 date = opts.get('date')
642 date = opts.get('date')
643 if date:
643 if date:
644 opts['date'] = dateutil.parsedate(date)
644 opts['date'] = dateutil.parsedate(date)
645
645
646 cmdutil.checkunfinished(repo)
646 cmdutil.checkunfinished(repo)
647 cmdutil.bailifchanged(repo)
647 cmdutil.bailifchanged(repo)
648 node = scmutil.revsingle(repo, rev).node()
648 node = scmutil.revsingle(repo, rev).node()
649
649
650 op1, op2 = repo.dirstate.parents()
650 op1, op2 = repo.dirstate.parents()
651 if not repo.changelog.isancestor(node, op1):
651 if not repo.changelog.isancestor(node, op1):
652 raise error.Abort(_('cannot backout change that is not an ancestor'))
652 raise error.Abort(_('cannot backout change that is not an ancestor'))
653
653
654 p1, p2 = repo.changelog.parents(node)
654 p1, p2 = repo.changelog.parents(node)
655 if p1 == nullid:
655 if p1 == nullid:
656 raise error.Abort(_('cannot backout a change with no parents'))
656 raise error.Abort(_('cannot backout a change with no parents'))
657 if p2 != nullid:
657 if p2 != nullid:
658 if not opts.get('parent'):
658 if not opts.get('parent'):
659 raise error.Abort(_('cannot backout a merge changeset'))
659 raise error.Abort(_('cannot backout a merge changeset'))
660 p = repo.lookup(opts['parent'])
660 p = repo.lookup(opts['parent'])
661 if p not in (p1, p2):
661 if p not in (p1, p2):
662 raise error.Abort(_('%s is not a parent of %s') %
662 raise error.Abort(_('%s is not a parent of %s') %
663 (short(p), short(node)))
663 (short(p), short(node)))
664 parent = p
664 parent = p
665 else:
665 else:
666 if opts.get('parent'):
666 if opts.get('parent'):
667 raise error.Abort(_('cannot use --parent on non-merge changeset'))
667 raise error.Abort(_('cannot use --parent on non-merge changeset'))
668 parent = p1
668 parent = p1
669
669
670 # the backout should appear on the same branch
670 # the backout should appear on the same branch
671 branch = repo.dirstate.branch()
671 branch = repo.dirstate.branch()
672 bheads = repo.branchheads(branch)
672 bheads = repo.branchheads(branch)
673 rctx = scmutil.revsingle(repo, hex(parent))
673 rctx = scmutil.revsingle(repo, hex(parent))
674 if not opts.get('merge') and op1 != node:
674 if not opts.get('merge') and op1 != node:
675 with dirstateguard.dirstateguard(repo, 'backout'):
675 with dirstateguard.dirstateguard(repo, 'backout'):
676 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
676 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
677 with ui.configoverride(overrides, 'backout'):
677 with ui.configoverride(overrides, 'backout'):
678 stats = mergemod.update(repo, parent, branchmerge=True,
678 stats = mergemod.update(repo, parent, branchmerge=True,
679 force=True, ancestor=node,
679 force=True, ancestor=node,
680 mergeancestor=False)
680 mergeancestor=False)
681 repo.setparents(op1, op2)
681 repo.setparents(op1, op2)
682 hg._showstats(repo, stats)
682 hg._showstats(repo, stats)
683 if stats.unresolvedcount:
683 if stats.unresolvedcount:
684 repo.ui.status(_("use 'hg resolve' to retry unresolved "
684 repo.ui.status(_("use 'hg resolve' to retry unresolved "
685 "file merges\n"))
685 "file merges\n"))
686 return 1
686 return 1
687 else:
687 else:
688 hg.clean(repo, node, show_stats=False)
688 hg.clean(repo, node, show_stats=False)
689 repo.dirstate.setbranch(branch)
689 repo.dirstate.setbranch(branch)
690 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
690 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
691
691
692 if opts.get('no_commit'):
692 if opts.get('no_commit'):
693 msg = _("changeset %s backed out, "
693 msg = _("changeset %s backed out, "
694 "don't forget to commit.\n")
694 "don't forget to commit.\n")
695 ui.status(msg % short(node))
695 ui.status(msg % short(node))
696 return 0
696 return 0
697
697
698 def commitfunc(ui, repo, message, match, opts):
698 def commitfunc(ui, repo, message, match, opts):
699 editform = 'backout'
699 editform = 'backout'
700 e = cmdutil.getcommiteditor(editform=editform,
700 e = cmdutil.getcommiteditor(editform=editform,
701 **pycompat.strkwargs(opts))
701 **pycompat.strkwargs(opts))
702 if not message:
702 if not message:
703 # we don't translate commit messages
703 # we don't translate commit messages
704 message = "Backed out changeset %s" % short(node)
704 message = "Backed out changeset %s" % short(node)
705 e = cmdutil.getcommiteditor(edit=True, editform=editform)
705 e = cmdutil.getcommiteditor(edit=True, editform=editform)
706 return repo.commit(message, opts.get('user'), opts.get('date'),
706 return repo.commit(message, opts.get('user'), opts.get('date'),
707 match, editor=e)
707 match, editor=e)
708 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
708 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
709 if not newnode:
709 if not newnode:
710 ui.status(_("nothing changed\n"))
710 ui.status(_("nothing changed\n"))
711 return 1
711 return 1
712 cmdutil.commitstatus(repo, newnode, branch, bheads)
712 cmdutil.commitstatus(repo, newnode, branch, bheads)
713
713
714 def nice(node):
714 def nice(node):
715 return '%d:%s' % (repo.changelog.rev(node), short(node))
715 return '%d:%s' % (repo.changelog.rev(node), short(node))
716 ui.status(_('changeset %s backs out changeset %s\n') %
716 ui.status(_('changeset %s backs out changeset %s\n') %
717 (nice(repo.changelog.tip()), nice(node)))
717 (nice(repo.changelog.tip()), nice(node)))
718 if opts.get('merge') and op1 != node:
718 if opts.get('merge') and op1 != node:
719 hg.clean(repo, op1, show_stats=False)
719 hg.clean(repo, op1, show_stats=False)
720 ui.status(_('merging with changeset %s\n')
720 ui.status(_('merging with changeset %s\n')
721 % nice(repo.changelog.tip()))
721 % nice(repo.changelog.tip()))
722 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
722 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
723 with ui.configoverride(overrides, 'backout'):
723 with ui.configoverride(overrides, 'backout'):
724 return hg.merge(repo, hex(repo.changelog.tip()))
724 return hg.merge(repo, hex(repo.changelog.tip()))
725 return 0
725 return 0
726
726
727 @command('bisect',
727 @command('bisect',
728 [('r', 'reset', False, _('reset bisect state')),
728 [('r', 'reset', False, _('reset bisect state')),
729 ('g', 'good', False, _('mark changeset good')),
729 ('g', 'good', False, _('mark changeset good')),
730 ('b', 'bad', False, _('mark changeset bad')),
730 ('b', 'bad', False, _('mark changeset bad')),
731 ('s', 'skip', False, _('skip testing changeset')),
731 ('s', 'skip', False, _('skip testing changeset')),
732 ('e', 'extend', False, _('extend the bisect range')),
732 ('e', 'extend', False, _('extend the bisect range')),
733 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
733 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
734 ('U', 'noupdate', False, _('do not update to target'))],
734 ('U', 'noupdate', False, _('do not update to target'))],
735 _("[-gbsr] [-U] [-c CMD] [REV]"),
735 _("[-gbsr] [-U] [-c CMD] [REV]"),
736 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
736 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
737 def bisect(ui, repo, rev=None, extra=None, command=None,
737 def bisect(ui, repo, rev=None, extra=None, command=None,
738 reset=None, good=None, bad=None, skip=None, extend=None,
738 reset=None, good=None, bad=None, skip=None, extend=None,
739 noupdate=None):
739 noupdate=None):
740 """subdivision search of changesets
740 """subdivision search of changesets
741
741
742 This command helps to find changesets which introduce problems. To
742 This command helps to find changesets which introduce problems. To
743 use, mark the earliest changeset you know exhibits the problem as
743 use, mark the earliest changeset you know exhibits the problem as
744 bad, then mark the latest changeset which is free from the problem
744 bad, then mark the latest changeset which is free from the problem
745 as good. Bisect will update your working directory to a revision
745 as good. Bisect will update your working directory to a revision
746 for testing (unless the -U/--noupdate option is specified). Once
746 for testing (unless the -U/--noupdate option is specified). Once
747 you have performed tests, mark the working directory as good or
747 you have performed tests, mark the working directory as good or
748 bad, and bisect will either update to another candidate changeset
748 bad, and bisect will either update to another candidate changeset
749 or announce that it has found the bad revision.
749 or announce that it has found the bad revision.
750
750
751 As a shortcut, you can also use the revision argument to mark a
751 As a shortcut, you can also use the revision argument to mark a
752 revision as good or bad without checking it out first.
752 revision as good or bad without checking it out first.
753
753
754 If you supply a command, it will be used for automatic bisection.
754 If you supply a command, it will be used for automatic bisection.
755 The environment variable HG_NODE will contain the ID of the
755 The environment variable HG_NODE will contain the ID of the
756 changeset being tested. The exit status of the command will be
756 changeset being tested. The exit status of the command will be
757 used to mark revisions as good or bad: status 0 means good, 125
757 used to mark revisions as good or bad: status 0 means good, 125
758 means to skip the revision, 127 (command not found) will abort the
758 means to skip the revision, 127 (command not found) will abort the
759 bisection, and any other non-zero exit status means the revision
759 bisection, and any other non-zero exit status means the revision
760 is bad.
760 is bad.
761
761
762 .. container:: verbose
762 .. container:: verbose
763
763
764 Some examples:
764 Some examples:
765
765
766 - start a bisection with known bad revision 34, and good revision 12::
766 - start a bisection with known bad revision 34, and good revision 12::
767
767
768 hg bisect --bad 34
768 hg bisect --bad 34
769 hg bisect --good 12
769 hg bisect --good 12
770
770
771 - advance the current bisection by marking current revision as good or
771 - advance the current bisection by marking current revision as good or
772 bad::
772 bad::
773
773
774 hg bisect --good
774 hg bisect --good
775 hg bisect --bad
775 hg bisect --bad
776
776
777 - mark the current revision, or a known revision, to be skipped (e.g. if
777 - mark the current revision, or a known revision, to be skipped (e.g. if
778 that revision is not usable because of another issue)::
778 that revision is not usable because of another issue)::
779
779
780 hg bisect --skip
780 hg bisect --skip
781 hg bisect --skip 23
781 hg bisect --skip 23
782
782
783 - skip all revisions that do not touch directories ``foo`` or ``bar``::
783 - skip all revisions that do not touch directories ``foo`` or ``bar``::
784
784
785 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
785 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
786
786
787 - forget the current bisection::
787 - forget the current bisection::
788
788
789 hg bisect --reset
789 hg bisect --reset
790
790
791 - use 'make && make tests' to automatically find the first broken
791 - use 'make && make tests' to automatically find the first broken
792 revision::
792 revision::
793
793
794 hg bisect --reset
794 hg bisect --reset
795 hg bisect --bad 34
795 hg bisect --bad 34
796 hg bisect --good 12
796 hg bisect --good 12
797 hg bisect --command "make && make tests"
797 hg bisect --command "make && make tests"
798
798
799 - see all changesets whose states are already known in the current
799 - see all changesets whose states are already known in the current
800 bisection::
800 bisection::
801
801
802 hg log -r "bisect(pruned)"
802 hg log -r "bisect(pruned)"
803
803
804 - see the changeset currently being bisected (especially useful
804 - see the changeset currently being bisected (especially useful
805 if running with -U/--noupdate)::
805 if running with -U/--noupdate)::
806
806
807 hg log -r "bisect(current)"
807 hg log -r "bisect(current)"
808
808
809 - see all changesets that took part in the current bisection::
809 - see all changesets that took part in the current bisection::
810
810
811 hg log -r "bisect(range)"
811 hg log -r "bisect(range)"
812
812
813 - you can even get a nice graph::
813 - you can even get a nice graph::
814
814
815 hg log --graph -r "bisect(range)"
815 hg log --graph -r "bisect(range)"
816
816
817 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
817 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
818
818
819 Returns 0 on success.
819 Returns 0 on success.
820 """
820 """
821 # backward compatibility
821 # backward compatibility
822 if rev in "good bad reset init".split():
822 if rev in "good bad reset init".split():
823 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
823 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
824 cmd, rev, extra = rev, extra, None
824 cmd, rev, extra = rev, extra, None
825 if cmd == "good":
825 if cmd == "good":
826 good = True
826 good = True
827 elif cmd == "bad":
827 elif cmd == "bad":
828 bad = True
828 bad = True
829 else:
829 else:
830 reset = True
830 reset = True
831 elif extra:
831 elif extra:
832 raise error.Abort(_('incompatible arguments'))
832 raise error.Abort(_('incompatible arguments'))
833
833
834 incompatibles = {
834 incompatibles = {
835 '--bad': bad,
835 '--bad': bad,
836 '--command': bool(command),
836 '--command': bool(command),
837 '--extend': extend,
837 '--extend': extend,
838 '--good': good,
838 '--good': good,
839 '--reset': reset,
839 '--reset': reset,
840 '--skip': skip,
840 '--skip': skip,
841 }
841 }
842
842
843 enabled = [x for x in incompatibles if incompatibles[x]]
843 enabled = [x for x in incompatibles if incompatibles[x]]
844
844
845 if len(enabled) > 1:
845 if len(enabled) > 1:
846 raise error.Abort(_('%s and %s are incompatible') %
846 raise error.Abort(_('%s and %s are incompatible') %
847 tuple(sorted(enabled)[0:2]))
847 tuple(sorted(enabled)[0:2]))
848
848
849 if reset:
849 if reset:
850 hbisect.resetstate(repo)
850 hbisect.resetstate(repo)
851 return
851 return
852
852
853 state = hbisect.load_state(repo)
853 state = hbisect.load_state(repo)
854
854
855 # update state
855 # update state
856 if good or bad or skip:
856 if good or bad or skip:
857 if rev:
857 if rev:
858 nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
858 nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
859 else:
859 else:
860 nodes = [repo.lookup('.')]
860 nodes = [repo.lookup('.')]
861 if good:
861 if good:
862 state['good'] += nodes
862 state['good'] += nodes
863 elif bad:
863 elif bad:
864 state['bad'] += nodes
864 state['bad'] += nodes
865 elif skip:
865 elif skip:
866 state['skip'] += nodes
866 state['skip'] += nodes
867 hbisect.save_state(repo, state)
867 hbisect.save_state(repo, state)
868 if not (state['good'] and state['bad']):
868 if not (state['good'] and state['bad']):
869 return
869 return
870
870
871 def mayupdate(repo, node, show_stats=True):
871 def mayupdate(repo, node, show_stats=True):
872 """common used update sequence"""
872 """common used update sequence"""
873 if noupdate:
873 if noupdate:
874 return
874 return
875 cmdutil.checkunfinished(repo)
875 cmdutil.checkunfinished(repo)
876 cmdutil.bailifchanged(repo)
876 cmdutil.bailifchanged(repo)
877 return hg.clean(repo, node, show_stats=show_stats)
877 return hg.clean(repo, node, show_stats=show_stats)
878
878
879 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
879 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
880
880
881 if command:
881 if command:
882 changesets = 1
882 changesets = 1
883 if noupdate:
883 if noupdate:
884 try:
884 try:
885 node = state['current'][0]
885 node = state['current'][0]
886 except LookupError:
886 except LookupError:
887 raise error.Abort(_('current bisect revision is unknown - '
887 raise error.Abort(_('current bisect revision is unknown - '
888 'start a new bisect to fix'))
888 'start a new bisect to fix'))
889 else:
889 else:
890 node, p2 = repo.dirstate.parents()
890 node, p2 = repo.dirstate.parents()
891 if p2 != nullid:
891 if p2 != nullid:
892 raise error.Abort(_('current bisect revision is a merge'))
892 raise error.Abort(_('current bisect revision is a merge'))
893 if rev:
893 if rev:
894 node = repo[scmutil.revsingle(repo, rev, node)].node()
894 node = repo[scmutil.revsingle(repo, rev, node)].node()
895 try:
895 try:
896 while changesets:
896 while changesets:
897 # update state
897 # update state
898 state['current'] = [node]
898 state['current'] = [node]
899 hbisect.save_state(repo, state)
899 hbisect.save_state(repo, state)
900 status = ui.system(command, environ={'HG_NODE': hex(node)},
900 status = ui.system(command, environ={'HG_NODE': hex(node)},
901 blockedtag='bisect_check')
901 blockedtag='bisect_check')
902 if status == 125:
902 if status == 125:
903 transition = "skip"
903 transition = "skip"
904 elif status == 0:
904 elif status == 0:
905 transition = "good"
905 transition = "good"
906 # status < 0 means process was killed
906 # status < 0 means process was killed
907 elif status == 127:
907 elif status == 127:
908 raise error.Abort(_("failed to execute %s") % command)
908 raise error.Abort(_("failed to execute %s") % command)
909 elif status < 0:
909 elif status < 0:
910 raise error.Abort(_("%s killed") % command)
910 raise error.Abort(_("%s killed") % command)
911 else:
911 else:
912 transition = "bad"
912 transition = "bad"
913 state[transition].append(node)
913 state[transition].append(node)
914 ctx = repo[node]
914 ctx = repo[node]
915 ui.status(_('changeset %d:%s: %s\n') % (ctx.rev(), ctx,
915 ui.status(_('changeset %d:%s: %s\n') % (ctx.rev(), ctx,
916 transition))
916 transition))
917 hbisect.checkstate(state)
917 hbisect.checkstate(state)
918 # bisect
918 # bisect
919 nodes, changesets, bgood = hbisect.bisect(repo, state)
919 nodes, changesets, bgood = hbisect.bisect(repo, state)
920 # update to next check
920 # update to next check
921 node = nodes[0]
921 node = nodes[0]
922 mayupdate(repo, node, show_stats=False)
922 mayupdate(repo, node, show_stats=False)
923 finally:
923 finally:
924 state['current'] = [node]
924 state['current'] = [node]
925 hbisect.save_state(repo, state)
925 hbisect.save_state(repo, state)
926 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
926 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
927 return
927 return
928
928
929 hbisect.checkstate(state)
929 hbisect.checkstate(state)
930
930
931 # actually bisect
931 # actually bisect
932 nodes, changesets, good = hbisect.bisect(repo, state)
932 nodes, changesets, good = hbisect.bisect(repo, state)
933 if extend:
933 if extend:
934 if not changesets:
934 if not changesets:
935 extendnode = hbisect.extendrange(repo, state, nodes, good)
935 extendnode = hbisect.extendrange(repo, state, nodes, good)
936 if extendnode is not None:
936 if extendnode is not None:
937 ui.write(_("Extending search to changeset %d:%s\n")
937 ui.write(_("Extending search to changeset %d:%s\n")
938 % (extendnode.rev(), extendnode))
938 % (extendnode.rev(), extendnode))
939 state['current'] = [extendnode.node()]
939 state['current'] = [extendnode.node()]
940 hbisect.save_state(repo, state)
940 hbisect.save_state(repo, state)
941 return mayupdate(repo, extendnode.node())
941 return mayupdate(repo, extendnode.node())
942 raise error.Abort(_("nothing to extend"))
942 raise error.Abort(_("nothing to extend"))
943
943
944 if changesets == 0:
944 if changesets == 0:
945 hbisect.printresult(ui, repo, state, displayer, nodes, good)
945 hbisect.printresult(ui, repo, state, displayer, nodes, good)
946 else:
946 else:
947 assert len(nodes) == 1 # only a single node can be tested next
947 assert len(nodes) == 1 # only a single node can be tested next
948 node = nodes[0]
948 node = nodes[0]
949 # compute the approximate number of remaining tests
949 # compute the approximate number of remaining tests
950 tests, size = 0, 2
950 tests, size = 0, 2
951 while size <= changesets:
951 while size <= changesets:
952 tests, size = tests + 1, size * 2
952 tests, size = tests + 1, size * 2
953 rev = repo.changelog.rev(node)
953 rev = repo.changelog.rev(node)
954 ui.write(_("Testing changeset %d:%s "
954 ui.write(_("Testing changeset %d:%s "
955 "(%d changesets remaining, ~%d tests)\n")
955 "(%d changesets remaining, ~%d tests)\n")
956 % (rev, short(node), changesets, tests))
956 % (rev, short(node), changesets, tests))
957 state['current'] = [node]
957 state['current'] = [node]
958 hbisect.save_state(repo, state)
958 hbisect.save_state(repo, state)
959 return mayupdate(repo, node)
959 return mayupdate(repo, node)
960
960
961 @command('bookmarks|bookmark',
961 @command('bookmarks|bookmark',
962 [('f', 'force', False, _('force')),
962 [('f', 'force', False, _('force')),
963 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
963 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
964 ('d', 'delete', False, _('delete a given bookmark')),
964 ('d', 'delete', False, _('delete a given bookmark')),
965 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
965 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
966 ('i', 'inactive', False, _('mark a bookmark inactive')),
966 ('i', 'inactive', False, _('mark a bookmark inactive')),
967 ('l', 'list', False, _('list existing bookmarks')),
967 ('l', 'list', False, _('list existing bookmarks')),
968 ] + formatteropts,
968 ] + formatteropts,
969 _('hg bookmarks [OPTIONS]... [NAME]...'),
969 _('hg bookmarks [OPTIONS]... [NAME]...'),
970 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
970 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
971 def bookmark(ui, repo, *names, **opts):
971 def bookmark(ui, repo, *names, **opts):
972 '''create a new bookmark or list existing bookmarks
972 '''create a new bookmark or list existing bookmarks
973
973
974 Bookmarks are labels on changesets to help track lines of development.
974 Bookmarks are labels on changesets to help track lines of development.
975 Bookmarks are unversioned and can be moved, renamed and deleted.
975 Bookmarks are unversioned and can be moved, renamed and deleted.
976 Deleting or moving a bookmark has no effect on the associated changesets.
976 Deleting or moving a bookmark has no effect on the associated changesets.
977
977
978 Creating or updating to a bookmark causes it to be marked as 'active'.
978 Creating or updating to a bookmark causes it to be marked as 'active'.
979 The active bookmark is indicated with a '*'.
979 The active bookmark is indicated with a '*'.
980 When a commit is made, the active bookmark will advance to the new commit.
980 When a commit is made, the active bookmark will advance to the new commit.
981 A plain :hg:`update` will also advance an active bookmark, if possible.
981 A plain :hg:`update` will also advance an active bookmark, if possible.
982 Updating away from a bookmark will cause it to be deactivated.
982 Updating away from a bookmark will cause it to be deactivated.
983
983
984 Bookmarks can be pushed and pulled between repositories (see
984 Bookmarks can be pushed and pulled between repositories (see
985 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
985 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
986 diverged, a new 'divergent bookmark' of the form 'name@path' will
986 diverged, a new 'divergent bookmark' of the form 'name@path' will
987 be created. Using :hg:`merge` will resolve the divergence.
987 be created. Using :hg:`merge` will resolve the divergence.
988
988
989 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
989 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
990 the active bookmark's name.
990 the active bookmark's name.
991
991
992 A bookmark named '@' has the special property that :hg:`clone` will
992 A bookmark named '@' has the special property that :hg:`clone` will
993 check it out by default if it exists.
993 check it out by default if it exists.
994
994
995 .. container:: verbose
995 .. container:: verbose
996
996
997 Template:
997 Template:
998
998
999 The following keywords are supported in addition to the common template
999 The following keywords are supported in addition to the common template
1000 keywords and functions such as ``{bookmark}``. See also
1000 keywords and functions such as ``{bookmark}``. See also
1001 :hg:`help templates`.
1001 :hg:`help templates`.
1002
1002
1003 :active: Boolean. True if the bookmark is active.
1003 :active: Boolean. True if the bookmark is active.
1004
1004
1005 Examples:
1005 Examples:
1006
1006
1007 - create an active bookmark for a new line of development::
1007 - create an active bookmark for a new line of development::
1008
1008
1009 hg book new-feature
1009 hg book new-feature
1010
1010
1011 - create an inactive bookmark as a place marker::
1011 - create an inactive bookmark as a place marker::
1012
1012
1013 hg book -i reviewed
1013 hg book -i reviewed
1014
1014
1015 - create an inactive bookmark on another changeset::
1015 - create an inactive bookmark on another changeset::
1016
1016
1017 hg book -r .^ tested
1017 hg book -r .^ tested
1018
1018
1019 - rename bookmark turkey to dinner::
1019 - rename bookmark turkey to dinner::
1020
1020
1021 hg book -m turkey dinner
1021 hg book -m turkey dinner
1022
1022
1023 - move the '@' bookmark from another branch::
1023 - move the '@' bookmark from another branch::
1024
1024
1025 hg book -f @
1025 hg book -f @
1026
1026
1027 - print only the active bookmark name::
1027 - print only the active bookmark name::
1028
1028
1029 hg book -ql .
1029 hg book -ql .
1030 '''
1030 '''
1031 opts = pycompat.byteskwargs(opts)
1031 opts = pycompat.byteskwargs(opts)
1032 force = opts.get('force')
1032 force = opts.get('force')
1033 rev = opts.get('rev')
1033 rev = opts.get('rev')
1034 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark
1034 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark
1035
1035
1036 selactions = [k for k in ['delete', 'rename', 'list'] if opts.get(k)]
1036 selactions = [k for k in ['delete', 'rename', 'list'] if opts.get(k)]
1037 if len(selactions) > 1:
1037 if len(selactions) > 1:
1038 raise error.Abort(_('--%s and --%s are incompatible')
1038 raise error.Abort(_('--%s and --%s are incompatible')
1039 % tuple(selactions[:2]))
1039 % tuple(selactions[:2]))
1040 if selactions:
1040 if selactions:
1041 action = selactions[0]
1041 action = selactions[0]
1042 elif names or rev:
1042 elif names or rev:
1043 action = 'add'
1043 action = 'add'
1044 elif inactive:
1044 elif inactive:
1045 action = 'inactive' # meaning deactivate
1045 action = 'inactive' # meaning deactivate
1046 else:
1046 else:
1047 action = 'list'
1047 action = 'list'
1048
1048
1049 if rev and action in {'delete', 'rename', 'list'}:
1049 if rev and action in {'delete', 'rename', 'list'}:
1050 raise error.Abort(_("--rev is incompatible with --%s") % action)
1050 raise error.Abort(_("--rev is incompatible with --%s") % action)
1051 if inactive and action in {'delete', 'list'}:
1051 if inactive and action in {'delete', 'list'}:
1052 raise error.Abort(_("--inactive is incompatible with --%s") % action)
1052 raise error.Abort(_("--inactive is incompatible with --%s") % action)
1053 if not names and action in {'add', 'delete'}:
1053 if not names and action in {'add', 'delete'}:
1054 raise error.Abort(_("bookmark name required"))
1054 raise error.Abort(_("bookmark name required"))
1055
1055
1056 if action in {'add', 'delete', 'rename', 'inactive'}:
1056 if action in {'add', 'delete', 'rename', 'inactive'}:
1057 with repo.wlock(), repo.lock(), repo.transaction('bookmark') as tr:
1057 with repo.wlock(), repo.lock(), repo.transaction('bookmark') as tr:
1058 if action == 'delete':
1058 if action == 'delete':
1059 names = pycompat.maplist(repo._bookmarks.expandname, names)
1059 names = pycompat.maplist(repo._bookmarks.expandname, names)
1060 bookmarks.delete(repo, tr, names)
1060 bookmarks.delete(repo, tr, names)
1061 elif action == 'rename':
1061 elif action == 'rename':
1062 if not names:
1062 if not names:
1063 raise error.Abort(_("new bookmark name required"))
1063 raise error.Abort(_("new bookmark name required"))
1064 elif len(names) > 1:
1064 elif len(names) > 1:
1065 raise error.Abort(_("only one new bookmark name allowed"))
1065 raise error.Abort(_("only one new bookmark name allowed"))
1066 oldname = repo._bookmarks.expandname(opts['rename'])
1066 oldname = repo._bookmarks.expandname(opts['rename'])
1067 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1067 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1068 elif action == 'add':
1068 elif action == 'add':
1069 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1069 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1070 elif action == 'inactive':
1070 elif action == 'inactive':
1071 if len(repo._bookmarks) == 0:
1071 if len(repo._bookmarks) == 0:
1072 ui.status(_("no bookmarks set\n"))
1072 ui.status(_("no bookmarks set\n"))
1073 elif not repo._activebookmark:
1073 elif not repo._activebookmark:
1074 ui.status(_("no active bookmark\n"))
1074 ui.status(_("no active bookmark\n"))
1075 else:
1075 else:
1076 bookmarks.deactivate(repo)
1076 bookmarks.deactivate(repo)
1077 elif action == 'list':
1077 elif action == 'list':
1078 names = pycompat.maplist(repo._bookmarks.expandname, names)
1078 names = pycompat.maplist(repo._bookmarks.expandname, names)
1079 with ui.formatter('bookmarks', opts) as fm:
1079 with ui.formatter('bookmarks', opts) as fm:
1080 bookmarks.printbookmarks(ui, repo, fm, names)
1080 bookmarks.printbookmarks(ui, repo, fm, names)
1081 else:
1081 else:
1082 raise error.ProgrammingError('invalid action: %s' % action)
1082 raise error.ProgrammingError('invalid action: %s' % action)
1083
1083
1084 @command('branch',
1084 @command('branch',
1085 [('f', 'force', None,
1085 [('f', 'force', None,
1086 _('set branch name even if it shadows an existing branch')),
1086 _('set branch name even if it shadows an existing branch')),
1087 ('C', 'clean', None, _('reset branch name to parent branch name')),
1087 ('C', 'clean', None, _('reset branch name to parent branch name')),
1088 ('r', 'rev', [], _('change branches of the given revs (EXPERIMENTAL)')),
1088 ('r', 'rev', [], _('change branches of the given revs (EXPERIMENTAL)')),
1089 ],
1089 ],
1090 _('[-fC] [NAME]'),
1090 _('[-fC] [NAME]'),
1091 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
1091 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
1092 def branch(ui, repo, label=None, **opts):
1092 def branch(ui, repo, label=None, **opts):
1093 """set or show the current branch name
1093 """set or show the current branch name
1094
1094
1095 .. note::
1095 .. note::
1096
1096
1097 Branch names are permanent and global. Use :hg:`bookmark` to create a
1097 Branch names are permanent and global. Use :hg:`bookmark` to create a
1098 light-weight bookmark instead. See :hg:`help glossary` for more
1098 light-weight bookmark instead. See :hg:`help glossary` for more
1099 information about named branches and bookmarks.
1099 information about named branches and bookmarks.
1100
1100
1101 With no argument, show the current branch name. With one argument,
1101 With no argument, show the current branch name. With one argument,
1102 set the working directory branch name (the branch will not exist
1102 set the working directory branch name (the branch will not exist
1103 in the repository until the next commit). Standard practice
1103 in the repository until the next commit). Standard practice
1104 recommends that primary development take place on the 'default'
1104 recommends that primary development take place on the 'default'
1105 branch.
1105 branch.
1106
1106
1107 Unless -f/--force is specified, branch will not let you set a
1107 Unless -f/--force is specified, branch will not let you set a
1108 branch name that already exists.
1108 branch name that already exists.
1109
1109
1110 Use -C/--clean to reset the working directory branch to that of
1110 Use -C/--clean to reset the working directory branch to that of
1111 the parent of the working directory, negating a previous branch
1111 the parent of the working directory, negating a previous branch
1112 change.
1112 change.
1113
1113
1114 Use the command :hg:`update` to switch to an existing branch. Use
1114 Use the command :hg:`update` to switch to an existing branch. Use
1115 :hg:`commit --close-branch` to mark this branch head as closed.
1115 :hg:`commit --close-branch` to mark this branch head as closed.
1116 When all heads of a branch are closed, the branch will be
1116 When all heads of a branch are closed, the branch will be
1117 considered closed.
1117 considered closed.
1118
1118
1119 Returns 0 on success.
1119 Returns 0 on success.
1120 """
1120 """
1121 opts = pycompat.byteskwargs(opts)
1121 opts = pycompat.byteskwargs(opts)
1122 revs = opts.get('rev')
1122 revs = opts.get('rev')
1123 if label:
1123 if label:
1124 label = label.strip()
1124 label = label.strip()
1125
1125
1126 if not opts.get('clean') and not label:
1126 if not opts.get('clean') and not label:
1127 if revs:
1127 if revs:
1128 raise error.Abort(_("no branch name specified for the revisions"))
1128 raise error.Abort(_("no branch name specified for the revisions"))
1129 ui.write("%s\n" % repo.dirstate.branch())
1129 ui.write("%s\n" % repo.dirstate.branch())
1130 return
1130 return
1131
1131
1132 with repo.wlock():
1132 with repo.wlock():
1133 if opts.get('clean'):
1133 if opts.get('clean'):
1134 label = repo['.'].branch()
1134 label = repo['.'].branch()
1135 repo.dirstate.setbranch(label)
1135 repo.dirstate.setbranch(label)
1136 ui.status(_('reset working directory to branch %s\n') % label)
1136 ui.status(_('reset working directory to branch %s\n') % label)
1137 elif label:
1137 elif label:
1138
1138
1139 scmutil.checknewlabel(repo, label, 'branch')
1139 scmutil.checknewlabel(repo, label, 'branch')
1140 if revs:
1140 if revs:
1141 return cmdutil.changebranch(ui, repo, revs, label)
1141 return cmdutil.changebranch(ui, repo, revs, label)
1142
1142
1143 if not opts.get('force') and label in repo.branchmap():
1143 if not opts.get('force') and label in repo.branchmap():
1144 if label not in [p.branch() for p in repo[None].parents()]:
1144 if label not in [p.branch() for p in repo[None].parents()]:
1145 raise error.Abort(_('a branch of the same name already'
1145 raise error.Abort(_('a branch of the same name already'
1146 ' exists'),
1146 ' exists'),
1147 # i18n: "it" refers to an existing branch
1147 # i18n: "it" refers to an existing branch
1148 hint=_("use 'hg update' to switch to it"))
1148 hint=_("use 'hg update' to switch to it"))
1149
1149
1150 repo.dirstate.setbranch(label)
1150 repo.dirstate.setbranch(label)
1151 ui.status(_('marked working directory as branch %s\n') % label)
1151 ui.status(_('marked working directory as branch %s\n') % label)
1152
1152
1153 # find any open named branches aside from default
1153 # find any open named branches aside from default
1154 for n, h, t, c in repo.branchmap().iterbranches():
1154 for n, h, t, c in repo.branchmap().iterbranches():
1155 if n != "default" and not c:
1155 if n != "default" and not c:
1156 return 0
1156 return 0
1157 ui.status(_('(branches are permanent and global, '
1157 ui.status(_('(branches are permanent and global, '
1158 'did you want a bookmark?)\n'))
1158 'did you want a bookmark?)\n'))
1159
1159
1160 @command('branches',
1160 @command('branches',
1161 [('a', 'active', False,
1161 [('a', 'active', False,
1162 _('show only branches that have unmerged heads (DEPRECATED)')),
1162 _('show only branches that have unmerged heads (DEPRECATED)')),
1163 ('c', 'closed', False, _('show normal and closed branches')),
1163 ('c', 'closed', False, _('show normal and closed branches')),
1164 ('r', 'rev', [], _('show branch name(s) of the given rev'))
1164 ('r', 'rev', [], _('show branch name(s) of the given rev'))
1165 ] + formatteropts,
1165 ] + formatteropts,
1166 _('[-c]'),
1166 _('[-c]'),
1167 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1167 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1168 intents={INTENT_READONLY})
1168 intents={INTENT_READONLY})
1169 def branches(ui, repo, active=False, closed=False, **opts):
1169 def branches(ui, repo, active=False, closed=False, **opts):
1170 """list repository named branches
1170 """list repository named branches
1171
1171
1172 List the repository's named branches, indicating which ones are
1172 List the repository's named branches, indicating which ones are
1173 inactive. If -c/--closed is specified, also list branches which have
1173 inactive. If -c/--closed is specified, also list branches which have
1174 been marked closed (see :hg:`commit --close-branch`).
1174 been marked closed (see :hg:`commit --close-branch`).
1175
1175
1176 Use the command :hg:`update` to switch to an existing branch.
1176 Use the command :hg:`update` to switch to an existing branch.
1177
1177
1178 .. container:: verbose
1178 .. container:: verbose
1179
1179
1180 Template:
1180 Template:
1181
1181
1182 The following keywords are supported in addition to the common template
1182 The following keywords are supported in addition to the common template
1183 keywords and functions such as ``{branch}``. See also
1183 keywords and functions such as ``{branch}``. See also
1184 :hg:`help templates`.
1184 :hg:`help templates`.
1185
1185
1186 :active: Boolean. True if the branch is active.
1186 :active: Boolean. True if the branch is active.
1187 :closed: Boolean. True if the branch is closed.
1187 :closed: Boolean. True if the branch is closed.
1188 :current: Boolean. True if it is the current branch.
1188 :current: Boolean. True if it is the current branch.
1189
1189
1190 Returns 0.
1190 Returns 0.
1191 """
1191 """
1192
1192
1193 opts = pycompat.byteskwargs(opts)
1193 opts = pycompat.byteskwargs(opts)
1194 revs = opts.get('rev')
1194 revs = opts.get('rev')
1195 selectedbranches = None
1195 selectedbranches = None
1196 if revs:
1196 if revs:
1197 revs = scmutil.revrange(repo, revs)
1197 revs = scmutil.revrange(repo, revs)
1198 getbi = repo.revbranchcache().branchinfo
1198 getbi = repo.revbranchcache().branchinfo
1199 selectedbranches = {getbi(r)[0] for r in revs}
1199 selectedbranches = {getbi(r)[0] for r in revs}
1200
1200
1201 ui.pager('branches')
1201 ui.pager('branches')
1202 fm = ui.formatter('branches', opts)
1202 fm = ui.formatter('branches', opts)
1203 hexfunc = fm.hexfunc
1203 hexfunc = fm.hexfunc
1204
1204
1205 allheads = set(repo.heads())
1205 allheads = set(repo.heads())
1206 branches = []
1206 branches = []
1207 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1207 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1208 if selectedbranches is not None and tag not in selectedbranches:
1208 if selectedbranches is not None and tag not in selectedbranches:
1209 continue
1209 continue
1210 isactive = False
1210 isactive = False
1211 if not isclosed:
1211 if not isclosed:
1212 openheads = set(repo.branchmap().iteropen(heads))
1212 openheads = set(repo.branchmap().iteropen(heads))
1213 isactive = bool(openheads & allheads)
1213 isactive = bool(openheads & allheads)
1214 branches.append((tag, repo[tip], isactive, not isclosed))
1214 branches.append((tag, repo[tip], isactive, not isclosed))
1215 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1215 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1216 reverse=True)
1216 reverse=True)
1217
1217
1218 for tag, ctx, isactive, isopen in branches:
1218 for tag, ctx, isactive, isopen in branches:
1219 if active and not isactive:
1219 if active and not isactive:
1220 continue
1220 continue
1221 if isactive:
1221 if isactive:
1222 label = 'branches.active'
1222 label = 'branches.active'
1223 notice = ''
1223 notice = ''
1224 elif not isopen:
1224 elif not isopen:
1225 if not closed:
1225 if not closed:
1226 continue
1226 continue
1227 label = 'branches.closed'
1227 label = 'branches.closed'
1228 notice = _(' (closed)')
1228 notice = _(' (closed)')
1229 else:
1229 else:
1230 label = 'branches.inactive'
1230 label = 'branches.inactive'
1231 notice = _(' (inactive)')
1231 notice = _(' (inactive)')
1232 current = (tag == repo.dirstate.branch())
1232 current = (tag == repo.dirstate.branch())
1233 if current:
1233 if current:
1234 label = 'branches.current'
1234 label = 'branches.current'
1235
1235
1236 fm.startitem()
1236 fm.startitem()
1237 fm.write('branch', '%s', tag, label=label)
1237 fm.write('branch', '%s', tag, label=label)
1238 rev = ctx.rev()
1238 rev = ctx.rev()
1239 padsize = max(31 - len("%d" % rev) - encoding.colwidth(tag), 0)
1239 padsize = max(31 - len("%d" % rev) - encoding.colwidth(tag), 0)
1240 fmt = ' ' * padsize + ' %d:%s'
1240 fmt = ' ' * padsize + ' %d:%s'
1241 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1241 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1242 label='log.changeset changeset.%s' % ctx.phasestr())
1242 label='log.changeset changeset.%s' % ctx.phasestr())
1243 fm.context(ctx=ctx)
1243 fm.context(ctx=ctx)
1244 fm.data(active=isactive, closed=not isopen, current=current)
1244 fm.data(active=isactive, closed=not isopen, current=current)
1245 if not ui.quiet:
1245 if not ui.quiet:
1246 fm.plain(notice)
1246 fm.plain(notice)
1247 fm.plain('\n')
1247 fm.plain('\n')
1248 fm.end()
1248 fm.end()
1249
1249
1250 @command('bundle',
1250 @command('bundle',
1251 [('f', 'force', None, _('run even when the destination is unrelated')),
1251 [('f', 'force', None, _('run even when the destination is unrelated')),
1252 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1252 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1253 _('REV')),
1253 _('REV')),
1254 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1254 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1255 _('BRANCH')),
1255 _('BRANCH')),
1256 ('', 'base', [],
1256 ('', 'base', [],
1257 _('a base changeset assumed to be available at the destination'),
1257 _('a base changeset assumed to be available at the destination'),
1258 _('REV')),
1258 _('REV')),
1259 ('a', 'all', None, _('bundle all changesets in the repository')),
1259 ('a', 'all', None, _('bundle all changesets in the repository')),
1260 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1260 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1261 ] + remoteopts,
1261 ] + remoteopts,
1262 _('[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1262 _('[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1263 helpcategory=command.CATEGORY_IMPORT_EXPORT)
1263 helpcategory=command.CATEGORY_IMPORT_EXPORT)
1264 def bundle(ui, repo, fname, dest=None, **opts):
1264 def bundle(ui, repo, fname, dest=None, **opts):
1265 """create a bundle file
1265 """create a bundle file
1266
1266
1267 Generate a bundle file containing data to be transferred to another
1267 Generate a bundle file containing data to be transferred to another
1268 repository.
1268 repository.
1269
1269
1270 To create a bundle containing all changesets, use -a/--all
1270 To create a bundle containing all changesets, use -a/--all
1271 (or --base null). Otherwise, hg assumes the destination will have
1271 (or --base null). Otherwise, hg assumes the destination will have
1272 all the nodes you specify with --base parameters. Otherwise, hg
1272 all the nodes you specify with --base parameters. Otherwise, hg
1273 will assume the repository has all the nodes in destination, or
1273 will assume the repository has all the nodes in destination, or
1274 default-push/default if no destination is specified, where destination
1274 default-push/default if no destination is specified, where destination
1275 is the repository you provide through DEST option.
1275 is the repository you provide through DEST option.
1276
1276
1277 You can change bundle format with the -t/--type option. See
1277 You can change bundle format with the -t/--type option. See
1278 :hg:`help bundlespec` for documentation on this format. By default,
1278 :hg:`help bundlespec` for documentation on this format. By default,
1279 the most appropriate format is used and compression defaults to
1279 the most appropriate format is used and compression defaults to
1280 bzip2.
1280 bzip2.
1281
1281
1282 The bundle file can then be transferred using conventional means
1282 The bundle file can then be transferred using conventional means
1283 and applied to another repository with the unbundle or pull
1283 and applied to another repository with the unbundle or pull
1284 command. This is useful when direct push and pull are not
1284 command. This is useful when direct push and pull are not
1285 available or when exporting an entire repository is undesirable.
1285 available or when exporting an entire repository is undesirable.
1286
1286
1287 Applying bundles preserves all changeset contents including
1287 Applying bundles preserves all changeset contents including
1288 permissions, copy/rename information, and revision history.
1288 permissions, copy/rename information, and revision history.
1289
1289
1290 Returns 0 on success, 1 if no changes found.
1290 Returns 0 on success, 1 if no changes found.
1291 """
1291 """
1292 opts = pycompat.byteskwargs(opts)
1292 opts = pycompat.byteskwargs(opts)
1293 revs = None
1293 revs = None
1294 if 'rev' in opts:
1294 if 'rev' in opts:
1295 revstrings = opts['rev']
1295 revstrings = opts['rev']
1296 revs = scmutil.revrange(repo, revstrings)
1296 revs = scmutil.revrange(repo, revstrings)
1297 if revstrings and not revs:
1297 if revstrings and not revs:
1298 raise error.Abort(_('no commits to bundle'))
1298 raise error.Abort(_('no commits to bundle'))
1299
1299
1300 bundletype = opts.get('type', 'bzip2').lower()
1300 bundletype = opts.get('type', 'bzip2').lower()
1301 try:
1301 try:
1302 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
1302 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
1303 except error.UnsupportedBundleSpecification as e:
1303 except error.UnsupportedBundleSpecification as e:
1304 raise error.Abort(pycompat.bytestr(e),
1304 raise error.Abort(pycompat.bytestr(e),
1305 hint=_("see 'hg help bundlespec' for supported "
1305 hint=_("see 'hg help bundlespec' for supported "
1306 "values for --type"))
1306 "values for --type"))
1307 cgversion = bundlespec.contentopts["cg.version"]
1307 cgversion = bundlespec.contentopts["cg.version"]
1308
1308
1309 # Packed bundles are a pseudo bundle format for now.
1309 # Packed bundles are a pseudo bundle format for now.
1310 if cgversion == 's1':
1310 if cgversion == 's1':
1311 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1311 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1312 hint=_("use 'hg debugcreatestreamclonebundle'"))
1312 hint=_("use 'hg debugcreatestreamclonebundle'"))
1313
1313
1314 if opts.get('all'):
1314 if opts.get('all'):
1315 if dest:
1315 if dest:
1316 raise error.Abort(_("--all is incompatible with specifying "
1316 raise error.Abort(_("--all is incompatible with specifying "
1317 "a destination"))
1317 "a destination"))
1318 if opts.get('base'):
1318 if opts.get('base'):
1319 ui.warn(_("ignoring --base because --all was specified\n"))
1319 ui.warn(_("ignoring --base because --all was specified\n"))
1320 base = [nullrev]
1320 base = [nullrev]
1321 else:
1321 else:
1322 base = scmutil.revrange(repo, opts.get('base'))
1322 base = scmutil.revrange(repo, opts.get('base'))
1323 if cgversion not in changegroup.supportedoutgoingversions(repo):
1323 if cgversion not in changegroup.supportedoutgoingversions(repo):
1324 raise error.Abort(_("repository does not support bundle version %s") %
1324 raise error.Abort(_("repository does not support bundle version %s") %
1325 cgversion)
1325 cgversion)
1326
1326
1327 if base:
1327 if base:
1328 if dest:
1328 if dest:
1329 raise error.Abort(_("--base is incompatible with specifying "
1329 raise error.Abort(_("--base is incompatible with specifying "
1330 "a destination"))
1330 "a destination"))
1331 common = [repo[rev].node() for rev in base]
1331 common = [repo[rev].node() for rev in base]
1332 heads = [repo[r].node() for r in revs] if revs else None
1332 heads = [repo[r].node() for r in revs] if revs else None
1333 outgoing = discovery.outgoing(repo, common, heads)
1333 outgoing = discovery.outgoing(repo, common, heads)
1334 else:
1334 else:
1335 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1335 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1336 dest, branches = hg.parseurl(dest, opts.get('branch'))
1336 dest, branches = hg.parseurl(dest, opts.get('branch'))
1337 other = hg.peer(repo, opts, dest)
1337 other = hg.peer(repo, opts, dest)
1338 revs = [repo[r].hex() for r in revs]
1338 revs = [repo[r].hex() for r in revs]
1339 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1339 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1340 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1340 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1341 outgoing = discovery.findcommonoutgoing(repo, other,
1341 outgoing = discovery.findcommonoutgoing(repo, other,
1342 onlyheads=heads,
1342 onlyheads=heads,
1343 force=opts.get('force'),
1343 force=opts.get('force'),
1344 portable=True)
1344 portable=True)
1345
1345
1346 if not outgoing.missing:
1346 if not outgoing.missing:
1347 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1347 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1348 return 1
1348 return 1
1349
1349
1350 if cgversion == '01': #bundle1
1350 if cgversion == '01': #bundle1
1351 bversion = 'HG10' + bundlespec.wirecompression
1351 bversion = 'HG10' + bundlespec.wirecompression
1352 bcompression = None
1352 bcompression = None
1353 elif cgversion in ('02', '03'):
1353 elif cgversion in ('02', '03'):
1354 bversion = 'HG20'
1354 bversion = 'HG20'
1355 bcompression = bundlespec.wirecompression
1355 bcompression = bundlespec.wirecompression
1356 else:
1356 else:
1357 raise error.ProgrammingError(
1357 raise error.ProgrammingError(
1358 'bundle: unexpected changegroup version %s' % cgversion)
1358 'bundle: unexpected changegroup version %s' % cgversion)
1359
1359
1360 # TODO compression options should be derived from bundlespec parsing.
1360 # TODO compression options should be derived from bundlespec parsing.
1361 # This is a temporary hack to allow adjusting bundle compression
1361 # This is a temporary hack to allow adjusting bundle compression
1362 # level without a) formalizing the bundlespec changes to declare it
1362 # level without a) formalizing the bundlespec changes to declare it
1363 # b) introducing a command flag.
1363 # b) introducing a command flag.
1364 compopts = {}
1364 compopts = {}
1365 complevel = ui.configint('experimental',
1365 complevel = ui.configint('experimental',
1366 'bundlecomplevel.' + bundlespec.compression)
1366 'bundlecomplevel.' + bundlespec.compression)
1367 if complevel is None:
1367 if complevel is None:
1368 complevel = ui.configint('experimental', 'bundlecomplevel')
1368 complevel = ui.configint('experimental', 'bundlecomplevel')
1369 if complevel is not None:
1369 if complevel is not None:
1370 compopts['level'] = complevel
1370 compopts['level'] = complevel
1371
1371
1372 # Allow overriding the bundling of obsmarker in phases through
1372 # Allow overriding the bundling of obsmarker in phases through
1373 # configuration while we don't have a bundle version that include them
1373 # configuration while we don't have a bundle version that include them
1374 if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'):
1374 if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'):
1375 bundlespec.contentopts['obsolescence'] = True
1375 bundlespec.contentopts['obsolescence'] = True
1376 if repo.ui.configbool('experimental', 'bundle-phases'):
1376 if repo.ui.configbool('experimental', 'bundle-phases'):
1377 bundlespec.contentopts['phases'] = True
1377 bundlespec.contentopts['phases'] = True
1378
1378
1379 bundle2.writenewbundle(ui, repo, 'bundle', fname, bversion, outgoing,
1379 bundle2.writenewbundle(ui, repo, 'bundle', fname, bversion, outgoing,
1380 bundlespec.contentopts, compression=bcompression,
1380 bundlespec.contentopts, compression=bcompression,
1381 compopts=compopts)
1381 compopts=compopts)
1382
1382
1383 @command('cat',
1383 @command('cat',
1384 [('o', 'output', '',
1384 [('o', 'output', '',
1385 _('print output to file with formatted name'), _('FORMAT')),
1385 _('print output to file with formatted name'), _('FORMAT')),
1386 ('r', 'rev', '', _('print the given revision'), _('REV')),
1386 ('r', 'rev', '', _('print the given revision'), _('REV')),
1387 ('', 'decode', None, _('apply any matching decode filter')),
1387 ('', 'decode', None, _('apply any matching decode filter')),
1388 ] + walkopts + formatteropts,
1388 ] + walkopts + formatteropts,
1389 _('[OPTION]... FILE...'),
1389 _('[OPTION]... FILE...'),
1390 helpcategory=command.CATEGORY_FILE_CONTENTS,
1390 helpcategory=command.CATEGORY_FILE_CONTENTS,
1391 inferrepo=True,
1391 inferrepo=True,
1392 intents={INTENT_READONLY})
1392 intents={INTENT_READONLY})
1393 def cat(ui, repo, file1, *pats, **opts):
1393 def cat(ui, repo, file1, *pats, **opts):
1394 """output the current or given revision of files
1394 """output the current or given revision of files
1395
1395
1396 Print the specified files as they were at the given revision. If
1396 Print the specified files as they were at the given revision. If
1397 no revision is given, the parent of the working directory is used.
1397 no revision is given, the parent of the working directory is used.
1398
1398
1399 Output may be to a file, in which case the name of the file is
1399 Output may be to a file, in which case the name of the file is
1400 given using a template string. See :hg:`help templates`. In addition
1400 given using a template string. See :hg:`help templates`. In addition
1401 to the common template keywords, the following formatting rules are
1401 to the common template keywords, the following formatting rules are
1402 supported:
1402 supported:
1403
1403
1404 :``%%``: literal "%" character
1404 :``%%``: literal "%" character
1405 :``%s``: basename of file being printed
1405 :``%s``: basename of file being printed
1406 :``%d``: dirname of file being printed, or '.' if in repository root
1406 :``%d``: dirname of file being printed, or '.' if in repository root
1407 :``%p``: root-relative path name of file being printed
1407 :``%p``: root-relative path name of file being printed
1408 :``%H``: changeset hash (40 hexadecimal digits)
1408 :``%H``: changeset hash (40 hexadecimal digits)
1409 :``%R``: changeset revision number
1409 :``%R``: changeset revision number
1410 :``%h``: short-form changeset hash (12 hexadecimal digits)
1410 :``%h``: short-form changeset hash (12 hexadecimal digits)
1411 :``%r``: zero-padded changeset revision number
1411 :``%r``: zero-padded changeset revision number
1412 :``%b``: basename of the exporting repository
1412 :``%b``: basename of the exporting repository
1413 :``\\``: literal "\\" character
1413 :``\\``: literal "\\" character
1414
1414
1415 .. container:: verbose
1415 .. container:: verbose
1416
1416
1417 Template:
1417 Template:
1418
1418
1419 The following keywords are supported in addition to the common template
1419 The following keywords are supported in addition to the common template
1420 keywords and functions. See also :hg:`help templates`.
1420 keywords and functions. See also :hg:`help templates`.
1421
1421
1422 :data: String. File content.
1422 :data: String. File content.
1423 :path: String. Repository-absolute path of the file.
1423 :path: String. Repository-absolute path of the file.
1424
1424
1425 Returns 0 on success.
1425 Returns 0 on success.
1426 """
1426 """
1427 opts = pycompat.byteskwargs(opts)
1427 opts = pycompat.byteskwargs(opts)
1428 rev = opts.get('rev')
1428 rev = opts.get('rev')
1429 if rev:
1429 if rev:
1430 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
1430 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
1431 ctx = scmutil.revsingle(repo, rev)
1431 ctx = scmutil.revsingle(repo, rev)
1432 m = scmutil.match(ctx, (file1,) + pats, opts)
1432 m = scmutil.match(ctx, (file1,) + pats, opts)
1433 fntemplate = opts.pop('output', '')
1433 fntemplate = opts.pop('output', '')
1434 if cmdutil.isstdiofilename(fntemplate):
1434 if cmdutil.isstdiofilename(fntemplate):
1435 fntemplate = ''
1435 fntemplate = ''
1436
1436
1437 if fntemplate:
1437 if fntemplate:
1438 fm = formatter.nullformatter(ui, 'cat', opts)
1438 fm = formatter.nullformatter(ui, 'cat', opts)
1439 else:
1439 else:
1440 ui.pager('cat')
1440 ui.pager('cat')
1441 fm = ui.formatter('cat', opts)
1441 fm = ui.formatter('cat', opts)
1442 with fm:
1442 with fm:
1443 return cmdutil.cat(ui, repo, ctx, m, fm, fntemplate, '',
1443 return cmdutil.cat(ui, repo, ctx, m, fm, fntemplate, '',
1444 **pycompat.strkwargs(opts))
1444 **pycompat.strkwargs(opts))
1445
1445
1446 @command('clone',
1446 @command('clone',
1447 [('U', 'noupdate', None, _('the clone will include an empty working '
1447 [('U', 'noupdate', None, _('the clone will include an empty working '
1448 'directory (only a repository)')),
1448 'directory (only a repository)')),
1449 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1449 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1450 _('REV')),
1450 _('REV')),
1451 ('r', 'rev', [], _('do not clone everything, but include this changeset'
1451 ('r', 'rev', [], _('do not clone everything, but include this changeset'
1452 ' and its ancestors'), _('REV')),
1452 ' and its ancestors'), _('REV')),
1453 ('b', 'branch', [], _('do not clone everything, but include this branch\'s'
1453 ('b', 'branch', [], _('do not clone everything, but include this branch\'s'
1454 ' changesets and their ancestors'), _('BRANCH')),
1454 ' changesets and their ancestors'), _('BRANCH')),
1455 ('', 'pull', None, _('use pull protocol to copy metadata')),
1455 ('', 'pull', None, _('use pull protocol to copy metadata')),
1456 ('', 'uncompressed', None,
1456 ('', 'uncompressed', None,
1457 _('an alias to --stream (DEPRECATED)')),
1457 _('an alias to --stream (DEPRECATED)')),
1458 ('', 'stream', None,
1458 ('', 'stream', None,
1459 _('clone with minimal data processing')),
1459 _('clone with minimal data processing')),
1460 ] + remoteopts,
1460 ] + remoteopts,
1461 _('[OPTION]... SOURCE [DEST]'),
1461 _('[OPTION]... SOURCE [DEST]'),
1462 helpcategory=command.CATEGORY_REPO_CREATION,
1462 helpcategory=command.CATEGORY_REPO_CREATION,
1463 helpbasic=True, norepo=True)
1463 helpbasic=True, norepo=True)
1464 def clone(ui, source, dest=None, **opts):
1464 def clone(ui, source, dest=None, **opts):
1465 """make a copy of an existing repository
1465 """make a copy of an existing repository
1466
1466
1467 Create a copy of an existing repository in a new directory.
1467 Create a copy of an existing repository in a new directory.
1468
1468
1469 If no destination directory name is specified, it defaults to the
1469 If no destination directory name is specified, it defaults to the
1470 basename of the source.
1470 basename of the source.
1471
1471
1472 The location of the source is added to the new repository's
1472 The location of the source is added to the new repository's
1473 ``.hg/hgrc`` file, as the default to be used for future pulls.
1473 ``.hg/hgrc`` file, as the default to be used for future pulls.
1474
1474
1475 Only local paths and ``ssh://`` URLs are supported as
1475 Only local paths and ``ssh://`` URLs are supported as
1476 destinations. For ``ssh://`` destinations, no working directory or
1476 destinations. For ``ssh://`` destinations, no working directory or
1477 ``.hg/hgrc`` will be created on the remote side.
1477 ``.hg/hgrc`` will be created on the remote side.
1478
1478
1479 If the source repository has a bookmark called '@' set, that
1479 If the source repository has a bookmark called '@' set, that
1480 revision will be checked out in the new repository by default.
1480 revision will be checked out in the new repository by default.
1481
1481
1482 To check out a particular version, use -u/--update, or
1482 To check out a particular version, use -u/--update, or
1483 -U/--noupdate to create a clone with no working directory.
1483 -U/--noupdate to create a clone with no working directory.
1484
1484
1485 To pull only a subset of changesets, specify one or more revisions
1485 To pull only a subset of changesets, specify one or more revisions
1486 identifiers with -r/--rev or branches with -b/--branch. The
1486 identifiers with -r/--rev or branches with -b/--branch. The
1487 resulting clone will contain only the specified changesets and
1487 resulting clone will contain only the specified changesets and
1488 their ancestors. These options (or 'clone src#rev dest') imply
1488 their ancestors. These options (or 'clone src#rev dest') imply
1489 --pull, even for local source repositories.
1489 --pull, even for local source repositories.
1490
1490
1491 In normal clone mode, the remote normalizes repository data into a common
1491 In normal clone mode, the remote normalizes repository data into a common
1492 exchange format and the receiving end translates this data into its local
1492 exchange format and the receiving end translates this data into its local
1493 storage format. --stream activates a different clone mode that essentially
1493 storage format. --stream activates a different clone mode that essentially
1494 copies repository files from the remote with minimal data processing. This
1494 copies repository files from the remote with minimal data processing. This
1495 significantly reduces the CPU cost of a clone both remotely and locally.
1495 significantly reduces the CPU cost of a clone both remotely and locally.
1496 However, it often increases the transferred data size by 30-40%. This can
1496 However, it often increases the transferred data size by 30-40%. This can
1497 result in substantially faster clones where I/O throughput is plentiful,
1497 result in substantially faster clones where I/O throughput is plentiful,
1498 especially for larger repositories. A side-effect of --stream clones is
1498 especially for larger repositories. A side-effect of --stream clones is
1499 that storage settings and requirements on the remote are applied locally:
1499 that storage settings and requirements on the remote are applied locally:
1500 a modern client may inherit legacy or inefficient storage used by the
1500 a modern client may inherit legacy or inefficient storage used by the
1501 remote or a legacy Mercurial client may not be able to clone from a
1501 remote or a legacy Mercurial client may not be able to clone from a
1502 modern Mercurial remote.
1502 modern Mercurial remote.
1503
1503
1504 .. note::
1504 .. note::
1505
1505
1506 Specifying a tag will include the tagged changeset but not the
1506 Specifying a tag will include the tagged changeset but not the
1507 changeset containing the tag.
1507 changeset containing the tag.
1508
1508
1509 .. container:: verbose
1509 .. container:: verbose
1510
1510
1511 For efficiency, hardlinks are used for cloning whenever the
1511 For efficiency, hardlinks are used for cloning whenever the
1512 source and destination are on the same filesystem (note this
1512 source and destination are on the same filesystem (note this
1513 applies only to the repository data, not to the working
1513 applies only to the repository data, not to the working
1514 directory). Some filesystems, such as AFS, implement hardlinking
1514 directory). Some filesystems, such as AFS, implement hardlinking
1515 incorrectly, but do not report errors. In these cases, use the
1515 incorrectly, but do not report errors. In these cases, use the
1516 --pull option to avoid hardlinking.
1516 --pull option to avoid hardlinking.
1517
1517
1518 Mercurial will update the working directory to the first applicable
1518 Mercurial will update the working directory to the first applicable
1519 revision from this list:
1519 revision from this list:
1520
1520
1521 a) null if -U or the source repository has no changesets
1521 a) null if -U or the source repository has no changesets
1522 b) if -u . and the source repository is local, the first parent of
1522 b) if -u . and the source repository is local, the first parent of
1523 the source repository's working directory
1523 the source repository's working directory
1524 c) the changeset specified with -u (if a branch name, this means the
1524 c) the changeset specified with -u (if a branch name, this means the
1525 latest head of that branch)
1525 latest head of that branch)
1526 d) the changeset specified with -r
1526 d) the changeset specified with -r
1527 e) the tipmost head specified with -b
1527 e) the tipmost head specified with -b
1528 f) the tipmost head specified with the url#branch source syntax
1528 f) the tipmost head specified with the url#branch source syntax
1529 g) the revision marked with the '@' bookmark, if present
1529 g) the revision marked with the '@' bookmark, if present
1530 h) the tipmost head of the default branch
1530 h) the tipmost head of the default branch
1531 i) tip
1531 i) tip
1532
1532
1533 When cloning from servers that support it, Mercurial may fetch
1533 When cloning from servers that support it, Mercurial may fetch
1534 pre-generated data from a server-advertised URL or inline from the
1534 pre-generated data from a server-advertised URL or inline from the
1535 same stream. When this is done, hooks operating on incoming changesets
1535 same stream. When this is done, hooks operating on incoming changesets
1536 and changegroups may fire more than once, once for each pre-generated
1536 and changegroups may fire more than once, once for each pre-generated
1537 bundle and as well as for any additional remaining data. In addition,
1537 bundle and as well as for any additional remaining data. In addition,
1538 if an error occurs, the repository may be rolled back to a partial
1538 if an error occurs, the repository may be rolled back to a partial
1539 clone. This behavior may change in future releases.
1539 clone. This behavior may change in future releases.
1540 See :hg:`help -e clonebundles` for more.
1540 See :hg:`help -e clonebundles` for more.
1541
1541
1542 Examples:
1542 Examples:
1543
1543
1544 - clone a remote repository to a new directory named hg/::
1544 - clone a remote repository to a new directory named hg/::
1545
1545
1546 hg clone https://www.mercurial-scm.org/repo/hg/
1546 hg clone https://www.mercurial-scm.org/repo/hg/
1547
1547
1548 - create a lightweight local clone::
1548 - create a lightweight local clone::
1549
1549
1550 hg clone project/ project-feature/
1550 hg clone project/ project-feature/
1551
1551
1552 - clone from an absolute path on an ssh server (note double-slash)::
1552 - clone from an absolute path on an ssh server (note double-slash)::
1553
1553
1554 hg clone ssh://user@server//home/projects/alpha/
1554 hg clone ssh://user@server//home/projects/alpha/
1555
1555
1556 - do a streaming clone while checking out a specified version::
1556 - do a streaming clone while checking out a specified version::
1557
1557
1558 hg clone --stream http://server/repo -u 1.5
1558 hg clone --stream http://server/repo -u 1.5
1559
1559
1560 - create a repository without changesets after a particular revision::
1560 - create a repository without changesets after a particular revision::
1561
1561
1562 hg clone -r 04e544 experimental/ good/
1562 hg clone -r 04e544 experimental/ good/
1563
1563
1564 - clone (and track) a particular named branch::
1564 - clone (and track) a particular named branch::
1565
1565
1566 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1566 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1567
1567
1568 See :hg:`help urls` for details on specifying URLs.
1568 See :hg:`help urls` for details on specifying URLs.
1569
1569
1570 Returns 0 on success.
1570 Returns 0 on success.
1571 """
1571 """
1572 opts = pycompat.byteskwargs(opts)
1572 opts = pycompat.byteskwargs(opts)
1573 if opts.get('noupdate') and opts.get('updaterev'):
1573 if opts.get('noupdate') and opts.get('updaterev'):
1574 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1574 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1575
1575
1576 # --include/--exclude can come from narrow or sparse.
1576 # --include/--exclude can come from narrow or sparse.
1577 includepats, excludepats = None, None
1577 includepats, excludepats = None, None
1578
1578
1579 # hg.clone() differentiates between None and an empty set. So make sure
1579 # hg.clone() differentiates between None and an empty set. So make sure
1580 # patterns are sets if narrow is requested without patterns.
1580 # patterns are sets if narrow is requested without patterns.
1581 if opts.get('narrow'):
1581 if opts.get('narrow'):
1582 includepats = set()
1582 includepats = set()
1583 excludepats = set()
1583 excludepats = set()
1584
1584
1585 if opts.get('include'):
1585 if opts.get('include'):
1586 includepats = narrowspec.parsepatterns(opts.get('include'))
1586 includepats = narrowspec.parsepatterns(opts.get('include'))
1587 if opts.get('exclude'):
1587 if opts.get('exclude'):
1588 excludepats = narrowspec.parsepatterns(opts.get('exclude'))
1588 excludepats = narrowspec.parsepatterns(opts.get('exclude'))
1589
1589
1590 r = hg.clone(ui, opts, source, dest,
1590 r = hg.clone(ui, opts, source, dest,
1591 pull=opts.get('pull'),
1591 pull=opts.get('pull'),
1592 stream=opts.get('stream') or opts.get('uncompressed'),
1592 stream=opts.get('stream') or opts.get('uncompressed'),
1593 revs=opts.get('rev'),
1593 revs=opts.get('rev'),
1594 update=opts.get('updaterev') or not opts.get('noupdate'),
1594 update=opts.get('updaterev') or not opts.get('noupdate'),
1595 branch=opts.get('branch'),
1595 branch=opts.get('branch'),
1596 shareopts=opts.get('shareopts'),
1596 shareopts=opts.get('shareopts'),
1597 storeincludepats=includepats,
1597 storeincludepats=includepats,
1598 storeexcludepats=excludepats,
1598 storeexcludepats=excludepats,
1599 depth=opts.get('depth') or None)
1599 depth=opts.get('depth') or None)
1600
1600
1601 return r is None
1601 return r is None
1602
1602
1603 @command('commit|ci',
1603 @command('commit|ci',
1604 [('A', 'addremove', None,
1604 [('A', 'addremove', None,
1605 _('mark new/missing files as added/removed before committing')),
1605 _('mark new/missing files as added/removed before committing')),
1606 ('', 'close-branch', None,
1606 ('', 'close-branch', None,
1607 _('mark a branch head as closed')),
1607 _('mark a branch head as closed')),
1608 ('', 'amend', None, _('amend the parent of the working directory')),
1608 ('', 'amend', None, _('amend the parent of the working directory')),
1609 ('s', 'secret', None, _('use the secret phase for committing')),
1609 ('s', 'secret', None, _('use the secret phase for committing')),
1610 ('e', 'edit', None, _('invoke editor on commit messages')),
1610 ('e', 'edit', None, _('invoke editor on commit messages')),
1611 ('', 'force-close-branch', None,
1611 ('', 'force-close-branch', None,
1612 _('forcibly close branch from a non-head changeset (ADVANCED)')),
1612 _('forcibly close branch from a non-head changeset (ADVANCED)')),
1613 ('i', 'interactive', None, _('use interactive mode')),
1613 ('i', 'interactive', None, _('use interactive mode')),
1614 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1614 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1615 _('[OPTION]... [FILE]...'),
1615 _('[OPTION]... [FILE]...'),
1616 helpcategory=command.CATEGORY_COMMITTING, helpbasic=True,
1616 helpcategory=command.CATEGORY_COMMITTING, helpbasic=True,
1617 inferrepo=True)
1617 inferrepo=True)
1618 def commit(ui, repo, *pats, **opts):
1618 def commit(ui, repo, *pats, **opts):
1619 """commit the specified files or all outstanding changes
1619 """commit the specified files or all outstanding changes
1620
1620
1621 Commit changes to the given files into the repository. Unlike a
1621 Commit changes to the given files into the repository. Unlike a
1622 centralized SCM, this operation is a local operation. See
1622 centralized SCM, this operation is a local operation. See
1623 :hg:`push` for a way to actively distribute your changes.
1623 :hg:`push` for a way to actively distribute your changes.
1624
1624
1625 If a list of files is omitted, all changes reported by :hg:`status`
1625 If a list of files is omitted, all changes reported by :hg:`status`
1626 will be committed.
1626 will be committed.
1627
1627
1628 If you are committing the result of a merge, do not provide any
1628 If you are committing the result of a merge, do not provide any
1629 filenames or -I/-X filters.
1629 filenames or -I/-X filters.
1630
1630
1631 If no commit message is specified, Mercurial starts your
1631 If no commit message is specified, Mercurial starts your
1632 configured editor where you can enter a message. In case your
1632 configured editor where you can enter a message. In case your
1633 commit fails, you will find a backup of your message in
1633 commit fails, you will find a backup of your message in
1634 ``.hg/last-message.txt``.
1634 ``.hg/last-message.txt``.
1635
1635
1636 The --close-branch flag can be used to mark the current branch
1636 The --close-branch flag can be used to mark the current branch
1637 head closed. When all heads of a branch are closed, the branch
1637 head closed. When all heads of a branch are closed, the branch
1638 will be considered closed and no longer listed.
1638 will be considered closed and no longer listed.
1639
1639
1640 The --amend flag can be used to amend the parent of the
1640 The --amend flag can be used to amend the parent of the
1641 working directory with a new commit that contains the changes
1641 working directory with a new commit that contains the changes
1642 in the parent in addition to those currently reported by :hg:`status`,
1642 in the parent in addition to those currently reported by :hg:`status`,
1643 if there are any. The old commit is stored in a backup bundle in
1643 if there are any. The old commit is stored in a backup bundle in
1644 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1644 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1645 on how to restore it).
1645 on how to restore it).
1646
1646
1647 Message, user and date are taken from the amended commit unless
1647 Message, user and date are taken from the amended commit unless
1648 specified. When a message isn't specified on the command line,
1648 specified. When a message isn't specified on the command line,
1649 the editor will open with the message of the amended commit.
1649 the editor will open with the message of the amended commit.
1650
1650
1651 It is not possible to amend public changesets (see :hg:`help phases`)
1651 It is not possible to amend public changesets (see :hg:`help phases`)
1652 or changesets that have children.
1652 or changesets that have children.
1653
1653
1654 See :hg:`help dates` for a list of formats valid for -d/--date.
1654 See :hg:`help dates` for a list of formats valid for -d/--date.
1655
1655
1656 Returns 0 on success, 1 if nothing changed.
1656 Returns 0 on success, 1 if nothing changed.
1657
1657
1658 .. container:: verbose
1658 .. container:: verbose
1659
1659
1660 Examples:
1660 Examples:
1661
1661
1662 - commit all files ending in .py::
1662 - commit all files ending in .py::
1663
1663
1664 hg commit --include "set:**.py"
1664 hg commit --include "set:**.py"
1665
1665
1666 - commit all non-binary files::
1666 - commit all non-binary files::
1667
1667
1668 hg commit --exclude "set:binary()"
1668 hg commit --exclude "set:binary()"
1669
1669
1670 - amend the current commit and set the date to now::
1670 - amend the current commit and set the date to now::
1671
1671
1672 hg commit --amend --date now
1672 hg commit --amend --date now
1673 """
1673 """
1674 with repo.wlock(), repo.lock():
1674 with repo.wlock(), repo.lock():
1675 return _docommit(ui, repo, *pats, **opts)
1675 return _docommit(ui, repo, *pats, **opts)
1676
1676
1677 def _docommit(ui, repo, *pats, **opts):
1677 def _docommit(ui, repo, *pats, **opts):
1678 if opts.get(r'interactive'):
1678 if opts.get(r'interactive'):
1679 opts.pop(r'interactive')
1679 opts.pop(r'interactive')
1680 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1680 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1681 cmdutil.recordfilter, *pats,
1681 cmdutil.recordfilter, *pats,
1682 **opts)
1682 **opts)
1683 # ret can be 0 (no changes to record) or the value returned by
1683 # ret can be 0 (no changes to record) or the value returned by
1684 # commit(), 1 if nothing changed or None on success.
1684 # commit(), 1 if nothing changed or None on success.
1685 return 1 if ret == 0 else ret
1685 return 1 if ret == 0 else ret
1686
1686
1687 opts = pycompat.byteskwargs(opts)
1687 opts = pycompat.byteskwargs(opts)
1688 if opts.get('subrepos'):
1688 if opts.get('subrepos'):
1689 if opts.get('amend'):
1689 if opts.get('amend'):
1690 raise error.Abort(_('cannot amend with --subrepos'))
1690 raise error.Abort(_('cannot amend with --subrepos'))
1691 # Let --subrepos on the command line override config setting.
1691 # Let --subrepos on the command line override config setting.
1692 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1692 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1693
1693
1694 cmdutil.checkunfinished(repo, commit=True)
1694 cmdutil.checkunfinished(repo, commit=True)
1695
1695
1696 branch = repo[None].branch()
1696 branch = repo[None].branch()
1697 bheads = repo.branchheads(branch)
1697 bheads = repo.branchheads(branch)
1698
1698
1699 extra = {}
1699 extra = {}
1700 if opts.get('close_branch') or opts.get('force_close_branch'):
1700 if opts.get('close_branch') or opts.get('force_close_branch'):
1701 extra['close'] = '1'
1701 extra['close'] = '1'
1702
1702
1703 if repo['.'].closesbranch():
1703 if repo['.'].closesbranch():
1704 raise error.Abort(_('current revision is already a branch closing'
1704 raise error.Abort(_('current revision is already a branch closing'
1705 ' head'))
1705 ' head'))
1706 elif not bheads:
1706 elif not bheads:
1707 raise error.Abort(_('branch "%s" has no heads to close') % branch)
1707 raise error.Abort(_('branch "%s" has no heads to close') % branch)
1708 elif (branch == repo['.'].branch() and repo['.'].node() not in bheads
1708 elif (branch == repo['.'].branch() and repo['.'].node() not in bheads
1709 and not opts.get('force_close_branch')):
1709 and not opts.get('force_close_branch')):
1710 hint = _('use --force-close-branch to close branch from a non-head'
1710 hint = _('use --force-close-branch to close branch from a non-head'
1711 ' changeset')
1711 ' changeset')
1712 raise error.Abort(_('can only close branch heads'), hint=hint)
1712 raise error.Abort(_('can only close branch heads'), hint=hint)
1713 elif opts.get('amend'):
1713 elif opts.get('amend'):
1714 if (repo['.'].p1().branch() != branch and
1714 if (repo['.'].p1().branch() != branch and
1715 repo['.'].p2().branch() != branch):
1715 repo['.'].p2().branch() != branch):
1716 raise error.Abort(_('can only close branch heads'))
1716 raise error.Abort(_('can only close branch heads'))
1717
1717
1718 if opts.get('amend'):
1718 if opts.get('amend'):
1719 if ui.configbool('ui', 'commitsubrepos'):
1719 if ui.configbool('ui', 'commitsubrepos'):
1720 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1720 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1721
1721
1722 old = repo['.']
1722 old = repo['.']
1723 rewriteutil.precheck(repo, [old.rev()], 'amend')
1723 rewriteutil.precheck(repo, [old.rev()], 'amend')
1724
1724
1725 # Currently histedit gets confused if an amend happens while histedit
1725 # Currently histedit gets confused if an amend happens while histedit
1726 # is in progress. Since we have a checkunfinished command, we are
1726 # is in progress. Since we have a checkunfinished command, we are
1727 # temporarily honoring it.
1727 # temporarily honoring it.
1728 #
1728 #
1729 # Note: eventually this guard will be removed. Please do not expect
1729 # Note: eventually this guard will be removed. Please do not expect
1730 # this behavior to remain.
1730 # this behavior to remain.
1731 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1731 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1732 cmdutil.checkunfinished(repo)
1732 cmdutil.checkunfinished(repo)
1733
1733
1734 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
1734 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
1735 if node == old.node():
1735 if node == old.node():
1736 ui.status(_("nothing changed\n"))
1736 ui.status(_("nothing changed\n"))
1737 return 1
1737 return 1
1738 else:
1738 else:
1739 def commitfunc(ui, repo, message, match, opts):
1739 def commitfunc(ui, repo, message, match, opts):
1740 overrides = {}
1740 overrides = {}
1741 if opts.get('secret'):
1741 if opts.get('secret'):
1742 overrides[('phases', 'new-commit')] = 'secret'
1742 overrides[('phases', 'new-commit')] = 'secret'
1743
1743
1744 baseui = repo.baseui
1744 baseui = repo.baseui
1745 with baseui.configoverride(overrides, 'commit'):
1745 with baseui.configoverride(overrides, 'commit'):
1746 with ui.configoverride(overrides, 'commit'):
1746 with ui.configoverride(overrides, 'commit'):
1747 editform = cmdutil.mergeeditform(repo[None],
1747 editform = cmdutil.mergeeditform(repo[None],
1748 'commit.normal')
1748 'commit.normal')
1749 editor = cmdutil.getcommiteditor(
1749 editor = cmdutil.getcommiteditor(
1750 editform=editform, **pycompat.strkwargs(opts))
1750 editform=editform, **pycompat.strkwargs(opts))
1751 return repo.commit(message,
1751 return repo.commit(message,
1752 opts.get('user'),
1752 opts.get('user'),
1753 opts.get('date'),
1753 opts.get('date'),
1754 match,
1754 match,
1755 editor=editor,
1755 editor=editor,
1756 extra=extra)
1756 extra=extra)
1757
1757
1758 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1758 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1759
1759
1760 if not node:
1760 if not node:
1761 stat = cmdutil.postcommitstatus(repo, pats, opts)
1761 stat = cmdutil.postcommitstatus(repo, pats, opts)
1762 if stat[3]:
1762 if stat[3]:
1763 ui.status(_("nothing changed (%d missing files, see "
1763 ui.status(_("nothing changed (%d missing files, see "
1764 "'hg status')\n") % len(stat[3]))
1764 "'hg status')\n") % len(stat[3]))
1765 else:
1765 else:
1766 ui.status(_("nothing changed\n"))
1766 ui.status(_("nothing changed\n"))
1767 return 1
1767 return 1
1768
1768
1769 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1769 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1770
1770
1771 if not ui.quiet and ui.configbool('commands', 'commit.post-status'):
1771 if not ui.quiet and ui.configbool('commands', 'commit.post-status'):
1772 status(ui, repo, modified=True, added=True, removed=True, deleted=True,
1772 status(ui, repo, modified=True, added=True, removed=True, deleted=True,
1773 unknown=True, subrepos=opts.get('subrepos'))
1773 unknown=True, subrepos=opts.get('subrepos'))
1774
1774
1775 @command('config|showconfig|debugconfig',
1775 @command('config|showconfig|debugconfig',
1776 [('u', 'untrusted', None, _('show untrusted configuration options')),
1776 [('u', 'untrusted', None, _('show untrusted configuration options')),
1777 ('e', 'edit', None, _('edit user config')),
1777 ('e', 'edit', None, _('edit user config')),
1778 ('l', 'local', None, _('edit repository config')),
1778 ('l', 'local', None, _('edit repository config')),
1779 ('g', 'global', None, _('edit global config'))] + formatteropts,
1779 ('g', 'global', None, _('edit global config'))] + formatteropts,
1780 _('[-u] [NAME]...'),
1780 _('[-u] [NAME]...'),
1781 helpcategory=command.CATEGORY_HELP,
1781 helpcategory=command.CATEGORY_HELP,
1782 optionalrepo=True,
1782 optionalrepo=True,
1783 intents={INTENT_READONLY})
1783 intents={INTENT_READONLY})
1784 def config(ui, repo, *values, **opts):
1784 def config(ui, repo, *values, **opts):
1785 """show combined config settings from all hgrc files
1785 """show combined config settings from all hgrc files
1786
1786
1787 With no arguments, print names and values of all config items.
1787 With no arguments, print names and values of all config items.
1788
1788
1789 With one argument of the form section.name, print just the value
1789 With one argument of the form section.name, print just the value
1790 of that config item.
1790 of that config item.
1791
1791
1792 With multiple arguments, print names and values of all config
1792 With multiple arguments, print names and values of all config
1793 items with matching section names or section.names.
1793 items with matching section names or section.names.
1794
1794
1795 With --edit, start an editor on the user-level config file. With
1795 With --edit, start an editor on the user-level config file. With
1796 --global, edit the system-wide config file. With --local, edit the
1796 --global, edit the system-wide config file. With --local, edit the
1797 repository-level config file.
1797 repository-level config file.
1798
1798
1799 With --debug, the source (filename and line number) is printed
1799 With --debug, the source (filename and line number) is printed
1800 for each config item.
1800 for each config item.
1801
1801
1802 See :hg:`help config` for more information about config files.
1802 See :hg:`help config` for more information about config files.
1803
1803
1804 .. container:: verbose
1804 .. container:: verbose
1805
1805
1806 Template:
1806 Template:
1807
1807
1808 The following keywords are supported. See also :hg:`help templates`.
1808 The following keywords are supported. See also :hg:`help templates`.
1809
1809
1810 :name: String. Config name.
1810 :name: String. Config name.
1811 :source: String. Filename and line number where the item is defined.
1811 :source: String. Filename and line number where the item is defined.
1812 :value: String. Config value.
1812 :value: String. Config value.
1813
1813
1814 Returns 0 on success, 1 if NAME does not exist.
1814 Returns 0 on success, 1 if NAME does not exist.
1815
1815
1816 """
1816 """
1817
1817
1818 opts = pycompat.byteskwargs(opts)
1818 opts = pycompat.byteskwargs(opts)
1819 if opts.get('edit') or opts.get('local') or opts.get('global'):
1819 if opts.get('edit') or opts.get('local') or opts.get('global'):
1820 if opts.get('local') and opts.get('global'):
1820 if opts.get('local') and opts.get('global'):
1821 raise error.Abort(_("can't use --local and --global together"))
1821 raise error.Abort(_("can't use --local and --global together"))
1822
1822
1823 if opts.get('local'):
1823 if opts.get('local'):
1824 if not repo:
1824 if not repo:
1825 raise error.Abort(_("can't use --local outside a repository"))
1825 raise error.Abort(_("can't use --local outside a repository"))
1826 paths = [repo.vfs.join('hgrc')]
1826 paths = [repo.vfs.join('hgrc')]
1827 elif opts.get('global'):
1827 elif opts.get('global'):
1828 paths = rcutil.systemrcpath()
1828 paths = rcutil.systemrcpath()
1829 else:
1829 else:
1830 paths = rcutil.userrcpath()
1830 paths = rcutil.userrcpath()
1831
1831
1832 for f in paths:
1832 for f in paths:
1833 if os.path.exists(f):
1833 if os.path.exists(f):
1834 break
1834 break
1835 else:
1835 else:
1836 if opts.get('global'):
1836 if opts.get('global'):
1837 samplehgrc = uimod.samplehgrcs['global']
1837 samplehgrc = uimod.samplehgrcs['global']
1838 elif opts.get('local'):
1838 elif opts.get('local'):
1839 samplehgrc = uimod.samplehgrcs['local']
1839 samplehgrc = uimod.samplehgrcs['local']
1840 else:
1840 else:
1841 samplehgrc = uimod.samplehgrcs['user']
1841 samplehgrc = uimod.samplehgrcs['user']
1842
1842
1843 f = paths[0]
1843 f = paths[0]
1844 fp = open(f, "wb")
1844 fp = open(f, "wb")
1845 fp.write(util.tonativeeol(samplehgrc))
1845 fp.write(util.tonativeeol(samplehgrc))
1846 fp.close()
1846 fp.close()
1847
1847
1848 editor = ui.geteditor()
1848 editor = ui.geteditor()
1849 ui.system("%s \"%s\"" % (editor, f),
1849 ui.system("%s \"%s\"" % (editor, f),
1850 onerr=error.Abort, errprefix=_("edit failed"),
1850 onerr=error.Abort, errprefix=_("edit failed"),
1851 blockedtag='config_edit')
1851 blockedtag='config_edit')
1852 return
1852 return
1853 ui.pager('config')
1853 ui.pager('config')
1854 fm = ui.formatter('config', opts)
1854 fm = ui.formatter('config', opts)
1855 for t, f in rcutil.rccomponents():
1855 for t, f in rcutil.rccomponents():
1856 if t == 'path':
1856 if t == 'path':
1857 ui.debug('read config from: %s\n' % f)
1857 ui.debug('read config from: %s\n' % f)
1858 elif t == 'items':
1858 elif t == 'items':
1859 for section, name, value, source in f:
1859 for section, name, value, source in f:
1860 ui.debug('set config by: %s\n' % source)
1860 ui.debug('set config by: %s\n' % source)
1861 else:
1861 else:
1862 raise error.ProgrammingError('unknown rctype: %s' % t)
1862 raise error.ProgrammingError('unknown rctype: %s' % t)
1863 untrusted = bool(opts.get('untrusted'))
1863 untrusted = bool(opts.get('untrusted'))
1864
1864
1865 selsections = selentries = []
1865 selsections = selentries = []
1866 if values:
1866 if values:
1867 selsections = [v for v in values if '.' not in v]
1867 selsections = [v for v in values if '.' not in v]
1868 selentries = [v for v in values if '.' in v]
1868 selentries = [v for v in values if '.' in v]
1869 uniquesel = (len(selentries) == 1 and not selsections)
1869 uniquesel = (len(selentries) == 1 and not selsections)
1870 selsections = set(selsections)
1870 selsections = set(selsections)
1871 selentries = set(selentries)
1871 selentries = set(selentries)
1872
1872
1873 matched = False
1873 matched = False
1874 for section, name, value in ui.walkconfig(untrusted=untrusted):
1874 for section, name, value in ui.walkconfig(untrusted=untrusted):
1875 source = ui.configsource(section, name, untrusted)
1875 source = ui.configsource(section, name, untrusted)
1876 value = pycompat.bytestr(value)
1876 value = pycompat.bytestr(value)
1877 if fm.isplain():
1877 if fm.isplain():
1878 source = source or 'none'
1878 source = source or 'none'
1879 value = value.replace('\n', '\\n')
1879 value = value.replace('\n', '\\n')
1880 entryname = section + '.' + name
1880 entryname = section + '.' + name
1881 if values and not (section in selsections or entryname in selentries):
1881 if values and not (section in selsections or entryname in selentries):
1882 continue
1882 continue
1883 fm.startitem()
1883 fm.startitem()
1884 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1884 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1885 if uniquesel:
1885 if uniquesel:
1886 fm.data(name=entryname)
1886 fm.data(name=entryname)
1887 fm.write('value', '%s\n', value)
1887 fm.write('value', '%s\n', value)
1888 else:
1888 else:
1889 fm.write('name value', '%s=%s\n', entryname, value)
1889 fm.write('name value', '%s=%s\n', entryname, value)
1890 matched = True
1890 matched = True
1891 fm.end()
1891 fm.end()
1892 if matched:
1892 if matched:
1893 return 0
1893 return 0
1894 return 1
1894 return 1
1895
1895
1896 @command('continue',
1897 dryrunopts, helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
1898 helpbasic=True)
1899 def continuecmd(ui, repo, **opts):
1900 """resumes an interrupted operation (EXPERIMENTAL)
1901
1902 Finishes a multistep operation like graft, histedit, rebase, merge,
1903 and unshelve if they are in an interrupted state.
1904
1905 use --dry-run/-n to dry run the command.
1906 A new operation can be added to this by registering the operation and
1907 continue logic in the unfinishedstates list under statemod.
1908 """
1909 dryrun = opts.get(r'dry_run')
1910 contstate = cmdutil.getunfinishedstate(repo)
1911 if not contstate:
1912 raise error.Abort(_('no operation in progress'))
1913 if not contstate.continuefunc:
1914 raise error.Abort((_("%s in progress but does not support "
1915 "'hg continue'") % (contstate._opname)),
1916 hint=contstate.continuemsg())
1917 if dryrun:
1918 ui.status(_('%s in progress, will be resumed\n') % (contstate._opname))
1919 return
1920 return contstate.continuefunc(ui, repo)
1921
1896 @command('copy|cp',
1922 @command('copy|cp',
1897 [('A', 'after', None, _('record a copy that has already occurred')),
1923 [('A', 'after', None, _('record a copy that has already occurred')),
1898 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1924 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1899 ] + walkopts + dryrunopts,
1925 ] + walkopts + dryrunopts,
1900 _('[OPTION]... SOURCE... DEST'),
1926 _('[OPTION]... SOURCE... DEST'),
1901 helpcategory=command.CATEGORY_FILE_CONTENTS)
1927 helpcategory=command.CATEGORY_FILE_CONTENTS)
1902 def copy(ui, repo, *pats, **opts):
1928 def copy(ui, repo, *pats, **opts):
1903 """mark files as copied for the next commit
1929 """mark files as copied for the next commit
1904
1930
1905 Mark dest as having copies of source files. If dest is a
1931 Mark dest as having copies of source files. If dest is a
1906 directory, copies are put in that directory. If dest is a file,
1932 directory, copies are put in that directory. If dest is a file,
1907 the source must be a single file.
1933 the source must be a single file.
1908
1934
1909 By default, this command copies the contents of files as they
1935 By default, this command copies the contents of files as they
1910 exist in the working directory. If invoked with -A/--after, the
1936 exist in the working directory. If invoked with -A/--after, the
1911 operation is recorded, but no copying is performed.
1937 operation is recorded, but no copying is performed.
1912
1938
1913 This command takes effect with the next commit. To undo a copy
1939 This command takes effect with the next commit. To undo a copy
1914 before that, see :hg:`revert`.
1940 before that, see :hg:`revert`.
1915
1941
1916 Returns 0 on success, 1 if errors are encountered.
1942 Returns 0 on success, 1 if errors are encountered.
1917 """
1943 """
1918 opts = pycompat.byteskwargs(opts)
1944 opts = pycompat.byteskwargs(opts)
1919 with repo.wlock(False):
1945 with repo.wlock(False):
1920 return cmdutil.copy(ui, repo, pats, opts)
1946 return cmdutil.copy(ui, repo, pats, opts)
1921
1947
1922 @command(
1948 @command(
1923 'debugcommands', [], _('[COMMAND]'),
1949 'debugcommands', [], _('[COMMAND]'),
1924 helpcategory=command.CATEGORY_HELP,
1950 helpcategory=command.CATEGORY_HELP,
1925 norepo=True)
1951 norepo=True)
1926 def debugcommands(ui, cmd='', *args):
1952 def debugcommands(ui, cmd='', *args):
1927 """list all available commands and options"""
1953 """list all available commands and options"""
1928 for cmd, vals in sorted(table.iteritems()):
1954 for cmd, vals in sorted(table.iteritems()):
1929 cmd = cmd.split('|')[0]
1955 cmd = cmd.split('|')[0]
1930 opts = ', '.join([i[1] for i in vals[1]])
1956 opts = ', '.join([i[1] for i in vals[1]])
1931 ui.write('%s: %s\n' % (cmd, opts))
1957 ui.write('%s: %s\n' % (cmd, opts))
1932
1958
1933 @command('debugcomplete',
1959 @command('debugcomplete',
1934 [('o', 'options', None, _('show the command options'))],
1960 [('o', 'options', None, _('show the command options'))],
1935 _('[-o] CMD'),
1961 _('[-o] CMD'),
1936 helpcategory=command.CATEGORY_HELP,
1962 helpcategory=command.CATEGORY_HELP,
1937 norepo=True)
1963 norepo=True)
1938 def debugcomplete(ui, cmd='', **opts):
1964 def debugcomplete(ui, cmd='', **opts):
1939 """returns the completion list associated with the given command"""
1965 """returns the completion list associated with the given command"""
1940
1966
1941 if opts.get(r'options'):
1967 if opts.get(r'options'):
1942 options = []
1968 options = []
1943 otables = [globalopts]
1969 otables = [globalopts]
1944 if cmd:
1970 if cmd:
1945 aliases, entry = cmdutil.findcmd(cmd, table, False)
1971 aliases, entry = cmdutil.findcmd(cmd, table, False)
1946 otables.append(entry[1])
1972 otables.append(entry[1])
1947 for t in otables:
1973 for t in otables:
1948 for o in t:
1974 for o in t:
1949 if "(DEPRECATED)" in o[3]:
1975 if "(DEPRECATED)" in o[3]:
1950 continue
1976 continue
1951 if o[0]:
1977 if o[0]:
1952 options.append('-%s' % o[0])
1978 options.append('-%s' % o[0])
1953 options.append('--%s' % o[1])
1979 options.append('--%s' % o[1])
1954 ui.write("%s\n" % "\n".join(options))
1980 ui.write("%s\n" % "\n".join(options))
1955 return
1981 return
1956
1982
1957 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
1983 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
1958 if ui.verbose:
1984 if ui.verbose:
1959 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1985 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1960 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1986 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1961
1987
1962 @command('diff',
1988 @command('diff',
1963 [('r', 'rev', [], _('revision'), _('REV')),
1989 [('r', 'rev', [], _('revision'), _('REV')),
1964 ('c', 'change', '', _('change made by revision'), _('REV'))
1990 ('c', 'change', '', _('change made by revision'), _('REV'))
1965 ] + diffopts + diffopts2 + walkopts + subrepoopts,
1991 ] + diffopts + diffopts2 + walkopts + subrepoopts,
1966 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1992 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1967 helpcategory=command.CATEGORY_FILE_CONTENTS,
1993 helpcategory=command.CATEGORY_FILE_CONTENTS,
1968 helpbasic=True, inferrepo=True, intents={INTENT_READONLY})
1994 helpbasic=True, inferrepo=True, intents={INTENT_READONLY})
1969 def diff(ui, repo, *pats, **opts):
1995 def diff(ui, repo, *pats, **opts):
1970 """diff repository (or selected files)
1996 """diff repository (or selected files)
1971
1997
1972 Show differences between revisions for the specified files.
1998 Show differences between revisions for the specified files.
1973
1999
1974 Differences between files are shown using the unified diff format.
2000 Differences between files are shown using the unified diff format.
1975
2001
1976 .. note::
2002 .. note::
1977
2003
1978 :hg:`diff` may generate unexpected results for merges, as it will
2004 :hg:`diff` may generate unexpected results for merges, as it will
1979 default to comparing against the working directory's first
2005 default to comparing against the working directory's first
1980 parent changeset if no revisions are specified.
2006 parent changeset if no revisions are specified.
1981
2007
1982 When two revision arguments are given, then changes are shown
2008 When two revision arguments are given, then changes are shown
1983 between those revisions. If only one revision is specified then
2009 between those revisions. If only one revision is specified then
1984 that revision is compared to the working directory, and, when no
2010 that revision is compared to the working directory, and, when no
1985 revisions are specified, the working directory files are compared
2011 revisions are specified, the working directory files are compared
1986 to its first parent.
2012 to its first parent.
1987
2013
1988 Alternatively you can specify -c/--change with a revision to see
2014 Alternatively you can specify -c/--change with a revision to see
1989 the changes in that changeset relative to its first parent.
2015 the changes in that changeset relative to its first parent.
1990
2016
1991 Without the -a/--text option, diff will avoid generating diffs of
2017 Without the -a/--text option, diff will avoid generating diffs of
1992 files it detects as binary. With -a, diff will generate a diff
2018 files it detects as binary. With -a, diff will generate a diff
1993 anyway, probably with undesirable results.
2019 anyway, probably with undesirable results.
1994
2020
1995 Use the -g/--git option to generate diffs in the git extended diff
2021 Use the -g/--git option to generate diffs in the git extended diff
1996 format. For more information, read :hg:`help diffs`.
2022 format. For more information, read :hg:`help diffs`.
1997
2023
1998 .. container:: verbose
2024 .. container:: verbose
1999
2025
2000 Examples:
2026 Examples:
2001
2027
2002 - compare a file in the current working directory to its parent::
2028 - compare a file in the current working directory to its parent::
2003
2029
2004 hg diff foo.c
2030 hg diff foo.c
2005
2031
2006 - compare two historical versions of a directory, with rename info::
2032 - compare two historical versions of a directory, with rename info::
2007
2033
2008 hg diff --git -r 1.0:1.2 lib/
2034 hg diff --git -r 1.0:1.2 lib/
2009
2035
2010 - get change stats relative to the last change on some date::
2036 - get change stats relative to the last change on some date::
2011
2037
2012 hg diff --stat -r "date('may 2')"
2038 hg diff --stat -r "date('may 2')"
2013
2039
2014 - diff all newly-added files that contain a keyword::
2040 - diff all newly-added files that contain a keyword::
2015
2041
2016 hg diff "set:added() and grep(GNU)"
2042 hg diff "set:added() and grep(GNU)"
2017
2043
2018 - compare a revision and its parents::
2044 - compare a revision and its parents::
2019
2045
2020 hg diff -c 9353 # compare against first parent
2046 hg diff -c 9353 # compare against first parent
2021 hg diff -r 9353^:9353 # same using revset syntax
2047 hg diff -r 9353^:9353 # same using revset syntax
2022 hg diff -r 9353^2:9353 # compare against the second parent
2048 hg diff -r 9353^2:9353 # compare against the second parent
2023
2049
2024 Returns 0 on success.
2050 Returns 0 on success.
2025 """
2051 """
2026
2052
2027 opts = pycompat.byteskwargs(opts)
2053 opts = pycompat.byteskwargs(opts)
2028 revs = opts.get('rev')
2054 revs = opts.get('rev')
2029 change = opts.get('change')
2055 change = opts.get('change')
2030 stat = opts.get('stat')
2056 stat = opts.get('stat')
2031 reverse = opts.get('reverse')
2057 reverse = opts.get('reverse')
2032
2058
2033 if revs and change:
2059 if revs and change:
2034 msg = _('cannot specify --rev and --change at the same time')
2060 msg = _('cannot specify --rev and --change at the same time')
2035 raise error.Abort(msg)
2061 raise error.Abort(msg)
2036 elif change:
2062 elif change:
2037 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
2063 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
2038 ctx2 = scmutil.revsingle(repo, change, None)
2064 ctx2 = scmutil.revsingle(repo, change, None)
2039 ctx1 = ctx2.p1()
2065 ctx1 = ctx2.p1()
2040 else:
2066 else:
2041 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
2067 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
2042 ctx1, ctx2 = scmutil.revpair(repo, revs)
2068 ctx1, ctx2 = scmutil.revpair(repo, revs)
2043 node1, node2 = ctx1.node(), ctx2.node()
2069 node1, node2 = ctx1.node(), ctx2.node()
2044
2070
2045 if reverse:
2071 if reverse:
2046 node1, node2 = node2, node1
2072 node1, node2 = node2, node1
2047
2073
2048 diffopts = patch.diffallopts(ui, opts)
2074 diffopts = patch.diffallopts(ui, opts)
2049 m = scmutil.match(ctx2, pats, opts)
2075 m = scmutil.match(ctx2, pats, opts)
2050 m = repo.narrowmatch(m)
2076 m = repo.narrowmatch(m)
2051 ui.pager('diff')
2077 ui.pager('diff')
2052 logcmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2078 logcmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2053 listsubrepos=opts.get('subrepos'),
2079 listsubrepos=opts.get('subrepos'),
2054 root=opts.get('root'))
2080 root=opts.get('root'))
2055
2081
2056 @command('export',
2082 @command('export',
2057 [('B', 'bookmark', '',
2083 [('B', 'bookmark', '',
2058 _('export changes only reachable by given bookmark'), _('BOOKMARK')),
2084 _('export changes only reachable by given bookmark'), _('BOOKMARK')),
2059 ('o', 'output', '',
2085 ('o', 'output', '',
2060 _('print output to file with formatted name'), _('FORMAT')),
2086 _('print output to file with formatted name'), _('FORMAT')),
2061 ('', 'switch-parent', None, _('diff against the second parent')),
2087 ('', 'switch-parent', None, _('diff against the second parent')),
2062 ('r', 'rev', [], _('revisions to export'), _('REV')),
2088 ('r', 'rev', [], _('revisions to export'), _('REV')),
2063 ] + diffopts + formatteropts,
2089 ] + diffopts + formatteropts,
2064 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2090 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2065 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2091 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2066 helpbasic=True, intents={INTENT_READONLY})
2092 helpbasic=True, intents={INTENT_READONLY})
2067 def export(ui, repo, *changesets, **opts):
2093 def export(ui, repo, *changesets, **opts):
2068 """dump the header and diffs for one or more changesets
2094 """dump the header and diffs for one or more changesets
2069
2095
2070 Print the changeset header and diffs for one or more revisions.
2096 Print the changeset header and diffs for one or more revisions.
2071 If no revision is given, the parent of the working directory is used.
2097 If no revision is given, the parent of the working directory is used.
2072
2098
2073 The information shown in the changeset header is: author, date,
2099 The information shown in the changeset header is: author, date,
2074 branch name (if non-default), changeset hash, parent(s) and commit
2100 branch name (if non-default), changeset hash, parent(s) and commit
2075 comment.
2101 comment.
2076
2102
2077 .. note::
2103 .. note::
2078
2104
2079 :hg:`export` may generate unexpected diff output for merge
2105 :hg:`export` may generate unexpected diff output for merge
2080 changesets, as it will compare the merge changeset against its
2106 changesets, as it will compare the merge changeset against its
2081 first parent only.
2107 first parent only.
2082
2108
2083 Output may be to a file, in which case the name of the file is
2109 Output may be to a file, in which case the name of the file is
2084 given using a template string. See :hg:`help templates`. In addition
2110 given using a template string. See :hg:`help templates`. In addition
2085 to the common template keywords, the following formatting rules are
2111 to the common template keywords, the following formatting rules are
2086 supported:
2112 supported:
2087
2113
2088 :``%%``: literal "%" character
2114 :``%%``: literal "%" character
2089 :``%H``: changeset hash (40 hexadecimal digits)
2115 :``%H``: changeset hash (40 hexadecimal digits)
2090 :``%N``: number of patches being generated
2116 :``%N``: number of patches being generated
2091 :``%R``: changeset revision number
2117 :``%R``: changeset revision number
2092 :``%b``: basename of the exporting repository
2118 :``%b``: basename of the exporting repository
2093 :``%h``: short-form changeset hash (12 hexadecimal digits)
2119 :``%h``: short-form changeset hash (12 hexadecimal digits)
2094 :``%m``: first line of the commit message (only alphanumeric characters)
2120 :``%m``: first line of the commit message (only alphanumeric characters)
2095 :``%n``: zero-padded sequence number, starting at 1
2121 :``%n``: zero-padded sequence number, starting at 1
2096 :``%r``: zero-padded changeset revision number
2122 :``%r``: zero-padded changeset revision number
2097 :``\\``: literal "\\" character
2123 :``\\``: literal "\\" character
2098
2124
2099 Without the -a/--text option, export will avoid generating diffs
2125 Without the -a/--text option, export will avoid generating diffs
2100 of files it detects as binary. With -a, export will generate a
2126 of files it detects as binary. With -a, export will generate a
2101 diff anyway, probably with undesirable results.
2127 diff anyway, probably with undesirable results.
2102
2128
2103 With -B/--bookmark changesets reachable by the given bookmark are
2129 With -B/--bookmark changesets reachable by the given bookmark are
2104 selected.
2130 selected.
2105
2131
2106 Use the -g/--git option to generate diffs in the git extended diff
2132 Use the -g/--git option to generate diffs in the git extended diff
2107 format. See :hg:`help diffs` for more information.
2133 format. See :hg:`help diffs` for more information.
2108
2134
2109 With the --switch-parent option, the diff will be against the
2135 With the --switch-parent option, the diff will be against the
2110 second parent. It can be useful to review a merge.
2136 second parent. It can be useful to review a merge.
2111
2137
2112 .. container:: verbose
2138 .. container:: verbose
2113
2139
2114 Template:
2140 Template:
2115
2141
2116 The following keywords are supported in addition to the common template
2142 The following keywords are supported in addition to the common template
2117 keywords and functions. See also :hg:`help templates`.
2143 keywords and functions. See also :hg:`help templates`.
2118
2144
2119 :diff: String. Diff content.
2145 :diff: String. Diff content.
2120 :parents: List of strings. Parent nodes of the changeset.
2146 :parents: List of strings. Parent nodes of the changeset.
2121
2147
2122 Examples:
2148 Examples:
2123
2149
2124 - use export and import to transplant a bugfix to the current
2150 - use export and import to transplant a bugfix to the current
2125 branch::
2151 branch::
2126
2152
2127 hg export -r 9353 | hg import -
2153 hg export -r 9353 | hg import -
2128
2154
2129 - export all the changesets between two revisions to a file with
2155 - export all the changesets between two revisions to a file with
2130 rename information::
2156 rename information::
2131
2157
2132 hg export --git -r 123:150 > changes.txt
2158 hg export --git -r 123:150 > changes.txt
2133
2159
2134 - split outgoing changes into a series of patches with
2160 - split outgoing changes into a series of patches with
2135 descriptive names::
2161 descriptive names::
2136
2162
2137 hg export -r "outgoing()" -o "%n-%m.patch"
2163 hg export -r "outgoing()" -o "%n-%m.patch"
2138
2164
2139 Returns 0 on success.
2165 Returns 0 on success.
2140 """
2166 """
2141 opts = pycompat.byteskwargs(opts)
2167 opts = pycompat.byteskwargs(opts)
2142 bookmark = opts.get('bookmark')
2168 bookmark = opts.get('bookmark')
2143 changesets += tuple(opts.get('rev', []))
2169 changesets += tuple(opts.get('rev', []))
2144
2170
2145 if bookmark and changesets:
2171 if bookmark and changesets:
2146 raise error.Abort(_("-r and -B are mutually exclusive"))
2172 raise error.Abort(_("-r and -B are mutually exclusive"))
2147
2173
2148 if bookmark:
2174 if bookmark:
2149 if bookmark not in repo._bookmarks:
2175 if bookmark not in repo._bookmarks:
2150 raise error.Abort(_("bookmark '%s' not found") % bookmark)
2176 raise error.Abort(_("bookmark '%s' not found") % bookmark)
2151
2177
2152 revs = scmutil.bookmarkrevs(repo, bookmark)
2178 revs = scmutil.bookmarkrevs(repo, bookmark)
2153 else:
2179 else:
2154 if not changesets:
2180 if not changesets:
2155 changesets = ['.']
2181 changesets = ['.']
2156
2182
2157 repo = scmutil.unhidehashlikerevs(repo, changesets, 'nowarn')
2183 repo = scmutil.unhidehashlikerevs(repo, changesets, 'nowarn')
2158 revs = scmutil.revrange(repo, changesets)
2184 revs = scmutil.revrange(repo, changesets)
2159
2185
2160 if not revs:
2186 if not revs:
2161 raise error.Abort(_("export requires at least one changeset"))
2187 raise error.Abort(_("export requires at least one changeset"))
2162 if len(revs) > 1:
2188 if len(revs) > 1:
2163 ui.note(_('exporting patches:\n'))
2189 ui.note(_('exporting patches:\n'))
2164 else:
2190 else:
2165 ui.note(_('exporting patch:\n'))
2191 ui.note(_('exporting patch:\n'))
2166
2192
2167 fntemplate = opts.get('output')
2193 fntemplate = opts.get('output')
2168 if cmdutil.isstdiofilename(fntemplate):
2194 if cmdutil.isstdiofilename(fntemplate):
2169 fntemplate = ''
2195 fntemplate = ''
2170
2196
2171 if fntemplate:
2197 if fntemplate:
2172 fm = formatter.nullformatter(ui, 'export', opts)
2198 fm = formatter.nullformatter(ui, 'export', opts)
2173 else:
2199 else:
2174 ui.pager('export')
2200 ui.pager('export')
2175 fm = ui.formatter('export', opts)
2201 fm = ui.formatter('export', opts)
2176 with fm:
2202 with fm:
2177 cmdutil.export(repo, revs, fm, fntemplate=fntemplate,
2203 cmdutil.export(repo, revs, fm, fntemplate=fntemplate,
2178 switch_parent=opts.get('switch_parent'),
2204 switch_parent=opts.get('switch_parent'),
2179 opts=patch.diffallopts(ui, opts))
2205 opts=patch.diffallopts(ui, opts))
2180
2206
2181 @command('files',
2207 @command('files',
2182 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2208 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2183 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2209 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2184 ] + walkopts + formatteropts + subrepoopts,
2210 ] + walkopts + formatteropts + subrepoopts,
2185 _('[OPTION]... [FILE]...'),
2211 _('[OPTION]... [FILE]...'),
2186 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2212 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2187 intents={INTENT_READONLY})
2213 intents={INTENT_READONLY})
2188 def files(ui, repo, *pats, **opts):
2214 def files(ui, repo, *pats, **opts):
2189 """list tracked files
2215 """list tracked files
2190
2216
2191 Print files under Mercurial control in the working directory or
2217 Print files under Mercurial control in the working directory or
2192 specified revision for given files (excluding removed files).
2218 specified revision for given files (excluding removed files).
2193 Files can be specified as filenames or filesets.
2219 Files can be specified as filenames or filesets.
2194
2220
2195 If no files are given to match, this command prints the names
2221 If no files are given to match, this command prints the names
2196 of all files under Mercurial control.
2222 of all files under Mercurial control.
2197
2223
2198 .. container:: verbose
2224 .. container:: verbose
2199
2225
2200 Template:
2226 Template:
2201
2227
2202 The following keywords are supported in addition to the common template
2228 The following keywords are supported in addition to the common template
2203 keywords and functions. See also :hg:`help templates`.
2229 keywords and functions. See also :hg:`help templates`.
2204
2230
2205 :flags: String. Character denoting file's symlink and executable bits.
2231 :flags: String. Character denoting file's symlink and executable bits.
2206 :path: String. Repository-absolute path of the file.
2232 :path: String. Repository-absolute path of the file.
2207 :size: Integer. Size of the file in bytes.
2233 :size: Integer. Size of the file in bytes.
2208
2234
2209 Examples:
2235 Examples:
2210
2236
2211 - list all files under the current directory::
2237 - list all files under the current directory::
2212
2238
2213 hg files .
2239 hg files .
2214
2240
2215 - shows sizes and flags for current revision::
2241 - shows sizes and flags for current revision::
2216
2242
2217 hg files -vr .
2243 hg files -vr .
2218
2244
2219 - list all files named README::
2245 - list all files named README::
2220
2246
2221 hg files -I "**/README"
2247 hg files -I "**/README"
2222
2248
2223 - list all binary files::
2249 - list all binary files::
2224
2250
2225 hg files "set:binary()"
2251 hg files "set:binary()"
2226
2252
2227 - find files containing a regular expression::
2253 - find files containing a regular expression::
2228
2254
2229 hg files "set:grep('bob')"
2255 hg files "set:grep('bob')"
2230
2256
2231 - search tracked file contents with xargs and grep::
2257 - search tracked file contents with xargs and grep::
2232
2258
2233 hg files -0 | xargs -0 grep foo
2259 hg files -0 | xargs -0 grep foo
2234
2260
2235 See :hg:`help patterns` and :hg:`help filesets` for more information
2261 See :hg:`help patterns` and :hg:`help filesets` for more information
2236 on specifying file patterns.
2262 on specifying file patterns.
2237
2263
2238 Returns 0 if a match is found, 1 otherwise.
2264 Returns 0 if a match is found, 1 otherwise.
2239
2265
2240 """
2266 """
2241
2267
2242 opts = pycompat.byteskwargs(opts)
2268 opts = pycompat.byteskwargs(opts)
2243 rev = opts.get('rev')
2269 rev = opts.get('rev')
2244 if rev:
2270 if rev:
2245 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
2271 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
2246 ctx = scmutil.revsingle(repo, rev, None)
2272 ctx = scmutil.revsingle(repo, rev, None)
2247
2273
2248 end = '\n'
2274 end = '\n'
2249 if opts.get('print0'):
2275 if opts.get('print0'):
2250 end = '\0'
2276 end = '\0'
2251 fmt = '%s' + end
2277 fmt = '%s' + end
2252
2278
2253 m = scmutil.match(ctx, pats, opts)
2279 m = scmutil.match(ctx, pats, opts)
2254 ui.pager('files')
2280 ui.pager('files')
2255 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2281 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2256 with ui.formatter('files', opts) as fm:
2282 with ui.formatter('files', opts) as fm:
2257 return cmdutil.files(ui, ctx, m, uipathfn, fm, fmt,
2283 return cmdutil.files(ui, ctx, m, uipathfn, fm, fmt,
2258 opts.get('subrepos'))
2284 opts.get('subrepos'))
2259
2285
2260 @command(
2286 @command(
2261 'forget',
2287 'forget',
2262 [('i', 'interactive', None, _('use interactive mode')),
2288 [('i', 'interactive', None, _('use interactive mode')),
2263 ] + walkopts + dryrunopts,
2289 ] + walkopts + dryrunopts,
2264 _('[OPTION]... FILE...'),
2290 _('[OPTION]... FILE...'),
2265 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2291 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2266 helpbasic=True, inferrepo=True)
2292 helpbasic=True, inferrepo=True)
2267 def forget(ui, repo, *pats, **opts):
2293 def forget(ui, repo, *pats, **opts):
2268 """forget the specified files on the next commit
2294 """forget the specified files on the next commit
2269
2295
2270 Mark the specified files so they will no longer be tracked
2296 Mark the specified files so they will no longer be tracked
2271 after the next commit.
2297 after the next commit.
2272
2298
2273 This only removes files from the current branch, not from the
2299 This only removes files from the current branch, not from the
2274 entire project history, and it does not delete them from the
2300 entire project history, and it does not delete them from the
2275 working directory.
2301 working directory.
2276
2302
2277 To delete the file from the working directory, see :hg:`remove`.
2303 To delete the file from the working directory, see :hg:`remove`.
2278
2304
2279 To undo a forget before the next commit, see :hg:`add`.
2305 To undo a forget before the next commit, see :hg:`add`.
2280
2306
2281 .. container:: verbose
2307 .. container:: verbose
2282
2308
2283 Examples:
2309 Examples:
2284
2310
2285 - forget newly-added binary files::
2311 - forget newly-added binary files::
2286
2312
2287 hg forget "set:added() and binary()"
2313 hg forget "set:added() and binary()"
2288
2314
2289 - forget files that would be excluded by .hgignore::
2315 - forget files that would be excluded by .hgignore::
2290
2316
2291 hg forget "set:hgignore()"
2317 hg forget "set:hgignore()"
2292
2318
2293 Returns 0 on success.
2319 Returns 0 on success.
2294 """
2320 """
2295
2321
2296 opts = pycompat.byteskwargs(opts)
2322 opts = pycompat.byteskwargs(opts)
2297 if not pats:
2323 if not pats:
2298 raise error.Abort(_('no files specified'))
2324 raise error.Abort(_('no files specified'))
2299
2325
2300 m = scmutil.match(repo[None], pats, opts)
2326 m = scmutil.match(repo[None], pats, opts)
2301 dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
2327 dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
2302 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2328 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2303 rejected = cmdutil.forget(ui, repo, m, prefix="", uipathfn=uipathfn,
2329 rejected = cmdutil.forget(ui, repo, m, prefix="", uipathfn=uipathfn,
2304 explicitonly=False, dryrun=dryrun,
2330 explicitonly=False, dryrun=dryrun,
2305 interactive=interactive)[0]
2331 interactive=interactive)[0]
2306 return rejected and 1 or 0
2332 return rejected and 1 or 0
2307
2333
2308 @command(
2334 @command(
2309 'graft',
2335 'graft',
2310 [('r', 'rev', [], _('revisions to graft'), _('REV')),
2336 [('r', 'rev', [], _('revisions to graft'), _('REV')),
2311 ('', 'base', '',
2337 ('', 'base', '',
2312 _('base revision when doing the graft merge (ADVANCED)'), _('REV')),
2338 _('base revision when doing the graft merge (ADVANCED)'), _('REV')),
2313 ('c', 'continue', False, _('resume interrupted graft')),
2339 ('c', 'continue', False, _('resume interrupted graft')),
2314 ('', 'stop', False, _('stop interrupted graft')),
2340 ('', 'stop', False, _('stop interrupted graft')),
2315 ('', 'abort', False, _('abort interrupted graft')),
2341 ('', 'abort', False, _('abort interrupted graft')),
2316 ('e', 'edit', False, _('invoke editor on commit messages')),
2342 ('e', 'edit', False, _('invoke editor on commit messages')),
2317 ('', 'log', None, _('append graft info to log message')),
2343 ('', 'log', None, _('append graft info to log message')),
2318 ('', 'no-commit', None,
2344 ('', 'no-commit', None,
2319 _("don't commit, just apply the changes in working directory")),
2345 _("don't commit, just apply the changes in working directory")),
2320 ('f', 'force', False, _('force graft')),
2346 ('f', 'force', False, _('force graft')),
2321 ('D', 'currentdate', False,
2347 ('D', 'currentdate', False,
2322 _('record the current date as commit date')),
2348 _('record the current date as commit date')),
2323 ('U', 'currentuser', False,
2349 ('U', 'currentuser', False,
2324 _('record the current user as committer'))]
2350 _('record the current user as committer'))]
2325 + commitopts2 + mergetoolopts + dryrunopts,
2351 + commitopts2 + mergetoolopts + dryrunopts,
2326 _('[OPTION]... [-r REV]... REV...'),
2352 _('[OPTION]... [-r REV]... REV...'),
2327 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
2353 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
2328 def graft(ui, repo, *revs, **opts):
2354 def graft(ui, repo, *revs, **opts):
2329 '''copy changes from other branches onto the current branch
2355 '''copy changes from other branches onto the current branch
2330
2356
2331 This command uses Mercurial's merge logic to copy individual
2357 This command uses Mercurial's merge logic to copy individual
2332 changes from other branches without merging branches in the
2358 changes from other branches without merging branches in the
2333 history graph. This is sometimes known as 'backporting' or
2359 history graph. This is sometimes known as 'backporting' or
2334 'cherry-picking'. By default, graft will copy user, date, and
2360 'cherry-picking'. By default, graft will copy user, date, and
2335 description from the source changesets.
2361 description from the source changesets.
2336
2362
2337 Changesets that are ancestors of the current revision, that have
2363 Changesets that are ancestors of the current revision, that have
2338 already been grafted, or that are merges will be skipped.
2364 already been grafted, or that are merges will be skipped.
2339
2365
2340 If --log is specified, log messages will have a comment appended
2366 If --log is specified, log messages will have a comment appended
2341 of the form::
2367 of the form::
2342
2368
2343 (grafted from CHANGESETHASH)
2369 (grafted from CHANGESETHASH)
2344
2370
2345 If --force is specified, revisions will be grafted even if they
2371 If --force is specified, revisions will be grafted even if they
2346 are already ancestors of, or have been grafted to, the destination.
2372 are already ancestors of, or have been grafted to, the destination.
2347 This is useful when the revisions have since been backed out.
2373 This is useful when the revisions have since been backed out.
2348
2374
2349 If a graft merge results in conflicts, the graft process is
2375 If a graft merge results in conflicts, the graft process is
2350 interrupted so that the current merge can be manually resolved.
2376 interrupted so that the current merge can be manually resolved.
2351 Once all conflicts are addressed, the graft process can be
2377 Once all conflicts are addressed, the graft process can be
2352 continued with the -c/--continue option.
2378 continued with the -c/--continue option.
2353
2379
2354 The -c/--continue option reapplies all the earlier options.
2380 The -c/--continue option reapplies all the earlier options.
2355
2381
2356 .. container:: verbose
2382 .. container:: verbose
2357
2383
2358 The --base option exposes more of how graft internally uses merge with a
2384 The --base option exposes more of how graft internally uses merge with a
2359 custom base revision. --base can be used to specify another ancestor than
2385 custom base revision. --base can be used to specify another ancestor than
2360 the first and only parent.
2386 the first and only parent.
2361
2387
2362 The command::
2388 The command::
2363
2389
2364 hg graft -r 345 --base 234
2390 hg graft -r 345 --base 234
2365
2391
2366 is thus pretty much the same as::
2392 is thus pretty much the same as::
2367
2393
2368 hg diff -r 234 -r 345 | hg import
2394 hg diff -r 234 -r 345 | hg import
2369
2395
2370 but using merge to resolve conflicts and track moved files.
2396 but using merge to resolve conflicts and track moved files.
2371
2397
2372 The result of a merge can thus be backported as a single commit by
2398 The result of a merge can thus be backported as a single commit by
2373 specifying one of the merge parents as base, and thus effectively
2399 specifying one of the merge parents as base, and thus effectively
2374 grafting the changes from the other side.
2400 grafting the changes from the other side.
2375
2401
2376 It is also possible to collapse multiple changesets and clean up history
2402 It is also possible to collapse multiple changesets and clean up history
2377 by specifying another ancestor as base, much like rebase --collapse
2403 by specifying another ancestor as base, much like rebase --collapse
2378 --keep.
2404 --keep.
2379
2405
2380 The commit message can be tweaked after the fact using commit --amend .
2406 The commit message can be tweaked after the fact using commit --amend .
2381
2407
2382 For using non-ancestors as the base to backout changes, see the backout
2408 For using non-ancestors as the base to backout changes, see the backout
2383 command and the hidden --parent option.
2409 command and the hidden --parent option.
2384
2410
2385 .. container:: verbose
2411 .. container:: verbose
2386
2412
2387 Examples:
2413 Examples:
2388
2414
2389 - copy a single change to the stable branch and edit its description::
2415 - copy a single change to the stable branch and edit its description::
2390
2416
2391 hg update stable
2417 hg update stable
2392 hg graft --edit 9393
2418 hg graft --edit 9393
2393
2419
2394 - graft a range of changesets with one exception, updating dates::
2420 - graft a range of changesets with one exception, updating dates::
2395
2421
2396 hg graft -D "2085::2093 and not 2091"
2422 hg graft -D "2085::2093 and not 2091"
2397
2423
2398 - continue a graft after resolving conflicts::
2424 - continue a graft after resolving conflicts::
2399
2425
2400 hg graft -c
2426 hg graft -c
2401
2427
2402 - show the source of a grafted changeset::
2428 - show the source of a grafted changeset::
2403
2429
2404 hg log --debug -r .
2430 hg log --debug -r .
2405
2431
2406 - show revisions sorted by date::
2432 - show revisions sorted by date::
2407
2433
2408 hg log -r "sort(all(), date)"
2434 hg log -r "sort(all(), date)"
2409
2435
2410 - backport the result of a merge as a single commit::
2436 - backport the result of a merge as a single commit::
2411
2437
2412 hg graft -r 123 --base 123^
2438 hg graft -r 123 --base 123^
2413
2439
2414 - land a feature branch as one changeset::
2440 - land a feature branch as one changeset::
2415
2441
2416 hg up -cr default
2442 hg up -cr default
2417 hg graft -r featureX --base "ancestor('featureX', 'default')"
2443 hg graft -r featureX --base "ancestor('featureX', 'default')"
2418
2444
2419 See :hg:`help revisions` for more about specifying revisions.
2445 See :hg:`help revisions` for more about specifying revisions.
2420
2446
2421 Returns 0 on successful completion.
2447 Returns 0 on successful completion.
2422 '''
2448 '''
2423 with repo.wlock():
2449 with repo.wlock():
2424 return _dograft(ui, repo, *revs, **opts)
2450 return _dograft(ui, repo, *revs, **opts)
2425
2451
2426 def _dograft(ui, repo, *revs, **opts):
2452 def _dograft(ui, repo, *revs, **opts):
2427 opts = pycompat.byteskwargs(opts)
2453 opts = pycompat.byteskwargs(opts)
2428 if revs and opts.get('rev'):
2454 if revs and opts.get('rev'):
2429 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
2455 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
2430 'revision ordering!\n'))
2456 'revision ordering!\n'))
2431
2457
2432 revs = list(revs)
2458 revs = list(revs)
2433 revs.extend(opts.get('rev'))
2459 revs.extend(opts.get('rev'))
2434 basectx = None
2460 basectx = None
2435 if opts.get('base'):
2461 if opts.get('base'):
2436 basectx = scmutil.revsingle(repo, opts['base'], None)
2462 basectx = scmutil.revsingle(repo, opts['base'], None)
2437 # a dict of data to be stored in state file
2463 # a dict of data to be stored in state file
2438 statedata = {}
2464 statedata = {}
2439 # list of new nodes created by ongoing graft
2465 # list of new nodes created by ongoing graft
2440 statedata['newnodes'] = []
2466 statedata['newnodes'] = []
2441
2467
2442 if opts.get('user') and opts.get('currentuser'):
2468 if opts.get('user') and opts.get('currentuser'):
2443 raise error.Abort(_('--user and --currentuser are mutually exclusive'))
2469 raise error.Abort(_('--user and --currentuser are mutually exclusive'))
2444 if opts.get('date') and opts.get('currentdate'):
2470 if opts.get('date') and opts.get('currentdate'):
2445 raise error.Abort(_('--date and --currentdate are mutually exclusive'))
2471 raise error.Abort(_('--date and --currentdate are mutually exclusive'))
2446 if not opts.get('user') and opts.get('currentuser'):
2472 if not opts.get('user') and opts.get('currentuser'):
2447 opts['user'] = ui.username()
2473 opts['user'] = ui.username()
2448 if not opts.get('date') and opts.get('currentdate'):
2474 if not opts.get('date') and opts.get('currentdate'):
2449 opts['date'] = "%d %d" % dateutil.makedate()
2475 opts['date'] = "%d %d" % dateutil.makedate()
2450
2476
2451 editor = cmdutil.getcommiteditor(editform='graft',
2477 editor = cmdutil.getcommiteditor(editform='graft',
2452 **pycompat.strkwargs(opts))
2478 **pycompat.strkwargs(opts))
2453
2479
2454 cont = False
2480 cont = False
2455 if opts.get('no_commit'):
2481 if opts.get('no_commit'):
2456 if opts.get('edit'):
2482 if opts.get('edit'):
2457 raise error.Abort(_("cannot specify --no-commit and "
2483 raise error.Abort(_("cannot specify --no-commit and "
2458 "--edit together"))
2484 "--edit together"))
2459 if opts.get('currentuser'):
2485 if opts.get('currentuser'):
2460 raise error.Abort(_("cannot specify --no-commit and "
2486 raise error.Abort(_("cannot specify --no-commit and "
2461 "--currentuser together"))
2487 "--currentuser together"))
2462 if opts.get('currentdate'):
2488 if opts.get('currentdate'):
2463 raise error.Abort(_("cannot specify --no-commit and "
2489 raise error.Abort(_("cannot specify --no-commit and "
2464 "--currentdate together"))
2490 "--currentdate together"))
2465 if opts.get('log'):
2491 if opts.get('log'):
2466 raise error.Abort(_("cannot specify --no-commit and "
2492 raise error.Abort(_("cannot specify --no-commit and "
2467 "--log together"))
2493 "--log together"))
2468
2494
2469 graftstate = statemod.cmdstate(repo, 'graftstate')
2495 graftstate = statemod.cmdstate(repo, 'graftstate')
2470
2496
2471 if opts.get('stop'):
2497 if opts.get('stop'):
2472 if opts.get('continue'):
2498 if opts.get('continue'):
2473 raise error.Abort(_("cannot use '--continue' and "
2499 raise error.Abort(_("cannot use '--continue' and "
2474 "'--stop' together"))
2500 "'--stop' together"))
2475 if opts.get('abort'):
2501 if opts.get('abort'):
2476 raise error.Abort(_("cannot use '--abort' and '--stop' together"))
2502 raise error.Abort(_("cannot use '--abort' and '--stop' together"))
2477
2503
2478 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2504 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2479 opts.get('date'), opts.get('currentdate'),
2505 opts.get('date'), opts.get('currentdate'),
2480 opts.get('currentuser'), opts.get('rev'))):
2506 opts.get('currentuser'), opts.get('rev'))):
2481 raise error.Abort(_("cannot specify any other flag with '--stop'"))
2507 raise error.Abort(_("cannot specify any other flag with '--stop'"))
2482 return _stopgraft(ui, repo, graftstate)
2508 return _stopgraft(ui, repo, graftstate)
2483 elif opts.get('abort'):
2509 elif opts.get('abort'):
2484 if opts.get('continue'):
2510 if opts.get('continue'):
2485 raise error.Abort(_("cannot use '--continue' and "
2511 raise error.Abort(_("cannot use '--continue' and "
2486 "'--abort' together"))
2512 "'--abort' together"))
2487 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2513 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2488 opts.get('date'), opts.get('currentdate'),
2514 opts.get('date'), opts.get('currentdate'),
2489 opts.get('currentuser'), opts.get('rev'))):
2515 opts.get('currentuser'), opts.get('rev'))):
2490 raise error.Abort(_("cannot specify any other flag with '--abort'"))
2516 raise error.Abort(_("cannot specify any other flag with '--abort'"))
2491
2517
2492 return cmdutil.abortgraft(ui, repo, graftstate)
2518 return cmdutil.abortgraft(ui, repo, graftstate)
2493 elif opts.get('continue'):
2519 elif opts.get('continue'):
2494 cont = True
2520 cont = True
2495 if revs:
2521 if revs:
2496 raise error.Abort(_("can't specify --continue and revisions"))
2522 raise error.Abort(_("can't specify --continue and revisions"))
2497 # read in unfinished revisions
2523 # read in unfinished revisions
2498 if graftstate.exists():
2524 if graftstate.exists():
2499 statedata = cmdutil.readgraftstate(repo, graftstate)
2525 statedata = cmdutil.readgraftstate(repo, graftstate)
2500 if statedata.get('date'):
2526 if statedata.get('date'):
2501 opts['date'] = statedata['date']
2527 opts['date'] = statedata['date']
2502 if statedata.get('user'):
2528 if statedata.get('user'):
2503 opts['user'] = statedata['user']
2529 opts['user'] = statedata['user']
2504 if statedata.get('log'):
2530 if statedata.get('log'):
2505 opts['log'] = True
2531 opts['log'] = True
2506 if statedata.get('no_commit'):
2532 if statedata.get('no_commit'):
2507 opts['no_commit'] = statedata.get('no_commit')
2533 opts['no_commit'] = statedata.get('no_commit')
2508 nodes = statedata['nodes']
2534 nodes = statedata['nodes']
2509 revs = [repo[node].rev() for node in nodes]
2535 revs = [repo[node].rev() for node in nodes]
2510 else:
2536 else:
2511 cmdutil.wrongtooltocontinue(repo, _('graft'))
2537 cmdutil.wrongtooltocontinue(repo, _('graft'))
2512 else:
2538 else:
2513 if not revs:
2539 if not revs:
2514 raise error.Abort(_('no revisions specified'))
2540 raise error.Abort(_('no revisions specified'))
2515 cmdutil.checkunfinished(repo)
2541 cmdutil.checkunfinished(repo)
2516 cmdutil.bailifchanged(repo)
2542 cmdutil.bailifchanged(repo)
2517 revs = scmutil.revrange(repo, revs)
2543 revs = scmutil.revrange(repo, revs)
2518
2544
2519 skipped = set()
2545 skipped = set()
2520 if basectx is None:
2546 if basectx is None:
2521 # check for merges
2547 # check for merges
2522 for rev in repo.revs('%ld and merge()', revs):
2548 for rev in repo.revs('%ld and merge()', revs):
2523 ui.warn(_('skipping ungraftable merge revision %d\n') % rev)
2549 ui.warn(_('skipping ungraftable merge revision %d\n') % rev)
2524 skipped.add(rev)
2550 skipped.add(rev)
2525 revs = [r for r in revs if r not in skipped]
2551 revs = [r for r in revs if r not in skipped]
2526 if not revs:
2552 if not revs:
2527 return -1
2553 return -1
2528 if basectx is not None and len(revs) != 1:
2554 if basectx is not None and len(revs) != 1:
2529 raise error.Abort(_('only one revision allowed with --base '))
2555 raise error.Abort(_('only one revision allowed with --base '))
2530
2556
2531 # Don't check in the --continue case, in effect retaining --force across
2557 # Don't check in the --continue case, in effect retaining --force across
2532 # --continues. That's because without --force, any revisions we decided to
2558 # --continues. That's because without --force, any revisions we decided to
2533 # skip would have been filtered out here, so they wouldn't have made their
2559 # skip would have been filtered out here, so they wouldn't have made their
2534 # way to the graftstate. With --force, any revisions we would have otherwise
2560 # way to the graftstate. With --force, any revisions we would have otherwise
2535 # skipped would not have been filtered out, and if they hadn't been applied
2561 # skipped would not have been filtered out, and if they hadn't been applied
2536 # already, they'd have been in the graftstate.
2562 # already, they'd have been in the graftstate.
2537 if not (cont or opts.get('force')) and basectx is None:
2563 if not (cont or opts.get('force')) and basectx is None:
2538 # check for ancestors of dest branch
2564 # check for ancestors of dest branch
2539 crev = repo['.'].rev()
2565 crev = repo['.'].rev()
2540 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2566 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2541 # XXX make this lazy in the future
2567 # XXX make this lazy in the future
2542 # don't mutate while iterating, create a copy
2568 # don't mutate while iterating, create a copy
2543 for rev in list(revs):
2569 for rev in list(revs):
2544 if rev in ancestors:
2570 if rev in ancestors:
2545 ui.warn(_('skipping ancestor revision %d:%s\n') %
2571 ui.warn(_('skipping ancestor revision %d:%s\n') %
2546 (rev, repo[rev]))
2572 (rev, repo[rev]))
2547 # XXX remove on list is slow
2573 # XXX remove on list is slow
2548 revs.remove(rev)
2574 revs.remove(rev)
2549 if not revs:
2575 if not revs:
2550 return -1
2576 return -1
2551
2577
2552 # analyze revs for earlier grafts
2578 # analyze revs for earlier grafts
2553 ids = {}
2579 ids = {}
2554 for ctx in repo.set("%ld", revs):
2580 for ctx in repo.set("%ld", revs):
2555 ids[ctx.hex()] = ctx.rev()
2581 ids[ctx.hex()] = ctx.rev()
2556 n = ctx.extra().get('source')
2582 n = ctx.extra().get('source')
2557 if n:
2583 if n:
2558 ids[n] = ctx.rev()
2584 ids[n] = ctx.rev()
2559
2585
2560 # check ancestors for earlier grafts
2586 # check ancestors for earlier grafts
2561 ui.debug('scanning for duplicate grafts\n')
2587 ui.debug('scanning for duplicate grafts\n')
2562
2588
2563 # The only changesets we can be sure doesn't contain grafts of any
2589 # The only changesets we can be sure doesn't contain grafts of any
2564 # revs, are the ones that are common ancestors of *all* revs:
2590 # revs, are the ones that are common ancestors of *all* revs:
2565 for rev in repo.revs('only(%d,ancestor(%ld))', crev, revs):
2591 for rev in repo.revs('only(%d,ancestor(%ld))', crev, revs):
2566 ctx = repo[rev]
2592 ctx = repo[rev]
2567 n = ctx.extra().get('source')
2593 n = ctx.extra().get('source')
2568 if n in ids:
2594 if n in ids:
2569 try:
2595 try:
2570 r = repo[n].rev()
2596 r = repo[n].rev()
2571 except error.RepoLookupError:
2597 except error.RepoLookupError:
2572 r = None
2598 r = None
2573 if r in revs:
2599 if r in revs:
2574 ui.warn(_('skipping revision %d:%s '
2600 ui.warn(_('skipping revision %d:%s '
2575 '(already grafted to %d:%s)\n')
2601 '(already grafted to %d:%s)\n')
2576 % (r, repo[r], rev, ctx))
2602 % (r, repo[r], rev, ctx))
2577 revs.remove(r)
2603 revs.remove(r)
2578 elif ids[n] in revs:
2604 elif ids[n] in revs:
2579 if r is None:
2605 if r is None:
2580 ui.warn(_('skipping already grafted revision %d:%s '
2606 ui.warn(_('skipping already grafted revision %d:%s '
2581 '(%d:%s also has unknown origin %s)\n')
2607 '(%d:%s also has unknown origin %s)\n')
2582 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
2608 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
2583 else:
2609 else:
2584 ui.warn(_('skipping already grafted revision %d:%s '
2610 ui.warn(_('skipping already grafted revision %d:%s '
2585 '(%d:%s also has origin %d:%s)\n')
2611 '(%d:%s also has origin %d:%s)\n')
2586 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
2612 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
2587 revs.remove(ids[n])
2613 revs.remove(ids[n])
2588 elif ctx.hex() in ids:
2614 elif ctx.hex() in ids:
2589 r = ids[ctx.hex()]
2615 r = ids[ctx.hex()]
2590 if r in revs:
2616 if r in revs:
2591 ui.warn(_('skipping already grafted revision %d:%s '
2617 ui.warn(_('skipping already grafted revision %d:%s '
2592 '(was grafted from %d:%s)\n') %
2618 '(was grafted from %d:%s)\n') %
2593 (r, repo[r], rev, ctx))
2619 (r, repo[r], rev, ctx))
2594 revs.remove(r)
2620 revs.remove(r)
2595 if not revs:
2621 if not revs:
2596 return -1
2622 return -1
2597
2623
2598 if opts.get('no_commit'):
2624 if opts.get('no_commit'):
2599 statedata['no_commit'] = True
2625 statedata['no_commit'] = True
2600 for pos, ctx in enumerate(repo.set("%ld", revs)):
2626 for pos, ctx in enumerate(repo.set("%ld", revs)):
2601 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
2627 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
2602 ctx.description().split('\n', 1)[0])
2628 ctx.description().split('\n', 1)[0])
2603 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2629 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2604 if names:
2630 if names:
2605 desc += ' (%s)' % ' '.join(names)
2631 desc += ' (%s)' % ' '.join(names)
2606 ui.status(_('grafting %s\n') % desc)
2632 ui.status(_('grafting %s\n') % desc)
2607 if opts.get('dry_run'):
2633 if opts.get('dry_run'):
2608 continue
2634 continue
2609
2635
2610 source = ctx.extra().get('source')
2636 source = ctx.extra().get('source')
2611 extra = {}
2637 extra = {}
2612 if source:
2638 if source:
2613 extra['source'] = source
2639 extra['source'] = source
2614 extra['intermediate-source'] = ctx.hex()
2640 extra['intermediate-source'] = ctx.hex()
2615 else:
2641 else:
2616 extra['source'] = ctx.hex()
2642 extra['source'] = ctx.hex()
2617 user = ctx.user()
2643 user = ctx.user()
2618 if opts.get('user'):
2644 if opts.get('user'):
2619 user = opts['user']
2645 user = opts['user']
2620 statedata['user'] = user
2646 statedata['user'] = user
2621 date = ctx.date()
2647 date = ctx.date()
2622 if opts.get('date'):
2648 if opts.get('date'):
2623 date = opts['date']
2649 date = opts['date']
2624 statedata['date'] = date
2650 statedata['date'] = date
2625 message = ctx.description()
2651 message = ctx.description()
2626 if opts.get('log'):
2652 if opts.get('log'):
2627 message += '\n(grafted from %s)' % ctx.hex()
2653 message += '\n(grafted from %s)' % ctx.hex()
2628 statedata['log'] = True
2654 statedata['log'] = True
2629
2655
2630 # we don't merge the first commit when continuing
2656 # we don't merge the first commit when continuing
2631 if not cont:
2657 if not cont:
2632 # perform the graft merge with p1(rev) as 'ancestor'
2658 # perform the graft merge with p1(rev) as 'ancestor'
2633 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
2659 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
2634 base = ctx.p1() if basectx is None else basectx
2660 base = ctx.p1() if basectx is None else basectx
2635 with ui.configoverride(overrides, 'graft'):
2661 with ui.configoverride(overrides, 'graft'):
2636 stats = mergemod.graft(repo, ctx, base, ['local', 'graft'])
2662 stats = mergemod.graft(repo, ctx, base, ['local', 'graft'])
2637 # report any conflicts
2663 # report any conflicts
2638 if stats.unresolvedcount > 0:
2664 if stats.unresolvedcount > 0:
2639 # write out state for --continue
2665 # write out state for --continue
2640 nodes = [repo[rev].hex() for rev in revs[pos:]]
2666 nodes = [repo[rev].hex() for rev in revs[pos:]]
2641 statedata['nodes'] = nodes
2667 statedata['nodes'] = nodes
2642 stateversion = 1
2668 stateversion = 1
2643 graftstate.save(stateversion, statedata)
2669 graftstate.save(stateversion, statedata)
2644 hint = _("use 'hg resolve' and 'hg graft --continue'")
2670 hint = _("use 'hg resolve' and 'hg graft --continue'")
2645 raise error.Abort(
2671 raise error.Abort(
2646 _("unresolved conflicts, can't continue"),
2672 _("unresolved conflicts, can't continue"),
2647 hint=hint)
2673 hint=hint)
2648 else:
2674 else:
2649 cont = False
2675 cont = False
2650
2676
2651 # commit if --no-commit is false
2677 # commit if --no-commit is false
2652 if not opts.get('no_commit'):
2678 if not opts.get('no_commit'):
2653 node = repo.commit(text=message, user=user, date=date, extra=extra,
2679 node = repo.commit(text=message, user=user, date=date, extra=extra,
2654 editor=editor)
2680 editor=editor)
2655 if node is None:
2681 if node is None:
2656 ui.warn(
2682 ui.warn(
2657 _('note: graft of %d:%s created no changes to commit\n') %
2683 _('note: graft of %d:%s created no changes to commit\n') %
2658 (ctx.rev(), ctx))
2684 (ctx.rev(), ctx))
2659 # checking that newnodes exist because old state files won't have it
2685 # checking that newnodes exist because old state files won't have it
2660 elif statedata.get('newnodes') is not None:
2686 elif statedata.get('newnodes') is not None:
2661 statedata['newnodes'].append(node)
2687 statedata['newnodes'].append(node)
2662
2688
2663 # remove state when we complete successfully
2689 # remove state when we complete successfully
2664 if not opts.get('dry_run'):
2690 if not opts.get('dry_run'):
2665 graftstate.delete()
2691 graftstate.delete()
2666
2692
2667 return 0
2693 return 0
2668
2694
2669 def _stopgraft(ui, repo, graftstate):
2695 def _stopgraft(ui, repo, graftstate):
2670 """stop the interrupted graft"""
2696 """stop the interrupted graft"""
2671 if not graftstate.exists():
2697 if not graftstate.exists():
2672 raise error.Abort(_("no interrupted graft found"))
2698 raise error.Abort(_("no interrupted graft found"))
2673 pctx = repo['.']
2699 pctx = repo['.']
2674 hg.updaterepo(repo, pctx.node(), overwrite=True)
2700 hg.updaterepo(repo, pctx.node(), overwrite=True)
2675 graftstate.delete()
2701 graftstate.delete()
2676 ui.status(_("stopped the interrupted graft\n"))
2702 ui.status(_("stopped the interrupted graft\n"))
2677 ui.status(_("working directory is now at %s\n") % pctx.hex()[:12])
2703 ui.status(_("working directory is now at %s\n") % pctx.hex()[:12])
2678 return 0
2704 return 0
2679
2705
2680 statemod.addunfinished(
2706 statemod.addunfinished(
2681 'graft', fname='graftstate', clearable=True, stopflag=True,
2707 'graft', fname='graftstate', clearable=True, stopflag=True,
2682 continueflag=True, abortfunc=cmdutil.hgabortgraft,
2708 continueflag=True, abortfunc=cmdutil.hgabortgraft,
2683 cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop")
2709 cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop")
2684 )
2710 )
2685
2711
2686 @command('grep',
2712 @command('grep',
2687 [('0', 'print0', None, _('end fields with NUL')),
2713 [('0', 'print0', None, _('end fields with NUL')),
2688 ('', 'all', None, _('print all revisions that match (DEPRECATED) ')),
2714 ('', 'all', None, _('print all revisions that match (DEPRECATED) ')),
2689 ('', 'diff', None, _('print all revisions when the term was introduced '
2715 ('', 'diff', None, _('print all revisions when the term was introduced '
2690 'or removed')),
2716 'or removed')),
2691 ('a', 'text', None, _('treat all files as text')),
2717 ('a', 'text', None, _('treat all files as text')),
2692 ('f', 'follow', None,
2718 ('f', 'follow', None,
2693 _('follow changeset history,'
2719 _('follow changeset history,'
2694 ' or file history across copies and renames')),
2720 ' or file history across copies and renames')),
2695 ('i', 'ignore-case', None, _('ignore case when matching')),
2721 ('i', 'ignore-case', None, _('ignore case when matching')),
2696 ('l', 'files-with-matches', None,
2722 ('l', 'files-with-matches', None,
2697 _('print only filenames and revisions that match')),
2723 _('print only filenames and revisions that match')),
2698 ('n', 'line-number', None, _('print matching line numbers')),
2724 ('n', 'line-number', None, _('print matching line numbers')),
2699 ('r', 'rev', [],
2725 ('r', 'rev', [],
2700 _('only search files changed within revision range'), _('REV')),
2726 _('only search files changed within revision range'), _('REV')),
2701 ('', 'all-files', None,
2727 ('', 'all-files', None,
2702 _('include all files in the changeset while grepping (EXPERIMENTAL)')),
2728 _('include all files in the changeset while grepping (EXPERIMENTAL)')),
2703 ('u', 'user', None, _('list the author (long with -v)')),
2729 ('u', 'user', None, _('list the author (long with -v)')),
2704 ('d', 'date', None, _('list the date (short with -q)')),
2730 ('d', 'date', None, _('list the date (short with -q)')),
2705 ] + formatteropts + walkopts,
2731 ] + formatteropts + walkopts,
2706 _('[OPTION]... PATTERN [FILE]...'),
2732 _('[OPTION]... PATTERN [FILE]...'),
2707 helpcategory=command.CATEGORY_FILE_CONTENTS,
2733 helpcategory=command.CATEGORY_FILE_CONTENTS,
2708 inferrepo=True,
2734 inferrepo=True,
2709 intents={INTENT_READONLY})
2735 intents={INTENT_READONLY})
2710 def grep(ui, repo, pattern, *pats, **opts):
2736 def grep(ui, repo, pattern, *pats, **opts):
2711 """search revision history for a pattern in specified files
2737 """search revision history for a pattern in specified files
2712
2738
2713 Search revision history for a regular expression in the specified
2739 Search revision history for a regular expression in the specified
2714 files or the entire project.
2740 files or the entire project.
2715
2741
2716 By default, grep prints the most recent revision number for each
2742 By default, grep prints the most recent revision number for each
2717 file in which it finds a match. To get it to print every revision
2743 file in which it finds a match. To get it to print every revision
2718 that contains a change in match status ("-" for a match that becomes
2744 that contains a change in match status ("-" for a match that becomes
2719 a non-match, or "+" for a non-match that becomes a match), use the
2745 a non-match, or "+" for a non-match that becomes a match), use the
2720 --diff flag.
2746 --diff flag.
2721
2747
2722 PATTERN can be any Python (roughly Perl-compatible) regular
2748 PATTERN can be any Python (roughly Perl-compatible) regular
2723 expression.
2749 expression.
2724
2750
2725 If no FILEs are specified (and -f/--follow isn't set), all files in
2751 If no FILEs are specified (and -f/--follow isn't set), all files in
2726 the repository are searched, including those that don't exist in the
2752 the repository are searched, including those that don't exist in the
2727 current branch or have been deleted in a prior changeset.
2753 current branch or have been deleted in a prior changeset.
2728
2754
2729 .. container:: verbose
2755 .. container:: verbose
2730
2756
2731 Template:
2757 Template:
2732
2758
2733 The following keywords are supported in addition to the common template
2759 The following keywords are supported in addition to the common template
2734 keywords and functions. See also :hg:`help templates`.
2760 keywords and functions. See also :hg:`help templates`.
2735
2761
2736 :change: String. Character denoting insertion ``+`` or removal ``-``.
2762 :change: String. Character denoting insertion ``+`` or removal ``-``.
2737 Available if ``--diff`` is specified.
2763 Available if ``--diff`` is specified.
2738 :lineno: Integer. Line number of the match.
2764 :lineno: Integer. Line number of the match.
2739 :path: String. Repository-absolute path of the file.
2765 :path: String. Repository-absolute path of the file.
2740 :texts: List of text chunks.
2766 :texts: List of text chunks.
2741
2767
2742 And each entry of ``{texts}`` provides the following sub-keywords.
2768 And each entry of ``{texts}`` provides the following sub-keywords.
2743
2769
2744 :matched: Boolean. True if the chunk matches the specified pattern.
2770 :matched: Boolean. True if the chunk matches the specified pattern.
2745 :text: String. Chunk content.
2771 :text: String. Chunk content.
2746
2772
2747 See :hg:`help templates.operators` for the list expansion syntax.
2773 See :hg:`help templates.operators` for the list expansion syntax.
2748
2774
2749 Returns 0 if a match is found, 1 otherwise.
2775 Returns 0 if a match is found, 1 otherwise.
2750 """
2776 """
2751 opts = pycompat.byteskwargs(opts)
2777 opts = pycompat.byteskwargs(opts)
2752 diff = opts.get('all') or opts.get('diff')
2778 diff = opts.get('all') or opts.get('diff')
2753 all_files = opts.get('all_files')
2779 all_files = opts.get('all_files')
2754 if diff and opts.get('all_files'):
2780 if diff and opts.get('all_files'):
2755 raise error.Abort(_('--diff and --all-files are mutually exclusive'))
2781 raise error.Abort(_('--diff and --all-files are mutually exclusive'))
2756 # TODO: remove "not opts.get('rev')" if --all-files -rMULTIREV gets working
2782 # TODO: remove "not opts.get('rev')" if --all-files -rMULTIREV gets working
2757 if opts.get('all_files') is None and not opts.get('rev') and not diff:
2783 if opts.get('all_files') is None and not opts.get('rev') and not diff:
2758 # experimental config: commands.grep.all-files
2784 # experimental config: commands.grep.all-files
2759 opts['all_files'] = ui.configbool('commands', 'grep.all-files')
2785 opts['all_files'] = ui.configbool('commands', 'grep.all-files')
2760 plaingrep = opts.get('all_files') and not opts.get('rev')
2786 plaingrep = opts.get('all_files') and not opts.get('rev')
2761 if plaingrep:
2787 if plaingrep:
2762 opts['rev'] = ['wdir()']
2788 opts['rev'] = ['wdir()']
2763
2789
2764 reflags = re.M
2790 reflags = re.M
2765 if opts.get('ignore_case'):
2791 if opts.get('ignore_case'):
2766 reflags |= re.I
2792 reflags |= re.I
2767 try:
2793 try:
2768 regexp = util.re.compile(pattern, reflags)
2794 regexp = util.re.compile(pattern, reflags)
2769 except re.error as inst:
2795 except re.error as inst:
2770 ui.warn(_("grep: invalid match pattern: %s\n") % pycompat.bytestr(inst))
2796 ui.warn(_("grep: invalid match pattern: %s\n") % pycompat.bytestr(inst))
2771 return 1
2797 return 1
2772 sep, eol = ':', '\n'
2798 sep, eol = ':', '\n'
2773 if opts.get('print0'):
2799 if opts.get('print0'):
2774 sep = eol = '\0'
2800 sep = eol = '\0'
2775
2801
2776 getfile = util.lrucachefunc(repo.file)
2802 getfile = util.lrucachefunc(repo.file)
2777
2803
2778 def matchlines(body):
2804 def matchlines(body):
2779 begin = 0
2805 begin = 0
2780 linenum = 0
2806 linenum = 0
2781 while begin < len(body):
2807 while begin < len(body):
2782 match = regexp.search(body, begin)
2808 match = regexp.search(body, begin)
2783 if not match:
2809 if not match:
2784 break
2810 break
2785 mstart, mend = match.span()
2811 mstart, mend = match.span()
2786 linenum += body.count('\n', begin, mstart) + 1
2812 linenum += body.count('\n', begin, mstart) + 1
2787 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2813 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2788 begin = body.find('\n', mend) + 1 or len(body) + 1
2814 begin = body.find('\n', mend) + 1 or len(body) + 1
2789 lend = begin - 1
2815 lend = begin - 1
2790 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2816 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2791
2817
2792 class linestate(object):
2818 class linestate(object):
2793 def __init__(self, line, linenum, colstart, colend):
2819 def __init__(self, line, linenum, colstart, colend):
2794 self.line = line
2820 self.line = line
2795 self.linenum = linenum
2821 self.linenum = linenum
2796 self.colstart = colstart
2822 self.colstart = colstart
2797 self.colend = colend
2823 self.colend = colend
2798
2824
2799 def __hash__(self):
2825 def __hash__(self):
2800 return hash((self.linenum, self.line))
2826 return hash((self.linenum, self.line))
2801
2827
2802 def __eq__(self, other):
2828 def __eq__(self, other):
2803 return self.line == other.line
2829 return self.line == other.line
2804
2830
2805 def findpos(self):
2831 def findpos(self):
2806 """Iterate all (start, end) indices of matches"""
2832 """Iterate all (start, end) indices of matches"""
2807 yield self.colstart, self.colend
2833 yield self.colstart, self.colend
2808 p = self.colend
2834 p = self.colend
2809 while p < len(self.line):
2835 while p < len(self.line):
2810 m = regexp.search(self.line, p)
2836 m = regexp.search(self.line, p)
2811 if not m:
2837 if not m:
2812 break
2838 break
2813 yield m.span()
2839 yield m.span()
2814 p = m.end()
2840 p = m.end()
2815
2841
2816 matches = {}
2842 matches = {}
2817 copies = {}
2843 copies = {}
2818 def grepbody(fn, rev, body):
2844 def grepbody(fn, rev, body):
2819 matches[rev].setdefault(fn, [])
2845 matches[rev].setdefault(fn, [])
2820 m = matches[rev][fn]
2846 m = matches[rev][fn]
2821 for lnum, cstart, cend, line in matchlines(body):
2847 for lnum, cstart, cend, line in matchlines(body):
2822 s = linestate(line, lnum, cstart, cend)
2848 s = linestate(line, lnum, cstart, cend)
2823 m.append(s)
2849 m.append(s)
2824
2850
2825 def difflinestates(a, b):
2851 def difflinestates(a, b):
2826 sm = difflib.SequenceMatcher(None, a, b)
2852 sm = difflib.SequenceMatcher(None, a, b)
2827 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2853 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2828 if tag == r'insert':
2854 if tag == r'insert':
2829 for i in pycompat.xrange(blo, bhi):
2855 for i in pycompat.xrange(blo, bhi):
2830 yield ('+', b[i])
2856 yield ('+', b[i])
2831 elif tag == r'delete':
2857 elif tag == r'delete':
2832 for i in pycompat.xrange(alo, ahi):
2858 for i in pycompat.xrange(alo, ahi):
2833 yield ('-', a[i])
2859 yield ('-', a[i])
2834 elif tag == r'replace':
2860 elif tag == r'replace':
2835 for i in pycompat.xrange(alo, ahi):
2861 for i in pycompat.xrange(alo, ahi):
2836 yield ('-', a[i])
2862 yield ('-', a[i])
2837 for i in pycompat.xrange(blo, bhi):
2863 for i in pycompat.xrange(blo, bhi):
2838 yield ('+', b[i])
2864 yield ('+', b[i])
2839
2865
2840 uipathfn = scmutil.getuipathfn(repo)
2866 uipathfn = scmutil.getuipathfn(repo)
2841 def display(fm, fn, ctx, pstates, states):
2867 def display(fm, fn, ctx, pstates, states):
2842 rev = scmutil.intrev(ctx)
2868 rev = scmutil.intrev(ctx)
2843 if fm.isplain():
2869 if fm.isplain():
2844 formatuser = ui.shortuser
2870 formatuser = ui.shortuser
2845 else:
2871 else:
2846 formatuser = pycompat.bytestr
2872 formatuser = pycompat.bytestr
2847 if ui.quiet:
2873 if ui.quiet:
2848 datefmt = '%Y-%m-%d'
2874 datefmt = '%Y-%m-%d'
2849 else:
2875 else:
2850 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2876 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2851 found = False
2877 found = False
2852 @util.cachefunc
2878 @util.cachefunc
2853 def binary():
2879 def binary():
2854 flog = getfile(fn)
2880 flog = getfile(fn)
2855 try:
2881 try:
2856 return stringutil.binary(flog.read(ctx.filenode(fn)))
2882 return stringutil.binary(flog.read(ctx.filenode(fn)))
2857 except error.WdirUnsupported:
2883 except error.WdirUnsupported:
2858 return ctx[fn].isbinary()
2884 return ctx[fn].isbinary()
2859
2885
2860 fieldnamemap = {'linenumber': 'lineno'}
2886 fieldnamemap = {'linenumber': 'lineno'}
2861 if diff:
2887 if diff:
2862 iter = difflinestates(pstates, states)
2888 iter = difflinestates(pstates, states)
2863 else:
2889 else:
2864 iter = [('', l) for l in states]
2890 iter = [('', l) for l in states]
2865 for change, l in iter:
2891 for change, l in iter:
2866 fm.startitem()
2892 fm.startitem()
2867 fm.context(ctx=ctx)
2893 fm.context(ctx=ctx)
2868 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
2894 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
2869 fm.plain(uipathfn(fn), label='grep.filename')
2895 fm.plain(uipathfn(fn), label='grep.filename')
2870
2896
2871 cols = [
2897 cols = [
2872 ('rev', '%d', rev, not plaingrep, ''),
2898 ('rev', '%d', rev, not plaingrep, ''),
2873 ('linenumber', '%d', l.linenum, opts.get('line_number'), ''),
2899 ('linenumber', '%d', l.linenum, opts.get('line_number'), ''),
2874 ]
2900 ]
2875 if diff:
2901 if diff:
2876 cols.append(
2902 cols.append(
2877 ('change', '%s', change, True,
2903 ('change', '%s', change, True,
2878 'grep.inserted ' if change == '+' else 'grep.deleted ')
2904 'grep.inserted ' if change == '+' else 'grep.deleted ')
2879 )
2905 )
2880 cols.extend([
2906 cols.extend([
2881 ('user', '%s', formatuser(ctx.user()), opts.get('user'), ''),
2907 ('user', '%s', formatuser(ctx.user()), opts.get('user'), ''),
2882 ('date', '%s', fm.formatdate(ctx.date(), datefmt),
2908 ('date', '%s', fm.formatdate(ctx.date(), datefmt),
2883 opts.get('date'), ''),
2909 opts.get('date'), ''),
2884 ])
2910 ])
2885 for name, fmt, data, cond, extra_label in cols:
2911 for name, fmt, data, cond, extra_label in cols:
2886 if cond:
2912 if cond:
2887 fm.plain(sep, label='grep.sep')
2913 fm.plain(sep, label='grep.sep')
2888 field = fieldnamemap.get(name, name)
2914 field = fieldnamemap.get(name, name)
2889 label = extra_label + ('grep.%s' % name)
2915 label = extra_label + ('grep.%s' % name)
2890 fm.condwrite(cond, field, fmt, data, label=label)
2916 fm.condwrite(cond, field, fmt, data, label=label)
2891 if not opts.get('files_with_matches'):
2917 if not opts.get('files_with_matches'):
2892 fm.plain(sep, label='grep.sep')
2918 fm.plain(sep, label='grep.sep')
2893 if not opts.get('text') and binary():
2919 if not opts.get('text') and binary():
2894 fm.plain(_(" Binary file matches"))
2920 fm.plain(_(" Binary file matches"))
2895 else:
2921 else:
2896 displaymatches(fm.nested('texts', tmpl='{text}'), l)
2922 displaymatches(fm.nested('texts', tmpl='{text}'), l)
2897 fm.plain(eol)
2923 fm.plain(eol)
2898 found = True
2924 found = True
2899 if opts.get('files_with_matches'):
2925 if opts.get('files_with_matches'):
2900 break
2926 break
2901 return found
2927 return found
2902
2928
2903 def displaymatches(fm, l):
2929 def displaymatches(fm, l):
2904 p = 0
2930 p = 0
2905 for s, e in l.findpos():
2931 for s, e in l.findpos():
2906 if p < s:
2932 if p < s:
2907 fm.startitem()
2933 fm.startitem()
2908 fm.write('text', '%s', l.line[p:s])
2934 fm.write('text', '%s', l.line[p:s])
2909 fm.data(matched=False)
2935 fm.data(matched=False)
2910 fm.startitem()
2936 fm.startitem()
2911 fm.write('text', '%s', l.line[s:e], label='grep.match')
2937 fm.write('text', '%s', l.line[s:e], label='grep.match')
2912 fm.data(matched=True)
2938 fm.data(matched=True)
2913 p = e
2939 p = e
2914 if p < len(l.line):
2940 if p < len(l.line):
2915 fm.startitem()
2941 fm.startitem()
2916 fm.write('text', '%s', l.line[p:])
2942 fm.write('text', '%s', l.line[p:])
2917 fm.data(matched=False)
2943 fm.data(matched=False)
2918 fm.end()
2944 fm.end()
2919
2945
2920 skip = set()
2946 skip = set()
2921 revfiles = {}
2947 revfiles = {}
2922 match = scmutil.match(repo[None], pats, opts)
2948 match = scmutil.match(repo[None], pats, opts)
2923 found = False
2949 found = False
2924 follow = opts.get('follow')
2950 follow = opts.get('follow')
2925
2951
2926 getrenamed = scmutil.getrenamedfn(repo)
2952 getrenamed = scmutil.getrenamedfn(repo)
2927 def prep(ctx, fns):
2953 def prep(ctx, fns):
2928 rev = ctx.rev()
2954 rev = ctx.rev()
2929 pctx = ctx.p1()
2955 pctx = ctx.p1()
2930 parent = pctx.rev()
2956 parent = pctx.rev()
2931 matches.setdefault(rev, {})
2957 matches.setdefault(rev, {})
2932 matches.setdefault(parent, {})
2958 matches.setdefault(parent, {})
2933 files = revfiles.setdefault(rev, [])
2959 files = revfiles.setdefault(rev, [])
2934 for fn in fns:
2960 for fn in fns:
2935 flog = getfile(fn)
2961 flog = getfile(fn)
2936 try:
2962 try:
2937 fnode = ctx.filenode(fn)
2963 fnode = ctx.filenode(fn)
2938 except error.LookupError:
2964 except error.LookupError:
2939 continue
2965 continue
2940
2966
2941 copy = None
2967 copy = None
2942 if follow:
2968 if follow:
2943 copy = getrenamed(fn, rev)
2969 copy = getrenamed(fn, rev)
2944 if copy:
2970 if copy:
2945 copies.setdefault(rev, {})[fn] = copy
2971 copies.setdefault(rev, {})[fn] = copy
2946 if fn in skip:
2972 if fn in skip:
2947 skip.add(copy)
2973 skip.add(copy)
2948 if fn in skip:
2974 if fn in skip:
2949 continue
2975 continue
2950 files.append(fn)
2976 files.append(fn)
2951
2977
2952 if fn not in matches[rev]:
2978 if fn not in matches[rev]:
2953 try:
2979 try:
2954 content = flog.read(fnode)
2980 content = flog.read(fnode)
2955 except error.WdirUnsupported:
2981 except error.WdirUnsupported:
2956 content = ctx[fn].data()
2982 content = ctx[fn].data()
2957 grepbody(fn, rev, content)
2983 grepbody(fn, rev, content)
2958
2984
2959 pfn = copy or fn
2985 pfn = copy or fn
2960 if pfn not in matches[parent]:
2986 if pfn not in matches[parent]:
2961 try:
2987 try:
2962 fnode = pctx.filenode(pfn)
2988 fnode = pctx.filenode(pfn)
2963 grepbody(pfn, parent, flog.read(fnode))
2989 grepbody(pfn, parent, flog.read(fnode))
2964 except error.LookupError:
2990 except error.LookupError:
2965 pass
2991 pass
2966
2992
2967 ui.pager('grep')
2993 ui.pager('grep')
2968 fm = ui.formatter('grep', opts)
2994 fm = ui.formatter('grep', opts)
2969 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
2995 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
2970 rev = ctx.rev()
2996 rev = ctx.rev()
2971 parent = ctx.p1().rev()
2997 parent = ctx.p1().rev()
2972 for fn in sorted(revfiles.get(rev, [])):
2998 for fn in sorted(revfiles.get(rev, [])):
2973 states = matches[rev][fn]
2999 states = matches[rev][fn]
2974 copy = copies.get(rev, {}).get(fn)
3000 copy = copies.get(rev, {}).get(fn)
2975 if fn in skip:
3001 if fn in skip:
2976 if copy:
3002 if copy:
2977 skip.add(copy)
3003 skip.add(copy)
2978 continue
3004 continue
2979 pstates = matches.get(parent, {}).get(copy or fn, [])
3005 pstates = matches.get(parent, {}).get(copy or fn, [])
2980 if pstates or states:
3006 if pstates or states:
2981 r = display(fm, fn, ctx, pstates, states)
3007 r = display(fm, fn, ctx, pstates, states)
2982 found = found or r
3008 found = found or r
2983 if r and not diff and not all_files:
3009 if r and not diff and not all_files:
2984 skip.add(fn)
3010 skip.add(fn)
2985 if copy:
3011 if copy:
2986 skip.add(copy)
3012 skip.add(copy)
2987 del revfiles[rev]
3013 del revfiles[rev]
2988 # We will keep the matches dict for the duration of the window
3014 # We will keep the matches dict for the duration of the window
2989 # clear the matches dict once the window is over
3015 # clear the matches dict once the window is over
2990 if not revfiles:
3016 if not revfiles:
2991 matches.clear()
3017 matches.clear()
2992 fm.end()
3018 fm.end()
2993
3019
2994 return not found
3020 return not found
2995
3021
2996 @command('heads',
3022 @command('heads',
2997 [('r', 'rev', '',
3023 [('r', 'rev', '',
2998 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3024 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2999 ('t', 'topo', False, _('show topological heads only')),
3025 ('t', 'topo', False, _('show topological heads only')),
3000 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3026 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3001 ('c', 'closed', False, _('show normal and closed branch heads')),
3027 ('c', 'closed', False, _('show normal and closed branch heads')),
3002 ] + templateopts,
3028 ] + templateopts,
3003 _('[-ct] [-r STARTREV] [REV]...'),
3029 _('[-ct] [-r STARTREV] [REV]...'),
3004 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3030 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3005 intents={INTENT_READONLY})
3031 intents={INTENT_READONLY})
3006 def heads(ui, repo, *branchrevs, **opts):
3032 def heads(ui, repo, *branchrevs, **opts):
3007 """show branch heads
3033 """show branch heads
3008
3034
3009 With no arguments, show all open branch heads in the repository.
3035 With no arguments, show all open branch heads in the repository.
3010 Branch heads are changesets that have no descendants on the
3036 Branch heads are changesets that have no descendants on the
3011 same branch. They are where development generally takes place and
3037 same branch. They are where development generally takes place and
3012 are the usual targets for update and merge operations.
3038 are the usual targets for update and merge operations.
3013
3039
3014 If one or more REVs are given, only open branch heads on the
3040 If one or more REVs are given, only open branch heads on the
3015 branches associated with the specified changesets are shown. This
3041 branches associated with the specified changesets are shown. This
3016 means that you can use :hg:`heads .` to see the heads on the
3042 means that you can use :hg:`heads .` to see the heads on the
3017 currently checked-out branch.
3043 currently checked-out branch.
3018
3044
3019 If -c/--closed is specified, also show branch heads marked closed
3045 If -c/--closed is specified, also show branch heads marked closed
3020 (see :hg:`commit --close-branch`).
3046 (see :hg:`commit --close-branch`).
3021
3047
3022 If STARTREV is specified, only those heads that are descendants of
3048 If STARTREV is specified, only those heads that are descendants of
3023 STARTREV will be displayed.
3049 STARTREV will be displayed.
3024
3050
3025 If -t/--topo is specified, named branch mechanics will be ignored and only
3051 If -t/--topo is specified, named branch mechanics will be ignored and only
3026 topological heads (changesets with no children) will be shown.
3052 topological heads (changesets with no children) will be shown.
3027
3053
3028 Returns 0 if matching heads are found, 1 if not.
3054 Returns 0 if matching heads are found, 1 if not.
3029 """
3055 """
3030
3056
3031 opts = pycompat.byteskwargs(opts)
3057 opts = pycompat.byteskwargs(opts)
3032 start = None
3058 start = None
3033 rev = opts.get('rev')
3059 rev = opts.get('rev')
3034 if rev:
3060 if rev:
3035 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3061 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3036 start = scmutil.revsingle(repo, rev, None).node()
3062 start = scmutil.revsingle(repo, rev, None).node()
3037
3063
3038 if opts.get('topo'):
3064 if opts.get('topo'):
3039 heads = [repo[h] for h in repo.heads(start)]
3065 heads = [repo[h] for h in repo.heads(start)]
3040 else:
3066 else:
3041 heads = []
3067 heads = []
3042 for branch in repo.branchmap():
3068 for branch in repo.branchmap():
3043 heads += repo.branchheads(branch, start, opts.get('closed'))
3069 heads += repo.branchheads(branch, start, opts.get('closed'))
3044 heads = [repo[h] for h in heads]
3070 heads = [repo[h] for h in heads]
3045
3071
3046 if branchrevs:
3072 if branchrevs:
3047 branches = set(repo[r].branch()
3073 branches = set(repo[r].branch()
3048 for r in scmutil.revrange(repo, branchrevs))
3074 for r in scmutil.revrange(repo, branchrevs))
3049 heads = [h for h in heads if h.branch() in branches]
3075 heads = [h for h in heads if h.branch() in branches]
3050
3076
3051 if opts.get('active') and branchrevs:
3077 if opts.get('active') and branchrevs:
3052 dagheads = repo.heads(start)
3078 dagheads = repo.heads(start)
3053 heads = [h for h in heads if h.node() in dagheads]
3079 heads = [h for h in heads if h.node() in dagheads]
3054
3080
3055 if branchrevs:
3081 if branchrevs:
3056 haveheads = set(h.branch() for h in heads)
3082 haveheads = set(h.branch() for h in heads)
3057 if branches - haveheads:
3083 if branches - haveheads:
3058 headless = ', '.join(b for b in branches - haveheads)
3084 headless = ', '.join(b for b in branches - haveheads)
3059 msg = _('no open branch heads found on branches %s')
3085 msg = _('no open branch heads found on branches %s')
3060 if opts.get('rev'):
3086 if opts.get('rev'):
3061 msg += _(' (started at %s)') % opts['rev']
3087 msg += _(' (started at %s)') % opts['rev']
3062 ui.warn((msg + '\n') % headless)
3088 ui.warn((msg + '\n') % headless)
3063
3089
3064 if not heads:
3090 if not heads:
3065 return 1
3091 return 1
3066
3092
3067 ui.pager('heads')
3093 ui.pager('heads')
3068 heads = sorted(heads, key=lambda x: -x.rev())
3094 heads = sorted(heads, key=lambda x: -x.rev())
3069 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3095 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3070 for ctx in heads:
3096 for ctx in heads:
3071 displayer.show(ctx)
3097 displayer.show(ctx)
3072 displayer.close()
3098 displayer.close()
3073
3099
3074 @command('help',
3100 @command('help',
3075 [('e', 'extension', None, _('show only help for extensions')),
3101 [('e', 'extension', None, _('show only help for extensions')),
3076 ('c', 'command', None, _('show only help for commands')),
3102 ('c', 'command', None, _('show only help for commands')),
3077 ('k', 'keyword', None, _('show topics matching keyword')),
3103 ('k', 'keyword', None, _('show topics matching keyword')),
3078 ('s', 'system', [],
3104 ('s', 'system', [],
3079 _('show help for specific platform(s)'), _('PLATFORM')),
3105 _('show help for specific platform(s)'), _('PLATFORM')),
3080 ],
3106 ],
3081 _('[-eck] [-s PLATFORM] [TOPIC]'),
3107 _('[-eck] [-s PLATFORM] [TOPIC]'),
3082 helpcategory=command.CATEGORY_HELP,
3108 helpcategory=command.CATEGORY_HELP,
3083 norepo=True,
3109 norepo=True,
3084 intents={INTENT_READONLY})
3110 intents={INTENT_READONLY})
3085 def help_(ui, name=None, **opts):
3111 def help_(ui, name=None, **opts):
3086 """show help for a given topic or a help overview
3112 """show help for a given topic or a help overview
3087
3113
3088 With no arguments, print a list of commands with short help messages.
3114 With no arguments, print a list of commands with short help messages.
3089
3115
3090 Given a topic, extension, or command name, print help for that
3116 Given a topic, extension, or command name, print help for that
3091 topic.
3117 topic.
3092
3118
3093 Returns 0 if successful.
3119 Returns 0 if successful.
3094 """
3120 """
3095
3121
3096 keep = opts.get(r'system') or []
3122 keep = opts.get(r'system') or []
3097 if len(keep) == 0:
3123 if len(keep) == 0:
3098 if pycompat.sysplatform.startswith('win'):
3124 if pycompat.sysplatform.startswith('win'):
3099 keep.append('windows')
3125 keep.append('windows')
3100 elif pycompat.sysplatform == 'OpenVMS':
3126 elif pycompat.sysplatform == 'OpenVMS':
3101 keep.append('vms')
3127 keep.append('vms')
3102 elif pycompat.sysplatform == 'plan9':
3128 elif pycompat.sysplatform == 'plan9':
3103 keep.append('plan9')
3129 keep.append('plan9')
3104 else:
3130 else:
3105 keep.append('unix')
3131 keep.append('unix')
3106 keep.append(pycompat.sysplatform.lower())
3132 keep.append(pycompat.sysplatform.lower())
3107 if ui.verbose:
3133 if ui.verbose:
3108 keep.append('verbose')
3134 keep.append('verbose')
3109
3135
3110 commands = sys.modules[__name__]
3136 commands = sys.modules[__name__]
3111 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3137 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3112 ui.pager('help')
3138 ui.pager('help')
3113 ui.write(formatted)
3139 ui.write(formatted)
3114
3140
3115
3141
3116 @command('identify|id',
3142 @command('identify|id',
3117 [('r', 'rev', '',
3143 [('r', 'rev', '',
3118 _('identify the specified revision'), _('REV')),
3144 _('identify the specified revision'), _('REV')),
3119 ('n', 'num', None, _('show local revision number')),
3145 ('n', 'num', None, _('show local revision number')),
3120 ('i', 'id', None, _('show global revision id')),
3146 ('i', 'id', None, _('show global revision id')),
3121 ('b', 'branch', None, _('show branch')),
3147 ('b', 'branch', None, _('show branch')),
3122 ('t', 'tags', None, _('show tags')),
3148 ('t', 'tags', None, _('show tags')),
3123 ('B', 'bookmarks', None, _('show bookmarks')),
3149 ('B', 'bookmarks', None, _('show bookmarks')),
3124 ] + remoteopts + formatteropts,
3150 ] + remoteopts + formatteropts,
3125 _('[-nibtB] [-r REV] [SOURCE]'),
3151 _('[-nibtB] [-r REV] [SOURCE]'),
3126 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3152 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3127 optionalrepo=True,
3153 optionalrepo=True,
3128 intents={INTENT_READONLY})
3154 intents={INTENT_READONLY})
3129 def identify(ui, repo, source=None, rev=None,
3155 def identify(ui, repo, source=None, rev=None,
3130 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3156 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3131 """identify the working directory or specified revision
3157 """identify the working directory or specified revision
3132
3158
3133 Print a summary identifying the repository state at REV using one or
3159 Print a summary identifying the repository state at REV using one or
3134 two parent hash identifiers, followed by a "+" if the working
3160 two parent hash identifiers, followed by a "+" if the working
3135 directory has uncommitted changes, the branch name (if not default),
3161 directory has uncommitted changes, the branch name (if not default),
3136 a list of tags, and a list of bookmarks.
3162 a list of tags, and a list of bookmarks.
3137
3163
3138 When REV is not given, print a summary of the current state of the
3164 When REV is not given, print a summary of the current state of the
3139 repository including the working directory. Specify -r. to get information
3165 repository including the working directory. Specify -r. to get information
3140 of the working directory parent without scanning uncommitted changes.
3166 of the working directory parent without scanning uncommitted changes.
3141
3167
3142 Specifying a path to a repository root or Mercurial bundle will
3168 Specifying a path to a repository root or Mercurial bundle will
3143 cause lookup to operate on that repository/bundle.
3169 cause lookup to operate on that repository/bundle.
3144
3170
3145 .. container:: verbose
3171 .. container:: verbose
3146
3172
3147 Template:
3173 Template:
3148
3174
3149 The following keywords are supported in addition to the common template
3175 The following keywords are supported in addition to the common template
3150 keywords and functions. See also :hg:`help templates`.
3176 keywords and functions. See also :hg:`help templates`.
3151
3177
3152 :dirty: String. Character ``+`` denoting if the working directory has
3178 :dirty: String. Character ``+`` denoting if the working directory has
3153 uncommitted changes.
3179 uncommitted changes.
3154 :id: String. One or two nodes, optionally followed by ``+``.
3180 :id: String. One or two nodes, optionally followed by ``+``.
3155 :parents: List of strings. Parent nodes of the changeset.
3181 :parents: List of strings. Parent nodes of the changeset.
3156
3182
3157 Examples:
3183 Examples:
3158
3184
3159 - generate a build identifier for the working directory::
3185 - generate a build identifier for the working directory::
3160
3186
3161 hg id --id > build-id.dat
3187 hg id --id > build-id.dat
3162
3188
3163 - find the revision corresponding to a tag::
3189 - find the revision corresponding to a tag::
3164
3190
3165 hg id -n -r 1.3
3191 hg id -n -r 1.3
3166
3192
3167 - check the most recent revision of a remote repository::
3193 - check the most recent revision of a remote repository::
3168
3194
3169 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3195 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3170
3196
3171 See :hg:`log` for generating more information about specific revisions,
3197 See :hg:`log` for generating more information about specific revisions,
3172 including full hash identifiers.
3198 including full hash identifiers.
3173
3199
3174 Returns 0 if successful.
3200 Returns 0 if successful.
3175 """
3201 """
3176
3202
3177 opts = pycompat.byteskwargs(opts)
3203 opts = pycompat.byteskwargs(opts)
3178 if not repo and not source:
3204 if not repo and not source:
3179 raise error.Abort(_("there is no Mercurial repository here "
3205 raise error.Abort(_("there is no Mercurial repository here "
3180 "(.hg not found)"))
3206 "(.hg not found)"))
3181
3207
3182 default = not (num or id or branch or tags or bookmarks)
3208 default = not (num or id or branch or tags or bookmarks)
3183 output = []
3209 output = []
3184 revs = []
3210 revs = []
3185
3211
3186 if source:
3212 if source:
3187 source, branches = hg.parseurl(ui.expandpath(source))
3213 source, branches = hg.parseurl(ui.expandpath(source))
3188 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3214 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3189 repo = peer.local()
3215 repo = peer.local()
3190 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3216 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3191
3217
3192 fm = ui.formatter('identify', opts)
3218 fm = ui.formatter('identify', opts)
3193 fm.startitem()
3219 fm.startitem()
3194
3220
3195 if not repo:
3221 if not repo:
3196 if num or branch or tags:
3222 if num or branch or tags:
3197 raise error.Abort(
3223 raise error.Abort(
3198 _("can't query remote revision number, branch, or tags"))
3224 _("can't query remote revision number, branch, or tags"))
3199 if not rev and revs:
3225 if not rev and revs:
3200 rev = revs[0]
3226 rev = revs[0]
3201 if not rev:
3227 if not rev:
3202 rev = "tip"
3228 rev = "tip"
3203
3229
3204 remoterev = peer.lookup(rev)
3230 remoterev = peer.lookup(rev)
3205 hexrev = fm.hexfunc(remoterev)
3231 hexrev = fm.hexfunc(remoterev)
3206 if default or id:
3232 if default or id:
3207 output = [hexrev]
3233 output = [hexrev]
3208 fm.data(id=hexrev)
3234 fm.data(id=hexrev)
3209
3235
3210 @util.cachefunc
3236 @util.cachefunc
3211 def getbms():
3237 def getbms():
3212 bms = []
3238 bms = []
3213
3239
3214 if 'bookmarks' in peer.listkeys('namespaces'):
3240 if 'bookmarks' in peer.listkeys('namespaces'):
3215 hexremoterev = hex(remoterev)
3241 hexremoterev = hex(remoterev)
3216 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3242 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3217 if bmr == hexremoterev]
3243 if bmr == hexremoterev]
3218
3244
3219 return sorted(bms)
3245 return sorted(bms)
3220
3246
3221 if fm.isplain():
3247 if fm.isplain():
3222 if bookmarks:
3248 if bookmarks:
3223 output.extend(getbms())
3249 output.extend(getbms())
3224 elif default and not ui.quiet:
3250 elif default and not ui.quiet:
3225 # multiple bookmarks for a single parent separated by '/'
3251 # multiple bookmarks for a single parent separated by '/'
3226 bm = '/'.join(getbms())
3252 bm = '/'.join(getbms())
3227 if bm:
3253 if bm:
3228 output.append(bm)
3254 output.append(bm)
3229 else:
3255 else:
3230 fm.data(node=hex(remoterev))
3256 fm.data(node=hex(remoterev))
3231 if bookmarks or 'bookmarks' in fm.datahint():
3257 if bookmarks or 'bookmarks' in fm.datahint():
3232 fm.data(bookmarks=fm.formatlist(getbms(), name='bookmark'))
3258 fm.data(bookmarks=fm.formatlist(getbms(), name='bookmark'))
3233 else:
3259 else:
3234 if rev:
3260 if rev:
3235 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3261 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3236 ctx = scmutil.revsingle(repo, rev, None)
3262 ctx = scmutil.revsingle(repo, rev, None)
3237
3263
3238 if ctx.rev() is None:
3264 if ctx.rev() is None:
3239 ctx = repo[None]
3265 ctx = repo[None]
3240 parents = ctx.parents()
3266 parents = ctx.parents()
3241 taglist = []
3267 taglist = []
3242 for p in parents:
3268 for p in parents:
3243 taglist.extend(p.tags())
3269 taglist.extend(p.tags())
3244
3270
3245 dirty = ""
3271 dirty = ""
3246 if ctx.dirty(missing=True, merge=False, branch=False):
3272 if ctx.dirty(missing=True, merge=False, branch=False):
3247 dirty = '+'
3273 dirty = '+'
3248 fm.data(dirty=dirty)
3274 fm.data(dirty=dirty)
3249
3275
3250 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3276 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3251 if default or id:
3277 if default or id:
3252 output = ["%s%s" % ('+'.join(hexoutput), dirty)]
3278 output = ["%s%s" % ('+'.join(hexoutput), dirty)]
3253 fm.data(id="%s%s" % ('+'.join(hexoutput), dirty))
3279 fm.data(id="%s%s" % ('+'.join(hexoutput), dirty))
3254
3280
3255 if num:
3281 if num:
3256 numoutput = ["%d" % p.rev() for p in parents]
3282 numoutput = ["%d" % p.rev() for p in parents]
3257 output.append("%s%s" % ('+'.join(numoutput), dirty))
3283 output.append("%s%s" % ('+'.join(numoutput), dirty))
3258
3284
3259 fm.data(parents=fm.formatlist([fm.hexfunc(p.node())
3285 fm.data(parents=fm.formatlist([fm.hexfunc(p.node())
3260 for p in parents], name='node'))
3286 for p in parents], name='node'))
3261 else:
3287 else:
3262 hexoutput = fm.hexfunc(ctx.node())
3288 hexoutput = fm.hexfunc(ctx.node())
3263 if default or id:
3289 if default or id:
3264 output = [hexoutput]
3290 output = [hexoutput]
3265 fm.data(id=hexoutput)
3291 fm.data(id=hexoutput)
3266
3292
3267 if num:
3293 if num:
3268 output.append(pycompat.bytestr(ctx.rev()))
3294 output.append(pycompat.bytestr(ctx.rev()))
3269 taglist = ctx.tags()
3295 taglist = ctx.tags()
3270
3296
3271 if default and not ui.quiet:
3297 if default and not ui.quiet:
3272 b = ctx.branch()
3298 b = ctx.branch()
3273 if b != 'default':
3299 if b != 'default':
3274 output.append("(%s)" % b)
3300 output.append("(%s)" % b)
3275
3301
3276 # multiple tags for a single parent separated by '/'
3302 # multiple tags for a single parent separated by '/'
3277 t = '/'.join(taglist)
3303 t = '/'.join(taglist)
3278 if t:
3304 if t:
3279 output.append(t)
3305 output.append(t)
3280
3306
3281 # multiple bookmarks for a single parent separated by '/'
3307 # multiple bookmarks for a single parent separated by '/'
3282 bm = '/'.join(ctx.bookmarks())
3308 bm = '/'.join(ctx.bookmarks())
3283 if bm:
3309 if bm:
3284 output.append(bm)
3310 output.append(bm)
3285 else:
3311 else:
3286 if branch:
3312 if branch:
3287 output.append(ctx.branch())
3313 output.append(ctx.branch())
3288
3314
3289 if tags:
3315 if tags:
3290 output.extend(taglist)
3316 output.extend(taglist)
3291
3317
3292 if bookmarks:
3318 if bookmarks:
3293 output.extend(ctx.bookmarks())
3319 output.extend(ctx.bookmarks())
3294
3320
3295 fm.data(node=ctx.hex())
3321 fm.data(node=ctx.hex())
3296 fm.data(branch=ctx.branch())
3322 fm.data(branch=ctx.branch())
3297 fm.data(tags=fm.formatlist(taglist, name='tag', sep=':'))
3323 fm.data(tags=fm.formatlist(taglist, name='tag', sep=':'))
3298 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'))
3324 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'))
3299 fm.context(ctx=ctx)
3325 fm.context(ctx=ctx)
3300
3326
3301 fm.plain("%s\n" % ' '.join(output))
3327 fm.plain("%s\n" % ' '.join(output))
3302 fm.end()
3328 fm.end()
3303
3329
3304 @command('import|patch',
3330 @command('import|patch',
3305 [('p', 'strip', 1,
3331 [('p', 'strip', 1,
3306 _('directory strip option for patch. This has the same '
3332 _('directory strip option for patch. This has the same '
3307 'meaning as the corresponding patch option'), _('NUM')),
3333 'meaning as the corresponding patch option'), _('NUM')),
3308 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3334 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3309 ('e', 'edit', False, _('invoke editor on commit messages')),
3335 ('e', 'edit', False, _('invoke editor on commit messages')),
3310 ('f', 'force', None,
3336 ('f', 'force', None,
3311 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3337 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3312 ('', 'no-commit', None,
3338 ('', 'no-commit', None,
3313 _("don't commit, just update the working directory")),
3339 _("don't commit, just update the working directory")),
3314 ('', 'bypass', None,
3340 ('', 'bypass', None,
3315 _("apply patch without touching the working directory")),
3341 _("apply patch without touching the working directory")),
3316 ('', 'partial', None,
3342 ('', 'partial', None,
3317 _('commit even if some hunks fail')),
3343 _('commit even if some hunks fail')),
3318 ('', 'exact', None,
3344 ('', 'exact', None,
3319 _('abort if patch would apply lossily')),
3345 _('abort if patch would apply lossily')),
3320 ('', 'prefix', '',
3346 ('', 'prefix', '',
3321 _('apply patch to subdirectory'), _('DIR')),
3347 _('apply patch to subdirectory'), _('DIR')),
3322 ('', 'import-branch', None,
3348 ('', 'import-branch', None,
3323 _('use any branch information in patch (implied by --exact)'))] +
3349 _('use any branch information in patch (implied by --exact)'))] +
3324 commitopts + commitopts2 + similarityopts,
3350 commitopts + commitopts2 + similarityopts,
3325 _('[OPTION]... PATCH...'),
3351 _('[OPTION]... PATCH...'),
3326 helpcategory=command.CATEGORY_IMPORT_EXPORT)
3352 helpcategory=command.CATEGORY_IMPORT_EXPORT)
3327 def import_(ui, repo, patch1=None, *patches, **opts):
3353 def import_(ui, repo, patch1=None, *patches, **opts):
3328 """import an ordered set of patches
3354 """import an ordered set of patches
3329
3355
3330 Import a list of patches and commit them individually (unless
3356 Import a list of patches and commit them individually (unless
3331 --no-commit is specified).
3357 --no-commit is specified).
3332
3358
3333 To read a patch from standard input (stdin), use "-" as the patch
3359 To read a patch from standard input (stdin), use "-" as the patch
3334 name. If a URL is specified, the patch will be downloaded from
3360 name. If a URL is specified, the patch will be downloaded from
3335 there.
3361 there.
3336
3362
3337 Import first applies changes to the working directory (unless
3363 Import first applies changes to the working directory (unless
3338 --bypass is specified), import will abort if there are outstanding
3364 --bypass is specified), import will abort if there are outstanding
3339 changes.
3365 changes.
3340
3366
3341 Use --bypass to apply and commit patches directly to the
3367 Use --bypass to apply and commit patches directly to the
3342 repository, without affecting the working directory. Without
3368 repository, without affecting the working directory. Without
3343 --exact, patches will be applied on top of the working directory
3369 --exact, patches will be applied on top of the working directory
3344 parent revision.
3370 parent revision.
3345
3371
3346 You can import a patch straight from a mail message. Even patches
3372 You can import a patch straight from a mail message. Even patches
3347 as attachments work (to use the body part, it must have type
3373 as attachments work (to use the body part, it must have type
3348 text/plain or text/x-patch). From and Subject headers of email
3374 text/plain or text/x-patch). From and Subject headers of email
3349 message are used as default committer and commit message. All
3375 message are used as default committer and commit message. All
3350 text/plain body parts before first diff are added to the commit
3376 text/plain body parts before first diff are added to the commit
3351 message.
3377 message.
3352
3378
3353 If the imported patch was generated by :hg:`export`, user and
3379 If the imported patch was generated by :hg:`export`, user and
3354 description from patch override values from message headers and
3380 description from patch override values from message headers and
3355 body. Values given on command line with -m/--message and -u/--user
3381 body. Values given on command line with -m/--message and -u/--user
3356 override these.
3382 override these.
3357
3383
3358 If --exact is specified, import will set the working directory to
3384 If --exact is specified, import will set the working directory to
3359 the parent of each patch before applying it, and will abort if the
3385 the parent of each patch before applying it, and will abort if the
3360 resulting changeset has a different ID than the one recorded in
3386 resulting changeset has a different ID than the one recorded in
3361 the patch. This will guard against various ways that portable
3387 the patch. This will guard against various ways that portable
3362 patch formats and mail systems might fail to transfer Mercurial
3388 patch formats and mail systems might fail to transfer Mercurial
3363 data or metadata. See :hg:`bundle` for lossless transmission.
3389 data or metadata. See :hg:`bundle` for lossless transmission.
3364
3390
3365 Use --partial to ensure a changeset will be created from the patch
3391 Use --partial to ensure a changeset will be created from the patch
3366 even if some hunks fail to apply. Hunks that fail to apply will be
3392 even if some hunks fail to apply. Hunks that fail to apply will be
3367 written to a <target-file>.rej file. Conflicts can then be resolved
3393 written to a <target-file>.rej file. Conflicts can then be resolved
3368 by hand before :hg:`commit --amend` is run to update the created
3394 by hand before :hg:`commit --amend` is run to update the created
3369 changeset. This flag exists to let people import patches that
3395 changeset. This flag exists to let people import patches that
3370 partially apply without losing the associated metadata (author,
3396 partially apply without losing the associated metadata (author,
3371 date, description, ...).
3397 date, description, ...).
3372
3398
3373 .. note::
3399 .. note::
3374
3400
3375 When no hunks apply cleanly, :hg:`import --partial` will create
3401 When no hunks apply cleanly, :hg:`import --partial` will create
3376 an empty changeset, importing only the patch metadata.
3402 an empty changeset, importing only the patch metadata.
3377
3403
3378 With -s/--similarity, hg will attempt to discover renames and
3404 With -s/--similarity, hg will attempt to discover renames and
3379 copies in the patch in the same way as :hg:`addremove`.
3405 copies in the patch in the same way as :hg:`addremove`.
3380
3406
3381 It is possible to use external patch programs to perform the patch
3407 It is possible to use external patch programs to perform the patch
3382 by setting the ``ui.patch`` configuration option. For the default
3408 by setting the ``ui.patch`` configuration option. For the default
3383 internal tool, the fuzz can also be configured via ``patch.fuzz``.
3409 internal tool, the fuzz can also be configured via ``patch.fuzz``.
3384 See :hg:`help config` for more information about configuration
3410 See :hg:`help config` for more information about configuration
3385 files and how to use these options.
3411 files and how to use these options.
3386
3412
3387 See :hg:`help dates` for a list of formats valid for -d/--date.
3413 See :hg:`help dates` for a list of formats valid for -d/--date.
3388
3414
3389 .. container:: verbose
3415 .. container:: verbose
3390
3416
3391 Examples:
3417 Examples:
3392
3418
3393 - import a traditional patch from a website and detect renames::
3419 - import a traditional patch from a website and detect renames::
3394
3420
3395 hg import -s 80 http://example.com/bugfix.patch
3421 hg import -s 80 http://example.com/bugfix.patch
3396
3422
3397 - import a changeset from an hgweb server::
3423 - import a changeset from an hgweb server::
3398
3424
3399 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
3425 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
3400
3426
3401 - import all the patches in an Unix-style mbox::
3427 - import all the patches in an Unix-style mbox::
3402
3428
3403 hg import incoming-patches.mbox
3429 hg import incoming-patches.mbox
3404
3430
3405 - import patches from stdin::
3431 - import patches from stdin::
3406
3432
3407 hg import -
3433 hg import -
3408
3434
3409 - attempt to exactly restore an exported changeset (not always
3435 - attempt to exactly restore an exported changeset (not always
3410 possible)::
3436 possible)::
3411
3437
3412 hg import --exact proposed-fix.patch
3438 hg import --exact proposed-fix.patch
3413
3439
3414 - use an external tool to apply a patch which is too fuzzy for
3440 - use an external tool to apply a patch which is too fuzzy for
3415 the default internal tool.
3441 the default internal tool.
3416
3442
3417 hg import --config ui.patch="patch --merge" fuzzy.patch
3443 hg import --config ui.patch="patch --merge" fuzzy.patch
3418
3444
3419 - change the default fuzzing from 2 to a less strict 7
3445 - change the default fuzzing from 2 to a less strict 7
3420
3446
3421 hg import --config ui.fuzz=7 fuzz.patch
3447 hg import --config ui.fuzz=7 fuzz.patch
3422
3448
3423 Returns 0 on success, 1 on partial success (see --partial).
3449 Returns 0 on success, 1 on partial success (see --partial).
3424 """
3450 """
3425
3451
3426 opts = pycompat.byteskwargs(opts)
3452 opts = pycompat.byteskwargs(opts)
3427 if not patch1:
3453 if not patch1:
3428 raise error.Abort(_('need at least one patch to import'))
3454 raise error.Abort(_('need at least one patch to import'))
3429
3455
3430 patches = (patch1,) + patches
3456 patches = (patch1,) + patches
3431
3457
3432 date = opts.get('date')
3458 date = opts.get('date')
3433 if date:
3459 if date:
3434 opts['date'] = dateutil.parsedate(date)
3460 opts['date'] = dateutil.parsedate(date)
3435
3461
3436 exact = opts.get('exact')
3462 exact = opts.get('exact')
3437 update = not opts.get('bypass')
3463 update = not opts.get('bypass')
3438 if not update and opts.get('no_commit'):
3464 if not update and opts.get('no_commit'):
3439 raise error.Abort(_('cannot use --no-commit with --bypass'))
3465 raise error.Abort(_('cannot use --no-commit with --bypass'))
3440 try:
3466 try:
3441 sim = float(opts.get('similarity') or 0)
3467 sim = float(opts.get('similarity') or 0)
3442 except ValueError:
3468 except ValueError:
3443 raise error.Abort(_('similarity must be a number'))
3469 raise error.Abort(_('similarity must be a number'))
3444 if sim < 0 or sim > 100:
3470 if sim < 0 or sim > 100:
3445 raise error.Abort(_('similarity must be between 0 and 100'))
3471 raise error.Abort(_('similarity must be between 0 and 100'))
3446 if sim and not update:
3472 if sim and not update:
3447 raise error.Abort(_('cannot use --similarity with --bypass'))
3473 raise error.Abort(_('cannot use --similarity with --bypass'))
3448 if exact:
3474 if exact:
3449 if opts.get('edit'):
3475 if opts.get('edit'):
3450 raise error.Abort(_('cannot use --exact with --edit'))
3476 raise error.Abort(_('cannot use --exact with --edit'))
3451 if opts.get('prefix'):
3477 if opts.get('prefix'):
3452 raise error.Abort(_('cannot use --exact with --prefix'))
3478 raise error.Abort(_('cannot use --exact with --prefix'))
3453
3479
3454 base = opts["base"]
3480 base = opts["base"]
3455 msgs = []
3481 msgs = []
3456 ret = 0
3482 ret = 0
3457
3483
3458 with repo.wlock():
3484 with repo.wlock():
3459 if update:
3485 if update:
3460 cmdutil.checkunfinished(repo)
3486 cmdutil.checkunfinished(repo)
3461 if (exact or not opts.get('force')):
3487 if (exact or not opts.get('force')):
3462 cmdutil.bailifchanged(repo)
3488 cmdutil.bailifchanged(repo)
3463
3489
3464 if not opts.get('no_commit'):
3490 if not opts.get('no_commit'):
3465 lock = repo.lock
3491 lock = repo.lock
3466 tr = lambda: repo.transaction('import')
3492 tr = lambda: repo.transaction('import')
3467 dsguard = util.nullcontextmanager
3493 dsguard = util.nullcontextmanager
3468 else:
3494 else:
3469 lock = util.nullcontextmanager
3495 lock = util.nullcontextmanager
3470 tr = util.nullcontextmanager
3496 tr = util.nullcontextmanager
3471 dsguard = lambda: dirstateguard.dirstateguard(repo, 'import')
3497 dsguard = lambda: dirstateguard.dirstateguard(repo, 'import')
3472 with lock(), tr(), dsguard():
3498 with lock(), tr(), dsguard():
3473 parents = repo[None].parents()
3499 parents = repo[None].parents()
3474 for patchurl in patches:
3500 for patchurl in patches:
3475 if patchurl == '-':
3501 if patchurl == '-':
3476 ui.status(_('applying patch from stdin\n'))
3502 ui.status(_('applying patch from stdin\n'))
3477 patchfile = ui.fin
3503 patchfile = ui.fin
3478 patchurl = 'stdin' # for error message
3504 patchurl = 'stdin' # for error message
3479 else:
3505 else:
3480 patchurl = os.path.join(base, patchurl)
3506 patchurl = os.path.join(base, patchurl)
3481 ui.status(_('applying %s\n') % patchurl)
3507 ui.status(_('applying %s\n') % patchurl)
3482 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
3508 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
3483
3509
3484 haspatch = False
3510 haspatch = False
3485 for hunk in patch.split(patchfile):
3511 for hunk in patch.split(patchfile):
3486 with patch.extract(ui, hunk) as patchdata:
3512 with patch.extract(ui, hunk) as patchdata:
3487 msg, node, rej = cmdutil.tryimportone(ui, repo,
3513 msg, node, rej = cmdutil.tryimportone(ui, repo,
3488 patchdata,
3514 patchdata,
3489 parents, opts,
3515 parents, opts,
3490 msgs, hg.clean)
3516 msgs, hg.clean)
3491 if msg:
3517 if msg:
3492 haspatch = True
3518 haspatch = True
3493 ui.note(msg + '\n')
3519 ui.note(msg + '\n')
3494 if update or exact:
3520 if update or exact:
3495 parents = repo[None].parents()
3521 parents = repo[None].parents()
3496 else:
3522 else:
3497 parents = [repo[node]]
3523 parents = [repo[node]]
3498 if rej:
3524 if rej:
3499 ui.write_err(_("patch applied partially\n"))
3525 ui.write_err(_("patch applied partially\n"))
3500 ui.write_err(_("(fix the .rej files and run "
3526 ui.write_err(_("(fix the .rej files and run "
3501 "`hg commit --amend`)\n"))
3527 "`hg commit --amend`)\n"))
3502 ret = 1
3528 ret = 1
3503 break
3529 break
3504
3530
3505 if not haspatch:
3531 if not haspatch:
3506 raise error.Abort(_('%s: no diffs found') % patchurl)
3532 raise error.Abort(_('%s: no diffs found') % patchurl)
3507
3533
3508 if msgs:
3534 if msgs:
3509 repo.savecommitmessage('\n* * *\n'.join(msgs))
3535 repo.savecommitmessage('\n* * *\n'.join(msgs))
3510 return ret
3536 return ret
3511
3537
3512 @command('incoming|in',
3538 @command('incoming|in',
3513 [('f', 'force', None,
3539 [('f', 'force', None,
3514 _('run even if remote repository is unrelated')),
3540 _('run even if remote repository is unrelated')),
3515 ('n', 'newest-first', None, _('show newest record first')),
3541 ('n', 'newest-first', None, _('show newest record first')),
3516 ('', 'bundle', '',
3542 ('', 'bundle', '',
3517 _('file to store the bundles into'), _('FILE')),
3543 _('file to store the bundles into'), _('FILE')),
3518 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3544 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3519 ('B', 'bookmarks', False, _("compare bookmarks")),
3545 ('B', 'bookmarks', False, _("compare bookmarks")),
3520 ('b', 'branch', [],
3546 ('b', 'branch', [],
3521 _('a specific branch you would like to pull'), _('BRANCH')),
3547 _('a specific branch you would like to pull'), _('BRANCH')),
3522 ] + logopts + remoteopts + subrepoopts,
3548 ] + logopts + remoteopts + subrepoopts,
3523 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
3549 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
3524 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
3550 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
3525 def incoming(ui, repo, source="default", **opts):
3551 def incoming(ui, repo, source="default", **opts):
3526 """show new changesets found in source
3552 """show new changesets found in source
3527
3553
3528 Show new changesets found in the specified path/URL or the default
3554 Show new changesets found in the specified path/URL or the default
3529 pull location. These are the changesets that would have been pulled
3555 pull location. These are the changesets that would have been pulled
3530 by :hg:`pull` at the time you issued this command.
3556 by :hg:`pull` at the time you issued this command.
3531
3557
3532 See pull for valid source format details.
3558 See pull for valid source format details.
3533
3559
3534 .. container:: verbose
3560 .. container:: verbose
3535
3561
3536 With -B/--bookmarks, the result of bookmark comparison between
3562 With -B/--bookmarks, the result of bookmark comparison between
3537 local and remote repositories is displayed. With -v/--verbose,
3563 local and remote repositories is displayed. With -v/--verbose,
3538 status is also displayed for each bookmark like below::
3564 status is also displayed for each bookmark like below::
3539
3565
3540 BM1 01234567890a added
3566 BM1 01234567890a added
3541 BM2 1234567890ab advanced
3567 BM2 1234567890ab advanced
3542 BM3 234567890abc diverged
3568 BM3 234567890abc diverged
3543 BM4 34567890abcd changed
3569 BM4 34567890abcd changed
3544
3570
3545 The action taken locally when pulling depends on the
3571 The action taken locally when pulling depends on the
3546 status of each bookmark:
3572 status of each bookmark:
3547
3573
3548 :``added``: pull will create it
3574 :``added``: pull will create it
3549 :``advanced``: pull will update it
3575 :``advanced``: pull will update it
3550 :``diverged``: pull will create a divergent bookmark
3576 :``diverged``: pull will create a divergent bookmark
3551 :``changed``: result depends on remote changesets
3577 :``changed``: result depends on remote changesets
3552
3578
3553 From the point of view of pulling behavior, bookmark
3579 From the point of view of pulling behavior, bookmark
3554 existing only in the remote repository are treated as ``added``,
3580 existing only in the remote repository are treated as ``added``,
3555 even if it is in fact locally deleted.
3581 even if it is in fact locally deleted.
3556
3582
3557 .. container:: verbose
3583 .. container:: verbose
3558
3584
3559 For remote repository, using --bundle avoids downloading the
3585 For remote repository, using --bundle avoids downloading the
3560 changesets twice if the incoming is followed by a pull.
3586 changesets twice if the incoming is followed by a pull.
3561
3587
3562 Examples:
3588 Examples:
3563
3589
3564 - show incoming changes with patches and full description::
3590 - show incoming changes with patches and full description::
3565
3591
3566 hg incoming -vp
3592 hg incoming -vp
3567
3593
3568 - show incoming changes excluding merges, store a bundle::
3594 - show incoming changes excluding merges, store a bundle::
3569
3595
3570 hg in -vpM --bundle incoming.hg
3596 hg in -vpM --bundle incoming.hg
3571 hg pull incoming.hg
3597 hg pull incoming.hg
3572
3598
3573 - briefly list changes inside a bundle::
3599 - briefly list changes inside a bundle::
3574
3600
3575 hg in changes.hg -T "{desc|firstline}\\n"
3601 hg in changes.hg -T "{desc|firstline}\\n"
3576
3602
3577 Returns 0 if there are incoming changes, 1 otherwise.
3603 Returns 0 if there are incoming changes, 1 otherwise.
3578 """
3604 """
3579 opts = pycompat.byteskwargs(opts)
3605 opts = pycompat.byteskwargs(opts)
3580 if opts.get('graph'):
3606 if opts.get('graph'):
3581 logcmdutil.checkunsupportedgraphflags([], opts)
3607 logcmdutil.checkunsupportedgraphflags([], opts)
3582 def display(other, chlist, displayer):
3608 def display(other, chlist, displayer):
3583 revdag = logcmdutil.graphrevs(other, chlist, opts)
3609 revdag = logcmdutil.graphrevs(other, chlist, opts)
3584 logcmdutil.displaygraph(ui, repo, revdag, displayer,
3610 logcmdutil.displaygraph(ui, repo, revdag, displayer,
3585 graphmod.asciiedges)
3611 graphmod.asciiedges)
3586
3612
3587 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3613 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3588 return 0
3614 return 0
3589
3615
3590 if opts.get('bundle') and opts.get('subrepos'):
3616 if opts.get('bundle') and opts.get('subrepos'):
3591 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3617 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3592
3618
3593 if opts.get('bookmarks'):
3619 if opts.get('bookmarks'):
3594 source, branches = hg.parseurl(ui.expandpath(source),
3620 source, branches = hg.parseurl(ui.expandpath(source),
3595 opts.get('branch'))
3621 opts.get('branch'))
3596 other = hg.peer(repo, opts, source)
3622 other = hg.peer(repo, opts, source)
3597 if 'bookmarks' not in other.listkeys('namespaces'):
3623 if 'bookmarks' not in other.listkeys('namespaces'):
3598 ui.warn(_("remote doesn't support bookmarks\n"))
3624 ui.warn(_("remote doesn't support bookmarks\n"))
3599 return 0
3625 return 0
3600 ui.pager('incoming')
3626 ui.pager('incoming')
3601 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3627 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3602 return bookmarks.incoming(ui, repo, other)
3628 return bookmarks.incoming(ui, repo, other)
3603
3629
3604 repo._subtoppath = ui.expandpath(source)
3630 repo._subtoppath = ui.expandpath(source)
3605 try:
3631 try:
3606 return hg.incoming(ui, repo, source, opts)
3632 return hg.incoming(ui, repo, source, opts)
3607 finally:
3633 finally:
3608 del repo._subtoppath
3634 del repo._subtoppath
3609
3635
3610
3636
3611 @command('init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
3637 @command('init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
3612 helpcategory=command.CATEGORY_REPO_CREATION,
3638 helpcategory=command.CATEGORY_REPO_CREATION,
3613 helpbasic=True, norepo=True)
3639 helpbasic=True, norepo=True)
3614 def init(ui, dest=".", **opts):
3640 def init(ui, dest=".", **opts):
3615 """create a new repository in the given directory
3641 """create a new repository in the given directory
3616
3642
3617 Initialize a new repository in the given directory. If the given
3643 Initialize a new repository in the given directory. If the given
3618 directory does not exist, it will be created.
3644 directory does not exist, it will be created.
3619
3645
3620 If no directory is given, the current directory is used.
3646 If no directory is given, the current directory is used.
3621
3647
3622 It is possible to specify an ``ssh://`` URL as the destination.
3648 It is possible to specify an ``ssh://`` URL as the destination.
3623 See :hg:`help urls` for more information.
3649 See :hg:`help urls` for more information.
3624
3650
3625 Returns 0 on success.
3651 Returns 0 on success.
3626 """
3652 """
3627 opts = pycompat.byteskwargs(opts)
3653 opts = pycompat.byteskwargs(opts)
3628 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3654 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3629
3655
3630 @command('locate',
3656 @command('locate',
3631 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3657 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3632 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3658 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3633 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3659 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3634 ] + walkopts,
3660 ] + walkopts,
3635 _('[OPTION]... [PATTERN]...'),
3661 _('[OPTION]... [PATTERN]...'),
3636 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
3662 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
3637 def locate(ui, repo, *pats, **opts):
3663 def locate(ui, repo, *pats, **opts):
3638 """locate files matching specific patterns (DEPRECATED)
3664 """locate files matching specific patterns (DEPRECATED)
3639
3665
3640 Print files under Mercurial control in the working directory whose
3666 Print files under Mercurial control in the working directory whose
3641 names match the given patterns.
3667 names match the given patterns.
3642
3668
3643 By default, this command searches all directories in the working
3669 By default, this command searches all directories in the working
3644 directory. To search just the current directory and its
3670 directory. To search just the current directory and its
3645 subdirectories, use "--include .".
3671 subdirectories, use "--include .".
3646
3672
3647 If no patterns are given to match, this command prints the names
3673 If no patterns are given to match, this command prints the names
3648 of all files under Mercurial control in the working directory.
3674 of all files under Mercurial control in the working directory.
3649
3675
3650 If you want to feed the output of this command into the "xargs"
3676 If you want to feed the output of this command into the "xargs"
3651 command, use the -0 option to both this command and "xargs". This
3677 command, use the -0 option to both this command and "xargs". This
3652 will avoid the problem of "xargs" treating single filenames that
3678 will avoid the problem of "xargs" treating single filenames that
3653 contain whitespace as multiple filenames.
3679 contain whitespace as multiple filenames.
3654
3680
3655 See :hg:`help files` for a more versatile command.
3681 See :hg:`help files` for a more versatile command.
3656
3682
3657 Returns 0 if a match is found, 1 otherwise.
3683 Returns 0 if a match is found, 1 otherwise.
3658 """
3684 """
3659 opts = pycompat.byteskwargs(opts)
3685 opts = pycompat.byteskwargs(opts)
3660 if opts.get('print0'):
3686 if opts.get('print0'):
3661 end = '\0'
3687 end = '\0'
3662 else:
3688 else:
3663 end = '\n'
3689 end = '\n'
3664 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3690 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3665
3691
3666 ret = 1
3692 ret = 1
3667 m = scmutil.match(ctx, pats, opts, default='relglob',
3693 m = scmutil.match(ctx, pats, opts, default='relglob',
3668 badfn=lambda x, y: False)
3694 badfn=lambda x, y: False)
3669
3695
3670 ui.pager('locate')
3696 ui.pager('locate')
3671 if ctx.rev() is None:
3697 if ctx.rev() is None:
3672 # When run on the working copy, "locate" includes removed files, so
3698 # When run on the working copy, "locate" includes removed files, so
3673 # we get the list of files from the dirstate.
3699 # we get the list of files from the dirstate.
3674 filesgen = sorted(repo.dirstate.matches(m))
3700 filesgen = sorted(repo.dirstate.matches(m))
3675 else:
3701 else:
3676 filesgen = ctx.matches(m)
3702 filesgen = ctx.matches(m)
3677 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
3703 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
3678 for abs in filesgen:
3704 for abs in filesgen:
3679 if opts.get('fullpath'):
3705 if opts.get('fullpath'):
3680 ui.write(repo.wjoin(abs), end)
3706 ui.write(repo.wjoin(abs), end)
3681 else:
3707 else:
3682 ui.write(uipathfn(abs), end)
3708 ui.write(uipathfn(abs), end)
3683 ret = 0
3709 ret = 0
3684
3710
3685 return ret
3711 return ret
3686
3712
3687 @command('log|history',
3713 @command('log|history',
3688 [('f', 'follow', None,
3714 [('f', 'follow', None,
3689 _('follow changeset history, or file history across copies and renames')),
3715 _('follow changeset history, or file history across copies and renames')),
3690 ('', 'follow-first', None,
3716 ('', 'follow-first', None,
3691 _('only follow the first parent of merge changesets (DEPRECATED)')),
3717 _('only follow the first parent of merge changesets (DEPRECATED)')),
3692 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3718 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3693 ('C', 'copies', None, _('show copied files')),
3719 ('C', 'copies', None, _('show copied files')),
3694 ('k', 'keyword', [],
3720 ('k', 'keyword', [],
3695 _('do case-insensitive search for a given text'), _('TEXT')),
3721 _('do case-insensitive search for a given text'), _('TEXT')),
3696 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3722 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3697 ('L', 'line-range', [],
3723 ('L', 'line-range', [],
3698 _('follow line range of specified file (EXPERIMENTAL)'),
3724 _('follow line range of specified file (EXPERIMENTAL)'),
3699 _('FILE,RANGE')),
3725 _('FILE,RANGE')),
3700 ('', 'removed', None, _('include revisions where files were removed')),
3726 ('', 'removed', None, _('include revisions where files were removed')),
3701 ('m', 'only-merges', None,
3727 ('m', 'only-merges', None,
3702 _('show only merges (DEPRECATED) (use -r "merge()" instead)')),
3728 _('show only merges (DEPRECATED) (use -r "merge()" instead)')),
3703 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3729 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3704 ('', 'only-branch', [],
3730 ('', 'only-branch', [],
3705 _('show only changesets within the given named branch (DEPRECATED)'),
3731 _('show only changesets within the given named branch (DEPRECATED)'),
3706 _('BRANCH')),
3732 _('BRANCH')),
3707 ('b', 'branch', [],
3733 ('b', 'branch', [],
3708 _('show changesets within the given named branch'), _('BRANCH')),
3734 _('show changesets within the given named branch'), _('BRANCH')),
3709 ('P', 'prune', [],
3735 ('P', 'prune', [],
3710 _('do not display revision or any of its ancestors'), _('REV')),
3736 _('do not display revision or any of its ancestors'), _('REV')),
3711 ] + logopts + walkopts,
3737 ] + logopts + walkopts,
3712 _('[OPTION]... [FILE]'),
3738 _('[OPTION]... [FILE]'),
3713 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3739 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3714 helpbasic=True, inferrepo=True,
3740 helpbasic=True, inferrepo=True,
3715 intents={INTENT_READONLY})
3741 intents={INTENT_READONLY})
3716 def log(ui, repo, *pats, **opts):
3742 def log(ui, repo, *pats, **opts):
3717 """show revision history of entire repository or files
3743 """show revision history of entire repository or files
3718
3744
3719 Print the revision history of the specified files or the entire
3745 Print the revision history of the specified files or the entire
3720 project.
3746 project.
3721
3747
3722 If no revision range is specified, the default is ``tip:0`` unless
3748 If no revision range is specified, the default is ``tip:0`` unless
3723 --follow is set, in which case the working directory parent is
3749 --follow is set, in which case the working directory parent is
3724 used as the starting revision.
3750 used as the starting revision.
3725
3751
3726 File history is shown without following rename or copy history of
3752 File history is shown without following rename or copy history of
3727 files. Use -f/--follow with a filename to follow history across
3753 files. Use -f/--follow with a filename to follow history across
3728 renames and copies. --follow without a filename will only show
3754 renames and copies. --follow without a filename will only show
3729 ancestors of the starting revision.
3755 ancestors of the starting revision.
3730
3756
3731 By default this command prints revision number and changeset id,
3757 By default this command prints revision number and changeset id,
3732 tags, non-trivial parents, user, date and time, and a summary for
3758 tags, non-trivial parents, user, date and time, and a summary for
3733 each commit. When the -v/--verbose switch is used, the list of
3759 each commit. When the -v/--verbose switch is used, the list of
3734 changed files and full commit message are shown.
3760 changed files and full commit message are shown.
3735
3761
3736 With --graph the revisions are shown as an ASCII art DAG with the most
3762 With --graph the revisions are shown as an ASCII art DAG with the most
3737 recent changeset at the top.
3763 recent changeset at the top.
3738 'o' is a changeset, '@' is a working directory parent, '_' closes a branch,
3764 'o' is a changeset, '@' is a working directory parent, '_' closes a branch,
3739 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
3765 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
3740 changeset from the lines below is a parent of the 'o' merge on the same
3766 changeset from the lines below is a parent of the 'o' merge on the same
3741 line.
3767 line.
3742 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
3768 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
3743 of a '|' indicates one or more revisions in a path are omitted.
3769 of a '|' indicates one or more revisions in a path are omitted.
3744
3770
3745 .. container:: verbose
3771 .. container:: verbose
3746
3772
3747 Use -L/--line-range FILE,M:N options to follow the history of lines
3773 Use -L/--line-range FILE,M:N options to follow the history of lines
3748 from M to N in FILE. With -p/--patch only diff hunks affecting
3774 from M to N in FILE. With -p/--patch only diff hunks affecting
3749 specified line range will be shown. This option requires --follow;
3775 specified line range will be shown. This option requires --follow;
3750 it can be specified multiple times. Currently, this option is not
3776 it can be specified multiple times. Currently, this option is not
3751 compatible with --graph. This option is experimental.
3777 compatible with --graph. This option is experimental.
3752
3778
3753 .. note::
3779 .. note::
3754
3780
3755 :hg:`log --patch` may generate unexpected diff output for merge
3781 :hg:`log --patch` may generate unexpected diff output for merge
3756 changesets, as it will only compare the merge changeset against
3782 changesets, as it will only compare the merge changeset against
3757 its first parent. Also, only files different from BOTH parents
3783 its first parent. Also, only files different from BOTH parents
3758 will appear in files:.
3784 will appear in files:.
3759
3785
3760 .. note::
3786 .. note::
3761
3787
3762 For performance reasons, :hg:`log FILE` may omit duplicate changes
3788 For performance reasons, :hg:`log FILE` may omit duplicate changes
3763 made on branches and will not show removals or mode changes. To
3789 made on branches and will not show removals or mode changes. To
3764 see all such changes, use the --removed switch.
3790 see all such changes, use the --removed switch.
3765
3791
3766 .. container:: verbose
3792 .. container:: verbose
3767
3793
3768 .. note::
3794 .. note::
3769
3795
3770 The history resulting from -L/--line-range options depends on diff
3796 The history resulting from -L/--line-range options depends on diff
3771 options; for instance if white-spaces are ignored, respective changes
3797 options; for instance if white-spaces are ignored, respective changes
3772 with only white-spaces in specified line range will not be listed.
3798 with only white-spaces in specified line range will not be listed.
3773
3799
3774 .. container:: verbose
3800 .. container:: verbose
3775
3801
3776 Some examples:
3802 Some examples:
3777
3803
3778 - changesets with full descriptions and file lists::
3804 - changesets with full descriptions and file lists::
3779
3805
3780 hg log -v
3806 hg log -v
3781
3807
3782 - changesets ancestral to the working directory::
3808 - changesets ancestral to the working directory::
3783
3809
3784 hg log -f
3810 hg log -f
3785
3811
3786 - last 10 commits on the current branch::
3812 - last 10 commits on the current branch::
3787
3813
3788 hg log -l 10 -b .
3814 hg log -l 10 -b .
3789
3815
3790 - changesets showing all modifications of a file, including removals::
3816 - changesets showing all modifications of a file, including removals::
3791
3817
3792 hg log --removed file.c
3818 hg log --removed file.c
3793
3819
3794 - all changesets that touch a directory, with diffs, excluding merges::
3820 - all changesets that touch a directory, with diffs, excluding merges::
3795
3821
3796 hg log -Mp lib/
3822 hg log -Mp lib/
3797
3823
3798 - all revision numbers that match a keyword::
3824 - all revision numbers that match a keyword::
3799
3825
3800 hg log -k bug --template "{rev}\\n"
3826 hg log -k bug --template "{rev}\\n"
3801
3827
3802 - the full hash identifier of the working directory parent::
3828 - the full hash identifier of the working directory parent::
3803
3829
3804 hg log -r . --template "{node}\\n"
3830 hg log -r . --template "{node}\\n"
3805
3831
3806 - list available log templates::
3832 - list available log templates::
3807
3833
3808 hg log -T list
3834 hg log -T list
3809
3835
3810 - check if a given changeset is included in a tagged release::
3836 - check if a given changeset is included in a tagged release::
3811
3837
3812 hg log -r "a21ccf and ancestor(1.9)"
3838 hg log -r "a21ccf and ancestor(1.9)"
3813
3839
3814 - find all changesets by some user in a date range::
3840 - find all changesets by some user in a date range::
3815
3841
3816 hg log -k alice -d "may 2008 to jul 2008"
3842 hg log -k alice -d "may 2008 to jul 2008"
3817
3843
3818 - summary of all changesets after the last tag::
3844 - summary of all changesets after the last tag::
3819
3845
3820 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3846 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3821
3847
3822 - changesets touching lines 13 to 23 for file.c::
3848 - changesets touching lines 13 to 23 for file.c::
3823
3849
3824 hg log -L file.c,13:23
3850 hg log -L file.c,13:23
3825
3851
3826 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
3852 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
3827 main.c with patch::
3853 main.c with patch::
3828
3854
3829 hg log -L file.c,13:23 -L main.c,2:6 -p
3855 hg log -L file.c,13:23 -L main.c,2:6 -p
3830
3856
3831 See :hg:`help dates` for a list of formats valid for -d/--date.
3857 See :hg:`help dates` for a list of formats valid for -d/--date.
3832
3858
3833 See :hg:`help revisions` for more about specifying and ordering
3859 See :hg:`help revisions` for more about specifying and ordering
3834 revisions.
3860 revisions.
3835
3861
3836 See :hg:`help templates` for more about pre-packaged styles and
3862 See :hg:`help templates` for more about pre-packaged styles and
3837 specifying custom templates. The default template used by the log
3863 specifying custom templates. The default template used by the log
3838 command can be customized via the ``ui.logtemplate`` configuration
3864 command can be customized via the ``ui.logtemplate`` configuration
3839 setting.
3865 setting.
3840
3866
3841 Returns 0 on success.
3867 Returns 0 on success.
3842
3868
3843 """
3869 """
3844 opts = pycompat.byteskwargs(opts)
3870 opts = pycompat.byteskwargs(opts)
3845 linerange = opts.get('line_range')
3871 linerange = opts.get('line_range')
3846
3872
3847 if linerange and not opts.get('follow'):
3873 if linerange and not opts.get('follow'):
3848 raise error.Abort(_('--line-range requires --follow'))
3874 raise error.Abort(_('--line-range requires --follow'))
3849
3875
3850 if linerange and pats:
3876 if linerange and pats:
3851 # TODO: take pats as patterns with no line-range filter
3877 # TODO: take pats as patterns with no line-range filter
3852 raise error.Abort(
3878 raise error.Abort(
3853 _('FILE arguments are not compatible with --line-range option')
3879 _('FILE arguments are not compatible with --line-range option')
3854 )
3880 )
3855
3881
3856 repo = scmutil.unhidehashlikerevs(repo, opts.get('rev'), 'nowarn')
3882 repo = scmutil.unhidehashlikerevs(repo, opts.get('rev'), 'nowarn')
3857 revs, differ = logcmdutil.getrevs(repo, pats, opts)
3883 revs, differ = logcmdutil.getrevs(repo, pats, opts)
3858 if linerange:
3884 if linerange:
3859 # TODO: should follow file history from logcmdutil._initialrevs(),
3885 # TODO: should follow file history from logcmdutil._initialrevs(),
3860 # then filter the result by logcmdutil._makerevset() and --limit
3886 # then filter the result by logcmdutil._makerevset() and --limit
3861 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
3887 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
3862
3888
3863 getcopies = None
3889 getcopies = None
3864 if opts.get('copies'):
3890 if opts.get('copies'):
3865 endrev = None
3891 endrev = None
3866 if revs:
3892 if revs:
3867 endrev = revs.max() + 1
3893 endrev = revs.max() + 1
3868 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
3894 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
3869
3895
3870 ui.pager('log')
3896 ui.pager('log')
3871 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, differ,
3897 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, differ,
3872 buffered=True)
3898 buffered=True)
3873 if opts.get('graph'):
3899 if opts.get('graph'):
3874 displayfn = logcmdutil.displaygraphrevs
3900 displayfn = logcmdutil.displaygraphrevs
3875 else:
3901 else:
3876 displayfn = logcmdutil.displayrevs
3902 displayfn = logcmdutil.displayrevs
3877 displayfn(ui, repo, revs, displayer, getcopies)
3903 displayfn(ui, repo, revs, displayer, getcopies)
3878
3904
3879 @command('manifest',
3905 @command('manifest',
3880 [('r', 'rev', '', _('revision to display'), _('REV')),
3906 [('r', 'rev', '', _('revision to display'), _('REV')),
3881 ('', 'all', False, _("list files from all revisions"))]
3907 ('', 'all', False, _("list files from all revisions"))]
3882 + formatteropts,
3908 + formatteropts,
3883 _('[-r REV]'),
3909 _('[-r REV]'),
3884 helpcategory=command.CATEGORY_MAINTENANCE,
3910 helpcategory=command.CATEGORY_MAINTENANCE,
3885 intents={INTENT_READONLY})
3911 intents={INTENT_READONLY})
3886 def manifest(ui, repo, node=None, rev=None, **opts):
3912 def manifest(ui, repo, node=None, rev=None, **opts):
3887 """output the current or given revision of the project manifest
3913 """output the current or given revision of the project manifest
3888
3914
3889 Print a list of version controlled files for the given revision.
3915 Print a list of version controlled files for the given revision.
3890 If no revision is given, the first parent of the working directory
3916 If no revision is given, the first parent of the working directory
3891 is used, or the null revision if no revision is checked out.
3917 is used, or the null revision if no revision is checked out.
3892
3918
3893 With -v, print file permissions, symlink and executable bits.
3919 With -v, print file permissions, symlink and executable bits.
3894 With --debug, print file revision hashes.
3920 With --debug, print file revision hashes.
3895
3921
3896 If option --all is specified, the list of all files from all revisions
3922 If option --all is specified, the list of all files from all revisions
3897 is printed. This includes deleted and renamed files.
3923 is printed. This includes deleted and renamed files.
3898
3924
3899 Returns 0 on success.
3925 Returns 0 on success.
3900 """
3926 """
3901 opts = pycompat.byteskwargs(opts)
3927 opts = pycompat.byteskwargs(opts)
3902 fm = ui.formatter('manifest', opts)
3928 fm = ui.formatter('manifest', opts)
3903
3929
3904 if opts.get('all'):
3930 if opts.get('all'):
3905 if rev or node:
3931 if rev or node:
3906 raise error.Abort(_("can't specify a revision with --all"))
3932 raise error.Abort(_("can't specify a revision with --all"))
3907
3933
3908 res = set()
3934 res = set()
3909 for rev in repo:
3935 for rev in repo:
3910 ctx = repo[rev]
3936 ctx = repo[rev]
3911 res |= set(ctx.files())
3937 res |= set(ctx.files())
3912
3938
3913 ui.pager('manifest')
3939 ui.pager('manifest')
3914 for f in sorted(res):
3940 for f in sorted(res):
3915 fm.startitem()
3941 fm.startitem()
3916 fm.write("path", '%s\n', f)
3942 fm.write("path", '%s\n', f)
3917 fm.end()
3943 fm.end()
3918 return
3944 return
3919
3945
3920 if rev and node:
3946 if rev and node:
3921 raise error.Abort(_("please specify just one revision"))
3947 raise error.Abort(_("please specify just one revision"))
3922
3948
3923 if not node:
3949 if not node:
3924 node = rev
3950 node = rev
3925
3951
3926 char = {'l': '@', 'x': '*', '': '', 't': 'd'}
3952 char = {'l': '@', 'x': '*', '': '', 't': 'd'}
3927 mode = {'l': '644', 'x': '755', '': '644', 't': '755'}
3953 mode = {'l': '644', 'x': '755', '': '644', 't': '755'}
3928 if node:
3954 if node:
3929 repo = scmutil.unhidehashlikerevs(repo, [node], 'nowarn')
3955 repo = scmutil.unhidehashlikerevs(repo, [node], 'nowarn')
3930 ctx = scmutil.revsingle(repo, node)
3956 ctx = scmutil.revsingle(repo, node)
3931 mf = ctx.manifest()
3957 mf = ctx.manifest()
3932 ui.pager('manifest')
3958 ui.pager('manifest')
3933 for f in ctx:
3959 for f in ctx:
3934 fm.startitem()
3960 fm.startitem()
3935 fm.context(ctx=ctx)
3961 fm.context(ctx=ctx)
3936 fl = ctx[f].flags()
3962 fl = ctx[f].flags()
3937 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3963 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3938 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3964 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3939 fm.write('path', '%s\n', f)
3965 fm.write('path', '%s\n', f)
3940 fm.end()
3966 fm.end()
3941
3967
3942 @command('merge',
3968 @command('merge',
3943 [('f', 'force', None,
3969 [('f', 'force', None,
3944 _('force a merge including outstanding changes (DEPRECATED)')),
3970 _('force a merge including outstanding changes (DEPRECATED)')),
3945 ('r', 'rev', '', _('revision to merge'), _('REV')),
3971 ('r', 'rev', '', _('revision to merge'), _('REV')),
3946 ('P', 'preview', None,
3972 ('P', 'preview', None,
3947 _('review revisions to merge (no merge is performed)')),
3973 _('review revisions to merge (no merge is performed)')),
3948 ('', 'abort', None, _('abort the ongoing merge')),
3974 ('', 'abort', None, _('abort the ongoing merge')),
3949 ] + mergetoolopts,
3975 ] + mergetoolopts,
3950 _('[-P] [[-r] REV]'),
3976 _('[-P] [[-r] REV]'),
3951 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, helpbasic=True)
3977 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, helpbasic=True)
3952 def merge(ui, repo, node=None, **opts):
3978 def merge(ui, repo, node=None, **opts):
3953 """merge another revision into working directory
3979 """merge another revision into working directory
3954
3980
3955 The current working directory is updated with all changes made in
3981 The current working directory is updated with all changes made in
3956 the requested revision since the last common predecessor revision.
3982 the requested revision since the last common predecessor revision.
3957
3983
3958 Files that changed between either parent are marked as changed for
3984 Files that changed between either parent are marked as changed for
3959 the next commit and a commit must be performed before any further
3985 the next commit and a commit must be performed before any further
3960 updates to the repository are allowed. The next commit will have
3986 updates to the repository are allowed. The next commit will have
3961 two parents.
3987 two parents.
3962
3988
3963 ``--tool`` can be used to specify the merge tool used for file
3989 ``--tool`` can be used to specify the merge tool used for file
3964 merges. It overrides the HGMERGE environment variable and your
3990 merges. It overrides the HGMERGE environment variable and your
3965 configuration files. See :hg:`help merge-tools` for options.
3991 configuration files. See :hg:`help merge-tools` for options.
3966
3992
3967 If no revision is specified, the working directory's parent is a
3993 If no revision is specified, the working directory's parent is a
3968 head revision, and the current branch contains exactly one other
3994 head revision, and the current branch contains exactly one other
3969 head, the other head is merged with by default. Otherwise, an
3995 head, the other head is merged with by default. Otherwise, an
3970 explicit revision with which to merge must be provided.
3996 explicit revision with which to merge must be provided.
3971
3997
3972 See :hg:`help resolve` for information on handling file conflicts.
3998 See :hg:`help resolve` for information on handling file conflicts.
3973
3999
3974 To undo an uncommitted merge, use :hg:`merge --abort` which
4000 To undo an uncommitted merge, use :hg:`merge --abort` which
3975 will check out a clean copy of the original merge parent, losing
4001 will check out a clean copy of the original merge parent, losing
3976 all changes.
4002 all changes.
3977
4003
3978 Returns 0 on success, 1 if there are unresolved files.
4004 Returns 0 on success, 1 if there are unresolved files.
3979 """
4005 """
3980
4006
3981 opts = pycompat.byteskwargs(opts)
4007 opts = pycompat.byteskwargs(opts)
3982 abort = opts.get('abort')
4008 abort = opts.get('abort')
3983 if abort and repo.dirstate.p2() == nullid:
4009 if abort and repo.dirstate.p2() == nullid:
3984 cmdutil.wrongtooltocontinue(repo, _('merge'))
4010 cmdutil.wrongtooltocontinue(repo, _('merge'))
3985 if abort:
4011 if abort:
3986 state = cmdutil.getunfinishedstate(repo)
4012 state = cmdutil.getunfinishedstate(repo)
3987 if state and state._opname != 'merge':
4013 if state and state._opname != 'merge':
3988 raise error.Abort(_('cannot abort merge with %s in progress') %
4014 raise error.Abort(_('cannot abort merge with %s in progress') %
3989 (state._opname), hint=state.hint())
4015 (state._opname), hint=state.hint())
3990 if node:
4016 if node:
3991 raise error.Abort(_("cannot specify a node with --abort"))
4017 raise error.Abort(_("cannot specify a node with --abort"))
3992 if opts.get('rev'):
4018 if opts.get('rev'):
3993 raise error.Abort(_("cannot specify both --rev and --abort"))
4019 raise error.Abort(_("cannot specify both --rev and --abort"))
3994 if opts.get('preview'):
4020 if opts.get('preview'):
3995 raise error.Abort(_("cannot specify --preview with --abort"))
4021 raise error.Abort(_("cannot specify --preview with --abort"))
3996 if opts.get('rev') and node:
4022 if opts.get('rev') and node:
3997 raise error.Abort(_("please specify just one revision"))
4023 raise error.Abort(_("please specify just one revision"))
3998 if not node:
4024 if not node:
3999 node = opts.get('rev')
4025 node = opts.get('rev')
4000
4026
4001 if node:
4027 if node:
4002 node = scmutil.revsingle(repo, node).node()
4028 node = scmutil.revsingle(repo, node).node()
4003
4029
4004 if not node and not abort:
4030 if not node and not abort:
4005 node = repo[destutil.destmerge(repo)].node()
4031 node = repo[destutil.destmerge(repo)].node()
4006
4032
4007 if opts.get('preview'):
4033 if opts.get('preview'):
4008 # find nodes that are ancestors of p2 but not of p1
4034 # find nodes that are ancestors of p2 but not of p1
4009 p1 = repo.lookup('.')
4035 p1 = repo.lookup('.')
4010 p2 = node
4036 p2 = node
4011 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4037 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4012
4038
4013 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4039 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4014 for node in nodes:
4040 for node in nodes:
4015 displayer.show(repo[node])
4041 displayer.show(repo[node])
4016 displayer.close()
4042 displayer.close()
4017 return 0
4043 return 0
4018
4044
4019 # ui.forcemerge is an internal variable, do not document
4045 # ui.forcemerge is an internal variable, do not document
4020 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4046 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4021 with ui.configoverride(overrides, 'merge'):
4047 with ui.configoverride(overrides, 'merge'):
4022 force = opts.get('force')
4048 force = opts.get('force')
4023 labels = ['working copy', 'merge rev']
4049 labels = ['working copy', 'merge rev']
4024 return hg.merge(repo, node, force=force, mergeforce=force,
4050 return hg.merge(repo, node, force=force, mergeforce=force,
4025 labels=labels, abort=abort)
4051 labels=labels, abort=abort)
4026
4052
4027 statemod.addunfinished(
4053 statemod.addunfinished(
4028 'merge', fname=None, clearable=True, allowcommit=True,
4054 'merge', fname=None, clearable=True, allowcommit=True,
4029 cmdmsg=_('outstanding uncommitted merge'), abortfunc=hg.abortmerge,
4055 cmdmsg=_('outstanding uncommitted merge'), abortfunc=hg.abortmerge,
4030 statushint=_('To continue: hg commit\n'
4056 statushint=_('To continue: hg commit\n'
4031 'To abort: hg merge --abort'),
4057 'To abort: hg merge --abort'),
4032 cmdhint=_("use 'hg commit' or 'hg merge --abort'")
4058 cmdhint=_("use 'hg commit' or 'hg merge --abort'")
4033 )
4059 )
4034
4060
4035 @command('outgoing|out',
4061 @command('outgoing|out',
4036 [('f', 'force', None, _('run even when the destination is unrelated')),
4062 [('f', 'force', None, _('run even when the destination is unrelated')),
4037 ('r', 'rev', [],
4063 ('r', 'rev', [],
4038 _('a changeset intended to be included in the destination'), _('REV')),
4064 _('a changeset intended to be included in the destination'), _('REV')),
4039 ('n', 'newest-first', None, _('show newest record first')),
4065 ('n', 'newest-first', None, _('show newest record first')),
4040 ('B', 'bookmarks', False, _('compare bookmarks')),
4066 ('B', 'bookmarks', False, _('compare bookmarks')),
4041 ('b', 'branch', [], _('a specific branch you would like to push'),
4067 ('b', 'branch', [], _('a specific branch you would like to push'),
4042 _('BRANCH')),
4068 _('BRANCH')),
4043 ] + logopts + remoteopts + subrepoopts,
4069 ] + logopts + remoteopts + subrepoopts,
4044 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4070 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4045 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
4071 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
4046 def outgoing(ui, repo, dest=None, **opts):
4072 def outgoing(ui, repo, dest=None, **opts):
4047 """show changesets not found in the destination
4073 """show changesets not found in the destination
4048
4074
4049 Show changesets not found in the specified destination repository
4075 Show changesets not found in the specified destination repository
4050 or the default push location. These are the changesets that would
4076 or the default push location. These are the changesets that would
4051 be pushed if a push was requested.
4077 be pushed if a push was requested.
4052
4078
4053 See pull for details of valid destination formats.
4079 See pull for details of valid destination formats.
4054
4080
4055 .. container:: verbose
4081 .. container:: verbose
4056
4082
4057 With -B/--bookmarks, the result of bookmark comparison between
4083 With -B/--bookmarks, the result of bookmark comparison between
4058 local and remote repositories is displayed. With -v/--verbose,
4084 local and remote repositories is displayed. With -v/--verbose,
4059 status is also displayed for each bookmark like below::
4085 status is also displayed for each bookmark like below::
4060
4086
4061 BM1 01234567890a added
4087 BM1 01234567890a added
4062 BM2 deleted
4088 BM2 deleted
4063 BM3 234567890abc advanced
4089 BM3 234567890abc advanced
4064 BM4 34567890abcd diverged
4090 BM4 34567890abcd diverged
4065 BM5 4567890abcde changed
4091 BM5 4567890abcde changed
4066
4092
4067 The action taken when pushing depends on the
4093 The action taken when pushing depends on the
4068 status of each bookmark:
4094 status of each bookmark:
4069
4095
4070 :``added``: push with ``-B`` will create it
4096 :``added``: push with ``-B`` will create it
4071 :``deleted``: push with ``-B`` will delete it
4097 :``deleted``: push with ``-B`` will delete it
4072 :``advanced``: push will update it
4098 :``advanced``: push will update it
4073 :``diverged``: push with ``-B`` will update it
4099 :``diverged``: push with ``-B`` will update it
4074 :``changed``: push with ``-B`` will update it
4100 :``changed``: push with ``-B`` will update it
4075
4101
4076 From the point of view of pushing behavior, bookmarks
4102 From the point of view of pushing behavior, bookmarks
4077 existing only in the remote repository are treated as
4103 existing only in the remote repository are treated as
4078 ``deleted``, even if it is in fact added remotely.
4104 ``deleted``, even if it is in fact added remotely.
4079
4105
4080 Returns 0 if there are outgoing changes, 1 otherwise.
4106 Returns 0 if there are outgoing changes, 1 otherwise.
4081 """
4107 """
4082 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4108 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4083 # style URLs, so don't overwrite dest.
4109 # style URLs, so don't overwrite dest.
4084 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4110 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4085 if not path:
4111 if not path:
4086 raise error.Abort(_('default repository not configured!'),
4112 raise error.Abort(_('default repository not configured!'),
4087 hint=_("see 'hg help config.paths'"))
4113 hint=_("see 'hg help config.paths'"))
4088
4114
4089 opts = pycompat.byteskwargs(opts)
4115 opts = pycompat.byteskwargs(opts)
4090 if opts.get('graph'):
4116 if opts.get('graph'):
4091 logcmdutil.checkunsupportedgraphflags([], opts)
4117 logcmdutil.checkunsupportedgraphflags([], opts)
4092 o, other = hg._outgoing(ui, repo, dest, opts)
4118 o, other = hg._outgoing(ui, repo, dest, opts)
4093 if not o:
4119 if not o:
4094 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4120 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4095 return
4121 return
4096
4122
4097 revdag = logcmdutil.graphrevs(repo, o, opts)
4123 revdag = logcmdutil.graphrevs(repo, o, opts)
4098 ui.pager('outgoing')
4124 ui.pager('outgoing')
4099 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4125 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4100 logcmdutil.displaygraph(ui, repo, revdag, displayer,
4126 logcmdutil.displaygraph(ui, repo, revdag, displayer,
4101 graphmod.asciiedges)
4127 graphmod.asciiedges)
4102 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4128 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4103 return 0
4129 return 0
4104
4130
4105 if opts.get('bookmarks'):
4131 if opts.get('bookmarks'):
4106 dest = path.pushloc or path.loc
4132 dest = path.pushloc or path.loc
4107 other = hg.peer(repo, opts, dest)
4133 other = hg.peer(repo, opts, dest)
4108 if 'bookmarks' not in other.listkeys('namespaces'):
4134 if 'bookmarks' not in other.listkeys('namespaces'):
4109 ui.warn(_("remote doesn't support bookmarks\n"))
4135 ui.warn(_("remote doesn't support bookmarks\n"))
4110 return 0
4136 return 0
4111 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4137 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4112 ui.pager('outgoing')
4138 ui.pager('outgoing')
4113 return bookmarks.outgoing(ui, repo, other)
4139 return bookmarks.outgoing(ui, repo, other)
4114
4140
4115 repo._subtoppath = path.pushloc or path.loc
4141 repo._subtoppath = path.pushloc or path.loc
4116 try:
4142 try:
4117 return hg.outgoing(ui, repo, dest, opts)
4143 return hg.outgoing(ui, repo, dest, opts)
4118 finally:
4144 finally:
4119 del repo._subtoppath
4145 del repo._subtoppath
4120
4146
4121 @command('parents',
4147 @command('parents',
4122 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4148 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4123 ] + templateopts,
4149 ] + templateopts,
4124 _('[-r REV] [FILE]'),
4150 _('[-r REV] [FILE]'),
4125 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4151 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4126 inferrepo=True)
4152 inferrepo=True)
4127 def parents(ui, repo, file_=None, **opts):
4153 def parents(ui, repo, file_=None, **opts):
4128 """show the parents of the working directory or revision (DEPRECATED)
4154 """show the parents of the working directory or revision (DEPRECATED)
4129
4155
4130 Print the working directory's parent revisions. If a revision is
4156 Print the working directory's parent revisions. If a revision is
4131 given via -r/--rev, the parent of that revision will be printed.
4157 given via -r/--rev, the parent of that revision will be printed.
4132 If a file argument is given, the revision in which the file was
4158 If a file argument is given, the revision in which the file was
4133 last changed (before the working directory revision or the
4159 last changed (before the working directory revision or the
4134 argument to --rev if given) is printed.
4160 argument to --rev if given) is printed.
4135
4161
4136 This command is equivalent to::
4162 This command is equivalent to::
4137
4163
4138 hg log -r "p1()+p2()" or
4164 hg log -r "p1()+p2()" or
4139 hg log -r "p1(REV)+p2(REV)" or
4165 hg log -r "p1(REV)+p2(REV)" or
4140 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
4166 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
4141 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
4167 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
4142
4168
4143 See :hg:`summary` and :hg:`help revsets` for related information.
4169 See :hg:`summary` and :hg:`help revsets` for related information.
4144
4170
4145 Returns 0 on success.
4171 Returns 0 on success.
4146 """
4172 """
4147
4173
4148 opts = pycompat.byteskwargs(opts)
4174 opts = pycompat.byteskwargs(opts)
4149 rev = opts.get('rev')
4175 rev = opts.get('rev')
4150 if rev:
4176 if rev:
4151 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
4177 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
4152 ctx = scmutil.revsingle(repo, rev, None)
4178 ctx = scmutil.revsingle(repo, rev, None)
4153
4179
4154 if file_:
4180 if file_:
4155 m = scmutil.match(ctx, (file_,), opts)
4181 m = scmutil.match(ctx, (file_,), opts)
4156 if m.anypats() or len(m.files()) != 1:
4182 if m.anypats() or len(m.files()) != 1:
4157 raise error.Abort(_('can only specify an explicit filename'))
4183 raise error.Abort(_('can only specify an explicit filename'))
4158 file_ = m.files()[0]
4184 file_ = m.files()[0]
4159 filenodes = []
4185 filenodes = []
4160 for cp in ctx.parents():
4186 for cp in ctx.parents():
4161 if not cp:
4187 if not cp:
4162 continue
4188 continue
4163 try:
4189 try:
4164 filenodes.append(cp.filenode(file_))
4190 filenodes.append(cp.filenode(file_))
4165 except error.LookupError:
4191 except error.LookupError:
4166 pass
4192 pass
4167 if not filenodes:
4193 if not filenodes:
4168 raise error.Abort(_("'%s' not found in manifest!") % file_)
4194 raise error.Abort(_("'%s' not found in manifest!") % file_)
4169 p = []
4195 p = []
4170 for fn in filenodes:
4196 for fn in filenodes:
4171 fctx = repo.filectx(file_, fileid=fn)
4197 fctx = repo.filectx(file_, fileid=fn)
4172 p.append(fctx.node())
4198 p.append(fctx.node())
4173 else:
4199 else:
4174 p = [cp.node() for cp in ctx.parents()]
4200 p = [cp.node() for cp in ctx.parents()]
4175
4201
4176 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4202 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4177 for n in p:
4203 for n in p:
4178 if n != nullid:
4204 if n != nullid:
4179 displayer.show(repo[n])
4205 displayer.show(repo[n])
4180 displayer.close()
4206 displayer.close()
4181
4207
4182 @command('paths', formatteropts, _('[NAME]'),
4208 @command('paths', formatteropts, _('[NAME]'),
4183 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4209 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4184 optionalrepo=True, intents={INTENT_READONLY})
4210 optionalrepo=True, intents={INTENT_READONLY})
4185 def paths(ui, repo, search=None, **opts):
4211 def paths(ui, repo, search=None, **opts):
4186 """show aliases for remote repositories
4212 """show aliases for remote repositories
4187
4213
4188 Show definition of symbolic path name NAME. If no name is given,
4214 Show definition of symbolic path name NAME. If no name is given,
4189 show definition of all available names.
4215 show definition of all available names.
4190
4216
4191 Option -q/--quiet suppresses all output when searching for NAME
4217 Option -q/--quiet suppresses all output when searching for NAME
4192 and shows only the path names when listing all definitions.
4218 and shows only the path names when listing all definitions.
4193
4219
4194 Path names are defined in the [paths] section of your
4220 Path names are defined in the [paths] section of your
4195 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4221 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4196 repository, ``.hg/hgrc`` is used, too.
4222 repository, ``.hg/hgrc`` is used, too.
4197
4223
4198 The path names ``default`` and ``default-push`` have a special
4224 The path names ``default`` and ``default-push`` have a special
4199 meaning. When performing a push or pull operation, they are used
4225 meaning. When performing a push or pull operation, they are used
4200 as fallbacks if no location is specified on the command-line.
4226 as fallbacks if no location is specified on the command-line.
4201 When ``default-push`` is set, it will be used for push and
4227 When ``default-push`` is set, it will be used for push and
4202 ``default`` will be used for pull; otherwise ``default`` is used
4228 ``default`` will be used for pull; otherwise ``default`` is used
4203 as the fallback for both. When cloning a repository, the clone
4229 as the fallback for both. When cloning a repository, the clone
4204 source is written as ``default`` in ``.hg/hgrc``.
4230 source is written as ``default`` in ``.hg/hgrc``.
4205
4231
4206 .. note::
4232 .. note::
4207
4233
4208 ``default`` and ``default-push`` apply to all inbound (e.g.
4234 ``default`` and ``default-push`` apply to all inbound (e.g.
4209 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
4235 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
4210 and :hg:`bundle`) operations.
4236 and :hg:`bundle`) operations.
4211
4237
4212 See :hg:`help urls` for more information.
4238 See :hg:`help urls` for more information.
4213
4239
4214 .. container:: verbose
4240 .. container:: verbose
4215
4241
4216 Template:
4242 Template:
4217
4243
4218 The following keywords are supported. See also :hg:`help templates`.
4244 The following keywords are supported. See also :hg:`help templates`.
4219
4245
4220 :name: String. Symbolic name of the path alias.
4246 :name: String. Symbolic name of the path alias.
4221 :pushurl: String. URL for push operations.
4247 :pushurl: String. URL for push operations.
4222 :url: String. URL or directory path for the other operations.
4248 :url: String. URL or directory path for the other operations.
4223
4249
4224 Returns 0 on success.
4250 Returns 0 on success.
4225 """
4251 """
4226
4252
4227 opts = pycompat.byteskwargs(opts)
4253 opts = pycompat.byteskwargs(opts)
4228 ui.pager('paths')
4254 ui.pager('paths')
4229 if search:
4255 if search:
4230 pathitems = [(name, path) for name, path in ui.paths.iteritems()
4256 pathitems = [(name, path) for name, path in ui.paths.iteritems()
4231 if name == search]
4257 if name == search]
4232 else:
4258 else:
4233 pathitems = sorted(ui.paths.iteritems())
4259 pathitems = sorted(ui.paths.iteritems())
4234
4260
4235 fm = ui.formatter('paths', opts)
4261 fm = ui.formatter('paths', opts)
4236 if fm.isplain():
4262 if fm.isplain():
4237 hidepassword = util.hidepassword
4263 hidepassword = util.hidepassword
4238 else:
4264 else:
4239 hidepassword = bytes
4265 hidepassword = bytes
4240 if ui.quiet:
4266 if ui.quiet:
4241 namefmt = '%s\n'
4267 namefmt = '%s\n'
4242 else:
4268 else:
4243 namefmt = '%s = '
4269 namefmt = '%s = '
4244 showsubopts = not search and not ui.quiet
4270 showsubopts = not search and not ui.quiet
4245
4271
4246 for name, path in pathitems:
4272 for name, path in pathitems:
4247 fm.startitem()
4273 fm.startitem()
4248 fm.condwrite(not search, 'name', namefmt, name)
4274 fm.condwrite(not search, 'name', namefmt, name)
4249 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
4275 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
4250 for subopt, value in sorted(path.suboptions.items()):
4276 for subopt, value in sorted(path.suboptions.items()):
4251 assert subopt not in ('name', 'url')
4277 assert subopt not in ('name', 'url')
4252 if showsubopts:
4278 if showsubopts:
4253 fm.plain('%s:%s = ' % (name, subopt))
4279 fm.plain('%s:%s = ' % (name, subopt))
4254 fm.condwrite(showsubopts, subopt, '%s\n', value)
4280 fm.condwrite(showsubopts, subopt, '%s\n', value)
4255
4281
4256 fm.end()
4282 fm.end()
4257
4283
4258 if search and not pathitems:
4284 if search and not pathitems:
4259 if not ui.quiet:
4285 if not ui.quiet:
4260 ui.warn(_("not found!\n"))
4286 ui.warn(_("not found!\n"))
4261 return 1
4287 return 1
4262 else:
4288 else:
4263 return 0
4289 return 0
4264
4290
4265 @command('phase',
4291 @command('phase',
4266 [('p', 'public', False, _('set changeset phase to public')),
4292 [('p', 'public', False, _('set changeset phase to public')),
4267 ('d', 'draft', False, _('set changeset phase to draft')),
4293 ('d', 'draft', False, _('set changeset phase to draft')),
4268 ('s', 'secret', False, _('set changeset phase to secret')),
4294 ('s', 'secret', False, _('set changeset phase to secret')),
4269 ('f', 'force', False, _('allow to move boundary backward')),
4295 ('f', 'force', False, _('allow to move boundary backward')),
4270 ('r', 'rev', [], _('target revision'), _('REV')),
4296 ('r', 'rev', [], _('target revision'), _('REV')),
4271 ],
4297 ],
4272 _('[-p|-d|-s] [-f] [-r] [REV...]'),
4298 _('[-p|-d|-s] [-f] [-r] [REV...]'),
4273 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
4299 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
4274 def phase(ui, repo, *revs, **opts):
4300 def phase(ui, repo, *revs, **opts):
4275 """set or show the current phase name
4301 """set or show the current phase name
4276
4302
4277 With no argument, show the phase name of the current revision(s).
4303 With no argument, show the phase name of the current revision(s).
4278
4304
4279 With one of -p/--public, -d/--draft or -s/--secret, change the
4305 With one of -p/--public, -d/--draft or -s/--secret, change the
4280 phase value of the specified revisions.
4306 phase value of the specified revisions.
4281
4307
4282 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
4308 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
4283 lower phase to a higher phase. Phases are ordered as follows::
4309 lower phase to a higher phase. Phases are ordered as follows::
4284
4310
4285 public < draft < secret
4311 public < draft < secret
4286
4312
4287 Returns 0 on success, 1 if some phases could not be changed.
4313 Returns 0 on success, 1 if some phases could not be changed.
4288
4314
4289 (For more information about the phases concept, see :hg:`help phases`.)
4315 (For more information about the phases concept, see :hg:`help phases`.)
4290 """
4316 """
4291 opts = pycompat.byteskwargs(opts)
4317 opts = pycompat.byteskwargs(opts)
4292 # search for a unique phase argument
4318 # search for a unique phase argument
4293 targetphase = None
4319 targetphase = None
4294 for idx, name in enumerate(phases.cmdphasenames):
4320 for idx, name in enumerate(phases.cmdphasenames):
4295 if opts[name]:
4321 if opts[name]:
4296 if targetphase is not None:
4322 if targetphase is not None:
4297 raise error.Abort(_('only one phase can be specified'))
4323 raise error.Abort(_('only one phase can be specified'))
4298 targetphase = idx
4324 targetphase = idx
4299
4325
4300 # look for specified revision
4326 # look for specified revision
4301 revs = list(revs)
4327 revs = list(revs)
4302 revs.extend(opts['rev'])
4328 revs.extend(opts['rev'])
4303 if not revs:
4329 if not revs:
4304 # display both parents as the second parent phase can influence
4330 # display both parents as the second parent phase can influence
4305 # the phase of a merge commit
4331 # the phase of a merge commit
4306 revs = [c.rev() for c in repo[None].parents()]
4332 revs = [c.rev() for c in repo[None].parents()]
4307
4333
4308 revs = scmutil.revrange(repo, revs)
4334 revs = scmutil.revrange(repo, revs)
4309
4335
4310 ret = 0
4336 ret = 0
4311 if targetphase is None:
4337 if targetphase is None:
4312 # display
4338 # display
4313 for r in revs:
4339 for r in revs:
4314 ctx = repo[r]
4340 ctx = repo[r]
4315 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4341 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4316 else:
4342 else:
4317 with repo.lock(), repo.transaction("phase") as tr:
4343 with repo.lock(), repo.transaction("phase") as tr:
4318 # set phase
4344 # set phase
4319 if not revs:
4345 if not revs:
4320 raise error.Abort(_('empty revision set'))
4346 raise error.Abort(_('empty revision set'))
4321 nodes = [repo[r].node() for r in revs]
4347 nodes = [repo[r].node() for r in revs]
4322 # moving revision from public to draft may hide them
4348 # moving revision from public to draft may hide them
4323 # We have to check result on an unfiltered repository
4349 # We have to check result on an unfiltered repository
4324 unfi = repo.unfiltered()
4350 unfi = repo.unfiltered()
4325 getphase = unfi._phasecache.phase
4351 getphase = unfi._phasecache.phase
4326 olddata = [getphase(unfi, r) for r in unfi]
4352 olddata = [getphase(unfi, r) for r in unfi]
4327 phases.advanceboundary(repo, tr, targetphase, nodes)
4353 phases.advanceboundary(repo, tr, targetphase, nodes)
4328 if opts['force']:
4354 if opts['force']:
4329 phases.retractboundary(repo, tr, targetphase, nodes)
4355 phases.retractboundary(repo, tr, targetphase, nodes)
4330 getphase = unfi._phasecache.phase
4356 getphase = unfi._phasecache.phase
4331 newdata = [getphase(unfi, r) for r in unfi]
4357 newdata = [getphase(unfi, r) for r in unfi]
4332 changes = sum(newdata[r] != olddata[r] for r in unfi)
4358 changes = sum(newdata[r] != olddata[r] for r in unfi)
4333 cl = unfi.changelog
4359 cl = unfi.changelog
4334 rejected = [n for n in nodes
4360 rejected = [n for n in nodes
4335 if newdata[cl.rev(n)] < targetphase]
4361 if newdata[cl.rev(n)] < targetphase]
4336 if rejected:
4362 if rejected:
4337 ui.warn(_('cannot move %i changesets to a higher '
4363 ui.warn(_('cannot move %i changesets to a higher '
4338 'phase, use --force\n') % len(rejected))
4364 'phase, use --force\n') % len(rejected))
4339 ret = 1
4365 ret = 1
4340 if changes:
4366 if changes:
4341 msg = _('phase changed for %i changesets\n') % changes
4367 msg = _('phase changed for %i changesets\n') % changes
4342 if ret:
4368 if ret:
4343 ui.status(msg)
4369 ui.status(msg)
4344 else:
4370 else:
4345 ui.note(msg)
4371 ui.note(msg)
4346 else:
4372 else:
4347 ui.warn(_('no phases changed\n'))
4373 ui.warn(_('no phases changed\n'))
4348 return ret
4374 return ret
4349
4375
4350 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
4376 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
4351 """Run after a changegroup has been added via pull/unbundle
4377 """Run after a changegroup has been added via pull/unbundle
4352
4378
4353 This takes arguments below:
4379 This takes arguments below:
4354
4380
4355 :modheads: change of heads by pull/unbundle
4381 :modheads: change of heads by pull/unbundle
4356 :optupdate: updating working directory is needed or not
4382 :optupdate: updating working directory is needed or not
4357 :checkout: update destination revision (or None to default destination)
4383 :checkout: update destination revision (or None to default destination)
4358 :brev: a name, which might be a bookmark to be activated after updating
4384 :brev: a name, which might be a bookmark to be activated after updating
4359 """
4385 """
4360 if modheads == 0:
4386 if modheads == 0:
4361 return
4387 return
4362 if optupdate:
4388 if optupdate:
4363 try:
4389 try:
4364 return hg.updatetotally(ui, repo, checkout, brev)
4390 return hg.updatetotally(ui, repo, checkout, brev)
4365 except error.UpdateAbort as inst:
4391 except error.UpdateAbort as inst:
4366 msg = _("not updating: %s") % stringutil.forcebytestr(inst)
4392 msg = _("not updating: %s") % stringutil.forcebytestr(inst)
4367 hint = inst.hint
4393 hint = inst.hint
4368 raise error.UpdateAbort(msg, hint=hint)
4394 raise error.UpdateAbort(msg, hint=hint)
4369 if modheads is not None and modheads > 1:
4395 if modheads is not None and modheads > 1:
4370 currentbranchheads = len(repo.branchheads())
4396 currentbranchheads = len(repo.branchheads())
4371 if currentbranchheads == modheads:
4397 if currentbranchheads == modheads:
4372 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4398 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4373 elif currentbranchheads > 1:
4399 elif currentbranchheads > 1:
4374 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4400 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4375 "merge)\n"))
4401 "merge)\n"))
4376 else:
4402 else:
4377 ui.status(_("(run 'hg heads' to see heads)\n"))
4403 ui.status(_("(run 'hg heads' to see heads)\n"))
4378 elif not ui.configbool('commands', 'update.requiredest'):
4404 elif not ui.configbool('commands', 'update.requiredest'):
4379 ui.status(_("(run 'hg update' to get a working copy)\n"))
4405 ui.status(_("(run 'hg update' to get a working copy)\n"))
4380
4406
4381 @command('pull',
4407 @command('pull',
4382 [('u', 'update', None,
4408 [('u', 'update', None,
4383 _('update to new branch head if new descendants were pulled')),
4409 _('update to new branch head if new descendants were pulled')),
4384 ('f', 'force', None, _('run even when remote repository is unrelated')),
4410 ('f', 'force', None, _('run even when remote repository is unrelated')),
4385 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4411 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4386 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4412 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4387 ('b', 'branch', [], _('a specific branch you would like to pull'),
4413 ('b', 'branch', [], _('a specific branch you would like to pull'),
4388 _('BRANCH')),
4414 _('BRANCH')),
4389 ] + remoteopts,
4415 ] + remoteopts,
4390 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
4416 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
4391 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4417 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4392 helpbasic=True)
4418 helpbasic=True)
4393 def pull(ui, repo, source="default", **opts):
4419 def pull(ui, repo, source="default", **opts):
4394 """pull changes from the specified source
4420 """pull changes from the specified source
4395
4421
4396 Pull changes from a remote repository to a local one.
4422 Pull changes from a remote repository to a local one.
4397
4423
4398 This finds all changes from the repository at the specified path
4424 This finds all changes from the repository at the specified path
4399 or URL and adds them to a local repository (the current one unless
4425 or URL and adds them to a local repository (the current one unless
4400 -R is specified). By default, this does not update the copy of the
4426 -R is specified). By default, this does not update the copy of the
4401 project in the working directory.
4427 project in the working directory.
4402
4428
4403 When cloning from servers that support it, Mercurial may fetch
4429 When cloning from servers that support it, Mercurial may fetch
4404 pre-generated data. When this is done, hooks operating on incoming
4430 pre-generated data. When this is done, hooks operating on incoming
4405 changesets and changegroups may fire more than once, once for each
4431 changesets and changegroups may fire more than once, once for each
4406 pre-generated bundle and as well as for any additional remaining
4432 pre-generated bundle and as well as for any additional remaining
4407 data. See :hg:`help -e clonebundles` for more.
4433 data. See :hg:`help -e clonebundles` for more.
4408
4434
4409 Use :hg:`incoming` if you want to see what would have been added
4435 Use :hg:`incoming` if you want to see what would have been added
4410 by a pull at the time you issued this command. If you then decide
4436 by a pull at the time you issued this command. If you then decide
4411 to add those changes to the repository, you should use :hg:`pull
4437 to add those changes to the repository, you should use :hg:`pull
4412 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4438 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4413
4439
4414 If SOURCE is omitted, the 'default' path will be used.
4440 If SOURCE is omitted, the 'default' path will be used.
4415 See :hg:`help urls` for more information.
4441 See :hg:`help urls` for more information.
4416
4442
4417 Specifying bookmark as ``.`` is equivalent to specifying the active
4443 Specifying bookmark as ``.`` is equivalent to specifying the active
4418 bookmark's name.
4444 bookmark's name.
4419
4445
4420 Returns 0 on success, 1 if an update had unresolved files.
4446 Returns 0 on success, 1 if an update had unresolved files.
4421 """
4447 """
4422
4448
4423 opts = pycompat.byteskwargs(opts)
4449 opts = pycompat.byteskwargs(opts)
4424 if ui.configbool('commands', 'update.requiredest') and opts.get('update'):
4450 if ui.configbool('commands', 'update.requiredest') and opts.get('update'):
4425 msg = _('update destination required by configuration')
4451 msg = _('update destination required by configuration')
4426 hint = _('use hg pull followed by hg update DEST')
4452 hint = _('use hg pull followed by hg update DEST')
4427 raise error.Abort(msg, hint=hint)
4453 raise error.Abort(msg, hint=hint)
4428
4454
4429 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4455 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4430 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4456 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4431 other = hg.peer(repo, opts, source)
4457 other = hg.peer(repo, opts, source)
4432 try:
4458 try:
4433 revs, checkout = hg.addbranchrevs(repo, other, branches,
4459 revs, checkout = hg.addbranchrevs(repo, other, branches,
4434 opts.get('rev'))
4460 opts.get('rev'))
4435
4461
4436 pullopargs = {}
4462 pullopargs = {}
4437
4463
4438 nodes = None
4464 nodes = None
4439 if opts.get('bookmark') or revs:
4465 if opts.get('bookmark') or revs:
4440 # The list of bookmark used here is the same used to actually update
4466 # The list of bookmark used here is the same used to actually update
4441 # the bookmark names, to avoid the race from issue 4689 and we do
4467 # the bookmark names, to avoid the race from issue 4689 and we do
4442 # all lookup and bookmark queries in one go so they see the same
4468 # all lookup and bookmark queries in one go so they see the same
4443 # version of the server state (issue 4700).
4469 # version of the server state (issue 4700).
4444 nodes = []
4470 nodes = []
4445 fnodes = []
4471 fnodes = []
4446 revs = revs or []
4472 revs = revs or []
4447 if revs and not other.capable('lookup'):
4473 if revs and not other.capable('lookup'):
4448 err = _("other repository doesn't support revision lookup, "
4474 err = _("other repository doesn't support revision lookup, "
4449 "so a rev cannot be specified.")
4475 "so a rev cannot be specified.")
4450 raise error.Abort(err)
4476 raise error.Abort(err)
4451 with other.commandexecutor() as e:
4477 with other.commandexecutor() as e:
4452 fremotebookmarks = e.callcommand('listkeys', {
4478 fremotebookmarks = e.callcommand('listkeys', {
4453 'namespace': 'bookmarks'
4479 'namespace': 'bookmarks'
4454 })
4480 })
4455 for r in revs:
4481 for r in revs:
4456 fnodes.append(e.callcommand('lookup', {'key': r}))
4482 fnodes.append(e.callcommand('lookup', {'key': r}))
4457 remotebookmarks = fremotebookmarks.result()
4483 remotebookmarks = fremotebookmarks.result()
4458 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
4484 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
4459 pullopargs['remotebookmarks'] = remotebookmarks
4485 pullopargs['remotebookmarks'] = remotebookmarks
4460 for b in opts.get('bookmark', []):
4486 for b in opts.get('bookmark', []):
4461 b = repo._bookmarks.expandname(b)
4487 b = repo._bookmarks.expandname(b)
4462 if b not in remotebookmarks:
4488 if b not in remotebookmarks:
4463 raise error.Abort(_('remote bookmark %s not found!') % b)
4489 raise error.Abort(_('remote bookmark %s not found!') % b)
4464 nodes.append(remotebookmarks[b])
4490 nodes.append(remotebookmarks[b])
4465 for i, rev in enumerate(revs):
4491 for i, rev in enumerate(revs):
4466 node = fnodes[i].result()
4492 node = fnodes[i].result()
4467 nodes.append(node)
4493 nodes.append(node)
4468 if rev == checkout:
4494 if rev == checkout:
4469 checkout = node
4495 checkout = node
4470
4496
4471 wlock = util.nullcontextmanager()
4497 wlock = util.nullcontextmanager()
4472 if opts.get('update'):
4498 if opts.get('update'):
4473 wlock = repo.wlock()
4499 wlock = repo.wlock()
4474 with wlock:
4500 with wlock:
4475 pullopargs.update(opts.get('opargs', {}))
4501 pullopargs.update(opts.get('opargs', {}))
4476 modheads = exchange.pull(repo, other, heads=nodes,
4502 modheads = exchange.pull(repo, other, heads=nodes,
4477 force=opts.get('force'),
4503 force=opts.get('force'),
4478 bookmarks=opts.get('bookmark', ()),
4504 bookmarks=opts.get('bookmark', ()),
4479 opargs=pullopargs).cgresult
4505 opargs=pullopargs).cgresult
4480
4506
4481 # brev is a name, which might be a bookmark to be activated at
4507 # brev is a name, which might be a bookmark to be activated at
4482 # the end of the update. In other words, it is an explicit
4508 # the end of the update. In other words, it is an explicit
4483 # destination of the update
4509 # destination of the update
4484 brev = None
4510 brev = None
4485
4511
4486 if checkout:
4512 if checkout:
4487 checkout = repo.unfiltered().changelog.rev(checkout)
4513 checkout = repo.unfiltered().changelog.rev(checkout)
4488
4514
4489 # order below depends on implementation of
4515 # order below depends on implementation of
4490 # hg.addbranchrevs(). opts['bookmark'] is ignored,
4516 # hg.addbranchrevs(). opts['bookmark'] is ignored,
4491 # because 'checkout' is determined without it.
4517 # because 'checkout' is determined without it.
4492 if opts.get('rev'):
4518 if opts.get('rev'):
4493 brev = opts['rev'][0]
4519 brev = opts['rev'][0]
4494 elif opts.get('branch'):
4520 elif opts.get('branch'):
4495 brev = opts['branch'][0]
4521 brev = opts['branch'][0]
4496 else:
4522 else:
4497 brev = branches[0]
4523 brev = branches[0]
4498 repo._subtoppath = source
4524 repo._subtoppath = source
4499 try:
4525 try:
4500 ret = postincoming(ui, repo, modheads, opts.get('update'),
4526 ret = postincoming(ui, repo, modheads, opts.get('update'),
4501 checkout, brev)
4527 checkout, brev)
4502 except error.FilteredRepoLookupError as exc:
4528 except error.FilteredRepoLookupError as exc:
4503 msg = _('cannot update to target: %s') % exc.args[0]
4529 msg = _('cannot update to target: %s') % exc.args[0]
4504 exc.args = (msg,) + exc.args[1:]
4530 exc.args = (msg,) + exc.args[1:]
4505 raise
4531 raise
4506 finally:
4532 finally:
4507 del repo._subtoppath
4533 del repo._subtoppath
4508
4534
4509 finally:
4535 finally:
4510 other.close()
4536 other.close()
4511 return ret
4537 return ret
4512
4538
4513 @command('push',
4539 @command('push',
4514 [('f', 'force', None, _('force push')),
4540 [('f', 'force', None, _('force push')),
4515 ('r', 'rev', [],
4541 ('r', 'rev', [],
4516 _('a changeset intended to be included in the destination'),
4542 _('a changeset intended to be included in the destination'),
4517 _('REV')),
4543 _('REV')),
4518 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4544 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4519 ('b', 'branch', [],
4545 ('b', 'branch', [],
4520 _('a specific branch you would like to push'), _('BRANCH')),
4546 _('a specific branch you would like to push'), _('BRANCH')),
4521 ('', 'new-branch', False, _('allow pushing a new branch')),
4547 ('', 'new-branch', False, _('allow pushing a new branch')),
4522 ('', 'pushvars', [], _('variables that can be sent to server (ADVANCED)')),
4548 ('', 'pushvars', [], _('variables that can be sent to server (ADVANCED)')),
4523 ('', 'publish', False, _('push the changeset as public (EXPERIMENTAL)')),
4549 ('', 'publish', False, _('push the changeset as public (EXPERIMENTAL)')),
4524 ] + remoteopts,
4550 ] + remoteopts,
4525 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
4551 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
4526 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4552 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4527 helpbasic=True)
4553 helpbasic=True)
4528 def push(ui, repo, dest=None, **opts):
4554 def push(ui, repo, dest=None, **opts):
4529 """push changes to the specified destination
4555 """push changes to the specified destination
4530
4556
4531 Push changesets from the local repository to the specified
4557 Push changesets from the local repository to the specified
4532 destination.
4558 destination.
4533
4559
4534 This operation is symmetrical to pull: it is identical to a pull
4560 This operation is symmetrical to pull: it is identical to a pull
4535 in the destination repository from the current one.
4561 in the destination repository from the current one.
4536
4562
4537 By default, push will not allow creation of new heads at the
4563 By default, push will not allow creation of new heads at the
4538 destination, since multiple heads would make it unclear which head
4564 destination, since multiple heads would make it unclear which head
4539 to use. In this situation, it is recommended to pull and merge
4565 to use. In this situation, it is recommended to pull and merge
4540 before pushing.
4566 before pushing.
4541
4567
4542 Use --new-branch if you want to allow push to create a new named
4568 Use --new-branch if you want to allow push to create a new named
4543 branch that is not present at the destination. This allows you to
4569 branch that is not present at the destination. This allows you to
4544 only create a new branch without forcing other changes.
4570 only create a new branch without forcing other changes.
4545
4571
4546 .. note::
4572 .. note::
4547
4573
4548 Extra care should be taken with the -f/--force option,
4574 Extra care should be taken with the -f/--force option,
4549 which will push all new heads on all branches, an action which will
4575 which will push all new heads on all branches, an action which will
4550 almost always cause confusion for collaborators.
4576 almost always cause confusion for collaborators.
4551
4577
4552 If -r/--rev is used, the specified revision and all its ancestors
4578 If -r/--rev is used, the specified revision and all its ancestors
4553 will be pushed to the remote repository.
4579 will be pushed to the remote repository.
4554
4580
4555 If -B/--bookmark is used, the specified bookmarked revision, its
4581 If -B/--bookmark is used, the specified bookmarked revision, its
4556 ancestors, and the bookmark will be pushed to the remote
4582 ancestors, and the bookmark will be pushed to the remote
4557 repository. Specifying ``.`` is equivalent to specifying the active
4583 repository. Specifying ``.`` is equivalent to specifying the active
4558 bookmark's name.
4584 bookmark's name.
4559
4585
4560 Please see :hg:`help urls` for important details about ``ssh://``
4586 Please see :hg:`help urls` for important details about ``ssh://``
4561 URLs. If DESTINATION is omitted, a default path will be used.
4587 URLs. If DESTINATION is omitted, a default path will be used.
4562
4588
4563 .. container:: verbose
4589 .. container:: verbose
4564
4590
4565 The --pushvars option sends strings to the server that become
4591 The --pushvars option sends strings to the server that become
4566 environment variables prepended with ``HG_USERVAR_``. For example,
4592 environment variables prepended with ``HG_USERVAR_``. For example,
4567 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
4593 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
4568 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
4594 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
4569
4595
4570 pushvars can provide for user-overridable hooks as well as set debug
4596 pushvars can provide for user-overridable hooks as well as set debug
4571 levels. One example is having a hook that blocks commits containing
4597 levels. One example is having a hook that blocks commits containing
4572 conflict markers, but enables the user to override the hook if the file
4598 conflict markers, but enables the user to override the hook if the file
4573 is using conflict markers for testing purposes or the file format has
4599 is using conflict markers for testing purposes or the file format has
4574 strings that look like conflict markers.
4600 strings that look like conflict markers.
4575
4601
4576 By default, servers will ignore `--pushvars`. To enable it add the
4602 By default, servers will ignore `--pushvars`. To enable it add the
4577 following to your configuration file::
4603 following to your configuration file::
4578
4604
4579 [push]
4605 [push]
4580 pushvars.server = true
4606 pushvars.server = true
4581
4607
4582 Returns 0 if push was successful, 1 if nothing to push.
4608 Returns 0 if push was successful, 1 if nothing to push.
4583 """
4609 """
4584
4610
4585 opts = pycompat.byteskwargs(opts)
4611 opts = pycompat.byteskwargs(opts)
4586 if opts.get('bookmark'):
4612 if opts.get('bookmark'):
4587 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4613 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4588 for b in opts['bookmark']:
4614 for b in opts['bookmark']:
4589 # translate -B options to -r so changesets get pushed
4615 # translate -B options to -r so changesets get pushed
4590 b = repo._bookmarks.expandname(b)
4616 b = repo._bookmarks.expandname(b)
4591 if b in repo._bookmarks:
4617 if b in repo._bookmarks:
4592 opts.setdefault('rev', []).append(b)
4618 opts.setdefault('rev', []).append(b)
4593 else:
4619 else:
4594 # if we try to push a deleted bookmark, translate it to null
4620 # if we try to push a deleted bookmark, translate it to null
4595 # this lets simultaneous -r, -b options continue working
4621 # this lets simultaneous -r, -b options continue working
4596 opts.setdefault('rev', []).append("null")
4622 opts.setdefault('rev', []).append("null")
4597
4623
4598 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4624 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4599 if not path:
4625 if not path:
4600 raise error.Abort(_('default repository not configured!'),
4626 raise error.Abort(_('default repository not configured!'),
4601 hint=_("see 'hg help config.paths'"))
4627 hint=_("see 'hg help config.paths'"))
4602 dest = path.pushloc or path.loc
4628 dest = path.pushloc or path.loc
4603 branches = (path.branch, opts.get('branch') or [])
4629 branches = (path.branch, opts.get('branch') or [])
4604 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4630 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4605 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4631 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4606 other = hg.peer(repo, opts, dest)
4632 other = hg.peer(repo, opts, dest)
4607
4633
4608 if revs:
4634 if revs:
4609 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
4635 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
4610 if not revs:
4636 if not revs:
4611 raise error.Abort(_("specified revisions evaluate to an empty set"),
4637 raise error.Abort(_("specified revisions evaluate to an empty set"),
4612 hint=_("use different revision arguments"))
4638 hint=_("use different revision arguments"))
4613 elif path.pushrev:
4639 elif path.pushrev:
4614 # It doesn't make any sense to specify ancestor revisions. So limit
4640 # It doesn't make any sense to specify ancestor revisions. So limit
4615 # to DAG heads to make discovery simpler.
4641 # to DAG heads to make discovery simpler.
4616 expr = revsetlang.formatspec('heads(%r)', path.pushrev)
4642 expr = revsetlang.formatspec('heads(%r)', path.pushrev)
4617 revs = scmutil.revrange(repo, [expr])
4643 revs = scmutil.revrange(repo, [expr])
4618 revs = [repo[rev].node() for rev in revs]
4644 revs = [repo[rev].node() for rev in revs]
4619 if not revs:
4645 if not revs:
4620 raise error.Abort(_('default push revset for path evaluates to an '
4646 raise error.Abort(_('default push revset for path evaluates to an '
4621 'empty set'))
4647 'empty set'))
4622
4648
4623 repo._subtoppath = dest
4649 repo._subtoppath = dest
4624 try:
4650 try:
4625 # push subrepos depth-first for coherent ordering
4651 # push subrepos depth-first for coherent ordering
4626 c = repo['.']
4652 c = repo['.']
4627 subs = c.substate # only repos that are committed
4653 subs = c.substate # only repos that are committed
4628 for s in sorted(subs):
4654 for s in sorted(subs):
4629 result = c.sub(s).push(opts)
4655 result = c.sub(s).push(opts)
4630 if result == 0:
4656 if result == 0:
4631 return not result
4657 return not result
4632 finally:
4658 finally:
4633 del repo._subtoppath
4659 del repo._subtoppath
4634
4660
4635 opargs = dict(opts.get('opargs', {})) # copy opargs since we may mutate it
4661 opargs = dict(opts.get('opargs', {})) # copy opargs since we may mutate it
4636 opargs.setdefault('pushvars', []).extend(opts.get('pushvars', []))
4662 opargs.setdefault('pushvars', []).extend(opts.get('pushvars', []))
4637
4663
4638 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
4664 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
4639 newbranch=opts.get('new_branch'),
4665 newbranch=opts.get('new_branch'),
4640 bookmarks=opts.get('bookmark', ()),
4666 bookmarks=opts.get('bookmark', ()),
4641 publish=opts.get('publish'),
4667 publish=opts.get('publish'),
4642 opargs=opargs)
4668 opargs=opargs)
4643
4669
4644 result = not pushop.cgresult
4670 result = not pushop.cgresult
4645
4671
4646 if pushop.bkresult is not None:
4672 if pushop.bkresult is not None:
4647 if pushop.bkresult == 2:
4673 if pushop.bkresult == 2:
4648 result = 2
4674 result = 2
4649 elif not result and pushop.bkresult:
4675 elif not result and pushop.bkresult:
4650 result = 2
4676 result = 2
4651
4677
4652 return result
4678 return result
4653
4679
4654 @command('recover',
4680 @command('recover',
4655 [('','verify', True, "run `hg verify` after succesful recover"),
4681 [('','verify', True, "run `hg verify` after succesful recover"),
4656 ],
4682 ],
4657 helpcategory=command.CATEGORY_MAINTENANCE)
4683 helpcategory=command.CATEGORY_MAINTENANCE)
4658 def recover(ui, repo, **opts):
4684 def recover(ui, repo, **opts):
4659 """roll back an interrupted transaction
4685 """roll back an interrupted transaction
4660
4686
4661 Recover from an interrupted commit or pull.
4687 Recover from an interrupted commit or pull.
4662
4688
4663 This command tries to fix the repository status after an
4689 This command tries to fix the repository status after an
4664 interrupted operation. It should only be necessary when Mercurial
4690 interrupted operation. It should only be necessary when Mercurial
4665 suggests it.
4691 suggests it.
4666
4692
4667 Returns 0 if successful, 1 if nothing to recover or verify fails.
4693 Returns 0 if successful, 1 if nothing to recover or verify fails.
4668 """
4694 """
4669 ret = repo.recover()
4695 ret = repo.recover()
4670 if ret:
4696 if ret:
4671 if opts[r'verify']:
4697 if opts[r'verify']:
4672 return hg.verify(repo)
4698 return hg.verify(repo)
4673 else:
4699 else:
4674 msg = _("(verify step skipped, run `hg verify` to check your "
4700 msg = _("(verify step skipped, run `hg verify` to check your "
4675 "repository content)\n")
4701 "repository content)\n")
4676 ui.warn(msg)
4702 ui.warn(msg)
4677 return 0
4703 return 0
4678 return 1
4704 return 1
4679
4705
4680 @command('remove|rm',
4706 @command('remove|rm',
4681 [('A', 'after', None, _('record delete for missing files')),
4707 [('A', 'after', None, _('record delete for missing files')),
4682 ('f', 'force', None,
4708 ('f', 'force', None,
4683 _('forget added files, delete modified files')),
4709 _('forget added files, delete modified files')),
4684 ] + subrepoopts + walkopts + dryrunopts,
4710 ] + subrepoopts + walkopts + dryrunopts,
4685 _('[OPTION]... FILE...'),
4711 _('[OPTION]... FILE...'),
4686 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4712 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4687 helpbasic=True, inferrepo=True)
4713 helpbasic=True, inferrepo=True)
4688 def remove(ui, repo, *pats, **opts):
4714 def remove(ui, repo, *pats, **opts):
4689 """remove the specified files on the next commit
4715 """remove the specified files on the next commit
4690
4716
4691 Schedule the indicated files for removal from the current branch.
4717 Schedule the indicated files for removal from the current branch.
4692
4718
4693 This command schedules the files to be removed at the next commit.
4719 This command schedules the files to be removed at the next commit.
4694 To undo a remove before that, see :hg:`revert`. To undo added
4720 To undo a remove before that, see :hg:`revert`. To undo added
4695 files, see :hg:`forget`.
4721 files, see :hg:`forget`.
4696
4722
4697 .. container:: verbose
4723 .. container:: verbose
4698
4724
4699 -A/--after can be used to remove only files that have already
4725 -A/--after can be used to remove only files that have already
4700 been deleted, -f/--force can be used to force deletion, and -Af
4726 been deleted, -f/--force can be used to force deletion, and -Af
4701 can be used to remove files from the next revision without
4727 can be used to remove files from the next revision without
4702 deleting them from the working directory.
4728 deleting them from the working directory.
4703
4729
4704 The following table details the behavior of remove for different
4730 The following table details the behavior of remove for different
4705 file states (columns) and option combinations (rows). The file
4731 file states (columns) and option combinations (rows). The file
4706 states are Added [A], Clean [C], Modified [M] and Missing [!]
4732 states are Added [A], Clean [C], Modified [M] and Missing [!]
4707 (as reported by :hg:`status`). The actions are Warn, Remove
4733 (as reported by :hg:`status`). The actions are Warn, Remove
4708 (from branch) and Delete (from disk):
4734 (from branch) and Delete (from disk):
4709
4735
4710 ========= == == == ==
4736 ========= == == == ==
4711 opt/state A C M !
4737 opt/state A C M !
4712 ========= == == == ==
4738 ========= == == == ==
4713 none W RD W R
4739 none W RD W R
4714 -f R RD RD R
4740 -f R RD RD R
4715 -A W W W R
4741 -A W W W R
4716 -Af R R R R
4742 -Af R R R R
4717 ========= == == == ==
4743 ========= == == == ==
4718
4744
4719 .. note::
4745 .. note::
4720
4746
4721 :hg:`remove` never deletes files in Added [A] state from the
4747 :hg:`remove` never deletes files in Added [A] state from the
4722 working directory, not even if ``--force`` is specified.
4748 working directory, not even if ``--force`` is specified.
4723
4749
4724 Returns 0 on success, 1 if any warnings encountered.
4750 Returns 0 on success, 1 if any warnings encountered.
4725 """
4751 """
4726
4752
4727 opts = pycompat.byteskwargs(opts)
4753 opts = pycompat.byteskwargs(opts)
4728 after, force = opts.get('after'), opts.get('force')
4754 after, force = opts.get('after'), opts.get('force')
4729 dryrun = opts.get('dry_run')
4755 dryrun = opts.get('dry_run')
4730 if not pats and not after:
4756 if not pats and not after:
4731 raise error.Abort(_('no files specified'))
4757 raise error.Abort(_('no files specified'))
4732
4758
4733 m = scmutil.match(repo[None], pats, opts)
4759 m = scmutil.match(repo[None], pats, opts)
4734 subrepos = opts.get('subrepos')
4760 subrepos = opts.get('subrepos')
4735 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
4761 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
4736 return cmdutil.remove(ui, repo, m, "", uipathfn, after, force, subrepos,
4762 return cmdutil.remove(ui, repo, m, "", uipathfn, after, force, subrepos,
4737 dryrun=dryrun)
4763 dryrun=dryrun)
4738
4764
4739 @command('rename|move|mv',
4765 @command('rename|move|mv',
4740 [('A', 'after', None, _('record a rename that has already occurred')),
4766 [('A', 'after', None, _('record a rename that has already occurred')),
4741 ('f', 'force', None, _('forcibly move over an existing managed file')),
4767 ('f', 'force', None, _('forcibly move over an existing managed file')),
4742 ] + walkopts + dryrunopts,
4768 ] + walkopts + dryrunopts,
4743 _('[OPTION]... SOURCE... DEST'),
4769 _('[OPTION]... SOURCE... DEST'),
4744 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
4770 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
4745 def rename(ui, repo, *pats, **opts):
4771 def rename(ui, repo, *pats, **opts):
4746 """rename files; equivalent of copy + remove
4772 """rename files; equivalent of copy + remove
4747
4773
4748 Mark dest as copies of sources; mark sources for deletion. If dest
4774 Mark dest as copies of sources; mark sources for deletion. If dest
4749 is a directory, copies are put in that directory. If dest is a
4775 is a directory, copies are put in that directory. If dest is a
4750 file, there can only be one source.
4776 file, there can only be one source.
4751
4777
4752 By default, this command copies the contents of files as they
4778 By default, this command copies the contents of files as they
4753 exist in the working directory. If invoked with -A/--after, the
4779 exist in the working directory. If invoked with -A/--after, the
4754 operation is recorded, but no copying is performed.
4780 operation is recorded, but no copying is performed.
4755
4781
4756 This command takes effect at the next commit. To undo a rename
4782 This command takes effect at the next commit. To undo a rename
4757 before that, see :hg:`revert`.
4783 before that, see :hg:`revert`.
4758
4784
4759 Returns 0 on success, 1 if errors are encountered.
4785 Returns 0 on success, 1 if errors are encountered.
4760 """
4786 """
4761 opts = pycompat.byteskwargs(opts)
4787 opts = pycompat.byteskwargs(opts)
4762 with repo.wlock(False):
4788 with repo.wlock(False):
4763 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4789 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4764
4790
4765 @command('resolve',
4791 @command('resolve',
4766 [('a', 'all', None, _('select all unresolved files')),
4792 [('a', 'all', None, _('select all unresolved files')),
4767 ('l', 'list', None, _('list state of files needing merge')),
4793 ('l', 'list', None, _('list state of files needing merge')),
4768 ('m', 'mark', None, _('mark files as resolved')),
4794 ('m', 'mark', None, _('mark files as resolved')),
4769 ('u', 'unmark', None, _('mark files as unresolved')),
4795 ('u', 'unmark', None, _('mark files as unresolved')),
4770 ('n', 'no-status', None, _('hide status prefix')),
4796 ('n', 'no-status', None, _('hide status prefix')),
4771 ('', 're-merge', None, _('re-merge files'))]
4797 ('', 're-merge', None, _('re-merge files'))]
4772 + mergetoolopts + walkopts + formatteropts,
4798 + mergetoolopts + walkopts + formatteropts,
4773 _('[OPTION]... [FILE]...'),
4799 _('[OPTION]... [FILE]...'),
4774 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4800 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4775 inferrepo=True)
4801 inferrepo=True)
4776 def resolve(ui, repo, *pats, **opts):
4802 def resolve(ui, repo, *pats, **opts):
4777 """redo merges or set/view the merge status of files
4803 """redo merges or set/view the merge status of files
4778
4804
4779 Merges with unresolved conflicts are often the result of
4805 Merges with unresolved conflicts are often the result of
4780 non-interactive merging using the ``internal:merge`` configuration
4806 non-interactive merging using the ``internal:merge`` configuration
4781 setting, or a command-line merge tool like ``diff3``. The resolve
4807 setting, or a command-line merge tool like ``diff3``. The resolve
4782 command is used to manage the files involved in a merge, after
4808 command is used to manage the files involved in a merge, after
4783 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4809 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4784 working directory must have two parents). See :hg:`help
4810 working directory must have two parents). See :hg:`help
4785 merge-tools` for information on configuring merge tools.
4811 merge-tools` for information on configuring merge tools.
4786
4812
4787 The resolve command can be used in the following ways:
4813 The resolve command can be used in the following ways:
4788
4814
4789 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
4815 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
4790 the specified files, discarding any previous merge attempts. Re-merging
4816 the specified files, discarding any previous merge attempts. Re-merging
4791 is not performed for files already marked as resolved. Use ``--all/-a``
4817 is not performed for files already marked as resolved. Use ``--all/-a``
4792 to select all unresolved files. ``--tool`` can be used to specify
4818 to select all unresolved files. ``--tool`` can be used to specify
4793 the merge tool used for the given files. It overrides the HGMERGE
4819 the merge tool used for the given files. It overrides the HGMERGE
4794 environment variable and your configuration files. Previous file
4820 environment variable and your configuration files. Previous file
4795 contents are saved with a ``.orig`` suffix.
4821 contents are saved with a ``.orig`` suffix.
4796
4822
4797 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4823 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4798 (e.g. after having manually fixed-up the files). The default is
4824 (e.g. after having manually fixed-up the files). The default is
4799 to mark all unresolved files.
4825 to mark all unresolved files.
4800
4826
4801 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4827 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4802 default is to mark all resolved files.
4828 default is to mark all resolved files.
4803
4829
4804 - :hg:`resolve -l`: list files which had or still have conflicts.
4830 - :hg:`resolve -l`: list files which had or still have conflicts.
4805 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4831 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4806 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
4832 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
4807 the list. See :hg:`help filesets` for details.
4833 the list. See :hg:`help filesets` for details.
4808
4834
4809 .. note::
4835 .. note::
4810
4836
4811 Mercurial will not let you commit files with unresolved merge
4837 Mercurial will not let you commit files with unresolved merge
4812 conflicts. You must use :hg:`resolve -m ...` before you can
4838 conflicts. You must use :hg:`resolve -m ...` before you can
4813 commit after a conflicting merge.
4839 commit after a conflicting merge.
4814
4840
4815 .. container:: verbose
4841 .. container:: verbose
4816
4842
4817 Template:
4843 Template:
4818
4844
4819 The following keywords are supported in addition to the common template
4845 The following keywords are supported in addition to the common template
4820 keywords and functions. See also :hg:`help templates`.
4846 keywords and functions. See also :hg:`help templates`.
4821
4847
4822 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
4848 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
4823 :path: String. Repository-absolute path of the file.
4849 :path: String. Repository-absolute path of the file.
4824
4850
4825 Returns 0 on success, 1 if any files fail a resolve attempt.
4851 Returns 0 on success, 1 if any files fail a resolve attempt.
4826 """
4852 """
4827
4853
4828 opts = pycompat.byteskwargs(opts)
4854 opts = pycompat.byteskwargs(opts)
4829 confirm = ui.configbool('commands', 'resolve.confirm')
4855 confirm = ui.configbool('commands', 'resolve.confirm')
4830 flaglist = 'all mark unmark list no_status re_merge'.split()
4856 flaglist = 'all mark unmark list no_status re_merge'.split()
4831 all, mark, unmark, show, nostatus, remerge = [
4857 all, mark, unmark, show, nostatus, remerge = [
4832 opts.get(o) for o in flaglist]
4858 opts.get(o) for o in flaglist]
4833
4859
4834 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
4860 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
4835 if actioncount > 1:
4861 if actioncount > 1:
4836 raise error.Abort(_("too many actions specified"))
4862 raise error.Abort(_("too many actions specified"))
4837 elif (actioncount == 0
4863 elif (actioncount == 0
4838 and ui.configbool('commands', 'resolve.explicit-re-merge')):
4864 and ui.configbool('commands', 'resolve.explicit-re-merge')):
4839 hint = _('use --mark, --unmark, --list or --re-merge')
4865 hint = _('use --mark, --unmark, --list or --re-merge')
4840 raise error.Abort(_('no action specified'), hint=hint)
4866 raise error.Abort(_('no action specified'), hint=hint)
4841 if pats and all:
4867 if pats and all:
4842 raise error.Abort(_("can't specify --all and patterns"))
4868 raise error.Abort(_("can't specify --all and patterns"))
4843 if not (all or pats or show or mark or unmark):
4869 if not (all or pats or show or mark or unmark):
4844 raise error.Abort(_('no files or directories specified'),
4870 raise error.Abort(_('no files or directories specified'),
4845 hint=('use --all to re-merge all unresolved files'))
4871 hint=('use --all to re-merge all unresolved files'))
4846
4872
4847 if confirm:
4873 if confirm:
4848 if all:
4874 if all:
4849 if ui.promptchoice(_(b're-merge all unresolved files (yn)?'
4875 if ui.promptchoice(_(b're-merge all unresolved files (yn)?'
4850 b'$$ &Yes $$ &No')):
4876 b'$$ &Yes $$ &No')):
4851 raise error.Abort(_('user quit'))
4877 raise error.Abort(_('user quit'))
4852 if mark and not pats:
4878 if mark and not pats:
4853 if ui.promptchoice(_(b'mark all unresolved files as resolved (yn)?'
4879 if ui.promptchoice(_(b'mark all unresolved files as resolved (yn)?'
4854 b'$$ &Yes $$ &No')):
4880 b'$$ &Yes $$ &No')):
4855 raise error.Abort(_('user quit'))
4881 raise error.Abort(_('user quit'))
4856 if unmark and not pats:
4882 if unmark and not pats:
4857 if ui.promptchoice(_(b'mark all resolved files as unresolved (yn)?'
4883 if ui.promptchoice(_(b'mark all resolved files as unresolved (yn)?'
4858 b'$$ &Yes $$ &No')):
4884 b'$$ &Yes $$ &No')):
4859 raise error.Abort(_('user quit'))
4885 raise error.Abort(_('user quit'))
4860
4886
4861 uipathfn = scmutil.getuipathfn(repo)
4887 uipathfn = scmutil.getuipathfn(repo)
4862
4888
4863 if show:
4889 if show:
4864 ui.pager('resolve')
4890 ui.pager('resolve')
4865 fm = ui.formatter('resolve', opts)
4891 fm = ui.formatter('resolve', opts)
4866 ms = mergemod.mergestate.read(repo)
4892 ms = mergemod.mergestate.read(repo)
4867 wctx = repo[None]
4893 wctx = repo[None]
4868 m = scmutil.match(wctx, pats, opts)
4894 m = scmutil.match(wctx, pats, opts)
4869
4895
4870 # Labels and keys based on merge state. Unresolved path conflicts show
4896 # Labels and keys based on merge state. Unresolved path conflicts show
4871 # as 'P'. Resolved path conflicts show as 'R', the same as normal
4897 # as 'P'. Resolved path conflicts show as 'R', the same as normal
4872 # resolved conflicts.
4898 # resolved conflicts.
4873 mergestateinfo = {
4899 mergestateinfo = {
4874 mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'),
4900 mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'),
4875 mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'),
4901 mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'),
4876 mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'),
4902 mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'),
4877 mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'),
4903 mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'),
4878 mergemod.MERGE_RECORD_DRIVER_RESOLVED: ('resolve.driverresolved',
4904 mergemod.MERGE_RECORD_DRIVER_RESOLVED: ('resolve.driverresolved',
4879 'D'),
4905 'D'),
4880 }
4906 }
4881
4907
4882 for f in ms:
4908 for f in ms:
4883 if not m(f):
4909 if not m(f):
4884 continue
4910 continue
4885
4911
4886 label, key = mergestateinfo[ms[f]]
4912 label, key = mergestateinfo[ms[f]]
4887 fm.startitem()
4913 fm.startitem()
4888 fm.context(ctx=wctx)
4914 fm.context(ctx=wctx)
4889 fm.condwrite(not nostatus, 'mergestatus', '%s ', key, label=label)
4915 fm.condwrite(not nostatus, 'mergestatus', '%s ', key, label=label)
4890 fm.data(path=f)
4916 fm.data(path=f)
4891 fm.plain('%s\n' % uipathfn(f), label=label)
4917 fm.plain('%s\n' % uipathfn(f), label=label)
4892 fm.end()
4918 fm.end()
4893 return 0
4919 return 0
4894
4920
4895 with repo.wlock():
4921 with repo.wlock():
4896 ms = mergemod.mergestate.read(repo)
4922 ms = mergemod.mergestate.read(repo)
4897
4923
4898 if not (ms.active() or repo.dirstate.p2() != nullid):
4924 if not (ms.active() or repo.dirstate.p2() != nullid):
4899 raise error.Abort(
4925 raise error.Abort(
4900 _('resolve command not applicable when not merging'))
4926 _('resolve command not applicable when not merging'))
4901
4927
4902 wctx = repo[None]
4928 wctx = repo[None]
4903
4929
4904 if (ms.mergedriver
4930 if (ms.mergedriver
4905 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED):
4931 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED):
4906 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4932 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4907 ms.commit()
4933 ms.commit()
4908 # allow mark and unmark to go through
4934 # allow mark and unmark to go through
4909 if not mark and not unmark and not proceed:
4935 if not mark and not unmark and not proceed:
4910 return 1
4936 return 1
4911
4937
4912 m = scmutil.match(wctx, pats, opts)
4938 m = scmutil.match(wctx, pats, opts)
4913 ret = 0
4939 ret = 0
4914 didwork = False
4940 didwork = False
4915 runconclude = False
4941 runconclude = False
4916
4942
4917 tocomplete = []
4943 tocomplete = []
4918 hasconflictmarkers = []
4944 hasconflictmarkers = []
4919 if mark:
4945 if mark:
4920 markcheck = ui.config('commands', 'resolve.mark-check')
4946 markcheck = ui.config('commands', 'resolve.mark-check')
4921 if markcheck not in ['warn', 'abort']:
4947 if markcheck not in ['warn', 'abort']:
4922 # Treat all invalid / unrecognized values as 'none'.
4948 # Treat all invalid / unrecognized values as 'none'.
4923 markcheck = False
4949 markcheck = False
4924 for f in ms:
4950 for f in ms:
4925 if not m(f):
4951 if not m(f):
4926 continue
4952 continue
4927
4953
4928 didwork = True
4954 didwork = True
4929
4955
4930 # don't let driver-resolved files be marked, and run the conclude
4956 # don't let driver-resolved files be marked, and run the conclude
4931 # step if asked to resolve
4957 # step if asked to resolve
4932 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
4958 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
4933 exact = m.exact(f)
4959 exact = m.exact(f)
4934 if mark:
4960 if mark:
4935 if exact:
4961 if exact:
4936 ui.warn(_('not marking %s as it is driver-resolved\n')
4962 ui.warn(_('not marking %s as it is driver-resolved\n')
4937 % uipathfn(f))
4963 % uipathfn(f))
4938 elif unmark:
4964 elif unmark:
4939 if exact:
4965 if exact:
4940 ui.warn(_('not unmarking %s as it is driver-resolved\n')
4966 ui.warn(_('not unmarking %s as it is driver-resolved\n')
4941 % uipathfn(f))
4967 % uipathfn(f))
4942 else:
4968 else:
4943 runconclude = True
4969 runconclude = True
4944 continue
4970 continue
4945
4971
4946 # path conflicts must be resolved manually
4972 # path conflicts must be resolved manually
4947 if ms[f] in (mergemod.MERGE_RECORD_UNRESOLVED_PATH,
4973 if ms[f] in (mergemod.MERGE_RECORD_UNRESOLVED_PATH,
4948 mergemod.MERGE_RECORD_RESOLVED_PATH):
4974 mergemod.MERGE_RECORD_RESOLVED_PATH):
4949 if mark:
4975 if mark:
4950 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
4976 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
4951 elif unmark:
4977 elif unmark:
4952 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
4978 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
4953 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
4979 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
4954 ui.warn(_('%s: path conflict must be resolved manually\n')
4980 ui.warn(_('%s: path conflict must be resolved manually\n')
4955 % uipathfn(f))
4981 % uipathfn(f))
4956 continue
4982 continue
4957
4983
4958 if mark:
4984 if mark:
4959 if markcheck:
4985 if markcheck:
4960 fdata = repo.wvfs.tryread(f)
4986 fdata = repo.wvfs.tryread(f)
4961 if (filemerge.hasconflictmarkers(fdata) and
4987 if (filemerge.hasconflictmarkers(fdata) and
4962 ms[f] != mergemod.MERGE_RECORD_RESOLVED):
4988 ms[f] != mergemod.MERGE_RECORD_RESOLVED):
4963 hasconflictmarkers.append(f)
4989 hasconflictmarkers.append(f)
4964 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
4990 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
4965 elif unmark:
4991 elif unmark:
4966 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
4992 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
4967 else:
4993 else:
4968 # backup pre-resolve (merge uses .orig for its own purposes)
4994 # backup pre-resolve (merge uses .orig for its own purposes)
4969 a = repo.wjoin(f)
4995 a = repo.wjoin(f)
4970 try:
4996 try:
4971 util.copyfile(a, a + ".resolve")
4997 util.copyfile(a, a + ".resolve")
4972 except (IOError, OSError) as inst:
4998 except (IOError, OSError) as inst:
4973 if inst.errno != errno.ENOENT:
4999 if inst.errno != errno.ENOENT:
4974 raise
5000 raise
4975
5001
4976 try:
5002 try:
4977 # preresolve file
5003 # preresolve file
4978 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
5004 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4979 with ui.configoverride(overrides, 'resolve'):
5005 with ui.configoverride(overrides, 'resolve'):
4980 complete, r = ms.preresolve(f, wctx)
5006 complete, r = ms.preresolve(f, wctx)
4981 if not complete:
5007 if not complete:
4982 tocomplete.append(f)
5008 tocomplete.append(f)
4983 elif r:
5009 elif r:
4984 ret = 1
5010 ret = 1
4985 finally:
5011 finally:
4986 ms.commit()
5012 ms.commit()
4987
5013
4988 # replace filemerge's .orig file with our resolve file, but only
5014 # replace filemerge's .orig file with our resolve file, but only
4989 # for merges that are complete
5015 # for merges that are complete
4990 if complete:
5016 if complete:
4991 try:
5017 try:
4992 util.rename(a + ".resolve",
5018 util.rename(a + ".resolve",
4993 scmutil.backuppath(ui, repo, f))
5019 scmutil.backuppath(ui, repo, f))
4994 except OSError as inst:
5020 except OSError as inst:
4995 if inst.errno != errno.ENOENT:
5021 if inst.errno != errno.ENOENT:
4996 raise
5022 raise
4997
5023
4998 if hasconflictmarkers:
5024 if hasconflictmarkers:
4999 ui.warn(_('warning: the following files still have conflict '
5025 ui.warn(_('warning: the following files still have conflict '
5000 'markers:\n') + ''.join(' ' + uipathfn(f) + '\n'
5026 'markers:\n') + ''.join(' ' + uipathfn(f) + '\n'
5001 for f in hasconflictmarkers))
5027 for f in hasconflictmarkers))
5002 if markcheck == 'abort' and not all and not pats:
5028 if markcheck == 'abort' and not all and not pats:
5003 raise error.Abort(_('conflict markers detected'),
5029 raise error.Abort(_('conflict markers detected'),
5004 hint=_('use --all to mark anyway'))
5030 hint=_('use --all to mark anyway'))
5005
5031
5006 for f in tocomplete:
5032 for f in tocomplete:
5007 try:
5033 try:
5008 # resolve file
5034 # resolve file
5009 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
5035 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
5010 with ui.configoverride(overrides, 'resolve'):
5036 with ui.configoverride(overrides, 'resolve'):
5011 r = ms.resolve(f, wctx)
5037 r = ms.resolve(f, wctx)
5012 if r:
5038 if r:
5013 ret = 1
5039 ret = 1
5014 finally:
5040 finally:
5015 ms.commit()
5041 ms.commit()
5016
5042
5017 # replace filemerge's .orig file with our resolve file
5043 # replace filemerge's .orig file with our resolve file
5018 a = repo.wjoin(f)
5044 a = repo.wjoin(f)
5019 try:
5045 try:
5020 util.rename(a + ".resolve", scmutil.backuppath(ui, repo, f))
5046 util.rename(a + ".resolve", scmutil.backuppath(ui, repo, f))
5021 except OSError as inst:
5047 except OSError as inst:
5022 if inst.errno != errno.ENOENT:
5048 if inst.errno != errno.ENOENT:
5023 raise
5049 raise
5024
5050
5025 ms.commit()
5051 ms.commit()
5026 ms.recordactions()
5052 ms.recordactions()
5027
5053
5028 if not didwork and pats:
5054 if not didwork and pats:
5029 hint = None
5055 hint = None
5030 if not any([p for p in pats if p.find(':') >= 0]):
5056 if not any([p for p in pats if p.find(':') >= 0]):
5031 pats = ['path:%s' % p for p in pats]
5057 pats = ['path:%s' % p for p in pats]
5032 m = scmutil.match(wctx, pats, opts)
5058 m = scmutil.match(wctx, pats, opts)
5033 for f in ms:
5059 for f in ms:
5034 if not m(f):
5060 if not m(f):
5035 continue
5061 continue
5036 def flag(o):
5062 def flag(o):
5037 if o == 're_merge':
5063 if o == 're_merge':
5038 return '--re-merge '
5064 return '--re-merge '
5039 return '-%s ' % o[0:1]
5065 return '-%s ' % o[0:1]
5040 flags = ''.join([flag(o) for o in flaglist if opts.get(o)])
5066 flags = ''.join([flag(o) for o in flaglist if opts.get(o)])
5041 hint = _("(try: hg resolve %s%s)\n") % (
5067 hint = _("(try: hg resolve %s%s)\n") % (
5042 flags,
5068 flags,
5043 ' '.join(pats))
5069 ' '.join(pats))
5044 break
5070 break
5045 ui.warn(_("arguments do not match paths that need resolving\n"))
5071 ui.warn(_("arguments do not match paths that need resolving\n"))
5046 if hint:
5072 if hint:
5047 ui.warn(hint)
5073 ui.warn(hint)
5048 elif ms.mergedriver and ms.mdstate() != 's':
5074 elif ms.mergedriver and ms.mdstate() != 's':
5049 # run conclude step when either a driver-resolved file is requested
5075 # run conclude step when either a driver-resolved file is requested
5050 # or there are no driver-resolved files
5076 # or there are no driver-resolved files
5051 # we can't use 'ret' to determine whether any files are unresolved
5077 # we can't use 'ret' to determine whether any files are unresolved
5052 # because we might not have tried to resolve some
5078 # because we might not have tried to resolve some
5053 if ((runconclude or not list(ms.driverresolved()))
5079 if ((runconclude or not list(ms.driverresolved()))
5054 and not list(ms.unresolved())):
5080 and not list(ms.unresolved())):
5055 proceed = mergemod.driverconclude(repo, ms, wctx)
5081 proceed = mergemod.driverconclude(repo, ms, wctx)
5056 ms.commit()
5082 ms.commit()
5057 if not proceed:
5083 if not proceed:
5058 return 1
5084 return 1
5059
5085
5060 # Nudge users into finishing an unfinished operation
5086 # Nudge users into finishing an unfinished operation
5061 unresolvedf = list(ms.unresolved())
5087 unresolvedf = list(ms.unresolved())
5062 driverresolvedf = list(ms.driverresolved())
5088 driverresolvedf = list(ms.driverresolved())
5063 if not unresolvedf and not driverresolvedf:
5089 if not unresolvedf and not driverresolvedf:
5064 ui.status(_('(no more unresolved files)\n'))
5090 ui.status(_('(no more unresolved files)\n'))
5065 cmdutil.checkafterresolved(repo)
5091 cmdutil.checkafterresolved(repo)
5066 elif not unresolvedf:
5092 elif not unresolvedf:
5067 ui.status(_('(no more unresolved files -- '
5093 ui.status(_('(no more unresolved files -- '
5068 'run "hg resolve --all" to conclude)\n'))
5094 'run "hg resolve --all" to conclude)\n'))
5069
5095
5070 return ret
5096 return ret
5071
5097
5072 @command('revert',
5098 @command('revert',
5073 [('a', 'all', None, _('revert all changes when no arguments given')),
5099 [('a', 'all', None, _('revert all changes when no arguments given')),
5074 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5100 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5075 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5101 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5076 ('C', 'no-backup', None, _('do not save backup copies of files')),
5102 ('C', 'no-backup', None, _('do not save backup copies of files')),
5077 ('i', 'interactive', None, _('interactively select the changes')),
5103 ('i', 'interactive', None, _('interactively select the changes')),
5078 ] + walkopts + dryrunopts,
5104 ] + walkopts + dryrunopts,
5079 _('[OPTION]... [-r REV] [NAME]...'),
5105 _('[OPTION]... [-r REV] [NAME]...'),
5080 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5106 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5081 def revert(ui, repo, *pats, **opts):
5107 def revert(ui, repo, *pats, **opts):
5082 """restore files to their checkout state
5108 """restore files to their checkout state
5083
5109
5084 .. note::
5110 .. note::
5085
5111
5086 To check out earlier revisions, you should use :hg:`update REV`.
5112 To check out earlier revisions, you should use :hg:`update REV`.
5087 To cancel an uncommitted merge (and lose your changes),
5113 To cancel an uncommitted merge (and lose your changes),
5088 use :hg:`merge --abort`.
5114 use :hg:`merge --abort`.
5089
5115
5090 With no revision specified, revert the specified files or directories
5116 With no revision specified, revert the specified files or directories
5091 to the contents they had in the parent of the working directory.
5117 to the contents they had in the parent of the working directory.
5092 This restores the contents of files to an unmodified
5118 This restores the contents of files to an unmodified
5093 state and unschedules adds, removes, copies, and renames. If the
5119 state and unschedules adds, removes, copies, and renames. If the
5094 working directory has two parents, you must explicitly specify a
5120 working directory has two parents, you must explicitly specify a
5095 revision.
5121 revision.
5096
5122
5097 Using the -r/--rev or -d/--date options, revert the given files or
5123 Using the -r/--rev or -d/--date options, revert the given files or
5098 directories to their states as of a specific revision. Because
5124 directories to their states as of a specific revision. Because
5099 revert does not change the working directory parents, this will
5125 revert does not change the working directory parents, this will
5100 cause these files to appear modified. This can be helpful to "back
5126 cause these files to appear modified. This can be helpful to "back
5101 out" some or all of an earlier change. See :hg:`backout` for a
5127 out" some or all of an earlier change. See :hg:`backout` for a
5102 related method.
5128 related method.
5103
5129
5104 Modified files are saved with a .orig suffix before reverting.
5130 Modified files are saved with a .orig suffix before reverting.
5105 To disable these backups, use --no-backup. It is possible to store
5131 To disable these backups, use --no-backup. It is possible to store
5106 the backup files in a custom directory relative to the root of the
5132 the backup files in a custom directory relative to the root of the
5107 repository by setting the ``ui.origbackuppath`` configuration
5133 repository by setting the ``ui.origbackuppath`` configuration
5108 option.
5134 option.
5109
5135
5110 See :hg:`help dates` for a list of formats valid for -d/--date.
5136 See :hg:`help dates` for a list of formats valid for -d/--date.
5111
5137
5112 See :hg:`help backout` for a way to reverse the effect of an
5138 See :hg:`help backout` for a way to reverse the effect of an
5113 earlier changeset.
5139 earlier changeset.
5114
5140
5115 Returns 0 on success.
5141 Returns 0 on success.
5116 """
5142 """
5117
5143
5118 opts = pycompat.byteskwargs(opts)
5144 opts = pycompat.byteskwargs(opts)
5119 if opts.get("date"):
5145 if opts.get("date"):
5120 if opts.get("rev"):
5146 if opts.get("rev"):
5121 raise error.Abort(_("you can't specify a revision and a date"))
5147 raise error.Abort(_("you can't specify a revision and a date"))
5122 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5148 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5123
5149
5124 parent, p2 = repo.dirstate.parents()
5150 parent, p2 = repo.dirstate.parents()
5125 if not opts.get('rev') and p2 != nullid:
5151 if not opts.get('rev') and p2 != nullid:
5126 # revert after merge is a trap for new users (issue2915)
5152 # revert after merge is a trap for new users (issue2915)
5127 raise error.Abort(_('uncommitted merge with no revision specified'),
5153 raise error.Abort(_('uncommitted merge with no revision specified'),
5128 hint=_("use 'hg update' or see 'hg help revert'"))
5154 hint=_("use 'hg update' or see 'hg help revert'"))
5129
5155
5130 rev = opts.get('rev')
5156 rev = opts.get('rev')
5131 if rev:
5157 if rev:
5132 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
5158 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
5133 ctx = scmutil.revsingle(repo, rev)
5159 ctx = scmutil.revsingle(repo, rev)
5134
5160
5135 if (not (pats or opts.get('include') or opts.get('exclude') or
5161 if (not (pats or opts.get('include') or opts.get('exclude') or
5136 opts.get('all') or opts.get('interactive'))):
5162 opts.get('all') or opts.get('interactive'))):
5137 msg = _("no files or directories specified")
5163 msg = _("no files or directories specified")
5138 if p2 != nullid:
5164 if p2 != nullid:
5139 hint = _("uncommitted merge, use --all to discard all changes,"
5165 hint = _("uncommitted merge, use --all to discard all changes,"
5140 " or 'hg update -C .' to abort the merge")
5166 " or 'hg update -C .' to abort the merge")
5141 raise error.Abort(msg, hint=hint)
5167 raise error.Abort(msg, hint=hint)
5142 dirty = any(repo.status())
5168 dirty = any(repo.status())
5143 node = ctx.node()
5169 node = ctx.node()
5144 if node != parent:
5170 if node != parent:
5145 if dirty:
5171 if dirty:
5146 hint = _("uncommitted changes, use --all to discard all"
5172 hint = _("uncommitted changes, use --all to discard all"
5147 " changes, or 'hg update %d' to update") % ctx.rev()
5173 " changes, or 'hg update %d' to update") % ctx.rev()
5148 else:
5174 else:
5149 hint = _("use --all to revert all files,"
5175 hint = _("use --all to revert all files,"
5150 " or 'hg update %d' to update") % ctx.rev()
5176 " or 'hg update %d' to update") % ctx.rev()
5151 elif dirty:
5177 elif dirty:
5152 hint = _("uncommitted changes, use --all to discard all changes")
5178 hint = _("uncommitted changes, use --all to discard all changes")
5153 else:
5179 else:
5154 hint = _("use --all to revert all files")
5180 hint = _("use --all to revert all files")
5155 raise error.Abort(msg, hint=hint)
5181 raise error.Abort(msg, hint=hint)
5156
5182
5157 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats,
5183 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats,
5158 **pycompat.strkwargs(opts))
5184 **pycompat.strkwargs(opts))
5159
5185
5160 @command(
5186 @command(
5161 'rollback',
5187 'rollback',
5162 dryrunopts + [('f', 'force', False, _('ignore safety measures'))],
5188 dryrunopts + [('f', 'force', False, _('ignore safety measures'))],
5163 helpcategory=command.CATEGORY_MAINTENANCE)
5189 helpcategory=command.CATEGORY_MAINTENANCE)
5164 def rollback(ui, repo, **opts):
5190 def rollback(ui, repo, **opts):
5165 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5191 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5166
5192
5167 Please use :hg:`commit --amend` instead of rollback to correct
5193 Please use :hg:`commit --amend` instead of rollback to correct
5168 mistakes in the last commit.
5194 mistakes in the last commit.
5169
5195
5170 This command should be used with care. There is only one level of
5196 This command should be used with care. There is only one level of
5171 rollback, and there is no way to undo a rollback. It will also
5197 rollback, and there is no way to undo a rollback. It will also
5172 restore the dirstate at the time of the last transaction, losing
5198 restore the dirstate at the time of the last transaction, losing
5173 any dirstate changes since that time. This command does not alter
5199 any dirstate changes since that time. This command does not alter
5174 the working directory.
5200 the working directory.
5175
5201
5176 Transactions are used to encapsulate the effects of all commands
5202 Transactions are used to encapsulate the effects of all commands
5177 that create new changesets or propagate existing changesets into a
5203 that create new changesets or propagate existing changesets into a
5178 repository.
5204 repository.
5179
5205
5180 .. container:: verbose
5206 .. container:: verbose
5181
5207
5182 For example, the following commands are transactional, and their
5208 For example, the following commands are transactional, and their
5183 effects can be rolled back:
5209 effects can be rolled back:
5184
5210
5185 - commit
5211 - commit
5186 - import
5212 - import
5187 - pull
5213 - pull
5188 - push (with this repository as the destination)
5214 - push (with this repository as the destination)
5189 - unbundle
5215 - unbundle
5190
5216
5191 To avoid permanent data loss, rollback will refuse to rollback a
5217 To avoid permanent data loss, rollback will refuse to rollback a
5192 commit transaction if it isn't checked out. Use --force to
5218 commit transaction if it isn't checked out. Use --force to
5193 override this protection.
5219 override this protection.
5194
5220
5195 The rollback command can be entirely disabled by setting the
5221 The rollback command can be entirely disabled by setting the
5196 ``ui.rollback`` configuration setting to false. If you're here
5222 ``ui.rollback`` configuration setting to false. If you're here
5197 because you want to use rollback and it's disabled, you can
5223 because you want to use rollback and it's disabled, you can
5198 re-enable the command by setting ``ui.rollback`` to true.
5224 re-enable the command by setting ``ui.rollback`` to true.
5199
5225
5200 This command is not intended for use on public repositories. Once
5226 This command is not intended for use on public repositories. Once
5201 changes are visible for pull by other users, rolling a transaction
5227 changes are visible for pull by other users, rolling a transaction
5202 back locally is ineffective (someone else may already have pulled
5228 back locally is ineffective (someone else may already have pulled
5203 the changes). Furthermore, a race is possible with readers of the
5229 the changes). Furthermore, a race is possible with readers of the
5204 repository; for example an in-progress pull from the repository
5230 repository; for example an in-progress pull from the repository
5205 may fail if a rollback is performed.
5231 may fail if a rollback is performed.
5206
5232
5207 Returns 0 on success, 1 if no rollback data is available.
5233 Returns 0 on success, 1 if no rollback data is available.
5208 """
5234 """
5209 if not ui.configbool('ui', 'rollback'):
5235 if not ui.configbool('ui', 'rollback'):
5210 raise error.Abort(_('rollback is disabled because it is unsafe'),
5236 raise error.Abort(_('rollback is disabled because it is unsafe'),
5211 hint=('see `hg help -v rollback` for information'))
5237 hint=('see `hg help -v rollback` for information'))
5212 return repo.rollback(dryrun=opts.get(r'dry_run'),
5238 return repo.rollback(dryrun=opts.get(r'dry_run'),
5213 force=opts.get(r'force'))
5239 force=opts.get(r'force'))
5214
5240
5215 @command(
5241 @command(
5216 'root', [] + formatteropts, intents={INTENT_READONLY},
5242 'root', [] + formatteropts, intents={INTENT_READONLY},
5217 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5243 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5218 def root(ui, repo, **opts):
5244 def root(ui, repo, **opts):
5219 """print the root (top) of the current working directory
5245 """print the root (top) of the current working directory
5220
5246
5221 Print the root directory of the current repository.
5247 Print the root directory of the current repository.
5222
5248
5223 .. container:: verbose
5249 .. container:: verbose
5224
5250
5225 Template:
5251 Template:
5226
5252
5227 The following keywords are supported in addition to the common template
5253 The following keywords are supported in addition to the common template
5228 keywords and functions. See also :hg:`help templates`.
5254 keywords and functions. See also :hg:`help templates`.
5229
5255
5230 :hgpath: String. Path to the .hg directory.
5256 :hgpath: String. Path to the .hg directory.
5231 :storepath: String. Path to the directory holding versioned data.
5257 :storepath: String. Path to the directory holding versioned data.
5232
5258
5233 Returns 0 on success.
5259 Returns 0 on success.
5234 """
5260 """
5235 opts = pycompat.byteskwargs(opts)
5261 opts = pycompat.byteskwargs(opts)
5236 with ui.formatter('root', opts) as fm:
5262 with ui.formatter('root', opts) as fm:
5237 fm.startitem()
5263 fm.startitem()
5238 fm.write('reporoot', '%s\n', repo.root)
5264 fm.write('reporoot', '%s\n', repo.root)
5239 fm.data(hgpath=repo.path, storepath=repo.spath)
5265 fm.data(hgpath=repo.path, storepath=repo.spath)
5240
5266
5241 @command('serve',
5267 @command('serve',
5242 [('A', 'accesslog', '', _('name of access log file to write to'),
5268 [('A', 'accesslog', '', _('name of access log file to write to'),
5243 _('FILE')),
5269 _('FILE')),
5244 ('d', 'daemon', None, _('run server in background')),
5270 ('d', 'daemon', None, _('run server in background')),
5245 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
5271 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
5246 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5272 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5247 # use string type, then we can check if something was passed
5273 # use string type, then we can check if something was passed
5248 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5274 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5249 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5275 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5250 _('ADDR')),
5276 _('ADDR')),
5251 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5277 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5252 _('PREFIX')),
5278 _('PREFIX')),
5253 ('n', 'name', '',
5279 ('n', 'name', '',
5254 _('name to show in web pages (default: working directory)'), _('NAME')),
5280 _('name to show in web pages (default: working directory)'), _('NAME')),
5255 ('', 'web-conf', '',
5281 ('', 'web-conf', '',
5256 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
5282 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
5257 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5283 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5258 _('FILE')),
5284 _('FILE')),
5259 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5285 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5260 ('', 'stdio', None, _('for remote clients (ADVANCED)')),
5286 ('', 'stdio', None, _('for remote clients (ADVANCED)')),
5261 ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')),
5287 ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')),
5262 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5288 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5263 ('', 'style', '', _('template style to use'), _('STYLE')),
5289 ('', 'style', '', _('template style to use'), _('STYLE')),
5264 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5290 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5265 ('', 'certificate', '', _('SSL certificate file'), _('FILE')),
5291 ('', 'certificate', '', _('SSL certificate file'), _('FILE')),
5266 ('', 'print-url', None, _('start and print only the URL'))]
5292 ('', 'print-url', None, _('start and print only the URL'))]
5267 + subrepoopts,
5293 + subrepoopts,
5268 _('[OPTION]...'),
5294 _('[OPTION]...'),
5269 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5295 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5270 helpbasic=True, optionalrepo=True)
5296 helpbasic=True, optionalrepo=True)
5271 def serve(ui, repo, **opts):
5297 def serve(ui, repo, **opts):
5272 """start stand-alone webserver
5298 """start stand-alone webserver
5273
5299
5274 Start a local HTTP repository browser and pull server. You can use
5300 Start a local HTTP repository browser and pull server. You can use
5275 this for ad-hoc sharing and browsing of repositories. It is
5301 this for ad-hoc sharing and browsing of repositories. It is
5276 recommended to use a real web server to serve a repository for
5302 recommended to use a real web server to serve a repository for
5277 longer periods of time.
5303 longer periods of time.
5278
5304
5279 Please note that the server does not implement access control.
5305 Please note that the server does not implement access control.
5280 This means that, by default, anybody can read from the server and
5306 This means that, by default, anybody can read from the server and
5281 nobody can write to it by default. Set the ``web.allow-push``
5307 nobody can write to it by default. Set the ``web.allow-push``
5282 option to ``*`` to allow everybody to push to the server. You
5308 option to ``*`` to allow everybody to push to the server. You
5283 should use a real web server if you need to authenticate users.
5309 should use a real web server if you need to authenticate users.
5284
5310
5285 By default, the server logs accesses to stdout and errors to
5311 By default, the server logs accesses to stdout and errors to
5286 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5312 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5287 files.
5313 files.
5288
5314
5289 To have the server choose a free port number to listen on, specify
5315 To have the server choose a free port number to listen on, specify
5290 a port number of 0; in this case, the server will print the port
5316 a port number of 0; in this case, the server will print the port
5291 number it uses.
5317 number it uses.
5292
5318
5293 Returns 0 on success.
5319 Returns 0 on success.
5294 """
5320 """
5295
5321
5296 opts = pycompat.byteskwargs(opts)
5322 opts = pycompat.byteskwargs(opts)
5297 if opts["stdio"] and opts["cmdserver"]:
5323 if opts["stdio"] and opts["cmdserver"]:
5298 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5324 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5299 if opts["print_url"] and ui.verbose:
5325 if opts["print_url"] and ui.verbose:
5300 raise error.Abort(_("cannot use --print-url with --verbose"))
5326 raise error.Abort(_("cannot use --print-url with --verbose"))
5301
5327
5302 if opts["stdio"]:
5328 if opts["stdio"]:
5303 if repo is None:
5329 if repo is None:
5304 raise error.RepoError(_("there is no Mercurial repository here"
5330 raise error.RepoError(_("there is no Mercurial repository here"
5305 " (.hg not found)"))
5331 " (.hg not found)"))
5306 s = wireprotoserver.sshserver(ui, repo)
5332 s = wireprotoserver.sshserver(ui, repo)
5307 s.serve_forever()
5333 s.serve_forever()
5308
5334
5309 service = server.createservice(ui, repo, opts)
5335 service = server.createservice(ui, repo, opts)
5310 return server.runservice(opts, initfn=service.init, runfn=service.run)
5336 return server.runservice(opts, initfn=service.init, runfn=service.run)
5311
5337
5312 @command('shelve',
5338 @command('shelve',
5313 [('A', 'addremove', None,
5339 [('A', 'addremove', None,
5314 _('mark new/missing files as added/removed before shelving')),
5340 _('mark new/missing files as added/removed before shelving')),
5315 ('u', 'unknown', None,
5341 ('u', 'unknown', None,
5316 _('store unknown files in the shelve')),
5342 _('store unknown files in the shelve')),
5317 ('', 'cleanup', None,
5343 ('', 'cleanup', None,
5318 _('delete all shelved changes')),
5344 _('delete all shelved changes')),
5319 ('', 'date', '',
5345 ('', 'date', '',
5320 _('shelve with the specified commit date'), _('DATE')),
5346 _('shelve with the specified commit date'), _('DATE')),
5321 ('d', 'delete', None,
5347 ('d', 'delete', None,
5322 _('delete the named shelved change(s)')),
5348 _('delete the named shelved change(s)')),
5323 ('e', 'edit', False,
5349 ('e', 'edit', False,
5324 _('invoke editor on commit messages')),
5350 _('invoke editor on commit messages')),
5325 ('k', 'keep', False,
5351 ('k', 'keep', False,
5326 _('shelve, but keep changes in the working directory')),
5352 _('shelve, but keep changes in the working directory')),
5327 ('l', 'list', None,
5353 ('l', 'list', None,
5328 _('list current shelves')),
5354 _('list current shelves')),
5329 ('m', 'message', '',
5355 ('m', 'message', '',
5330 _('use text as shelve message'), _('TEXT')),
5356 _('use text as shelve message'), _('TEXT')),
5331 ('n', 'name', '',
5357 ('n', 'name', '',
5332 _('use the given name for the shelved commit'), _('NAME')),
5358 _('use the given name for the shelved commit'), _('NAME')),
5333 ('p', 'patch', None,
5359 ('p', 'patch', None,
5334 _('output patches for changes (provide the names of the shelved '
5360 _('output patches for changes (provide the names of the shelved '
5335 'changes as positional arguments)')),
5361 'changes as positional arguments)')),
5336 ('i', 'interactive', None,
5362 ('i', 'interactive', None,
5337 _('interactive mode, only works while creating a shelve')),
5363 _('interactive mode, only works while creating a shelve')),
5338 ('', 'stat', None,
5364 ('', 'stat', None,
5339 _('output diffstat-style summary of changes (provide the names of '
5365 _('output diffstat-style summary of changes (provide the names of '
5340 'the shelved changes as positional arguments)')
5366 'the shelved changes as positional arguments)')
5341 )] + cmdutil.walkopts,
5367 )] + cmdutil.walkopts,
5342 _('hg shelve [OPTION]... [FILE]...'),
5368 _('hg shelve [OPTION]... [FILE]...'),
5343 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5369 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5344 def shelve(ui, repo, *pats, **opts):
5370 def shelve(ui, repo, *pats, **opts):
5345 '''save and set aside changes from the working directory
5371 '''save and set aside changes from the working directory
5346
5372
5347 Shelving takes files that "hg status" reports as not clean, saves
5373 Shelving takes files that "hg status" reports as not clean, saves
5348 the modifications to a bundle (a shelved change), and reverts the
5374 the modifications to a bundle (a shelved change), and reverts the
5349 files so that their state in the working directory becomes clean.
5375 files so that their state in the working directory becomes clean.
5350
5376
5351 To restore these changes to the working directory, using "hg
5377 To restore these changes to the working directory, using "hg
5352 unshelve"; this will work even if you switch to a different
5378 unshelve"; this will work even if you switch to a different
5353 commit.
5379 commit.
5354
5380
5355 When no files are specified, "hg shelve" saves all not-clean
5381 When no files are specified, "hg shelve" saves all not-clean
5356 files. If specific files or directories are named, only changes to
5382 files. If specific files or directories are named, only changes to
5357 those files are shelved.
5383 those files are shelved.
5358
5384
5359 In bare shelve (when no files are specified, without interactive,
5385 In bare shelve (when no files are specified, without interactive,
5360 include and exclude option), shelving remembers information if the
5386 include and exclude option), shelving remembers information if the
5361 working directory was on newly created branch, in other words working
5387 working directory was on newly created branch, in other words working
5362 directory was on different branch than its first parent. In this
5388 directory was on different branch than its first parent. In this
5363 situation unshelving restores branch information to the working directory.
5389 situation unshelving restores branch information to the working directory.
5364
5390
5365 Each shelved change has a name that makes it easier to find later.
5391 Each shelved change has a name that makes it easier to find later.
5366 The name of a shelved change defaults to being based on the active
5392 The name of a shelved change defaults to being based on the active
5367 bookmark, or if there is no active bookmark, the current named
5393 bookmark, or if there is no active bookmark, the current named
5368 branch. To specify a different name, use ``--name``.
5394 branch. To specify a different name, use ``--name``.
5369
5395
5370 To see a list of existing shelved changes, use the ``--list``
5396 To see a list of existing shelved changes, use the ``--list``
5371 option. For each shelved change, this will print its name, age,
5397 option. For each shelved change, this will print its name, age,
5372 and description; use ``--patch`` or ``--stat`` for more details.
5398 and description; use ``--patch`` or ``--stat`` for more details.
5373
5399
5374 To delete specific shelved changes, use ``--delete``. To delete
5400 To delete specific shelved changes, use ``--delete``. To delete
5375 all shelved changes, use ``--cleanup``.
5401 all shelved changes, use ``--cleanup``.
5376 '''
5402 '''
5377 opts = pycompat.byteskwargs(opts)
5403 opts = pycompat.byteskwargs(opts)
5378 allowables = [
5404 allowables = [
5379 ('addremove', {'create'}), # 'create' is pseudo action
5405 ('addremove', {'create'}), # 'create' is pseudo action
5380 ('unknown', {'create'}),
5406 ('unknown', {'create'}),
5381 ('cleanup', {'cleanup'}),
5407 ('cleanup', {'cleanup'}),
5382 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
5408 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
5383 ('delete', {'delete'}),
5409 ('delete', {'delete'}),
5384 ('edit', {'create'}),
5410 ('edit', {'create'}),
5385 ('keep', {'create'}),
5411 ('keep', {'create'}),
5386 ('list', {'list'}),
5412 ('list', {'list'}),
5387 ('message', {'create'}),
5413 ('message', {'create'}),
5388 ('name', {'create'}),
5414 ('name', {'create'}),
5389 ('patch', {'patch', 'list'}),
5415 ('patch', {'patch', 'list'}),
5390 ('stat', {'stat', 'list'}),
5416 ('stat', {'stat', 'list'}),
5391 ]
5417 ]
5392 def checkopt(opt):
5418 def checkopt(opt):
5393 if opts.get(opt):
5419 if opts.get(opt):
5394 for i, allowable in allowables:
5420 for i, allowable in allowables:
5395 if opts[i] and opt not in allowable:
5421 if opts[i] and opt not in allowable:
5396 raise error.Abort(_("options '--%s' and '--%s' may not be "
5422 raise error.Abort(_("options '--%s' and '--%s' may not be "
5397 "used together") % (opt, i))
5423 "used together") % (opt, i))
5398 return True
5424 return True
5399 if checkopt('cleanup'):
5425 if checkopt('cleanup'):
5400 if pats:
5426 if pats:
5401 raise error.Abort(_("cannot specify names when using '--cleanup'"))
5427 raise error.Abort(_("cannot specify names when using '--cleanup'"))
5402 return shelvemod.cleanupcmd(ui, repo)
5428 return shelvemod.cleanupcmd(ui, repo)
5403 elif checkopt('delete'):
5429 elif checkopt('delete'):
5404 return shelvemod.deletecmd(ui, repo, pats)
5430 return shelvemod.deletecmd(ui, repo, pats)
5405 elif checkopt('list'):
5431 elif checkopt('list'):
5406 return shelvemod.listcmd(ui, repo, pats, opts)
5432 return shelvemod.listcmd(ui, repo, pats, opts)
5407 elif checkopt('patch') or checkopt('stat'):
5433 elif checkopt('patch') or checkopt('stat'):
5408 return shelvemod.patchcmds(ui, repo, pats, opts)
5434 return shelvemod.patchcmds(ui, repo, pats, opts)
5409 else:
5435 else:
5410 return shelvemod.createcmd(ui, repo, pats, opts)
5436 return shelvemod.createcmd(ui, repo, pats, opts)
5411
5437
5412 _NOTTERSE = 'nothing'
5438 _NOTTERSE = 'nothing'
5413
5439
5414 @command('status|st',
5440 @command('status|st',
5415 [('A', 'all', None, _('show status of all files')),
5441 [('A', 'all', None, _('show status of all files')),
5416 ('m', 'modified', None, _('show only modified files')),
5442 ('m', 'modified', None, _('show only modified files')),
5417 ('a', 'added', None, _('show only added files')),
5443 ('a', 'added', None, _('show only added files')),
5418 ('r', 'removed', None, _('show only removed files')),
5444 ('r', 'removed', None, _('show only removed files')),
5419 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5445 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5420 ('c', 'clean', None, _('show only files without changes')),
5446 ('c', 'clean', None, _('show only files without changes')),
5421 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5447 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5422 ('i', 'ignored', None, _('show only ignored files')),
5448 ('i', 'ignored', None, _('show only ignored files')),
5423 ('n', 'no-status', None, _('hide status prefix')),
5449 ('n', 'no-status', None, _('hide status prefix')),
5424 ('t', 'terse', _NOTTERSE, _('show the terse output (EXPERIMENTAL)')),
5450 ('t', 'terse', _NOTTERSE, _('show the terse output (EXPERIMENTAL)')),
5425 ('C', 'copies', None, _('show source of copied files')),
5451 ('C', 'copies', None, _('show source of copied files')),
5426 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5452 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5427 ('', 'rev', [], _('show difference from revision'), _('REV')),
5453 ('', 'rev', [], _('show difference from revision'), _('REV')),
5428 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5454 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5429 ] + walkopts + subrepoopts + formatteropts,
5455 ] + walkopts + subrepoopts + formatteropts,
5430 _('[OPTION]... [FILE]...'),
5456 _('[OPTION]... [FILE]...'),
5431 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5457 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5432 helpbasic=True, inferrepo=True,
5458 helpbasic=True, inferrepo=True,
5433 intents={INTENT_READONLY})
5459 intents={INTENT_READONLY})
5434 def status(ui, repo, *pats, **opts):
5460 def status(ui, repo, *pats, **opts):
5435 """show changed files in the working directory
5461 """show changed files in the working directory
5436
5462
5437 Show status of files in the repository. If names are given, only
5463 Show status of files in the repository. If names are given, only
5438 files that match are shown. Files that are clean or ignored or
5464 files that match are shown. Files that are clean or ignored or
5439 the source of a copy/move operation, are not listed unless
5465 the source of a copy/move operation, are not listed unless
5440 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5466 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5441 Unless options described with "show only ..." are given, the
5467 Unless options described with "show only ..." are given, the
5442 options -mardu are used.
5468 options -mardu are used.
5443
5469
5444 Option -q/--quiet hides untracked (unknown and ignored) files
5470 Option -q/--quiet hides untracked (unknown and ignored) files
5445 unless explicitly requested with -u/--unknown or -i/--ignored.
5471 unless explicitly requested with -u/--unknown or -i/--ignored.
5446
5472
5447 .. note::
5473 .. note::
5448
5474
5449 :hg:`status` may appear to disagree with diff if permissions have
5475 :hg:`status` may appear to disagree with diff if permissions have
5450 changed or a merge has occurred. The standard diff format does
5476 changed or a merge has occurred. The standard diff format does
5451 not report permission changes and diff only reports changes
5477 not report permission changes and diff only reports changes
5452 relative to one merge parent.
5478 relative to one merge parent.
5453
5479
5454 If one revision is given, it is used as the base revision.
5480 If one revision is given, it is used as the base revision.
5455 If two revisions are given, the differences between them are
5481 If two revisions are given, the differences between them are
5456 shown. The --change option can also be used as a shortcut to list
5482 shown. The --change option can also be used as a shortcut to list
5457 the changed files of a revision from its first parent.
5483 the changed files of a revision from its first parent.
5458
5484
5459 The codes used to show the status of files are::
5485 The codes used to show the status of files are::
5460
5486
5461 M = modified
5487 M = modified
5462 A = added
5488 A = added
5463 R = removed
5489 R = removed
5464 C = clean
5490 C = clean
5465 ! = missing (deleted by non-hg command, but still tracked)
5491 ! = missing (deleted by non-hg command, but still tracked)
5466 ? = not tracked
5492 ? = not tracked
5467 I = ignored
5493 I = ignored
5468 = origin of the previous file (with --copies)
5494 = origin of the previous file (with --copies)
5469
5495
5470 .. container:: verbose
5496 .. container:: verbose
5471
5497
5472 The -t/--terse option abbreviates the output by showing only the directory
5498 The -t/--terse option abbreviates the output by showing only the directory
5473 name if all the files in it share the same status. The option takes an
5499 name if all the files in it share the same status. The option takes an
5474 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
5500 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
5475 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
5501 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
5476 for 'ignored' and 'c' for clean.
5502 for 'ignored' and 'c' for clean.
5477
5503
5478 It abbreviates only those statuses which are passed. Note that clean and
5504 It abbreviates only those statuses which are passed. Note that clean and
5479 ignored files are not displayed with '--terse ic' unless the -c/--clean
5505 ignored files are not displayed with '--terse ic' unless the -c/--clean
5480 and -i/--ignored options are also used.
5506 and -i/--ignored options are also used.
5481
5507
5482 The -v/--verbose option shows information when the repository is in an
5508 The -v/--verbose option shows information when the repository is in an
5483 unfinished merge, shelve, rebase state etc. You can have this behavior
5509 unfinished merge, shelve, rebase state etc. You can have this behavior
5484 turned on by default by enabling the ``commands.status.verbose`` option.
5510 turned on by default by enabling the ``commands.status.verbose`` option.
5485
5511
5486 You can skip displaying some of these states by setting
5512 You can skip displaying some of these states by setting
5487 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
5513 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
5488 'histedit', 'merge', 'rebase', or 'unshelve'.
5514 'histedit', 'merge', 'rebase', or 'unshelve'.
5489
5515
5490 Template:
5516 Template:
5491
5517
5492 The following keywords are supported in addition to the common template
5518 The following keywords are supported in addition to the common template
5493 keywords and functions. See also :hg:`help templates`.
5519 keywords and functions. See also :hg:`help templates`.
5494
5520
5495 :path: String. Repository-absolute path of the file.
5521 :path: String. Repository-absolute path of the file.
5496 :source: String. Repository-absolute path of the file originated from.
5522 :source: String. Repository-absolute path of the file originated from.
5497 Available if ``--copies`` is specified.
5523 Available if ``--copies`` is specified.
5498 :status: String. Character denoting file's status.
5524 :status: String. Character denoting file's status.
5499
5525
5500 Examples:
5526 Examples:
5501
5527
5502 - show changes in the working directory relative to a
5528 - show changes in the working directory relative to a
5503 changeset::
5529 changeset::
5504
5530
5505 hg status --rev 9353
5531 hg status --rev 9353
5506
5532
5507 - show changes in the working directory relative to the
5533 - show changes in the working directory relative to the
5508 current directory (see :hg:`help patterns` for more information)::
5534 current directory (see :hg:`help patterns` for more information)::
5509
5535
5510 hg status re:
5536 hg status re:
5511
5537
5512 - show all changes including copies in an existing changeset::
5538 - show all changes including copies in an existing changeset::
5513
5539
5514 hg status --copies --change 9353
5540 hg status --copies --change 9353
5515
5541
5516 - get a NUL separated list of added files, suitable for xargs::
5542 - get a NUL separated list of added files, suitable for xargs::
5517
5543
5518 hg status -an0
5544 hg status -an0
5519
5545
5520 - show more information about the repository status, abbreviating
5546 - show more information about the repository status, abbreviating
5521 added, removed, modified, deleted, and untracked paths::
5547 added, removed, modified, deleted, and untracked paths::
5522
5548
5523 hg status -v -t mardu
5549 hg status -v -t mardu
5524
5550
5525 Returns 0 on success.
5551 Returns 0 on success.
5526
5552
5527 """
5553 """
5528
5554
5529 opts = pycompat.byteskwargs(opts)
5555 opts = pycompat.byteskwargs(opts)
5530 revs = opts.get('rev')
5556 revs = opts.get('rev')
5531 change = opts.get('change')
5557 change = opts.get('change')
5532 terse = opts.get('terse')
5558 terse = opts.get('terse')
5533 if terse is _NOTTERSE:
5559 if terse is _NOTTERSE:
5534 if revs:
5560 if revs:
5535 terse = ''
5561 terse = ''
5536 else:
5562 else:
5537 terse = ui.config('commands', 'status.terse')
5563 terse = ui.config('commands', 'status.terse')
5538
5564
5539 if revs and change:
5565 if revs and change:
5540 msg = _('cannot specify --rev and --change at the same time')
5566 msg = _('cannot specify --rev and --change at the same time')
5541 raise error.Abort(msg)
5567 raise error.Abort(msg)
5542 elif revs and terse:
5568 elif revs and terse:
5543 msg = _('cannot use --terse with --rev')
5569 msg = _('cannot use --terse with --rev')
5544 raise error.Abort(msg)
5570 raise error.Abort(msg)
5545 elif change:
5571 elif change:
5546 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
5572 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
5547 ctx2 = scmutil.revsingle(repo, change, None)
5573 ctx2 = scmutil.revsingle(repo, change, None)
5548 ctx1 = ctx2.p1()
5574 ctx1 = ctx2.p1()
5549 else:
5575 else:
5550 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
5576 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
5551 ctx1, ctx2 = scmutil.revpair(repo, revs)
5577 ctx1, ctx2 = scmutil.revpair(repo, revs)
5552
5578
5553 forcerelativevalue = None
5579 forcerelativevalue = None
5554 if ui.hasconfig('commands', 'status.relative'):
5580 if ui.hasconfig('commands', 'status.relative'):
5555 forcerelativevalue = ui.configbool('commands', 'status.relative')
5581 forcerelativevalue = ui.configbool('commands', 'status.relative')
5556 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats),
5582 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats),
5557 forcerelativevalue=forcerelativevalue)
5583 forcerelativevalue=forcerelativevalue)
5558
5584
5559 if opts.get('print0'):
5585 if opts.get('print0'):
5560 end = '\0'
5586 end = '\0'
5561 else:
5587 else:
5562 end = '\n'
5588 end = '\n'
5563 copy = {}
5589 copy = {}
5564 states = 'modified added removed deleted unknown ignored clean'.split()
5590 states = 'modified added removed deleted unknown ignored clean'.split()
5565 show = [k for k in states if opts.get(k)]
5591 show = [k for k in states if opts.get(k)]
5566 if opts.get('all'):
5592 if opts.get('all'):
5567 show += ui.quiet and (states[:4] + ['clean']) or states
5593 show += ui.quiet and (states[:4] + ['clean']) or states
5568
5594
5569 if not show:
5595 if not show:
5570 if ui.quiet:
5596 if ui.quiet:
5571 show = states[:4]
5597 show = states[:4]
5572 else:
5598 else:
5573 show = states[:5]
5599 show = states[:5]
5574
5600
5575 m = scmutil.match(ctx2, pats, opts)
5601 m = scmutil.match(ctx2, pats, opts)
5576 if terse:
5602 if terse:
5577 # we need to compute clean and unknown to terse
5603 # we need to compute clean and unknown to terse
5578 stat = repo.status(ctx1.node(), ctx2.node(), m,
5604 stat = repo.status(ctx1.node(), ctx2.node(), m,
5579 'ignored' in show or 'i' in terse,
5605 'ignored' in show or 'i' in terse,
5580 clean=True, unknown=True,
5606 clean=True, unknown=True,
5581 listsubrepos=opts.get('subrepos'))
5607 listsubrepos=opts.get('subrepos'))
5582
5608
5583 stat = cmdutil.tersedir(stat, terse)
5609 stat = cmdutil.tersedir(stat, terse)
5584 else:
5610 else:
5585 stat = repo.status(ctx1.node(), ctx2.node(), m,
5611 stat = repo.status(ctx1.node(), ctx2.node(), m,
5586 'ignored' in show, 'clean' in show,
5612 'ignored' in show, 'clean' in show,
5587 'unknown' in show, opts.get('subrepos'))
5613 'unknown' in show, opts.get('subrepos'))
5588
5614
5589 changestates = zip(states, pycompat.iterbytestr('MAR!?IC'), stat)
5615 changestates = zip(states, pycompat.iterbytestr('MAR!?IC'), stat)
5590
5616
5591 if (opts.get('all') or opts.get('copies')
5617 if (opts.get('all') or opts.get('copies')
5592 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5618 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5593 copy = copies.pathcopies(ctx1, ctx2, m)
5619 copy = copies.pathcopies(ctx1, ctx2, m)
5594
5620
5595 ui.pager('status')
5621 ui.pager('status')
5596 fm = ui.formatter('status', opts)
5622 fm = ui.formatter('status', opts)
5597 fmt = '%s' + end
5623 fmt = '%s' + end
5598 showchar = not opts.get('no_status')
5624 showchar = not opts.get('no_status')
5599
5625
5600 for state, char, files in changestates:
5626 for state, char, files in changestates:
5601 if state in show:
5627 if state in show:
5602 label = 'status.' + state
5628 label = 'status.' + state
5603 for f in files:
5629 for f in files:
5604 fm.startitem()
5630 fm.startitem()
5605 fm.context(ctx=ctx2)
5631 fm.context(ctx=ctx2)
5606 fm.data(path=f)
5632 fm.data(path=f)
5607 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5633 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5608 fm.plain(fmt % uipathfn(f), label=label)
5634 fm.plain(fmt % uipathfn(f), label=label)
5609 if f in copy:
5635 if f in copy:
5610 fm.data(source=copy[f])
5636 fm.data(source=copy[f])
5611 fm.plain((' %s' + end) % uipathfn(copy[f]),
5637 fm.plain((' %s' + end) % uipathfn(copy[f]),
5612 label='status.copied')
5638 label='status.copied')
5613
5639
5614 if ((ui.verbose or ui.configbool('commands', 'status.verbose'))
5640 if ((ui.verbose or ui.configbool('commands', 'status.verbose'))
5615 and not ui.plain()):
5641 and not ui.plain()):
5616 cmdutil.morestatus(repo, fm)
5642 cmdutil.morestatus(repo, fm)
5617 fm.end()
5643 fm.end()
5618
5644
5619 @command('summary|sum',
5645 @command('summary|sum',
5620 [('', 'remote', None, _('check for push and pull'))],
5646 [('', 'remote', None, _('check for push and pull'))],
5621 '[--remote]',
5647 '[--remote]',
5622 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5648 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5623 helpbasic=True,
5649 helpbasic=True,
5624 intents={INTENT_READONLY})
5650 intents={INTENT_READONLY})
5625 def summary(ui, repo, **opts):
5651 def summary(ui, repo, **opts):
5626 """summarize working directory state
5652 """summarize working directory state
5627
5653
5628 This generates a brief summary of the working directory state,
5654 This generates a brief summary of the working directory state,
5629 including parents, branch, commit status, phase and available updates.
5655 including parents, branch, commit status, phase and available updates.
5630
5656
5631 With the --remote option, this will check the default paths for
5657 With the --remote option, this will check the default paths for
5632 incoming and outgoing changes. This can be time-consuming.
5658 incoming and outgoing changes. This can be time-consuming.
5633
5659
5634 Returns 0 on success.
5660 Returns 0 on success.
5635 """
5661 """
5636
5662
5637 opts = pycompat.byteskwargs(opts)
5663 opts = pycompat.byteskwargs(opts)
5638 ui.pager('summary')
5664 ui.pager('summary')
5639 ctx = repo[None]
5665 ctx = repo[None]
5640 parents = ctx.parents()
5666 parents = ctx.parents()
5641 pnode = parents[0].node()
5667 pnode = parents[0].node()
5642 marks = []
5668 marks = []
5643
5669
5644 try:
5670 try:
5645 ms = mergemod.mergestate.read(repo)
5671 ms = mergemod.mergestate.read(repo)
5646 except error.UnsupportedMergeRecords as e:
5672 except error.UnsupportedMergeRecords as e:
5647 s = ' '.join(e.recordtypes)
5673 s = ' '.join(e.recordtypes)
5648 ui.warn(
5674 ui.warn(
5649 _('warning: merge state has unsupported record types: %s\n') % s)
5675 _('warning: merge state has unsupported record types: %s\n') % s)
5650 unresolved = []
5676 unresolved = []
5651 else:
5677 else:
5652 unresolved = list(ms.unresolved())
5678 unresolved = list(ms.unresolved())
5653
5679
5654 for p in parents:
5680 for p in parents:
5655 # label with log.changeset (instead of log.parent) since this
5681 # label with log.changeset (instead of log.parent) since this
5656 # shows a working directory parent *changeset*:
5682 # shows a working directory parent *changeset*:
5657 # i18n: column positioning for "hg summary"
5683 # i18n: column positioning for "hg summary"
5658 ui.write(_('parent: %d:%s ') % (p.rev(), p),
5684 ui.write(_('parent: %d:%s ') % (p.rev(), p),
5659 label=logcmdutil.changesetlabels(p))
5685 label=logcmdutil.changesetlabels(p))
5660 ui.write(' '.join(p.tags()), label='log.tag')
5686 ui.write(' '.join(p.tags()), label='log.tag')
5661 if p.bookmarks():
5687 if p.bookmarks():
5662 marks.extend(p.bookmarks())
5688 marks.extend(p.bookmarks())
5663 if p.rev() == -1:
5689 if p.rev() == -1:
5664 if not len(repo):
5690 if not len(repo):
5665 ui.write(_(' (empty repository)'))
5691 ui.write(_(' (empty repository)'))
5666 else:
5692 else:
5667 ui.write(_(' (no revision checked out)'))
5693 ui.write(_(' (no revision checked out)'))
5668 if p.obsolete():
5694 if p.obsolete():
5669 ui.write(_(' (obsolete)'))
5695 ui.write(_(' (obsolete)'))
5670 if p.isunstable():
5696 if p.isunstable():
5671 instabilities = (ui.label(instability, 'trouble.%s' % instability)
5697 instabilities = (ui.label(instability, 'trouble.%s' % instability)
5672 for instability in p.instabilities())
5698 for instability in p.instabilities())
5673 ui.write(' ('
5699 ui.write(' ('
5674 + ', '.join(instabilities)
5700 + ', '.join(instabilities)
5675 + ')')
5701 + ')')
5676 ui.write('\n')
5702 ui.write('\n')
5677 if p.description():
5703 if p.description():
5678 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5704 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5679 label='log.summary')
5705 label='log.summary')
5680
5706
5681 branch = ctx.branch()
5707 branch = ctx.branch()
5682 bheads = repo.branchheads(branch)
5708 bheads = repo.branchheads(branch)
5683 # i18n: column positioning for "hg summary"
5709 # i18n: column positioning for "hg summary"
5684 m = _('branch: %s\n') % branch
5710 m = _('branch: %s\n') % branch
5685 if branch != 'default':
5711 if branch != 'default':
5686 ui.write(m, label='log.branch')
5712 ui.write(m, label='log.branch')
5687 else:
5713 else:
5688 ui.status(m, label='log.branch')
5714 ui.status(m, label='log.branch')
5689
5715
5690 if marks:
5716 if marks:
5691 active = repo._activebookmark
5717 active = repo._activebookmark
5692 # i18n: column positioning for "hg summary"
5718 # i18n: column positioning for "hg summary"
5693 ui.write(_('bookmarks:'), label='log.bookmark')
5719 ui.write(_('bookmarks:'), label='log.bookmark')
5694 if active is not None:
5720 if active is not None:
5695 if active in marks:
5721 if active in marks:
5696 ui.write(' *' + active, label=bookmarks.activebookmarklabel)
5722 ui.write(' *' + active, label=bookmarks.activebookmarklabel)
5697 marks.remove(active)
5723 marks.remove(active)
5698 else:
5724 else:
5699 ui.write(' [%s]' % active, label=bookmarks.activebookmarklabel)
5725 ui.write(' [%s]' % active, label=bookmarks.activebookmarklabel)
5700 for m in marks:
5726 for m in marks:
5701 ui.write(' ' + m, label='log.bookmark')
5727 ui.write(' ' + m, label='log.bookmark')
5702 ui.write('\n', label='log.bookmark')
5728 ui.write('\n', label='log.bookmark')
5703
5729
5704 status = repo.status(unknown=True)
5730 status = repo.status(unknown=True)
5705
5731
5706 c = repo.dirstate.copies()
5732 c = repo.dirstate.copies()
5707 copied, renamed = [], []
5733 copied, renamed = [], []
5708 for d, s in c.iteritems():
5734 for d, s in c.iteritems():
5709 if s in status.removed:
5735 if s in status.removed:
5710 status.removed.remove(s)
5736 status.removed.remove(s)
5711 renamed.append(d)
5737 renamed.append(d)
5712 else:
5738 else:
5713 copied.append(d)
5739 copied.append(d)
5714 if d in status.added:
5740 if d in status.added:
5715 status.added.remove(d)
5741 status.added.remove(d)
5716
5742
5717 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5743 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5718
5744
5719 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
5745 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
5720 (ui.label(_('%d added'), 'status.added'), status.added),
5746 (ui.label(_('%d added'), 'status.added'), status.added),
5721 (ui.label(_('%d removed'), 'status.removed'), status.removed),
5747 (ui.label(_('%d removed'), 'status.removed'), status.removed),
5722 (ui.label(_('%d renamed'), 'status.copied'), renamed),
5748 (ui.label(_('%d renamed'), 'status.copied'), renamed),
5723 (ui.label(_('%d copied'), 'status.copied'), copied),
5749 (ui.label(_('%d copied'), 'status.copied'), copied),
5724 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
5750 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
5725 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
5751 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
5726 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
5752 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
5727 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
5753 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
5728 t = []
5754 t = []
5729 for l, s in labels:
5755 for l, s in labels:
5730 if s:
5756 if s:
5731 t.append(l % len(s))
5757 t.append(l % len(s))
5732
5758
5733 t = ', '.join(t)
5759 t = ', '.join(t)
5734 cleanworkdir = False
5760 cleanworkdir = False
5735
5761
5736 if repo.vfs.exists('graftstate'):
5762 if repo.vfs.exists('graftstate'):
5737 t += _(' (graft in progress)')
5763 t += _(' (graft in progress)')
5738 if repo.vfs.exists('updatestate'):
5764 if repo.vfs.exists('updatestate'):
5739 t += _(' (interrupted update)')
5765 t += _(' (interrupted update)')
5740 elif len(parents) > 1:
5766 elif len(parents) > 1:
5741 t += _(' (merge)')
5767 t += _(' (merge)')
5742 elif branch != parents[0].branch():
5768 elif branch != parents[0].branch():
5743 t += _(' (new branch)')
5769 t += _(' (new branch)')
5744 elif (parents[0].closesbranch() and
5770 elif (parents[0].closesbranch() and
5745 pnode in repo.branchheads(branch, closed=True)):
5771 pnode in repo.branchheads(branch, closed=True)):
5746 t += _(' (head closed)')
5772 t += _(' (head closed)')
5747 elif not (status.modified or status.added or status.removed or renamed or
5773 elif not (status.modified or status.added or status.removed or renamed or
5748 copied or subs):
5774 copied or subs):
5749 t += _(' (clean)')
5775 t += _(' (clean)')
5750 cleanworkdir = True
5776 cleanworkdir = True
5751 elif pnode not in bheads:
5777 elif pnode not in bheads:
5752 t += _(' (new branch head)')
5778 t += _(' (new branch head)')
5753
5779
5754 if parents:
5780 if parents:
5755 pendingphase = max(p.phase() for p in parents)
5781 pendingphase = max(p.phase() for p in parents)
5756 else:
5782 else:
5757 pendingphase = phases.public
5783 pendingphase = phases.public
5758
5784
5759 if pendingphase > phases.newcommitphase(ui):
5785 if pendingphase > phases.newcommitphase(ui):
5760 t += ' (%s)' % phases.phasenames[pendingphase]
5786 t += ' (%s)' % phases.phasenames[pendingphase]
5761
5787
5762 if cleanworkdir:
5788 if cleanworkdir:
5763 # i18n: column positioning for "hg summary"
5789 # i18n: column positioning for "hg summary"
5764 ui.status(_('commit: %s\n') % t.strip())
5790 ui.status(_('commit: %s\n') % t.strip())
5765 else:
5791 else:
5766 # i18n: column positioning for "hg summary"
5792 # i18n: column positioning for "hg summary"
5767 ui.write(_('commit: %s\n') % t.strip())
5793 ui.write(_('commit: %s\n') % t.strip())
5768
5794
5769 # all ancestors of branch heads - all ancestors of parent = new csets
5795 # all ancestors of branch heads - all ancestors of parent = new csets
5770 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
5796 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
5771 bheads))
5797 bheads))
5772
5798
5773 if new == 0:
5799 if new == 0:
5774 # i18n: column positioning for "hg summary"
5800 # i18n: column positioning for "hg summary"
5775 ui.status(_('update: (current)\n'))
5801 ui.status(_('update: (current)\n'))
5776 elif pnode not in bheads:
5802 elif pnode not in bheads:
5777 # i18n: column positioning for "hg summary"
5803 # i18n: column positioning for "hg summary"
5778 ui.write(_('update: %d new changesets (update)\n') % new)
5804 ui.write(_('update: %d new changesets (update)\n') % new)
5779 else:
5805 else:
5780 # i18n: column positioning for "hg summary"
5806 # i18n: column positioning for "hg summary"
5781 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5807 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5782 (new, len(bheads)))
5808 (new, len(bheads)))
5783
5809
5784 t = []
5810 t = []
5785 draft = len(repo.revs('draft()'))
5811 draft = len(repo.revs('draft()'))
5786 if draft:
5812 if draft:
5787 t.append(_('%d draft') % draft)
5813 t.append(_('%d draft') % draft)
5788 secret = len(repo.revs('secret()'))
5814 secret = len(repo.revs('secret()'))
5789 if secret:
5815 if secret:
5790 t.append(_('%d secret') % secret)
5816 t.append(_('%d secret') % secret)
5791
5817
5792 if draft or secret:
5818 if draft or secret:
5793 ui.status(_('phases: %s\n') % ', '.join(t))
5819 ui.status(_('phases: %s\n') % ', '.join(t))
5794
5820
5795 if obsolete.isenabled(repo, obsolete.createmarkersopt):
5821 if obsolete.isenabled(repo, obsolete.createmarkersopt):
5796 for trouble in ("orphan", "contentdivergent", "phasedivergent"):
5822 for trouble in ("orphan", "contentdivergent", "phasedivergent"):
5797 numtrouble = len(repo.revs(trouble + "()"))
5823 numtrouble = len(repo.revs(trouble + "()"))
5798 # We write all the possibilities to ease translation
5824 # We write all the possibilities to ease translation
5799 troublemsg = {
5825 troublemsg = {
5800 "orphan": _("orphan: %d changesets"),
5826 "orphan": _("orphan: %d changesets"),
5801 "contentdivergent": _("content-divergent: %d changesets"),
5827 "contentdivergent": _("content-divergent: %d changesets"),
5802 "phasedivergent": _("phase-divergent: %d changesets"),
5828 "phasedivergent": _("phase-divergent: %d changesets"),
5803 }
5829 }
5804 if numtrouble > 0:
5830 if numtrouble > 0:
5805 ui.status(troublemsg[trouble] % numtrouble + "\n")
5831 ui.status(troublemsg[trouble] % numtrouble + "\n")
5806
5832
5807 cmdutil.summaryhooks(ui, repo)
5833 cmdutil.summaryhooks(ui, repo)
5808
5834
5809 if opts.get('remote'):
5835 if opts.get('remote'):
5810 needsincoming, needsoutgoing = True, True
5836 needsincoming, needsoutgoing = True, True
5811 else:
5837 else:
5812 needsincoming, needsoutgoing = False, False
5838 needsincoming, needsoutgoing = False, False
5813 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5839 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5814 if i:
5840 if i:
5815 needsincoming = True
5841 needsincoming = True
5816 if o:
5842 if o:
5817 needsoutgoing = True
5843 needsoutgoing = True
5818 if not needsincoming and not needsoutgoing:
5844 if not needsincoming and not needsoutgoing:
5819 return
5845 return
5820
5846
5821 def getincoming():
5847 def getincoming():
5822 source, branches = hg.parseurl(ui.expandpath('default'))
5848 source, branches = hg.parseurl(ui.expandpath('default'))
5823 sbranch = branches[0]
5849 sbranch = branches[0]
5824 try:
5850 try:
5825 other = hg.peer(repo, {}, source)
5851 other = hg.peer(repo, {}, source)
5826 except error.RepoError:
5852 except error.RepoError:
5827 if opts.get('remote'):
5853 if opts.get('remote'):
5828 raise
5854 raise
5829 return source, sbranch, None, None, None
5855 return source, sbranch, None, None, None
5830 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5856 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5831 if revs:
5857 if revs:
5832 revs = [other.lookup(rev) for rev in revs]
5858 revs = [other.lookup(rev) for rev in revs]
5833 ui.debug('comparing with %s\n' % util.hidepassword(source))
5859 ui.debug('comparing with %s\n' % util.hidepassword(source))
5834 repo.ui.pushbuffer()
5860 repo.ui.pushbuffer()
5835 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5861 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5836 repo.ui.popbuffer()
5862 repo.ui.popbuffer()
5837 return source, sbranch, other, commoninc, commoninc[1]
5863 return source, sbranch, other, commoninc, commoninc[1]
5838
5864
5839 if needsincoming:
5865 if needsincoming:
5840 source, sbranch, sother, commoninc, incoming = getincoming()
5866 source, sbranch, sother, commoninc, incoming = getincoming()
5841 else:
5867 else:
5842 source = sbranch = sother = commoninc = incoming = None
5868 source = sbranch = sother = commoninc = incoming = None
5843
5869
5844 def getoutgoing():
5870 def getoutgoing():
5845 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5871 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5846 dbranch = branches[0]
5872 dbranch = branches[0]
5847 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5873 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5848 if source != dest:
5874 if source != dest:
5849 try:
5875 try:
5850 dother = hg.peer(repo, {}, dest)
5876 dother = hg.peer(repo, {}, dest)
5851 except error.RepoError:
5877 except error.RepoError:
5852 if opts.get('remote'):
5878 if opts.get('remote'):
5853 raise
5879 raise
5854 return dest, dbranch, None, None
5880 return dest, dbranch, None, None
5855 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5881 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5856 elif sother is None:
5882 elif sother is None:
5857 # there is no explicit destination peer, but source one is invalid
5883 # there is no explicit destination peer, but source one is invalid
5858 return dest, dbranch, None, None
5884 return dest, dbranch, None, None
5859 else:
5885 else:
5860 dother = sother
5886 dother = sother
5861 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5887 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5862 common = None
5888 common = None
5863 else:
5889 else:
5864 common = commoninc
5890 common = commoninc
5865 if revs:
5891 if revs:
5866 revs = [repo.lookup(rev) for rev in revs]
5892 revs = [repo.lookup(rev) for rev in revs]
5867 repo.ui.pushbuffer()
5893 repo.ui.pushbuffer()
5868 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5894 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5869 commoninc=common)
5895 commoninc=common)
5870 repo.ui.popbuffer()
5896 repo.ui.popbuffer()
5871 return dest, dbranch, dother, outgoing
5897 return dest, dbranch, dother, outgoing
5872
5898
5873 if needsoutgoing:
5899 if needsoutgoing:
5874 dest, dbranch, dother, outgoing = getoutgoing()
5900 dest, dbranch, dother, outgoing = getoutgoing()
5875 else:
5901 else:
5876 dest = dbranch = dother = outgoing = None
5902 dest = dbranch = dother = outgoing = None
5877
5903
5878 if opts.get('remote'):
5904 if opts.get('remote'):
5879 t = []
5905 t = []
5880 if incoming:
5906 if incoming:
5881 t.append(_('1 or more incoming'))
5907 t.append(_('1 or more incoming'))
5882 o = outgoing.missing
5908 o = outgoing.missing
5883 if o:
5909 if o:
5884 t.append(_('%d outgoing') % len(o))
5910 t.append(_('%d outgoing') % len(o))
5885 other = dother or sother
5911 other = dother or sother
5886 if 'bookmarks' in other.listkeys('namespaces'):
5912 if 'bookmarks' in other.listkeys('namespaces'):
5887 counts = bookmarks.summary(repo, other)
5913 counts = bookmarks.summary(repo, other)
5888 if counts[0] > 0:
5914 if counts[0] > 0:
5889 t.append(_('%d incoming bookmarks') % counts[0])
5915 t.append(_('%d incoming bookmarks') % counts[0])
5890 if counts[1] > 0:
5916 if counts[1] > 0:
5891 t.append(_('%d outgoing bookmarks') % counts[1])
5917 t.append(_('%d outgoing bookmarks') % counts[1])
5892
5918
5893 if t:
5919 if t:
5894 # i18n: column positioning for "hg summary"
5920 # i18n: column positioning for "hg summary"
5895 ui.write(_('remote: %s\n') % (', '.join(t)))
5921 ui.write(_('remote: %s\n') % (', '.join(t)))
5896 else:
5922 else:
5897 # i18n: column positioning for "hg summary"
5923 # i18n: column positioning for "hg summary"
5898 ui.status(_('remote: (synced)\n'))
5924 ui.status(_('remote: (synced)\n'))
5899
5925
5900 cmdutil.summaryremotehooks(ui, repo, opts,
5926 cmdutil.summaryremotehooks(ui, repo, opts,
5901 ((source, sbranch, sother, commoninc),
5927 ((source, sbranch, sother, commoninc),
5902 (dest, dbranch, dother, outgoing)))
5928 (dest, dbranch, dother, outgoing)))
5903
5929
5904 @command('tag',
5930 @command('tag',
5905 [('f', 'force', None, _('force tag')),
5931 [('f', 'force', None, _('force tag')),
5906 ('l', 'local', None, _('make the tag local')),
5932 ('l', 'local', None, _('make the tag local')),
5907 ('r', 'rev', '', _('revision to tag'), _('REV')),
5933 ('r', 'rev', '', _('revision to tag'), _('REV')),
5908 ('', 'remove', None, _('remove a tag')),
5934 ('', 'remove', None, _('remove a tag')),
5909 # -l/--local is already there, commitopts cannot be used
5935 # -l/--local is already there, commitopts cannot be used
5910 ('e', 'edit', None, _('invoke editor on commit messages')),
5936 ('e', 'edit', None, _('invoke editor on commit messages')),
5911 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
5937 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
5912 ] + commitopts2,
5938 ] + commitopts2,
5913 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
5939 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
5914 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
5940 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
5915 def tag(ui, repo, name1, *names, **opts):
5941 def tag(ui, repo, name1, *names, **opts):
5916 """add one or more tags for the current or given revision
5942 """add one or more tags for the current or given revision
5917
5943
5918 Name a particular revision using <name>.
5944 Name a particular revision using <name>.
5919
5945
5920 Tags are used to name particular revisions of the repository and are
5946 Tags are used to name particular revisions of the repository and are
5921 very useful to compare different revisions, to go back to significant
5947 very useful to compare different revisions, to go back to significant
5922 earlier versions or to mark branch points as releases, etc. Changing
5948 earlier versions or to mark branch points as releases, etc. Changing
5923 an existing tag is normally disallowed; use -f/--force to override.
5949 an existing tag is normally disallowed; use -f/--force to override.
5924
5950
5925 If no revision is given, the parent of the working directory is
5951 If no revision is given, the parent of the working directory is
5926 used.
5952 used.
5927
5953
5928 To facilitate version control, distribution, and merging of tags,
5954 To facilitate version control, distribution, and merging of tags,
5929 they are stored as a file named ".hgtags" which is managed similarly
5955 they are stored as a file named ".hgtags" which is managed similarly
5930 to other project files and can be hand-edited if necessary. This
5956 to other project files and can be hand-edited if necessary. This
5931 also means that tagging creates a new commit. The file
5957 also means that tagging creates a new commit. The file
5932 ".hg/localtags" is used for local tags (not shared among
5958 ".hg/localtags" is used for local tags (not shared among
5933 repositories).
5959 repositories).
5934
5960
5935 Tag commits are usually made at the head of a branch. If the parent
5961 Tag commits are usually made at the head of a branch. If the parent
5936 of the working directory is not a branch head, :hg:`tag` aborts; use
5962 of the working directory is not a branch head, :hg:`tag` aborts; use
5937 -f/--force to force the tag commit to be based on a non-head
5963 -f/--force to force the tag commit to be based on a non-head
5938 changeset.
5964 changeset.
5939
5965
5940 See :hg:`help dates` for a list of formats valid for -d/--date.
5966 See :hg:`help dates` for a list of formats valid for -d/--date.
5941
5967
5942 Since tag names have priority over branch names during revision
5968 Since tag names have priority over branch names during revision
5943 lookup, using an existing branch name as a tag name is discouraged.
5969 lookup, using an existing branch name as a tag name is discouraged.
5944
5970
5945 Returns 0 on success.
5971 Returns 0 on success.
5946 """
5972 """
5947 opts = pycompat.byteskwargs(opts)
5973 opts = pycompat.byteskwargs(opts)
5948 with repo.wlock(), repo.lock():
5974 with repo.wlock(), repo.lock():
5949 rev_ = "."
5975 rev_ = "."
5950 names = [t.strip() for t in (name1,) + names]
5976 names = [t.strip() for t in (name1,) + names]
5951 if len(names) != len(set(names)):
5977 if len(names) != len(set(names)):
5952 raise error.Abort(_('tag names must be unique'))
5978 raise error.Abort(_('tag names must be unique'))
5953 for n in names:
5979 for n in names:
5954 scmutil.checknewlabel(repo, n, 'tag')
5980 scmutil.checknewlabel(repo, n, 'tag')
5955 if not n:
5981 if not n:
5956 raise error.Abort(_('tag names cannot consist entirely of '
5982 raise error.Abort(_('tag names cannot consist entirely of '
5957 'whitespace'))
5983 'whitespace'))
5958 if opts.get('rev') and opts.get('remove'):
5984 if opts.get('rev') and opts.get('remove'):
5959 raise error.Abort(_("--rev and --remove are incompatible"))
5985 raise error.Abort(_("--rev and --remove are incompatible"))
5960 if opts.get('rev'):
5986 if opts.get('rev'):
5961 rev_ = opts['rev']
5987 rev_ = opts['rev']
5962 message = opts.get('message')
5988 message = opts.get('message')
5963 if opts.get('remove'):
5989 if opts.get('remove'):
5964 if opts.get('local'):
5990 if opts.get('local'):
5965 expectedtype = 'local'
5991 expectedtype = 'local'
5966 else:
5992 else:
5967 expectedtype = 'global'
5993 expectedtype = 'global'
5968
5994
5969 for n in names:
5995 for n in names:
5970 if repo.tagtype(n) == 'global':
5996 if repo.tagtype(n) == 'global':
5971 alltags = tagsmod.findglobaltags(ui, repo)
5997 alltags = tagsmod.findglobaltags(ui, repo)
5972 if alltags[n][0] == nullid:
5998 if alltags[n][0] == nullid:
5973 raise error.Abort(_("tag '%s' is already removed") % n)
5999 raise error.Abort(_("tag '%s' is already removed") % n)
5974 if not repo.tagtype(n):
6000 if not repo.tagtype(n):
5975 raise error.Abort(_("tag '%s' does not exist") % n)
6001 raise error.Abort(_("tag '%s' does not exist") % n)
5976 if repo.tagtype(n) != expectedtype:
6002 if repo.tagtype(n) != expectedtype:
5977 if expectedtype == 'global':
6003 if expectedtype == 'global':
5978 raise error.Abort(_("tag '%s' is not a global tag") % n)
6004 raise error.Abort(_("tag '%s' is not a global tag") % n)
5979 else:
6005 else:
5980 raise error.Abort(_("tag '%s' is not a local tag") % n)
6006 raise error.Abort(_("tag '%s' is not a local tag") % n)
5981 rev_ = 'null'
6007 rev_ = 'null'
5982 if not message:
6008 if not message:
5983 # we don't translate commit messages
6009 # we don't translate commit messages
5984 message = 'Removed tag %s' % ', '.join(names)
6010 message = 'Removed tag %s' % ', '.join(names)
5985 elif not opts.get('force'):
6011 elif not opts.get('force'):
5986 for n in names:
6012 for n in names:
5987 if n in repo.tags():
6013 if n in repo.tags():
5988 raise error.Abort(_("tag '%s' already exists "
6014 raise error.Abort(_("tag '%s' already exists "
5989 "(use -f to force)") % n)
6015 "(use -f to force)") % n)
5990 if not opts.get('local'):
6016 if not opts.get('local'):
5991 p1, p2 = repo.dirstate.parents()
6017 p1, p2 = repo.dirstate.parents()
5992 if p2 != nullid:
6018 if p2 != nullid:
5993 raise error.Abort(_('uncommitted merge'))
6019 raise error.Abort(_('uncommitted merge'))
5994 bheads = repo.branchheads()
6020 bheads = repo.branchheads()
5995 if not opts.get('force') and bheads and p1 not in bheads:
6021 if not opts.get('force') and bheads and p1 not in bheads:
5996 raise error.Abort(_('working directory is not at a branch head '
6022 raise error.Abort(_('working directory is not at a branch head '
5997 '(use -f to force)'))
6023 '(use -f to force)'))
5998 node = scmutil.revsingle(repo, rev_).node()
6024 node = scmutil.revsingle(repo, rev_).node()
5999
6025
6000 if not message:
6026 if not message:
6001 # we don't translate commit messages
6027 # we don't translate commit messages
6002 message = ('Added tag %s for changeset %s' %
6028 message = ('Added tag %s for changeset %s' %
6003 (', '.join(names), short(node)))
6029 (', '.join(names), short(node)))
6004
6030
6005 date = opts.get('date')
6031 date = opts.get('date')
6006 if date:
6032 if date:
6007 date = dateutil.parsedate(date)
6033 date = dateutil.parsedate(date)
6008
6034
6009 if opts.get('remove'):
6035 if opts.get('remove'):
6010 editform = 'tag.remove'
6036 editform = 'tag.remove'
6011 else:
6037 else:
6012 editform = 'tag.add'
6038 editform = 'tag.add'
6013 editor = cmdutil.getcommiteditor(editform=editform,
6039 editor = cmdutil.getcommiteditor(editform=editform,
6014 **pycompat.strkwargs(opts))
6040 **pycompat.strkwargs(opts))
6015
6041
6016 # don't allow tagging the null rev
6042 # don't allow tagging the null rev
6017 if (not opts.get('remove') and
6043 if (not opts.get('remove') and
6018 scmutil.revsingle(repo, rev_).rev() == nullrev):
6044 scmutil.revsingle(repo, rev_).rev() == nullrev):
6019 raise error.Abort(_("cannot tag null revision"))
6045 raise error.Abort(_("cannot tag null revision"))
6020
6046
6021 tagsmod.tag(repo, names, node, message, opts.get('local'),
6047 tagsmod.tag(repo, names, node, message, opts.get('local'),
6022 opts.get('user'), date, editor=editor)
6048 opts.get('user'), date, editor=editor)
6023
6049
6024 @command(
6050 @command(
6025 'tags', formatteropts, '',
6051 'tags', formatteropts, '',
6026 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
6052 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
6027 intents={INTENT_READONLY})
6053 intents={INTENT_READONLY})
6028 def tags(ui, repo, **opts):
6054 def tags(ui, repo, **opts):
6029 """list repository tags
6055 """list repository tags
6030
6056
6031 This lists both regular and local tags. When the -v/--verbose
6057 This lists both regular and local tags. When the -v/--verbose
6032 switch is used, a third column "local" is printed for local tags.
6058 switch is used, a third column "local" is printed for local tags.
6033 When the -q/--quiet switch is used, only the tag name is printed.
6059 When the -q/--quiet switch is used, only the tag name is printed.
6034
6060
6035 .. container:: verbose
6061 .. container:: verbose
6036
6062
6037 Template:
6063 Template:
6038
6064
6039 The following keywords are supported in addition to the common template
6065 The following keywords are supported in addition to the common template
6040 keywords and functions such as ``{tag}``. See also
6066 keywords and functions such as ``{tag}``. See also
6041 :hg:`help templates`.
6067 :hg:`help templates`.
6042
6068
6043 :type: String. ``local`` for local tags.
6069 :type: String. ``local`` for local tags.
6044
6070
6045 Returns 0 on success.
6071 Returns 0 on success.
6046 """
6072 """
6047
6073
6048 opts = pycompat.byteskwargs(opts)
6074 opts = pycompat.byteskwargs(opts)
6049 ui.pager('tags')
6075 ui.pager('tags')
6050 fm = ui.formatter('tags', opts)
6076 fm = ui.formatter('tags', opts)
6051 hexfunc = fm.hexfunc
6077 hexfunc = fm.hexfunc
6052
6078
6053 for t, n in reversed(repo.tagslist()):
6079 for t, n in reversed(repo.tagslist()):
6054 hn = hexfunc(n)
6080 hn = hexfunc(n)
6055 label = 'tags.normal'
6081 label = 'tags.normal'
6056 tagtype = ''
6082 tagtype = ''
6057 if repo.tagtype(t) == 'local':
6083 if repo.tagtype(t) == 'local':
6058 label = 'tags.local'
6084 label = 'tags.local'
6059 tagtype = 'local'
6085 tagtype = 'local'
6060
6086
6061 fm.startitem()
6087 fm.startitem()
6062 fm.context(repo=repo)
6088 fm.context(repo=repo)
6063 fm.write('tag', '%s', t, label=label)
6089 fm.write('tag', '%s', t, label=label)
6064 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6090 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6065 fm.condwrite(not ui.quiet, 'rev node', fmt,
6091 fm.condwrite(not ui.quiet, 'rev node', fmt,
6066 repo.changelog.rev(n), hn, label=label)
6092 repo.changelog.rev(n), hn, label=label)
6067 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6093 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6068 tagtype, label=label)
6094 tagtype, label=label)
6069 fm.plain('\n')
6095 fm.plain('\n')
6070 fm.end()
6096 fm.end()
6071
6097
6072 @command('tip',
6098 @command('tip',
6073 [('p', 'patch', None, _('show patch')),
6099 [('p', 'patch', None, _('show patch')),
6074 ('g', 'git', None, _('use git extended diff format')),
6100 ('g', 'git', None, _('use git extended diff format')),
6075 ] + templateopts,
6101 ] + templateopts,
6076 _('[-p] [-g]'),
6102 _('[-p] [-g]'),
6077 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
6103 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
6078 def tip(ui, repo, **opts):
6104 def tip(ui, repo, **opts):
6079 """show the tip revision (DEPRECATED)
6105 """show the tip revision (DEPRECATED)
6080
6106
6081 The tip revision (usually just called the tip) is the changeset
6107 The tip revision (usually just called the tip) is the changeset
6082 most recently added to the repository (and therefore the most
6108 most recently added to the repository (and therefore the most
6083 recently changed head).
6109 recently changed head).
6084
6110
6085 If you have just made a commit, that commit will be the tip. If
6111 If you have just made a commit, that commit will be the tip. If
6086 you have just pulled changes from another repository, the tip of
6112 you have just pulled changes from another repository, the tip of
6087 that repository becomes the current tip. The "tip" tag is special
6113 that repository becomes the current tip. The "tip" tag is special
6088 and cannot be renamed or assigned to a different changeset.
6114 and cannot be renamed or assigned to a different changeset.
6089
6115
6090 This command is deprecated, please use :hg:`heads` instead.
6116 This command is deprecated, please use :hg:`heads` instead.
6091
6117
6092 Returns 0 on success.
6118 Returns 0 on success.
6093 """
6119 """
6094 opts = pycompat.byteskwargs(opts)
6120 opts = pycompat.byteskwargs(opts)
6095 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
6121 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
6096 displayer.show(repo['tip'])
6122 displayer.show(repo['tip'])
6097 displayer.close()
6123 displayer.close()
6098
6124
6099 @command('unbundle',
6125 @command('unbundle',
6100 [('u', 'update', None,
6126 [('u', 'update', None,
6101 _('update to new branch head if changesets were unbundled'))],
6127 _('update to new branch head if changesets were unbundled'))],
6102 _('[-u] FILE...'),
6128 _('[-u] FILE...'),
6103 helpcategory=command.CATEGORY_IMPORT_EXPORT)
6129 helpcategory=command.CATEGORY_IMPORT_EXPORT)
6104 def unbundle(ui, repo, fname1, *fnames, **opts):
6130 def unbundle(ui, repo, fname1, *fnames, **opts):
6105 """apply one or more bundle files
6131 """apply one or more bundle files
6106
6132
6107 Apply one or more bundle files generated by :hg:`bundle`.
6133 Apply one or more bundle files generated by :hg:`bundle`.
6108
6134
6109 Returns 0 on success, 1 if an update has unresolved files.
6135 Returns 0 on success, 1 if an update has unresolved files.
6110 """
6136 """
6111 fnames = (fname1,) + fnames
6137 fnames = (fname1,) + fnames
6112
6138
6113 with repo.lock():
6139 with repo.lock():
6114 for fname in fnames:
6140 for fname in fnames:
6115 f = hg.openpath(ui, fname)
6141 f = hg.openpath(ui, fname)
6116 gen = exchange.readbundle(ui, f, fname)
6142 gen = exchange.readbundle(ui, f, fname)
6117 if isinstance(gen, streamclone.streamcloneapplier):
6143 if isinstance(gen, streamclone.streamcloneapplier):
6118 raise error.Abort(
6144 raise error.Abort(
6119 _('packed bundles cannot be applied with '
6145 _('packed bundles cannot be applied with '
6120 '"hg unbundle"'),
6146 '"hg unbundle"'),
6121 hint=_('use "hg debugapplystreamclonebundle"'))
6147 hint=_('use "hg debugapplystreamclonebundle"'))
6122 url = 'bundle:' + fname
6148 url = 'bundle:' + fname
6123 try:
6149 try:
6124 txnname = 'unbundle'
6150 txnname = 'unbundle'
6125 if not isinstance(gen, bundle2.unbundle20):
6151 if not isinstance(gen, bundle2.unbundle20):
6126 txnname = 'unbundle\n%s' % util.hidepassword(url)
6152 txnname = 'unbundle\n%s' % util.hidepassword(url)
6127 with repo.transaction(txnname) as tr:
6153 with repo.transaction(txnname) as tr:
6128 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6154 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6129 url=url)
6155 url=url)
6130 except error.BundleUnknownFeatureError as exc:
6156 except error.BundleUnknownFeatureError as exc:
6131 raise error.Abort(
6157 raise error.Abort(
6132 _('%s: unknown bundle feature, %s') % (fname, exc),
6158 _('%s: unknown bundle feature, %s') % (fname, exc),
6133 hint=_("see https://mercurial-scm.org/"
6159 hint=_("see https://mercurial-scm.org/"
6134 "wiki/BundleFeature for more "
6160 "wiki/BundleFeature for more "
6135 "information"))
6161 "information"))
6136 modheads = bundle2.combinechangegroupresults(op)
6162 modheads = bundle2.combinechangegroupresults(op)
6137
6163
6138 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
6164 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
6139
6165
6140 @command('unshelve',
6166 @command('unshelve',
6141 [('a', 'abort', None,
6167 [('a', 'abort', None,
6142 _('abort an incomplete unshelve operation')),
6168 _('abort an incomplete unshelve operation')),
6143 ('c', 'continue', None,
6169 ('c', 'continue', None,
6144 _('continue an incomplete unshelve operation')),
6170 _('continue an incomplete unshelve operation')),
6145 ('k', 'keep', None,
6171 ('k', 'keep', None,
6146 _('keep shelve after unshelving')),
6172 _('keep shelve after unshelving')),
6147 ('n', 'name', '',
6173 ('n', 'name', '',
6148 _('restore shelved change with given name'), _('NAME')),
6174 _('restore shelved change with given name'), _('NAME')),
6149 ('t', 'tool', '', _('specify merge tool')),
6175 ('t', 'tool', '', _('specify merge tool')),
6150 ('', 'date', '',
6176 ('', 'date', '',
6151 _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
6177 _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
6152 _('hg unshelve [[-n] SHELVED]'),
6178 _('hg unshelve [[-n] SHELVED]'),
6153 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
6179 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
6154 def unshelve(ui, repo, *shelved, **opts):
6180 def unshelve(ui, repo, *shelved, **opts):
6155 """restore a shelved change to the working directory
6181 """restore a shelved change to the working directory
6156
6182
6157 This command accepts an optional name of a shelved change to
6183 This command accepts an optional name of a shelved change to
6158 restore. If none is given, the most recent shelved change is used.
6184 restore. If none is given, the most recent shelved change is used.
6159
6185
6160 If a shelved change is applied successfully, the bundle that
6186 If a shelved change is applied successfully, the bundle that
6161 contains the shelved changes is moved to a backup location
6187 contains the shelved changes is moved to a backup location
6162 (.hg/shelve-backup).
6188 (.hg/shelve-backup).
6163
6189
6164 Since you can restore a shelved change on top of an arbitrary
6190 Since you can restore a shelved change on top of an arbitrary
6165 commit, it is possible that unshelving will result in a conflict
6191 commit, it is possible that unshelving will result in a conflict
6166 between your changes and the commits you are unshelving onto. If
6192 between your changes and the commits you are unshelving onto. If
6167 this occurs, you must resolve the conflict, then use
6193 this occurs, you must resolve the conflict, then use
6168 ``--continue`` to complete the unshelve operation. (The bundle
6194 ``--continue`` to complete the unshelve operation. (The bundle
6169 will not be moved until you successfully complete the unshelve.)
6195 will not be moved until you successfully complete the unshelve.)
6170
6196
6171 (Alternatively, you can use ``--abort`` to abandon an unshelve
6197 (Alternatively, you can use ``--abort`` to abandon an unshelve
6172 that causes a conflict. This reverts the unshelved changes, and
6198 that causes a conflict. This reverts the unshelved changes, and
6173 leaves the bundle in place.)
6199 leaves the bundle in place.)
6174
6200
6175 If bare shelved change (when no files are specified, without interactive,
6201 If bare shelved change (when no files are specified, without interactive,
6176 include and exclude option) was done on newly created branch it would
6202 include and exclude option) was done on newly created branch it would
6177 restore branch information to the working directory.
6203 restore branch information to the working directory.
6178
6204
6179 After a successful unshelve, the shelved changes are stored in a
6205 After a successful unshelve, the shelved changes are stored in a
6180 backup directory. Only the N most recent backups are kept. N
6206 backup directory. Only the N most recent backups are kept. N
6181 defaults to 10 but can be overridden using the ``shelve.maxbackups``
6207 defaults to 10 but can be overridden using the ``shelve.maxbackups``
6182 configuration option.
6208 configuration option.
6183
6209
6184 .. container:: verbose
6210 .. container:: verbose
6185
6211
6186 Timestamp in seconds is used to decide order of backups. More
6212 Timestamp in seconds is used to decide order of backups. More
6187 than ``maxbackups`` backups are kept, if same timestamp
6213 than ``maxbackups`` backups are kept, if same timestamp
6188 prevents from deciding exact order of them, for safety.
6214 prevents from deciding exact order of them, for safety.
6189 """
6215 """
6190 with repo.wlock():
6216 with repo.wlock():
6191 return shelvemod.dounshelve(ui, repo, *shelved, **opts)
6217 return shelvemod.dounshelve(ui, repo, *shelved, **opts)
6192
6218
6193 statemod.addunfinished(
6219 statemod.addunfinished(
6194 'unshelve', fname='shelvedstate', continueflag=True,
6220 'unshelve', fname='shelvedstate', continueflag=True,
6195 abortfunc=shelvemod.hgabortunshelve,
6221 abortfunc=shelvemod.hgabortunshelve,
6196 cmdmsg=_('unshelve already in progress'),
6222 cmdmsg=_('unshelve already in progress'),
6197 )
6223 )
6198
6224
6199 @command('update|up|checkout|co',
6225 @command('update|up|checkout|co',
6200 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6226 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6201 ('c', 'check', None, _('require clean working directory')),
6227 ('c', 'check', None, _('require clean working directory')),
6202 ('m', 'merge', None, _('merge uncommitted changes')),
6228 ('m', 'merge', None, _('merge uncommitted changes')),
6203 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6229 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6204 ('r', 'rev', '', _('revision'), _('REV'))
6230 ('r', 'rev', '', _('revision'), _('REV'))
6205 ] + mergetoolopts,
6231 ] + mergetoolopts,
6206 _('[-C|-c|-m] [-d DATE] [[-r] REV]'),
6232 _('[-C|-c|-m] [-d DATE] [[-r] REV]'),
6207 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6233 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6208 helpbasic=True)
6234 helpbasic=True)
6209 def update(ui, repo, node=None, **opts):
6235 def update(ui, repo, node=None, **opts):
6210 """update working directory (or switch revisions)
6236 """update working directory (or switch revisions)
6211
6237
6212 Update the repository's working directory to the specified
6238 Update the repository's working directory to the specified
6213 changeset. If no changeset is specified, update to the tip of the
6239 changeset. If no changeset is specified, update to the tip of the
6214 current named branch and move the active bookmark (see :hg:`help
6240 current named branch and move the active bookmark (see :hg:`help
6215 bookmarks`).
6241 bookmarks`).
6216
6242
6217 Update sets the working directory's parent revision to the specified
6243 Update sets the working directory's parent revision to the specified
6218 changeset (see :hg:`help parents`).
6244 changeset (see :hg:`help parents`).
6219
6245
6220 If the changeset is not a descendant or ancestor of the working
6246 If the changeset is not a descendant or ancestor of the working
6221 directory's parent and there are uncommitted changes, the update is
6247 directory's parent and there are uncommitted changes, the update is
6222 aborted. With the -c/--check option, the working directory is checked
6248 aborted. With the -c/--check option, the working directory is checked
6223 for uncommitted changes; if none are found, the working directory is
6249 for uncommitted changes; if none are found, the working directory is
6224 updated to the specified changeset.
6250 updated to the specified changeset.
6225
6251
6226 .. container:: verbose
6252 .. container:: verbose
6227
6253
6228 The -C/--clean, -c/--check, and -m/--merge options control what
6254 The -C/--clean, -c/--check, and -m/--merge options control what
6229 happens if the working directory contains uncommitted changes.
6255 happens if the working directory contains uncommitted changes.
6230 At most of one of them can be specified.
6256 At most of one of them can be specified.
6231
6257
6232 1. If no option is specified, and if
6258 1. If no option is specified, and if
6233 the requested changeset is an ancestor or descendant of
6259 the requested changeset is an ancestor or descendant of
6234 the working directory's parent, the uncommitted changes
6260 the working directory's parent, the uncommitted changes
6235 are merged into the requested changeset and the merged
6261 are merged into the requested changeset and the merged
6236 result is left uncommitted. If the requested changeset is
6262 result is left uncommitted. If the requested changeset is
6237 not an ancestor or descendant (that is, it is on another
6263 not an ancestor or descendant (that is, it is on another
6238 branch), the update is aborted and the uncommitted changes
6264 branch), the update is aborted and the uncommitted changes
6239 are preserved.
6265 are preserved.
6240
6266
6241 2. With the -m/--merge option, the update is allowed even if the
6267 2. With the -m/--merge option, the update is allowed even if the
6242 requested changeset is not an ancestor or descendant of
6268 requested changeset is not an ancestor or descendant of
6243 the working directory's parent.
6269 the working directory's parent.
6244
6270
6245 3. With the -c/--check option, the update is aborted and the
6271 3. With the -c/--check option, the update is aborted and the
6246 uncommitted changes are preserved.
6272 uncommitted changes are preserved.
6247
6273
6248 4. With the -C/--clean option, uncommitted changes are discarded and
6274 4. With the -C/--clean option, uncommitted changes are discarded and
6249 the working directory is updated to the requested changeset.
6275 the working directory is updated to the requested changeset.
6250
6276
6251 To cancel an uncommitted merge (and lose your changes), use
6277 To cancel an uncommitted merge (and lose your changes), use
6252 :hg:`merge --abort`.
6278 :hg:`merge --abort`.
6253
6279
6254 Use null as the changeset to remove the working directory (like
6280 Use null as the changeset to remove the working directory (like
6255 :hg:`clone -U`).
6281 :hg:`clone -U`).
6256
6282
6257 If you want to revert just one file to an older revision, use
6283 If you want to revert just one file to an older revision, use
6258 :hg:`revert [-r REV] NAME`.
6284 :hg:`revert [-r REV] NAME`.
6259
6285
6260 See :hg:`help dates` for a list of formats valid for -d/--date.
6286 See :hg:`help dates` for a list of formats valid for -d/--date.
6261
6287
6262 Returns 0 on success, 1 if there are unresolved files.
6288 Returns 0 on success, 1 if there are unresolved files.
6263 """
6289 """
6264 rev = opts.get(r'rev')
6290 rev = opts.get(r'rev')
6265 date = opts.get(r'date')
6291 date = opts.get(r'date')
6266 clean = opts.get(r'clean')
6292 clean = opts.get(r'clean')
6267 check = opts.get(r'check')
6293 check = opts.get(r'check')
6268 merge = opts.get(r'merge')
6294 merge = opts.get(r'merge')
6269 if rev and node:
6295 if rev and node:
6270 raise error.Abort(_("please specify just one revision"))
6296 raise error.Abort(_("please specify just one revision"))
6271
6297
6272 if ui.configbool('commands', 'update.requiredest'):
6298 if ui.configbool('commands', 'update.requiredest'):
6273 if not node and not rev and not date:
6299 if not node and not rev and not date:
6274 raise error.Abort(_('you must specify a destination'),
6300 raise error.Abort(_('you must specify a destination'),
6275 hint=_('for example: hg update ".::"'))
6301 hint=_('for example: hg update ".::"'))
6276
6302
6277 if rev is None or rev == '':
6303 if rev is None or rev == '':
6278 rev = node
6304 rev = node
6279
6305
6280 if date and rev is not None:
6306 if date and rev is not None:
6281 raise error.Abort(_("you can't specify a revision and a date"))
6307 raise error.Abort(_("you can't specify a revision and a date"))
6282
6308
6283 if len([x for x in (clean, check, merge) if x]) > 1:
6309 if len([x for x in (clean, check, merge) if x]) > 1:
6284 raise error.Abort(_("can only specify one of -C/--clean, -c/--check, "
6310 raise error.Abort(_("can only specify one of -C/--clean, -c/--check, "
6285 "or -m/--merge"))
6311 "or -m/--merge"))
6286
6312
6287 updatecheck = None
6313 updatecheck = None
6288 if check:
6314 if check:
6289 updatecheck = 'abort'
6315 updatecheck = 'abort'
6290 elif merge:
6316 elif merge:
6291 updatecheck = 'none'
6317 updatecheck = 'none'
6292
6318
6293 with repo.wlock():
6319 with repo.wlock():
6294 cmdutil.clearunfinished(repo)
6320 cmdutil.clearunfinished(repo)
6295 if date:
6321 if date:
6296 rev = cmdutil.finddate(ui, repo, date)
6322 rev = cmdutil.finddate(ui, repo, date)
6297
6323
6298 # if we defined a bookmark, we have to remember the original name
6324 # if we defined a bookmark, we have to remember the original name
6299 brev = rev
6325 brev = rev
6300 if rev:
6326 if rev:
6301 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
6327 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
6302 ctx = scmutil.revsingle(repo, rev, default=None)
6328 ctx = scmutil.revsingle(repo, rev, default=None)
6303 rev = ctx.rev()
6329 rev = ctx.rev()
6304 hidden = ctx.hidden()
6330 hidden = ctx.hidden()
6305 overrides = {('ui', 'forcemerge'): opts.get(r'tool', '')}
6331 overrides = {('ui', 'forcemerge'): opts.get(r'tool', '')}
6306 with ui.configoverride(overrides, 'update'):
6332 with ui.configoverride(overrides, 'update'):
6307 ret = hg.updatetotally(ui, repo, rev, brev, clean=clean,
6333 ret = hg.updatetotally(ui, repo, rev, brev, clean=clean,
6308 updatecheck=updatecheck)
6334 updatecheck=updatecheck)
6309 if hidden:
6335 if hidden:
6310 ctxstr = ctx.hex()[:12]
6336 ctxstr = ctx.hex()[:12]
6311 ui.warn(_("updated to hidden changeset %s\n") % ctxstr)
6337 ui.warn(_("updated to hidden changeset %s\n") % ctxstr)
6312
6338
6313 if ctx.obsolete():
6339 if ctx.obsolete():
6314 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
6340 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
6315 ui.warn("(%s)\n" % obsfatemsg)
6341 ui.warn("(%s)\n" % obsfatemsg)
6316 return ret
6342 return ret
6317
6343
6318 @command('verify',
6344 @command('verify',
6319 [('', 'full', False, 'perform more checks (EXPERIMENTAL)')],
6345 [('', 'full', False, 'perform more checks (EXPERIMENTAL)')],
6320 helpcategory=command.CATEGORY_MAINTENANCE)
6346 helpcategory=command.CATEGORY_MAINTENANCE)
6321 def verify(ui, repo, **opts):
6347 def verify(ui, repo, **opts):
6322 """verify the integrity of the repository
6348 """verify the integrity of the repository
6323
6349
6324 Verify the integrity of the current repository.
6350 Verify the integrity of the current repository.
6325
6351
6326 This will perform an extensive check of the repository's
6352 This will perform an extensive check of the repository's
6327 integrity, validating the hashes and checksums of each entry in
6353 integrity, validating the hashes and checksums of each entry in
6328 the changelog, manifest, and tracked files, as well as the
6354 the changelog, manifest, and tracked files, as well as the
6329 integrity of their crosslinks and indices.
6355 integrity of their crosslinks and indices.
6330
6356
6331 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6357 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6332 for more information about recovery from corruption of the
6358 for more information about recovery from corruption of the
6333 repository.
6359 repository.
6334
6360
6335 Returns 0 on success, 1 if errors are encountered.
6361 Returns 0 on success, 1 if errors are encountered.
6336 """
6362 """
6337 opts = pycompat.byteskwargs(opts)
6363 opts = pycompat.byteskwargs(opts)
6338
6364
6339 level = None
6365 level = None
6340 if opts['full']:
6366 if opts['full']:
6341 level = verifymod.VERIFY_FULL
6367 level = verifymod.VERIFY_FULL
6342 return hg.verify(repo, level)
6368 return hg.verify(repo, level)
6343
6369
6344 @command(
6370 @command(
6345 'version', [] + formatteropts, helpcategory=command.CATEGORY_HELP,
6371 'version', [] + formatteropts, helpcategory=command.CATEGORY_HELP,
6346 norepo=True, intents={INTENT_READONLY})
6372 norepo=True, intents={INTENT_READONLY})
6347 def version_(ui, **opts):
6373 def version_(ui, **opts):
6348 """output version and copyright information
6374 """output version and copyright information
6349
6375
6350 .. container:: verbose
6376 .. container:: verbose
6351
6377
6352 Template:
6378 Template:
6353
6379
6354 The following keywords are supported. See also :hg:`help templates`.
6380 The following keywords are supported. See also :hg:`help templates`.
6355
6381
6356 :extensions: List of extensions.
6382 :extensions: List of extensions.
6357 :ver: String. Version number.
6383 :ver: String. Version number.
6358
6384
6359 And each entry of ``{extensions}`` provides the following sub-keywords
6385 And each entry of ``{extensions}`` provides the following sub-keywords
6360 in addition to ``{ver}``.
6386 in addition to ``{ver}``.
6361
6387
6362 :bundled: Boolean. True if included in the release.
6388 :bundled: Boolean. True if included in the release.
6363 :name: String. Extension name.
6389 :name: String. Extension name.
6364 """
6390 """
6365 opts = pycompat.byteskwargs(opts)
6391 opts = pycompat.byteskwargs(opts)
6366 if ui.verbose:
6392 if ui.verbose:
6367 ui.pager('version')
6393 ui.pager('version')
6368 fm = ui.formatter("version", opts)
6394 fm = ui.formatter("version", opts)
6369 fm.startitem()
6395 fm.startitem()
6370 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
6396 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
6371 util.version())
6397 util.version())
6372 license = _(
6398 license = _(
6373 "(see https://mercurial-scm.org for more information)\n"
6399 "(see https://mercurial-scm.org for more information)\n"
6374 "\nCopyright (C) 2005-2019 Matt Mackall and others\n"
6400 "\nCopyright (C) 2005-2019 Matt Mackall and others\n"
6375 "This is free software; see the source for copying conditions. "
6401 "This is free software; see the source for copying conditions. "
6376 "There is NO\nwarranty; "
6402 "There is NO\nwarranty; "
6377 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6403 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6378 )
6404 )
6379 if not ui.quiet:
6405 if not ui.quiet:
6380 fm.plain(license)
6406 fm.plain(license)
6381
6407
6382 if ui.verbose:
6408 if ui.verbose:
6383 fm.plain(_("\nEnabled extensions:\n\n"))
6409 fm.plain(_("\nEnabled extensions:\n\n"))
6384 # format names and versions into columns
6410 # format names and versions into columns
6385 names = []
6411 names = []
6386 vers = []
6412 vers = []
6387 isinternals = []
6413 isinternals = []
6388 for name, module in extensions.extensions():
6414 for name, module in extensions.extensions():
6389 names.append(name)
6415 names.append(name)
6390 vers.append(extensions.moduleversion(module) or None)
6416 vers.append(extensions.moduleversion(module) or None)
6391 isinternals.append(extensions.ismoduleinternal(module))
6417 isinternals.append(extensions.ismoduleinternal(module))
6392 fn = fm.nested("extensions", tmpl='{name}\n')
6418 fn = fm.nested("extensions", tmpl='{name}\n')
6393 if names:
6419 if names:
6394 namefmt = " %%-%ds " % max(len(n) for n in names)
6420 namefmt = " %%-%ds " % max(len(n) for n in names)
6395 places = [_("external"), _("internal")]
6421 places = [_("external"), _("internal")]
6396 for n, v, p in zip(names, vers, isinternals):
6422 for n, v, p in zip(names, vers, isinternals):
6397 fn.startitem()
6423 fn.startitem()
6398 fn.condwrite(ui.verbose, "name", namefmt, n)
6424 fn.condwrite(ui.verbose, "name", namefmt, n)
6399 if ui.verbose:
6425 if ui.verbose:
6400 fn.plain("%s " % places[p])
6426 fn.plain("%s " % places[p])
6401 fn.data(bundled=p)
6427 fn.data(bundled=p)
6402 fn.condwrite(ui.verbose and v, "ver", "%s", v)
6428 fn.condwrite(ui.verbose and v, "ver", "%s", v)
6403 if ui.verbose:
6429 if ui.verbose:
6404 fn.plain("\n")
6430 fn.plain("\n")
6405 fn.end()
6431 fn.end()
6406 fm.end()
6432 fm.end()
6407
6433
6408 def loadcmdtable(ui, name, cmdtable):
6434 def loadcmdtable(ui, name, cmdtable):
6409 """Load command functions from specified cmdtable
6435 """Load command functions from specified cmdtable
6410 """
6436 """
6411 overrides = [cmd for cmd in cmdtable if cmd in table]
6437 overrides = [cmd for cmd in cmdtable if cmd in table]
6412 if overrides:
6438 if overrides:
6413 ui.warn(_("extension '%s' overrides commands: %s\n")
6439 ui.warn(_("extension '%s' overrides commands: %s\n")
6414 % (name, " ".join(overrides)))
6440 % (name, " ".join(overrides)))
6415 table.update(cmdtable)
6441 table.update(cmdtable)
@@ -1,216 +1,220 b''
1 # state.py - writing and reading state files in Mercurial
1 # state.py - writing and reading state files in Mercurial
2 #
2 #
3 # Copyright 2018 Pulkit Goyal <pulkitmgoyal@gmail.com>
3 # Copyright 2018 Pulkit Goyal <pulkitmgoyal@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """
8 """
9 This file contains class to wrap the state for commands and other
9 This file contains class to wrap the state for commands and other
10 related logic.
10 related logic.
11
11
12 All the data related to the command state is stored as dictionary in the object.
12 All the data related to the command state is stored as dictionary in the object.
13 The class has methods using which the data can be stored to disk in a file under
13 The class has methods using which the data can be stored to disk in a file under
14 .hg/ directory.
14 .hg/ directory.
15
15
16 We store the data on disk in cbor, for which we use the CBOR format to encode
16 We store the data on disk in cbor, for which we use the CBOR format to encode
17 the data.
17 the data.
18 """
18 """
19
19
20 from __future__ import absolute_import
20 from __future__ import absolute_import
21
21
22 from .i18n import _
22 from .i18n import _
23
23
24 from . import (
24 from . import (
25 error,
25 error,
26 util,
26 util,
27 )
27 )
28 from .utils import (
28 from .utils import (
29 cborutil,
29 cborutil,
30 )
30 )
31
31
32 class cmdstate(object):
32 class cmdstate(object):
33 """a wrapper class to store the state of commands like `rebase`, `graft`,
33 """a wrapper class to store the state of commands like `rebase`, `graft`,
34 `histedit`, `shelve` etc. Extensions can also use this to write state files.
34 `histedit`, `shelve` etc. Extensions can also use this to write state files.
35
35
36 All the data for the state is stored in the form of key-value pairs in a
36 All the data for the state is stored in the form of key-value pairs in a
37 dictionary.
37 dictionary.
38
38
39 The class object can write all the data to a file in .hg/ directory and
39 The class object can write all the data to a file in .hg/ directory and
40 can populate the object data reading that file.
40 can populate the object data reading that file.
41
41
42 Uses cbor to serialize and deserialize data while writing and reading from
42 Uses cbor to serialize and deserialize data while writing and reading from
43 disk.
43 disk.
44 """
44 """
45
45
46 def __init__(self, repo, fname):
46 def __init__(self, repo, fname):
47 """ repo is the repo object
47 """ repo is the repo object
48 fname is the file name in which data should be stored in .hg directory
48 fname is the file name in which data should be stored in .hg directory
49 """
49 """
50 self._repo = repo
50 self._repo = repo
51 self.fname = fname
51 self.fname = fname
52
52
53 def read(self):
53 def read(self):
54 """read the existing state file and return a dict of data stored"""
54 """read the existing state file and return a dict of data stored"""
55 return self._read()
55 return self._read()
56
56
57 def save(self, version, data):
57 def save(self, version, data):
58 """write all the state data stored to .hg/<filename> file
58 """write all the state data stored to .hg/<filename> file
59
59
60 we use third-party library cbor to serialize data to write in the file.
60 we use third-party library cbor to serialize data to write in the file.
61 """
61 """
62 if not isinstance(version, int):
62 if not isinstance(version, int):
63 raise error.ProgrammingError("version of state file should be"
63 raise error.ProgrammingError("version of state file should be"
64 " an integer")
64 " an integer")
65
65
66 with self._repo.vfs(self.fname, 'wb', atomictemp=True) as fp:
66 with self._repo.vfs(self.fname, 'wb', atomictemp=True) as fp:
67 fp.write('%d\n' % version)
67 fp.write('%d\n' % version)
68 for chunk in cborutil.streamencode(data):
68 for chunk in cborutil.streamencode(data):
69 fp.write(chunk)
69 fp.write(chunk)
70
70
71 def _read(self):
71 def _read(self):
72 """reads the state file and returns a dictionary which contain
72 """reads the state file and returns a dictionary which contain
73 data in the same format as it was before storing"""
73 data in the same format as it was before storing"""
74 with self._repo.vfs(self.fname, 'rb') as fp:
74 with self._repo.vfs(self.fname, 'rb') as fp:
75 try:
75 try:
76 int(fp.readline())
76 int(fp.readline())
77 except ValueError:
77 except ValueError:
78 raise error.CorruptedState("unknown version of state file"
78 raise error.CorruptedState("unknown version of state file"
79 " found")
79 " found")
80
80
81 return cborutil.decodeall(fp.read())[0]
81 return cborutil.decodeall(fp.read())[0]
82
82
83 def delete(self):
83 def delete(self):
84 """drop the state file if exists"""
84 """drop the state file if exists"""
85 util.unlinkpath(self._repo.vfs.join(self.fname), ignoremissing=True)
85 util.unlinkpath(self._repo.vfs.join(self.fname), ignoremissing=True)
86
86
87 def exists(self):
87 def exists(self):
88 """check whether the state file exists or not"""
88 """check whether the state file exists or not"""
89 return self._repo.vfs.exists(self.fname)
89 return self._repo.vfs.exists(self.fname)
90
90
91 class _statecheck(object):
91 class _statecheck(object):
92 """a utility class that deals with multistep operations like graft,
92 """a utility class that deals with multistep operations like graft,
93 histedit, bisect, update etc and check whether such commands
93 histedit, bisect, update etc and check whether such commands
94 are in an unfinished conditition or not and return appropriate message
94 are in an unfinished conditition or not and return appropriate message
95 and hint.
95 and hint.
96 It also has the ability to register and determine the states of any new
96 It also has the ability to register and determine the states of any new
97 multistep operation or multistep command extension.
97 multistep operation or multistep command extension.
98 """
98 """
99
99
100 def __init__(self, opname, fname, clearable, allowcommit, reportonly,
100 def __init__(self, opname, fname, clearable, allowcommit, reportonly,
101 continueflag, stopflag, cmdmsg, cmdhint, statushint,
101 continueflag, stopflag, cmdmsg, cmdhint, statushint,
102 abortfunc):
102 abortfunc, continuefunc):
103 self._opname = opname
103 self._opname = opname
104 self._fname = fname
104 self._fname = fname
105 self._clearable = clearable
105 self._clearable = clearable
106 self._allowcommit = allowcommit
106 self._allowcommit = allowcommit
107 self._reportonly = reportonly
107 self._reportonly = reportonly
108 self._continueflag = continueflag
108 self._continueflag = continueflag
109 self._stopflag = stopflag
109 self._stopflag = stopflag
110 self._cmdmsg = cmdmsg
110 self._cmdmsg = cmdmsg
111 self._cmdhint = cmdhint
111 self._cmdhint = cmdhint
112 self._statushint = statushint
112 self._statushint = statushint
113 self.abortfunc = abortfunc
113 self.abortfunc = abortfunc
114 self.continuefunc = continuefunc
114
115
115 def statusmsg(self):
116 def statusmsg(self):
116 """returns the hint message corresponding to the command for
117 """returns the hint message corresponding to the command for
117 hg status --verbose
118 hg status --verbose
118 """
119 """
119 if not self._statushint:
120 if not self._statushint:
120 hint = (_('To continue: hg %s --continue\n'
121 hint = (_('To continue: hg %s --continue\n'
121 'To abort: hg %s --abort') % (self._opname,
122 'To abort: hg %s --abort') % (self._opname,
122 self._opname))
123 self._opname))
123 if self._stopflag:
124 if self._stopflag:
124 hint = hint + (_('\nTo stop: hg %s --stop') %
125 hint = hint + (_('\nTo stop: hg %s --stop') %
125 (self._opname))
126 (self._opname))
126 return hint
127 return hint
127 return self._statushint
128 return self._statushint
128
129
129 def hint(self):
130 def hint(self):
130 """returns the hint message corresponding to an interrupted
131 """returns the hint message corresponding to an interrupted
131 operation
132 operation
132 """
133 """
133 if not self._cmdhint:
134 if not self._cmdhint:
134 return (_("use 'hg %s --continue' or 'hg %s --abort'") %
135 return (_("use 'hg %s --continue' or 'hg %s --abort'") %
135 (self._opname, self._opname))
136 (self._opname, self._opname))
136 return self._cmdhint
137 return self._cmdhint
137
138
138 def msg(self):
139 def msg(self):
139 """returns the status message corresponding to the command"""
140 """returns the status message corresponding to the command"""
140 if not self._cmdmsg:
141 if not self._cmdmsg:
141 return _('%s in progress') % (self._opname)
142 return _('%s in progress') % (self._opname)
142 return self._cmdmsg
143 return self._cmdmsg
143
144
144 def continuemsg(self):
145 def continuemsg(self):
145 """ returns appropriate continue message corresponding to command"""
146 """ returns appropriate continue message corresponding to command"""
146 return _('hg %s --continue') % (self._opname)
147 return _('hg %s --continue') % (self._opname)
147
148
148 def isunfinished(self, repo):
149 def isunfinished(self, repo):
149 """determines whether a multi-step operation is in progress
150 """determines whether a multi-step operation is in progress
150 or not
151 or not
151 """
152 """
152 if self._opname == 'merge':
153 if self._opname == 'merge':
153 return len(repo[None].parents()) > 1
154 return len(repo[None].parents()) > 1
154 else:
155 else:
155 return repo.vfs.exists(self._fname)
156 return repo.vfs.exists(self._fname)
156
157
157 # A list of statecheck objects for multistep operations like graft.
158 # A list of statecheck objects for multistep operations like graft.
158 _unfinishedstates = []
159 _unfinishedstates = []
159
160
160 def addunfinished(opname, fname, clearable=False, allowcommit=False,
161 def addunfinished(opname, fname, clearable=False, allowcommit=False,
161 reportonly=False, continueflag=False, stopflag=False,
162 reportonly=False, continueflag=False, stopflag=False,
162 cmdmsg="", cmdhint="", statushint="", abortfunc=None):
163 cmdmsg="", cmdhint="", statushint="", abortfunc=None,
164 continuefunc=None):
163 """this registers a new command or operation to unfinishedstates
165 """this registers a new command or operation to unfinishedstates
164 opname is the name the command or operation
166 opname is the name the command or operation
165 fname is the file name in which data should be stored in .hg directory.
167 fname is the file name in which data should be stored in .hg directory.
166 It is None for merge command.
168 It is None for merge command.
167 clearable boolean determines whether or not interrupted states can be
169 clearable boolean determines whether or not interrupted states can be
168 cleared by running `hg update -C .` which in turn deletes the
170 cleared by running `hg update -C .` which in turn deletes the
169 state file.
171 state file.
170 allowcommit boolean decides whether commit is allowed during interrupted
172 allowcommit boolean decides whether commit is allowed during interrupted
171 state or not.
173 state or not.
172 reportonly flag is used for operations like bisect where we just
174 reportonly flag is used for operations like bisect where we just
173 need to detect the operation using 'hg status --verbose'
175 need to detect the operation using 'hg status --verbose'
174 continueflag is a boolean determines whether or not a command supports
176 continueflag is a boolean determines whether or not a command supports
175 `--continue` option or not.
177 `--continue` option or not.
176 stopflag is a boolean that determines whether or not a command supports
178 stopflag is a boolean that determines whether or not a command supports
177 --stop flag
179 --stop flag
178 cmdmsg is used to pass a different status message in case standard
180 cmdmsg is used to pass a different status message in case standard
179 message of the format "abort: cmdname in progress" is not desired.
181 message of the format "abort: cmdname in progress" is not desired.
180 cmdhint is used to pass a different hint message in case standard
182 cmdhint is used to pass a different hint message in case standard
181 message of the format "To continue: hg cmdname --continue
183 message of the format "To continue: hg cmdname --continue
182 To abort: hg cmdname --abort" is not desired.
184 To abort: hg cmdname --abort" is not desired.
183 statushint is used to pass a different status message in case standard
185 statushint is used to pass a different status message in case standard
184 message of the format ('To continue: hg cmdname --continue'
186 message of the format ('To continue: hg cmdname --continue'
185 'To abort: hg cmdname --abort') is not desired
187 'To abort: hg cmdname --abort') is not desired
186 abortfunc stores the function required to abort an unfinished state.
188 abortfunc stores the function required to abort an unfinished state.
189 continuefunc stores the function required to finish an interrupted
190 operation.
187 """
191 """
188 statecheckobj = _statecheck(opname, fname, clearable, allowcommit,
192 statecheckobj = _statecheck(opname, fname, clearable, allowcommit,
189 reportonly, continueflag, stopflag, cmdmsg,
193 reportonly, continueflag, stopflag, cmdmsg,
190 cmdhint, statushint, abortfunc)
194 cmdhint, statushint, abortfunc, continuefunc)
191 if opname == 'merge':
195 if opname == 'merge':
192 _unfinishedstates.append(statecheckobj)
196 _unfinishedstates.append(statecheckobj)
193 else:
197 else:
194 _unfinishedstates.insert(0, statecheckobj)
198 _unfinishedstates.insert(0, statecheckobj)
195
199
196 addunfinished(
200 addunfinished(
197 'update', fname='updatestate', clearable=True,
201 'update', fname='updatestate', clearable=True,
198 cmdmsg=_('last update was interrupted'),
202 cmdmsg=_('last update was interrupted'),
199 cmdhint=_("use 'hg update' to get a consistent checkout"),
203 cmdhint=_("use 'hg update' to get a consistent checkout"),
200 statushint=_("To continue: hg update")
204 statushint=_("To continue: hg update")
201 )
205 )
202 addunfinished(
206 addunfinished(
203 'bisect', fname='bisect.state', allowcommit=True, reportonly=True,
207 'bisect', fname='bisect.state', allowcommit=True, reportonly=True,
204 statushint=_('To mark the changeset good: hg bisect --good\n'
208 statushint=_('To mark the changeset good: hg bisect --good\n'
205 'To mark the changeset bad: hg bisect --bad\n'
209 'To mark the changeset bad: hg bisect --bad\n'
206 'To abort: hg bisect --reset\n')
210 'To abort: hg bisect --reset\n')
207 )
211 )
208
212
209 def getrepostate(repo):
213 def getrepostate(repo):
210 # experimental config: commands.status.skipstates
214 # experimental config: commands.status.skipstates
211 skip = set(repo.ui.configlist('commands', 'status.skipstates'))
215 skip = set(repo.ui.configlist('commands', 'status.skipstates'))
212 for state in _unfinishedstates:
216 for state in _unfinishedstates:
213 if state._opname in skip:
217 if state._opname in skip:
214 continue
218 continue
215 if state.isunfinished(repo):
219 if state.isunfinished(repo):
216 return (state._opname, state.statusmsg())
220 return (state._opname, state.statusmsg())
@@ -1,421 +1,423 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 abort
3 abort
4 add
4 add
5 addremove
5 addremove
6 annotate
6 annotate
7 archive
7 archive
8 backout
8 backout
9 bisect
9 bisect
10 bookmarks
10 bookmarks
11 branch
11 branch
12 branches
12 branches
13 bundle
13 bundle
14 cat
14 cat
15 clone
15 clone
16 commit
16 commit
17 config
17 config
18 continue
18 copy
19 copy
19 diff
20 diff
20 export
21 export
21 files
22 files
22 forget
23 forget
23 graft
24 graft
24 grep
25 grep
25 heads
26 heads
26 help
27 help
27 identify
28 identify
28 import
29 import
29 incoming
30 incoming
30 init
31 init
31 locate
32 locate
32 log
33 log
33 manifest
34 manifest
34 merge
35 merge
35 outgoing
36 outgoing
36 parents
37 parents
37 paths
38 paths
38 phase
39 phase
39 pull
40 pull
40 push
41 push
41 recover
42 recover
42 remove
43 remove
43 rename
44 rename
44 resolve
45 resolve
45 revert
46 revert
46 rollback
47 rollback
47 root
48 root
48 serve
49 serve
49 shelve
50 shelve
50 status
51 status
51 summary
52 summary
52 tag
53 tag
53 tags
54 tags
54 tip
55 tip
55 unbundle
56 unbundle
56 unshelve
57 unshelve
57 update
58 update
58 verify
59 verify
59 version
60 version
60
61
61 Show all commands that start with "a"
62 Show all commands that start with "a"
62 $ hg debugcomplete a
63 $ hg debugcomplete a
63 abort
64 abort
64 add
65 add
65 addremove
66 addremove
66 annotate
67 annotate
67 archive
68 archive
68
69
69 Do not show debug commands if there are other candidates
70 Do not show debug commands if there are other candidates
70 $ hg debugcomplete d
71 $ hg debugcomplete d
71 diff
72 diff
72
73
73 Show debug commands if there are no other candidates
74 Show debug commands if there are no other candidates
74 $ hg debugcomplete debug
75 $ hg debugcomplete debug
75 debugancestor
76 debugancestor
76 debugapplystreamclonebundle
77 debugapplystreamclonebundle
77 debugbuilddag
78 debugbuilddag
78 debugbundle
79 debugbundle
79 debugcapabilities
80 debugcapabilities
80 debugcheckstate
81 debugcheckstate
81 debugcolor
82 debugcolor
82 debugcommands
83 debugcommands
83 debugcomplete
84 debugcomplete
84 debugconfig
85 debugconfig
85 debugcreatestreamclonebundle
86 debugcreatestreamclonebundle
86 debugdag
87 debugdag
87 debugdata
88 debugdata
88 debugdate
89 debugdate
89 debugdeltachain
90 debugdeltachain
90 debugdirstate
91 debugdirstate
91 debugdiscovery
92 debugdiscovery
92 debugdownload
93 debugdownload
93 debugextensions
94 debugextensions
94 debugfileset
95 debugfileset
95 debugformat
96 debugformat
96 debugfsinfo
97 debugfsinfo
97 debuggetbundle
98 debuggetbundle
98 debugignore
99 debugignore
99 debugindex
100 debugindex
100 debugindexdot
101 debugindexdot
101 debugindexstats
102 debugindexstats
102 debuginstall
103 debuginstall
103 debugknown
104 debugknown
104 debuglabelcomplete
105 debuglabelcomplete
105 debuglocks
106 debuglocks
106 debugmanifestfulltextcache
107 debugmanifestfulltextcache
107 debugmergestate
108 debugmergestate
108 debugnamecomplete
109 debugnamecomplete
109 debugobsolete
110 debugobsolete
110 debugp1copies
111 debugp1copies
111 debugp2copies
112 debugp2copies
112 debugpathcomplete
113 debugpathcomplete
113 debugpathcopies
114 debugpathcopies
114 debugpeer
115 debugpeer
115 debugpickmergetool
116 debugpickmergetool
116 debugpushkey
117 debugpushkey
117 debugpvec
118 debugpvec
118 debugrebuilddirstate
119 debugrebuilddirstate
119 debugrebuildfncache
120 debugrebuildfncache
120 debugrename
121 debugrename
121 debugrevlog
122 debugrevlog
122 debugrevlogindex
123 debugrevlogindex
123 debugrevspec
124 debugrevspec
124 debugserve
125 debugserve
125 debugsetparents
126 debugsetparents
126 debugssl
127 debugssl
127 debugsub
128 debugsub
128 debugsuccessorssets
129 debugsuccessorssets
129 debugtemplate
130 debugtemplate
130 debuguigetpass
131 debuguigetpass
131 debuguiprompt
132 debuguiprompt
132 debugupdatecaches
133 debugupdatecaches
133 debugupgraderepo
134 debugupgraderepo
134 debugwalk
135 debugwalk
135 debugwhyunstable
136 debugwhyunstable
136 debugwireargs
137 debugwireargs
137 debugwireproto
138 debugwireproto
138
139
139 Do not show the alias of a debug command if there are other candidates
140 Do not show the alias of a debug command if there are other candidates
140 (this should hide rawcommit)
141 (this should hide rawcommit)
141 $ hg debugcomplete r
142 $ hg debugcomplete r
142 recover
143 recover
143 remove
144 remove
144 rename
145 rename
145 resolve
146 resolve
146 revert
147 revert
147 rollback
148 rollback
148 root
149 root
149 Show the alias of a debug command if there are no other candidates
150 Show the alias of a debug command if there are no other candidates
150 $ hg debugcomplete rawc
151 $ hg debugcomplete rawc
151
152
152
153
153 Show the global options
154 Show the global options
154 $ hg debugcomplete --options | sort
155 $ hg debugcomplete --options | sort
155 --color
156 --color
156 --config
157 --config
157 --cwd
158 --cwd
158 --debug
159 --debug
159 --debugger
160 --debugger
160 --encoding
161 --encoding
161 --encodingmode
162 --encodingmode
162 --help
163 --help
163 --hidden
164 --hidden
164 --noninteractive
165 --noninteractive
165 --pager
166 --pager
166 --profile
167 --profile
167 --quiet
168 --quiet
168 --repository
169 --repository
169 --time
170 --time
170 --traceback
171 --traceback
171 --verbose
172 --verbose
172 --version
173 --version
173 -R
174 -R
174 -h
175 -h
175 -q
176 -q
176 -v
177 -v
177 -y
178 -y
178
179
179 Show the options for the "serve" command
180 Show the options for the "serve" command
180 $ hg debugcomplete --options serve | sort
181 $ hg debugcomplete --options serve | sort
181 --accesslog
182 --accesslog
182 --address
183 --address
183 --certificate
184 --certificate
184 --cmdserver
185 --cmdserver
185 --color
186 --color
186 --config
187 --config
187 --cwd
188 --cwd
188 --daemon
189 --daemon
189 --daemon-postexec
190 --daemon-postexec
190 --debug
191 --debug
191 --debugger
192 --debugger
192 --encoding
193 --encoding
193 --encodingmode
194 --encodingmode
194 --errorlog
195 --errorlog
195 --help
196 --help
196 --hidden
197 --hidden
197 --ipv6
198 --ipv6
198 --name
199 --name
199 --noninteractive
200 --noninteractive
200 --pager
201 --pager
201 --pid-file
202 --pid-file
202 --port
203 --port
203 --prefix
204 --prefix
204 --print-url
205 --print-url
205 --profile
206 --profile
206 --quiet
207 --quiet
207 --repository
208 --repository
208 --stdio
209 --stdio
209 --style
210 --style
210 --subrepos
211 --subrepos
211 --templates
212 --templates
212 --time
213 --time
213 --traceback
214 --traceback
214 --verbose
215 --verbose
215 --version
216 --version
216 --web-conf
217 --web-conf
217 -6
218 -6
218 -A
219 -A
219 -E
220 -E
220 -R
221 -R
221 -S
222 -S
222 -a
223 -a
223 -d
224 -d
224 -h
225 -h
225 -n
226 -n
226 -p
227 -p
227 -q
228 -q
228 -t
229 -t
229 -v
230 -v
230 -y
231 -y
231
232
232 Show an error if we use --options with an ambiguous abbreviation
233 Show an error if we use --options with an ambiguous abbreviation
233 $ hg debugcomplete --options s
234 $ hg debugcomplete --options s
234 hg: command 's' is ambiguous:
235 hg: command 's' is ambiguous:
235 serve shelve showconfig status summary
236 serve shelve showconfig status summary
236 [255]
237 [255]
237
238
238 Show all commands + options
239 Show all commands + options
239 $ hg debugcommands
240 $ hg debugcommands
240 abort: dry-run
241 abort: dry-run
241 add: include, exclude, subrepos, dry-run
242 add: include, exclude, subrepos, dry-run
242 addremove: similarity, subrepos, include, exclude, dry-run
243 addremove: similarity, subrepos, include, exclude, dry-run
243 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
244 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
244 archive: no-decode, prefix, rev, type, subrepos, include, exclude
245 archive: no-decode, prefix, rev, type, subrepos, include, exclude
245 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
246 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
246 bisect: reset, good, bad, skip, extend, command, noupdate
247 bisect: reset, good, bad, skip, extend, command, noupdate
247 bookmarks: force, rev, delete, rename, inactive, list, template
248 bookmarks: force, rev, delete, rename, inactive, list, template
248 branch: force, clean, rev
249 branch: force, clean, rev
249 branches: active, closed, rev, template
250 branches: active, closed, rev, template
250 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
251 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
251 cat: output, rev, decode, include, exclude, template
252 cat: output, rev, decode, include, exclude, template
252 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
253 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
253 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
254 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
254 config: untrusted, edit, local, global, template
255 config: untrusted, edit, local, global, template
256 continue: dry-run
255 copy: after, force, include, exclude, dry-run
257 copy: after, force, include, exclude, dry-run
256 debugancestor:
258 debugancestor:
257 debugapplystreamclonebundle:
259 debugapplystreamclonebundle:
258 debugbuilddag: mergeable-file, overwritten-file, new-file
260 debugbuilddag: mergeable-file, overwritten-file, new-file
259 debugbundle: all, part-type, spec
261 debugbundle: all, part-type, spec
260 debugcapabilities:
262 debugcapabilities:
261 debugcheckstate:
263 debugcheckstate:
262 debugcolor: style
264 debugcolor: style
263 debugcommands:
265 debugcommands:
264 debugcomplete: options
266 debugcomplete: options
265 debugcreatestreamclonebundle:
267 debugcreatestreamclonebundle:
266 debugdag: tags, branches, dots, spaces
268 debugdag: tags, branches, dots, spaces
267 debugdata: changelog, manifest, dir
269 debugdata: changelog, manifest, dir
268 debugdate: extended
270 debugdate: extended
269 debugdeltachain: changelog, manifest, dir, template
271 debugdeltachain: changelog, manifest, dir, template
270 debugdirstate: nodates, dates, datesort
272 debugdirstate: nodates, dates, datesort
271 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
273 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
272 debugdownload: output
274 debugdownload: output
273 debugextensions: template
275 debugextensions: template
274 debugfileset: rev, all-files, show-matcher, show-stage
276 debugfileset: rev, all-files, show-matcher, show-stage
275 debugformat: template
277 debugformat: template
276 debugfsinfo:
278 debugfsinfo:
277 debuggetbundle: head, common, type
279 debuggetbundle: head, common, type
278 debugignore:
280 debugignore:
279 debugindex: changelog, manifest, dir, template
281 debugindex: changelog, manifest, dir, template
280 debugindexdot: changelog, manifest, dir
282 debugindexdot: changelog, manifest, dir
281 debugindexstats:
283 debugindexstats:
282 debuginstall: template
284 debuginstall: template
283 debugknown:
285 debugknown:
284 debuglabelcomplete:
286 debuglabelcomplete:
285 debuglocks: force-lock, force-wlock, set-lock, set-wlock
287 debuglocks: force-lock, force-wlock, set-lock, set-wlock
286 debugmanifestfulltextcache: clear, add
288 debugmanifestfulltextcache: clear, add
287 debugmergestate:
289 debugmergestate:
288 debugnamecomplete:
290 debugnamecomplete:
289 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
291 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
290 debugp1copies: rev
292 debugp1copies: rev
291 debugp2copies: rev
293 debugp2copies: rev
292 debugpathcomplete: full, normal, added, removed
294 debugpathcomplete: full, normal, added, removed
293 debugpathcopies: include, exclude
295 debugpathcopies: include, exclude
294 debugpeer:
296 debugpeer:
295 debugpickmergetool: rev, changedelete, include, exclude, tool
297 debugpickmergetool: rev, changedelete, include, exclude, tool
296 debugpushkey:
298 debugpushkey:
297 debugpvec:
299 debugpvec:
298 debugrebuilddirstate: rev, minimal
300 debugrebuilddirstate: rev, minimal
299 debugrebuildfncache:
301 debugrebuildfncache:
300 debugrename: rev
302 debugrename: rev
301 debugrevlog: changelog, manifest, dir, dump
303 debugrevlog: changelog, manifest, dir, dump
302 debugrevlogindex: changelog, manifest, dir, format
304 debugrevlogindex: changelog, manifest, dir, format
303 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
305 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
304 debugserve: sshstdio, logiofd, logiofile
306 debugserve: sshstdio, logiofd, logiofile
305 debugsetparents:
307 debugsetparents:
306 debugssl:
308 debugssl:
307 debugsub: rev
309 debugsub: rev
308 debugsuccessorssets: closest
310 debugsuccessorssets: closest
309 debugtemplate: rev, define
311 debugtemplate: rev, define
310 debuguigetpass: prompt
312 debuguigetpass: prompt
311 debuguiprompt: prompt
313 debuguiprompt: prompt
312 debugupdatecaches:
314 debugupdatecaches:
313 debugupgraderepo: optimize, run, backup
315 debugupgraderepo: optimize, run, backup
314 debugwalk: include, exclude
316 debugwalk: include, exclude
315 debugwhyunstable:
317 debugwhyunstable:
316 debugwireargs: three, four, five, ssh, remotecmd, insecure
318 debugwireargs: three, four, five, ssh, remotecmd, insecure
317 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
319 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
318 diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
320 diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
319 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
321 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
320 files: rev, print0, include, exclude, template, subrepos
322 files: rev, print0, include, exclude, template, subrepos
321 forget: interactive, include, exclude, dry-run
323 forget: interactive, include, exclude, dry-run
322 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
324 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
323 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
325 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
324 heads: rev, topo, active, closed, style, template
326 heads: rev, topo, active, closed, style, template
325 help: extension, command, keyword, system
327 help: extension, command, keyword, system
326 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
328 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
327 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
329 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
328 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
330 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
329 init: ssh, remotecmd, insecure
331 init: ssh, remotecmd, insecure
330 locate: rev, print0, fullpath, include, exclude
332 locate: rev, print0, fullpath, include, exclude
331 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
333 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
332 manifest: rev, all, template
334 manifest: rev, all, template
333 merge: force, rev, preview, abort, tool
335 merge: force, rev, preview, abort, tool
334 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
336 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
335 parents: rev, style, template
337 parents: rev, style, template
336 paths: template
338 paths: template
337 phase: public, draft, secret, force, rev
339 phase: public, draft, secret, force, rev
338 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
340 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
339 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
341 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
340 recover: verify
342 recover: verify
341 remove: after, force, subrepos, include, exclude, dry-run
343 remove: after, force, subrepos, include, exclude, dry-run
342 rename: after, force, include, exclude, dry-run
344 rename: after, force, include, exclude, dry-run
343 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
345 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
344 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
346 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
345 rollback: dry-run, force
347 rollback: dry-run, force
346 root: template
348 root: template
347 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
349 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
348 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
350 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
349 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
351 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
350 summary: remote
352 summary: remote
351 tag: force, local, rev, remove, edit, message, date, user
353 tag: force, local, rev, remove, edit, message, date, user
352 tags: template
354 tags: template
353 tip: patch, git, style, template
355 tip: patch, git, style, template
354 unbundle: update
356 unbundle: update
355 unshelve: abort, continue, keep, name, tool, date
357 unshelve: abort, continue, keep, name, tool, date
356 update: clean, check, merge, date, rev, tool
358 update: clean, check, merge, date, rev, tool
357 verify: full
359 verify: full
358 version: template
360 version: template
359
361
360 $ hg init a
362 $ hg init a
361 $ cd a
363 $ cd a
362 $ echo fee > fee
364 $ echo fee > fee
363 $ hg ci -q -Amfee
365 $ hg ci -q -Amfee
364 $ hg tag fee
366 $ hg tag fee
365 $ mkdir fie
367 $ mkdir fie
366 $ echo dead > fie/dead
368 $ echo dead > fie/dead
367 $ echo live > fie/live
369 $ echo live > fie/live
368 $ hg bookmark fo
370 $ hg bookmark fo
369 $ hg branch -q fie
371 $ hg branch -q fie
370 $ hg ci -q -Amfie
372 $ hg ci -q -Amfie
371 $ echo fo > fo
373 $ echo fo > fo
372 $ hg branch -qf default
374 $ hg branch -qf default
373 $ hg ci -q -Amfo
375 $ hg ci -q -Amfo
374 $ echo Fum > Fum
376 $ echo Fum > Fum
375 $ hg ci -q -AmFum
377 $ hg ci -q -AmFum
376 $ hg bookmark Fum
378 $ hg bookmark Fum
377
379
378 Test debugpathcomplete
380 Test debugpathcomplete
379
381
380 $ hg debugpathcomplete f
382 $ hg debugpathcomplete f
381 fee
383 fee
382 fie
384 fie
383 fo
385 fo
384 $ hg debugpathcomplete -f f
386 $ hg debugpathcomplete -f f
385 fee
387 fee
386 fie/dead
388 fie/dead
387 fie/live
389 fie/live
388 fo
390 fo
389
391
390 $ hg rm Fum
392 $ hg rm Fum
391 $ hg debugpathcomplete -r F
393 $ hg debugpathcomplete -r F
392 Fum
394 Fum
393
395
394 Test debugnamecomplete
396 Test debugnamecomplete
395
397
396 $ hg debugnamecomplete
398 $ hg debugnamecomplete
397 Fum
399 Fum
398 default
400 default
399 fee
401 fee
400 fie
402 fie
401 fo
403 fo
402 tip
404 tip
403 $ hg debugnamecomplete f
405 $ hg debugnamecomplete f
404 fee
406 fee
405 fie
407 fie
406 fo
408 fo
407
409
408 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
410 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
409 used for completions in some shells.
411 used for completions in some shells.
410
412
411 $ hg debuglabelcomplete
413 $ hg debuglabelcomplete
412 Fum
414 Fum
413 default
415 default
414 fee
416 fee
415 fie
417 fie
416 fo
418 fo
417 tip
419 tip
418 $ hg debuglabelcomplete f
420 $ hg debuglabelcomplete f
419 fee
421 fee
420 fie
422 fie
421 fo
423 fo
@@ -1,3883 +1,3891 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 revision history 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 revision history 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 diff diff repository (or selected files)
412 diff diff repository (or selected files)
412 export dump the header and diffs for one or more changesets
413 export dump the header and diffs for one or more changesets
413 forget forget the specified files on the next commit
414 forget forget the specified files on the next commit
414 init create a new repository in the given directory
415 init create a new repository in the given directory
415 log, history show revision history of entire repository or files
416 log, history show revision history of entire repository or files
416 merge merge another revision into working directory
417 merge merge another revision into working directory
417 pull pull changes from the specified source
418 pull pull changes from the specified source
418 push push changes to the specified destination
419 push push changes to the specified destination
419 remove, rm remove the specified files on the next commit
420 remove, rm remove the specified files on the next commit
420 serve start stand-alone webserver
421 serve start stand-alone webserver
421 status, st show changed files in the working directory
422 status, st show changed files in the working directory
422 summary, sum summarize working directory state
423 summary, sum summarize working directory state
423 update, up, checkout, co
424 update, up, checkout, co
424 update working directory (or switch revisions)
425 update working directory (or switch revisions)
425
426
426 global options ([+] can be repeated):
427 global options ([+] can be repeated):
427
428
428 -R --repository REPO repository root directory or name of overlay bundle
429 -R --repository REPO repository root directory or name of overlay bundle
429 file
430 file
430 --cwd DIR change working directory
431 --cwd DIR change working directory
431 -y --noninteractive do not prompt, automatically pick the first choice for
432 -y --noninteractive do not prompt, automatically pick the first choice for
432 all prompts
433 all prompts
433 -q --quiet suppress output
434 -q --quiet suppress output
434 -v --verbose enable additional output
435 -v --verbose enable additional output
435 --color TYPE when to colorize (boolean, always, auto, never, or
436 --color TYPE when to colorize (boolean, always, auto, never, or
436 debug)
437 debug)
437 --config CONFIG [+] set/override config option (use 'section.name=value')
438 --config CONFIG [+] set/override config option (use 'section.name=value')
438 --debug enable debugging output
439 --debug enable debugging output
439 --debugger start debugger
440 --debugger start debugger
440 --encoding ENCODE set the charset encoding (default: ascii)
441 --encoding ENCODE set the charset encoding (default: ascii)
441 --encodingmode MODE set the charset encoding mode (default: strict)
442 --encodingmode MODE set the charset encoding mode (default: strict)
442 --traceback always print a traceback on exception
443 --traceback always print a traceback on exception
443 --time time how long the command takes
444 --time time how long the command takes
444 --profile print command execution profile
445 --profile print command execution profile
445 --version output version information and exit
446 --version output version information and exit
446 -h --help display help and exit
447 -h --help display help and exit
447 --hidden consider hidden changesets
448 --hidden consider hidden changesets
448 --pager TYPE when to paginate (boolean, always, auto, or never)
449 --pager TYPE when to paginate (boolean, always, auto, or never)
449 (default: auto)
450 (default: auto)
450
451
451 (use 'hg help' for the full list of commands)
452 (use 'hg help' for the full list of commands)
452
453
453 $ hg add -h
454 $ hg add -h
454 hg add [OPTION]... [FILE]...
455 hg add [OPTION]... [FILE]...
455
456
456 add the specified files on the next commit
457 add the specified files on the next commit
457
458
458 Schedule files to be version controlled and added to the repository.
459 Schedule files to be version controlled and added to the repository.
459
460
460 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
461 add before that, see 'hg forget'.
462 add before that, see 'hg forget'.
462
463
463 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
464 matching ".hgignore").
465 matching ".hgignore").
465
466
466 Returns 0 if all files are successfully added.
467 Returns 0 if all files are successfully added.
467
468
468 options ([+] can be repeated):
469 options ([+] can be repeated):
469
470
470 -I --include PATTERN [+] include names matching the given patterns
471 -I --include PATTERN [+] include names matching the given patterns
471 -X --exclude PATTERN [+] exclude names matching the given patterns
472 -X --exclude PATTERN [+] exclude names matching the given patterns
472 -S --subrepos recurse into subrepositories
473 -S --subrepos recurse into subrepositories
473 -n --dry-run do not perform actions, just print output
474 -n --dry-run do not perform actions, just print output
474
475
475 (some details hidden, use --verbose to show complete help)
476 (some details hidden, use --verbose to show complete help)
476
477
477 Verbose help for add
478 Verbose help for add
478
479
479 $ hg add -hv
480 $ hg add -hv
480 hg add [OPTION]... [FILE]...
481 hg add [OPTION]... [FILE]...
481
482
482 add the specified files on the next commit
483 add the specified files on the next commit
483
484
484 Schedule files to be version controlled and added to the repository.
485 Schedule files to be version controlled and added to the repository.
485
486
486 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
487 add before that, see 'hg forget'.
488 add before that, see 'hg forget'.
488
489
489 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
490 matching ".hgignore").
491 matching ".hgignore").
491
492
492 Examples:
493 Examples:
493
494
494 - New (unknown) files are added automatically by 'hg add':
495 - New (unknown) files are added automatically by 'hg add':
495
496
496 $ ls
497 $ ls
497 foo.c
498 foo.c
498 $ hg status
499 $ hg status
499 ? foo.c
500 ? foo.c
500 $ hg add
501 $ hg add
501 adding foo.c
502 adding foo.c
502 $ hg status
503 $ hg status
503 A foo.c
504 A foo.c
504
505
505 - Specific files to be added can be specified:
506 - Specific files to be added can be specified:
506
507
507 $ ls
508 $ ls
508 bar.c foo.c
509 bar.c foo.c
509 $ hg status
510 $ hg status
510 ? bar.c
511 ? bar.c
511 ? foo.c
512 ? foo.c
512 $ hg add bar.c
513 $ hg add bar.c
513 $ hg status
514 $ hg status
514 A bar.c
515 A bar.c
515 ? foo.c
516 ? foo.c
516
517
517 Returns 0 if all files are successfully added.
518 Returns 0 if all files are successfully added.
518
519
519 options ([+] can be repeated):
520 options ([+] can be repeated):
520
521
521 -I --include PATTERN [+] include names matching the given patterns
522 -I --include PATTERN [+] include names matching the given patterns
522 -X --exclude PATTERN [+] exclude names matching the given patterns
523 -X --exclude PATTERN [+] exclude names matching the given patterns
523 -S --subrepos recurse into subrepositories
524 -S --subrepos recurse into subrepositories
524 -n --dry-run do not perform actions, just print output
525 -n --dry-run do not perform actions, just print output
525
526
526 global options ([+] can be repeated):
527 global options ([+] can be repeated):
527
528
528 -R --repository REPO repository root directory or name of overlay bundle
529 -R --repository REPO repository root directory or name of overlay bundle
529 file
530 file
530 --cwd DIR change working directory
531 --cwd DIR change working directory
531 -y --noninteractive do not prompt, automatically pick the first choice for
532 -y --noninteractive do not prompt, automatically pick the first choice for
532 all prompts
533 all prompts
533 -q --quiet suppress output
534 -q --quiet suppress output
534 -v --verbose enable additional output
535 -v --verbose enable additional output
535 --color TYPE when to colorize (boolean, always, auto, never, or
536 --color TYPE when to colorize (boolean, always, auto, never, or
536 debug)
537 debug)
537 --config CONFIG [+] set/override config option (use 'section.name=value')
538 --config CONFIG [+] set/override config option (use 'section.name=value')
538 --debug enable debugging output
539 --debug enable debugging output
539 --debugger start debugger
540 --debugger start debugger
540 --encoding ENCODE set the charset encoding (default: ascii)
541 --encoding ENCODE set the charset encoding (default: ascii)
541 --encodingmode MODE set the charset encoding mode (default: strict)
542 --encodingmode MODE set the charset encoding mode (default: strict)
542 --traceback always print a traceback on exception
543 --traceback always print a traceback on exception
543 --time time how long the command takes
544 --time time how long the command takes
544 --profile print command execution profile
545 --profile print command execution profile
545 --version output version information and exit
546 --version output version information and exit
546 -h --help display help and exit
547 -h --help display help and exit
547 --hidden consider hidden changesets
548 --hidden consider hidden changesets
548 --pager TYPE when to paginate (boolean, always, auto, or never)
549 --pager TYPE when to paginate (boolean, always, auto, or never)
549 (default: auto)
550 (default: auto)
550
551
551 Test the textwidth config option
552 Test the textwidth config option
552
553
553 $ hg root -h --config ui.textwidth=50
554 $ hg root -h --config ui.textwidth=50
554 hg root
555 hg root
555
556
556 print the root (top) of the current working
557 print the root (top) of the current working
557 directory
558 directory
558
559
559 Print the root directory of the current
560 Print the root directory of the current
560 repository.
561 repository.
561
562
562 Returns 0 on success.
563 Returns 0 on success.
563
564
564 options:
565 options:
565
566
566 -T --template TEMPLATE display with template
567 -T --template TEMPLATE display with template
567
568
568 (some details hidden, use --verbose to show
569 (some details hidden, use --verbose to show
569 complete help)
570 complete help)
570
571
571 Test help option with version option
572 Test help option with version option
572
573
573 $ hg add -h --version
574 $ hg add -h --version
574 Mercurial Distributed SCM (version *) (glob)
575 Mercurial Distributed SCM (version *) (glob)
575 (see https://mercurial-scm.org for more information)
576 (see https://mercurial-scm.org for more information)
576
577
577 Copyright (C) 2005-* Matt Mackall and others (glob)
578 Copyright (C) 2005-* Matt Mackall and others (glob)
578 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
579 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
580 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
580
581
581 $ hg add --skjdfks
582 $ hg add --skjdfks
582 hg add: option --skjdfks not recognized
583 hg add: option --skjdfks not recognized
583 hg add [OPTION]... [FILE]...
584 hg add [OPTION]... [FILE]...
584
585
585 add the specified files on the next commit
586 add the specified files on the next commit
586
587
587 options ([+] can be repeated):
588 options ([+] can be repeated):
588
589
589 -I --include PATTERN [+] include names matching the given patterns
590 -I --include PATTERN [+] include names matching the given patterns
590 -X --exclude PATTERN [+] exclude names matching the given patterns
591 -X --exclude PATTERN [+] exclude names matching the given patterns
591 -S --subrepos recurse into subrepositories
592 -S --subrepos recurse into subrepositories
592 -n --dry-run do not perform actions, just print output
593 -n --dry-run do not perform actions, just print output
593
594
594 (use 'hg add -h' to show more help)
595 (use 'hg add -h' to show more help)
595 [255]
596 [255]
596
597
597 Test ambiguous command help
598 Test ambiguous command help
598
599
599 $ hg help ad
600 $ hg help ad
600 list of commands:
601 list of commands:
601
602
602 add add the specified files on the next commit
603 add add the specified files on the next commit
603 addremove add all new files, delete all missing files
604 addremove add all new files, delete all missing files
604
605
605 (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)
606
607
607 Test command without options
608 Test command without options
608
609
609 $ hg help verify
610 $ hg help verify
610 hg verify
611 hg verify
611
612
612 verify the integrity of the repository
613 verify the integrity of the repository
613
614
614 Verify the integrity of the current repository.
615 Verify the integrity of the current repository.
615
616
616 This will perform an extensive check of the repository's integrity,
617 This will perform an extensive check of the repository's integrity,
617 validating the hashes and checksums of each entry in the changelog,
618 validating the hashes and checksums of each entry in the changelog,
618 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
619 and indices.
620 and indices.
620
621
621 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
622 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
622 information about recovery from corruption of the repository.
623 information about recovery from corruption of the repository.
623
624
624 Returns 0 on success, 1 if errors are encountered.
625 Returns 0 on success, 1 if errors are encountered.
625
626
626 options:
627 options:
627
628
628 (some details hidden, use --verbose to show complete help)
629 (some details hidden, use --verbose to show complete help)
629
630
630 $ hg help diff
631 $ hg help diff
631 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
632 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
632
633
633 diff repository (or selected files)
634 diff repository (or selected files)
634
635
635 Show differences between revisions for the specified files.
636 Show differences between revisions for the specified files.
636
637
637 Differences between files are shown using the unified diff format.
638 Differences between files are shown using the unified diff format.
638
639
639 Note:
640 Note:
640 'hg diff' may generate unexpected results for merges, as it will
641 'hg diff' may generate unexpected results for merges, as it will
641 default to comparing against the working directory's first parent
642 default to comparing against the working directory's first parent
642 changeset if no revisions are specified.
643 changeset if no revisions are specified.
643
644
644 When two revision arguments are given, then changes are shown between
645 When two revision arguments are given, then changes are shown between
645 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
646 compared to the working directory, and, when no revisions are specified,
647 compared to the working directory, and, when no revisions are specified,
647 the working directory files are compared to its first parent.
648 the working directory files are compared to its first parent.
648
649
649 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
650 changes in that changeset relative to its first parent.
651 changes in that changeset relative to its first parent.
651
652
652 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
653 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
654 with undesirable results.
655 with undesirable results.
655
656
656 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.
657 For more information, read 'hg help diffs'.
658 For more information, read 'hg help diffs'.
658
659
659 Returns 0 on success.
660 Returns 0 on success.
660
661
661 options ([+] can be repeated):
662 options ([+] can be repeated):
662
663
663 -r --rev REV [+] revision
664 -r --rev REV [+] revision
664 -c --change REV change made by revision
665 -c --change REV change made by revision
665 -a --text treat all files as text
666 -a --text treat all files as text
666 -g --git use git extended diff format
667 -g --git use git extended diff format
667 --binary generate binary diffs in git mode (default)
668 --binary generate binary diffs in git mode (default)
668 --nodates omit dates from diff headers
669 --nodates omit dates from diff headers
669 --noprefix omit a/ and b/ prefixes from filenames
670 --noprefix omit a/ and b/ prefixes from filenames
670 -p --show-function show which function each change is in
671 -p --show-function show which function each change is in
671 --reverse produce a diff that undoes the changes
672 --reverse produce a diff that undoes the changes
672 -w --ignore-all-space ignore white space when comparing lines
673 -w --ignore-all-space ignore white space when comparing lines
673 -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
674 -B --ignore-blank-lines ignore changes whose lines are all blank
675 -B --ignore-blank-lines ignore changes whose lines are all blank
675 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
676 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
676 -U --unified NUM number of lines of context to show
677 -U --unified NUM number of lines of context to show
677 --stat output diffstat-style summary of changes
678 --stat output diffstat-style summary of changes
678 --root DIR produce diffs relative to subdirectory
679 --root DIR produce diffs relative to subdirectory
679 -I --include PATTERN [+] include names matching the given patterns
680 -I --include PATTERN [+] include names matching the given patterns
680 -X --exclude PATTERN [+] exclude names matching the given patterns
681 -X --exclude PATTERN [+] exclude names matching the given patterns
681 -S --subrepos recurse into subrepositories
682 -S --subrepos recurse into subrepositories
682
683
683 (some details hidden, use --verbose to show complete help)
684 (some details hidden, use --verbose to show complete help)
684
685
685 $ hg help status
686 $ hg help status
686 hg status [OPTION]... [FILE]...
687 hg status [OPTION]... [FILE]...
687
688
688 aliases: st
689 aliases: st
689
690
690 show changed files in the working directory
691 show changed files in the working directory
691
692
692 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
693 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
694 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
695 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
695 -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
696 only ..." are given, the options -mardu are used.
697 only ..." are given, the options -mardu are used.
697
698
698 Option -q/--quiet hides untracked (unknown and ignored) files unless
699 Option -q/--quiet hides untracked (unknown and ignored) files unless
699 explicitly requested with -u/--unknown or -i/--ignored.
700 explicitly requested with -u/--unknown or -i/--ignored.
700
701
701 Note:
702 Note:
702 'hg status' may appear to disagree with diff if permissions have
703 'hg status' may appear to disagree with diff if permissions have
703 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
704 report permission changes and diff only reports changes relative to one
705 report permission changes and diff only reports changes relative to one
705 merge parent.
706 merge parent.
706
707
707 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
708 revisions are given, the differences between them are shown. The --change
709 revisions are given, the differences between them are shown. The --change
709 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
710 revision from its first parent.
711 revision from its first parent.
711
712
712 The codes used to show the status of files are:
713 The codes used to show the status of files are:
713
714
714 M = modified
715 M = modified
715 A = added
716 A = added
716 R = removed
717 R = removed
717 C = clean
718 C = clean
718 ! = missing (deleted by non-hg command, but still tracked)
719 ! = missing (deleted by non-hg command, but still tracked)
719 ? = not tracked
720 ? = not tracked
720 I = ignored
721 I = ignored
721 = origin of the previous file (with --copies)
722 = origin of the previous file (with --copies)
722
723
723 Returns 0 on success.
724 Returns 0 on success.
724
725
725 options ([+] can be repeated):
726 options ([+] can be repeated):
726
727
727 -A --all show status of all files
728 -A --all show status of all files
728 -m --modified show only modified files
729 -m --modified show only modified files
729 -a --added show only added files
730 -a --added show only added files
730 -r --removed show only removed files
731 -r --removed show only removed files
731 -d --deleted show only deleted (but tracked) files
732 -d --deleted show only deleted (but tracked) files
732 -c --clean show only files without changes
733 -c --clean show only files without changes
733 -u --unknown show only unknown (not tracked) files
734 -u --unknown show only unknown (not tracked) files
734 -i --ignored show only ignored files
735 -i --ignored show only ignored files
735 -n --no-status hide status prefix
736 -n --no-status hide status prefix
736 -C --copies show source of copied files
737 -C --copies show source of copied files
737 -0 --print0 end filenames with NUL, for use with xargs
738 -0 --print0 end filenames with NUL, for use with xargs
738 --rev REV [+] show difference from revision
739 --rev REV [+] show difference from revision
739 --change REV list the changed files of a revision
740 --change REV list the changed files of a revision
740 -I --include PATTERN [+] include names matching the given patterns
741 -I --include PATTERN [+] include names matching the given patterns
741 -X --exclude PATTERN [+] exclude names matching the given patterns
742 -X --exclude PATTERN [+] exclude names matching the given patterns
742 -S --subrepos recurse into subrepositories
743 -S --subrepos recurse into subrepositories
743 -T --template TEMPLATE display with template
744 -T --template TEMPLATE display with template
744
745
745 (some details hidden, use --verbose to show complete help)
746 (some details hidden, use --verbose to show complete help)
746
747
747 $ hg -q help status
748 $ hg -q help status
748 hg status [OPTION]... [FILE]...
749 hg status [OPTION]... [FILE]...
749
750
750 show changed files in the working directory
751 show changed files in the working directory
751
752
752 $ hg help foo
753 $ hg help foo
753 abort: no such help topic: foo
754 abort: no such help topic: foo
754 (try 'hg help --keyword foo')
755 (try 'hg help --keyword foo')
755 [255]
756 [255]
756
757
757 $ hg skjdfks
758 $ hg skjdfks
758 hg: unknown command 'skjdfks'
759 hg: unknown command 'skjdfks'
759 (use 'hg help' for a list of commands)
760 (use 'hg help' for a list of commands)
760 [255]
761 [255]
761
762
762 Typoed command gives suggestion
763 Typoed command gives suggestion
763 $ hg puls
764 $ hg puls
764 hg: unknown command 'puls'
765 hg: unknown command 'puls'
765 (did you mean one of pull, push?)
766 (did you mean one of pull, push?)
766 [255]
767 [255]
767
768
768 Not enabled extension gets suggested
769 Not enabled extension gets suggested
769
770
770 $ hg rebase
771 $ hg rebase
771 hg: unknown command 'rebase'
772 hg: unknown command 'rebase'
772 'rebase' is provided by the following extension:
773 'rebase' is provided by the following extension:
773
774
774 rebase command to move sets of revisions to a different ancestor
775 rebase command to move sets of revisions to a different ancestor
775
776
776 (use 'hg help extensions' for information on enabling extensions)
777 (use 'hg help extensions' for information on enabling extensions)
777 [255]
778 [255]
778
779
779 Disabled extension gets suggested
780 Disabled extension gets suggested
780 $ hg --config extensions.rebase=! rebase
781 $ hg --config extensions.rebase=! rebase
781 hg: unknown command 'rebase'
782 hg: unknown command 'rebase'
782 'rebase' is provided by the following extension:
783 'rebase' is provided by the following extension:
783
784
784 rebase command to move sets of revisions to a different ancestor
785 rebase command to move sets of revisions to a different ancestor
785
786
786 (use 'hg help extensions' for information on enabling extensions)
787 (use 'hg help extensions' for information on enabling extensions)
787 [255]
788 [255]
788
789
789 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
790 this is a section and erroring out weirdly.
791 this is a section and erroring out weirdly.
791
792
792 $ hg .log
793 $ hg .log
793 hg: unknown command '.log'
794 hg: unknown command '.log'
794 (did you mean log?)
795 (did you mean log?)
795 [255]
796 [255]
796
797
797 $ hg log.
798 $ hg log.
798 hg: unknown command 'log.'
799 hg: unknown command 'log.'
799 (did you mean log?)
800 (did you mean log?)
800 [255]
801 [255]
801 $ hg pu.lh
802 $ hg pu.lh
802 hg: unknown command 'pu.lh'
803 hg: unknown command 'pu.lh'
803 (did you mean one of pull, push?)
804 (did you mean one of pull, push?)
804 [255]
805 [255]
805
806
806 $ cat > helpext.py <<EOF
807 $ cat > helpext.py <<EOF
807 > import os
808 > import os
808 > from mercurial import commands, fancyopts, registrar
809 > from mercurial import commands, fancyopts, registrar
809 >
810 >
810 > def func(arg):
811 > def func(arg):
811 > return '%sfoo' % arg
812 > return '%sfoo' % arg
812 > class customopt(fancyopts.customopt):
813 > class customopt(fancyopts.customopt):
813 > def newstate(self, oldstate, newparam, abort):
814 > def newstate(self, oldstate, newparam, abort):
814 > return '%sbar' % oldstate
815 > return '%sbar' % oldstate
815 > cmdtable = {}
816 > cmdtable = {}
816 > command = registrar.command(cmdtable)
817 > command = registrar.command(cmdtable)
817 >
818 >
818 > @command(b'nohelp',
819 > @command(b'nohelp',
819 > [(b'', b'longdesc', 3, b'x'*67),
820 > [(b'', b'longdesc', 3, b'x'*67),
820 > (b'n', b'', None, b'normal desc'),
821 > (b'n', b'', None, b'normal desc'),
821 > (b'', b'newline', b'', b'line1\nline2'),
822 > (b'', b'newline', b'', b'line1\nline2'),
822 > (b'', b'default-off', False, b'enable X'),
823 > (b'', b'default-off', False, b'enable X'),
823 > (b'', b'default-on', True, b'enable Y'),
824 > (b'', b'default-on', True, b'enable Y'),
824 > (b'', b'callableopt', func, b'adds foo'),
825 > (b'', b'callableopt', func, b'adds foo'),
825 > (b'', b'customopt', customopt(''), b'adds bar'),
826 > (b'', b'customopt', customopt(''), b'adds bar'),
826 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
827 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
827 > b'hg nohelp',
828 > b'hg nohelp',
828 > norepo=True)
829 > norepo=True)
829 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
830 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
830 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
831 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
831 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
832 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
832 > def nohelp(ui, *args, **kwargs):
833 > def nohelp(ui, *args, **kwargs):
833 > pass
834 > pass
834 >
835 >
835 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
836 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
836 > def hashelp(ui, *args, **kwargs):
837 > def hashelp(ui, *args, **kwargs):
837 > """Extension command's help"""
838 > """Extension command's help"""
838 >
839 >
839 > def uisetup(ui):
840 > def uisetup(ui):
840 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
841 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
841 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
842 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
842 > 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')
843 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
844 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
844 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
845 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
845 >
846 >
846 > EOF
847 > EOF
847 $ echo '[extensions]' >> $HGRCPATH
848 $ echo '[extensions]' >> $HGRCPATH
848 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
849 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
849
850
850 Test for aliases
851 Test for aliases
851
852
852 $ hg help | grep hgalias
853 $ hg help | grep hgalias
853 hgalias My doc
854 hgalias My doc
854
855
855 $ hg help hgalias
856 $ hg help hgalias
856 hg hgalias [--remote]
857 hg hgalias [--remote]
857
858
858 alias for: hg summary
859 alias for: hg summary
859
860
860 My doc
861 My doc
861
862
862 defined by: helpext
863 defined by: helpext
863
864
864 options:
865 options:
865
866
866 --remote check for push and pull
867 --remote check for push and pull
867
868
868 (some details hidden, use --verbose to show complete help)
869 (some details hidden, use --verbose to show complete help)
869 $ hg help hgaliasnodoc
870 $ hg help hgaliasnodoc
870 hg hgaliasnodoc [--remote]
871 hg hgaliasnodoc [--remote]
871
872
872 alias for: hg summary
873 alias for: hg summary
873
874
874 summarize working directory state
875 summarize working directory state
875
876
876 This generates a brief summary of the working directory state, including
877 This generates a brief summary of the working directory state, including
877 parents, branch, commit status, phase and available updates.
878 parents, branch, commit status, phase and available updates.
878
879
879 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
880 and outgoing changes. This can be time-consuming.
881 and outgoing changes. This can be time-consuming.
881
882
882 Returns 0 on success.
883 Returns 0 on success.
883
884
884 defined by: helpext
885 defined by: helpext
885
886
886 options:
887 options:
887
888
888 --remote check for push and pull
889 --remote check for push and pull
889
890
890 (some details hidden, use --verbose to show complete help)
891 (some details hidden, use --verbose to show complete help)
891
892
892 $ hg help shellalias
893 $ hg help shellalias
893 hg shellalias
894 hg shellalias
894
895
895 shell alias for: echo hi
896 shell alias for: echo hi
896
897
897 (no help text available)
898 (no help text available)
898
899
899 defined by: helpext
900 defined by: helpext
900
901
901 (some details hidden, use --verbose to show complete help)
902 (some details hidden, use --verbose to show complete help)
902
903
903 Test command with no help text
904 Test command with no help text
904
905
905 $ hg help nohelp
906 $ hg help nohelp
906 hg nohelp
907 hg nohelp
907
908
908 (no help text available)
909 (no help text available)
909
910
910 options:
911 options:
911
912
912 --longdesc VALUE
913 --longdesc VALUE
913 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
914 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
914 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
915 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
915 -n -- normal desc
916 -n -- normal desc
916 --newline VALUE line1 line2
917 --newline VALUE line1 line2
917 --default-off enable X
918 --default-off enable X
918 --[no-]default-on enable Y (default: on)
919 --[no-]default-on enable Y (default: on)
919 --callableopt VALUE adds foo
920 --callableopt VALUE adds foo
920 --customopt VALUE adds bar
921 --customopt VALUE adds bar
921 --customopt-withdefault VALUE adds bar (default: foo)
922 --customopt-withdefault VALUE adds bar (default: foo)
922
923
923 (some details hidden, use --verbose to show complete help)
924 (some details hidden, use --verbose to show complete help)
924
925
925 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,
926 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
927 when help about the extension is requested.
928 when help about the extension is requested.
928
929
929 #if no-extraextensions
930 #if no-extraextensions
930
931
931 $ hg help | grep hashelp
932 $ hg help | grep hashelp
932 hashelp Extension command's help
933 hashelp Extension command's help
933 $ hg help | grep nohelp
934 $ hg help | grep nohelp
934 [1]
935 [1]
935 $ hg help -v | grep nohelp
936 $ hg help -v | grep nohelp
936 nohelp (no help text available)
937 nohelp (no help text available)
937
938
938 $ hg help -k nohelp
939 $ hg help -k nohelp
939 Commands:
940 Commands:
940
941
941 nohelp hg nohelp
942 nohelp hg nohelp
942
943
943 Extension Commands:
944 Extension Commands:
944
945
945 nohelp (no help text available)
946 nohelp (no help text available)
946
947
947 $ hg help helpext
948 $ hg help helpext
948 helpext extension - no help text available
949 helpext extension - no help text available
949
950
950 list of commands:
951 list of commands:
951
952
952 hashelp Extension command's help
953 hashelp Extension command's help
953 nohelp (no help text available)
954 nohelp (no help text available)
954
955
955 (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)
956
957
957 #endif
958 #endif
958
959
959 Test list of internal help commands
960 Test list of internal help commands
960
961
961 $ hg help debug
962 $ hg help debug
962 debug commands (internal and unsupported):
963 debug commands (internal and unsupported):
963
964
964 debugancestor
965 debugancestor
965 find the ancestor revision of two revisions in a given index
966 find the ancestor revision of two revisions in a given index
966 debugapplystreamclonebundle
967 debugapplystreamclonebundle
967 apply a stream clone bundle file
968 apply a stream clone bundle file
968 debugbuilddag
969 debugbuilddag
969 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
970 empty repo
971 empty repo
971 debugbundle lists the contents of a bundle
972 debugbundle lists the contents of a bundle
972 debugcapabilities
973 debugcapabilities
973 lists the capabilities of a remote peer
974 lists the capabilities of a remote peer
974 debugcheckstate
975 debugcheckstate
975 validate the correctness of the current dirstate
976 validate the correctness of the current dirstate
976 debugcolor show available color, effects or style
977 debugcolor show available color, effects or style
977 debugcommands
978 debugcommands
978 list all available commands and options
979 list all available commands and options
979 debugcomplete
980 debugcomplete
980 returns the completion list associated with the given command
981 returns the completion list associated with the given command
981 debugcreatestreamclonebundle
982 debugcreatestreamclonebundle
982 create a stream clone bundle file
983 create a stream clone bundle file
983 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
984 description
985 description
985 debugdata dump the contents of a data file revision
986 debugdata dump the contents of a data file revision
986 debugdate parse and display a date
987 debugdate parse and display a date
987 debugdeltachain
988 debugdeltachain
988 dump information about delta chains in a revlog
989 dump information about delta chains in a revlog
989 debugdirstate
990 debugdirstate
990 show the contents of the current dirstate
991 show the contents of the current dirstate
991 debugdiscovery
992 debugdiscovery
992 runs the changeset discovery protocol in isolation
993 runs the changeset discovery protocol in isolation
993 debugdownload
994 debugdownload
994 download a resource using Mercurial logic and config
995 download a resource using Mercurial logic and config
995 debugextensions
996 debugextensions
996 show information about active extensions
997 show information about active extensions
997 debugfileset parse and apply a fileset specification
998 debugfileset parse and apply a fileset specification
998 debugformat display format information about the current repository
999 debugformat display format information about the current repository
999 debugfsinfo show information detected about current filesystem
1000 debugfsinfo show information detected about current filesystem
1000 debuggetbundle
1001 debuggetbundle
1001 retrieves a bundle from a repo
1002 retrieves a bundle from a repo
1002 debugignore display the combined ignore pattern and information about
1003 debugignore display the combined ignore pattern and information about
1003 ignored files
1004 ignored files
1004 debugindex dump index data for a storage primitive
1005 debugindex dump index data for a storage primitive
1005 debugindexdot
1006 debugindexdot
1006 dump an index DAG as a graphviz dot file
1007 dump an index DAG as a graphviz dot file
1007 debugindexstats
1008 debugindexstats
1008 show stats related to the changelog index
1009 show stats related to the changelog index
1009 debuginstall test Mercurial installation
1010 debuginstall test Mercurial installation
1010 debugknown test whether node ids are known to a repo
1011 debugknown test whether node ids are known to a repo
1011 debuglocks show or modify state of locks
1012 debuglocks show or modify state of locks
1012 debugmanifestfulltextcache
1013 debugmanifestfulltextcache
1013 show, clear or amend the contents of the manifest fulltext
1014 show, clear or amend the contents of the manifest fulltext
1014 cache
1015 cache
1015 debugmergestate
1016 debugmergestate
1016 print merge state
1017 print merge state
1017 debugnamecomplete
1018 debugnamecomplete
1018 complete "names" - tags, open branch names, bookmark names
1019 complete "names" - tags, open branch names, bookmark names
1019 debugobsolete
1020 debugobsolete
1020 create arbitrary obsolete marker
1021 create arbitrary obsolete marker
1021 debugoptADV (no help text available)
1022 debugoptADV (no help text available)
1022 debugoptDEP (no help text available)
1023 debugoptDEP (no help text available)
1023 debugoptEXP (no help text available)
1024 debugoptEXP (no help text available)
1024 debugp1copies
1025 debugp1copies
1025 dump copy information compared to p1
1026 dump copy information compared to p1
1026 debugp2copies
1027 debugp2copies
1027 dump copy information compared to p2
1028 dump copy information compared to p2
1028 debugpathcomplete
1029 debugpathcomplete
1029 complete part or all of a tracked path
1030 complete part or all of a tracked path
1030 debugpathcopies
1031 debugpathcopies
1031 show copies between two revisions
1032 show copies between two revisions
1032 debugpeer establish a connection to a peer repository
1033 debugpeer establish a connection to a peer repository
1033 debugpickmergetool
1034 debugpickmergetool
1034 examine which merge tool is chosen for specified file
1035 examine which merge tool is chosen for specified file
1035 debugpushkey access the pushkey key/value protocol
1036 debugpushkey access the pushkey key/value protocol
1036 debugpvec (no help text available)
1037 debugpvec (no help text available)
1037 debugrebuilddirstate
1038 debugrebuilddirstate
1038 rebuild the dirstate as it would look like for the given
1039 rebuild the dirstate as it would look like for the given
1039 revision
1040 revision
1040 debugrebuildfncache
1041 debugrebuildfncache
1041 rebuild the fncache file
1042 rebuild the fncache file
1042 debugrename dump rename information
1043 debugrename dump rename information
1043 debugrevlog show data and statistics about a revlog
1044 debugrevlog show data and statistics about a revlog
1044 debugrevlogindex
1045 debugrevlogindex
1045 dump the contents of a revlog index
1046 dump the contents of a revlog index
1046 debugrevspec parse and apply a revision specification
1047 debugrevspec parse and apply a revision specification
1047 debugserve run a server with advanced settings
1048 debugserve run a server with advanced settings
1048 debugsetparents
1049 debugsetparents
1049 manually set the parents of the current working directory
1050 manually set the parents of the current working directory
1050 debugssl test a secure connection to a server
1051 debugssl test a secure connection to a server
1051 debugsub (no help text available)
1052 debugsub (no help text available)
1052 debugsuccessorssets
1053 debugsuccessorssets
1053 show set of successors for revision
1054 show set of successors for revision
1054 debugtemplate
1055 debugtemplate
1055 parse and apply a template
1056 parse and apply a template
1056 debuguigetpass
1057 debuguigetpass
1057 show prompt to type password
1058 show prompt to type password
1058 debuguiprompt
1059 debuguiprompt
1059 show plain prompt
1060 show plain prompt
1060 debugupdatecaches
1061 debugupdatecaches
1061 warm all known caches in the repository
1062 warm all known caches in the repository
1062 debugupgraderepo
1063 debugupgraderepo
1063 upgrade a repository to use different features
1064 upgrade a repository to use different features
1064 debugwalk show how files match on given patterns
1065 debugwalk show how files match on given patterns
1065 debugwhyunstable
1066 debugwhyunstable
1066 explain instabilities of a changeset
1067 explain instabilities of a changeset
1067 debugwireargs
1068 debugwireargs
1068 (no help text available)
1069 (no help text available)
1069 debugwireproto
1070 debugwireproto
1070 send wire protocol commands to a server
1071 send wire protocol commands to a server
1071
1072
1072 (use 'hg help -v debug' to show built-in aliases and global options)
1073 (use 'hg help -v debug' to show built-in aliases and global options)
1073
1074
1074 internals topic renders index of available sub-topics
1075 internals topic renders index of available sub-topics
1075
1076
1076 $ hg help internals
1077 $ hg help internals
1077 Technical implementation topics
1078 Technical implementation topics
1078 """""""""""""""""""""""""""""""
1079 """""""""""""""""""""""""""""""
1079
1080
1080 To access a subtopic, use "hg help internals.{subtopic-name}"
1081 To access a subtopic, use "hg help internals.{subtopic-name}"
1081
1082
1082 bundle2 Bundle2
1083 bundle2 Bundle2
1083 bundles Bundles
1084 bundles Bundles
1084 cbor CBOR
1085 cbor CBOR
1085 censor Censor
1086 censor Censor
1086 changegroups Changegroups
1087 changegroups Changegroups
1087 config Config Registrar
1088 config Config Registrar
1088 extensions Extension API
1089 extensions Extension API
1089 mergestate Mergestate
1090 mergestate Mergestate
1090 requirements Repository Requirements
1091 requirements Repository Requirements
1091 revlogs Revision Logs
1092 revlogs Revision Logs
1092 wireprotocol Wire Protocol
1093 wireprotocol Wire Protocol
1093 wireprotocolrpc
1094 wireprotocolrpc
1094 Wire Protocol RPC
1095 Wire Protocol RPC
1095 wireprotocolv2
1096 wireprotocolv2
1096 Wire Protocol Version 2
1097 Wire Protocol Version 2
1097
1098
1098 sub-topics can be accessed
1099 sub-topics can be accessed
1099
1100
1100 $ hg help internals.changegroups
1101 $ hg help internals.changegroups
1101 Changegroups
1102 Changegroups
1102 """"""""""""
1103 """"""""""""
1103
1104
1104 Changegroups are representations of repository revlog data, specifically
1105 Changegroups are representations of repository revlog data, specifically
1105 the changelog data, root/flat manifest data, treemanifest data, and
1106 the changelog data, root/flat manifest data, treemanifest data, and
1106 filelogs.
1107 filelogs.
1107
1108
1108 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1109 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1109 level, versions "1" and "2" are almost exactly the same, with the only
1110 level, versions "1" and "2" are almost exactly the same, with the only
1110 difference being an additional item in the *delta header*. Version "3"
1111 difference being an additional item in the *delta header*. Version "3"
1111 adds support for storage flags in the *delta header* and optionally
1112 adds support for storage flags in the *delta header* and optionally
1112 exchanging treemanifests (enabled by setting an option on the
1113 exchanging treemanifests (enabled by setting an option on the
1113 "changegroup" part in the bundle2).
1114 "changegroup" part in the bundle2).
1114
1115
1115 Changegroups when not exchanging treemanifests consist of 3 logical
1116 Changegroups when not exchanging treemanifests consist of 3 logical
1116 segments:
1117 segments:
1117
1118
1118 +---------------------------------+
1119 +---------------------------------+
1119 | | | |
1120 | | | |
1120 | changeset | manifest | filelogs |
1121 | changeset | manifest | filelogs |
1121 | | | |
1122 | | | |
1122 | | | |
1123 | | | |
1123 +---------------------------------+
1124 +---------------------------------+
1124
1125
1125 When exchanging treemanifests, there are 4 logical segments:
1126 When exchanging treemanifests, there are 4 logical segments:
1126
1127
1127 +-------------------------------------------------+
1128 +-------------------------------------------------+
1128 | | | | |
1129 | | | | |
1129 | changeset | root | treemanifests | filelogs |
1130 | changeset | root | treemanifests | filelogs |
1130 | | manifest | | |
1131 | | manifest | | |
1131 | | | | |
1132 | | | | |
1132 +-------------------------------------------------+
1133 +-------------------------------------------------+
1133
1134
1134 The principle building block of each segment is a *chunk*. A *chunk* is a
1135 The principle building block of each segment is a *chunk*. A *chunk* is a
1135 framed piece of data:
1136 framed piece of data:
1136
1137
1137 +---------------------------------------+
1138 +---------------------------------------+
1138 | | |
1139 | | |
1139 | length | data |
1140 | length | data |
1140 | (4 bytes) | (<length - 4> bytes) |
1141 | (4 bytes) | (<length - 4> bytes) |
1141 | | |
1142 | | |
1142 +---------------------------------------+
1143 +---------------------------------------+
1143
1144
1144 All integers are big-endian signed integers. Each chunk starts with a
1145 All integers are big-endian signed integers. Each chunk starts with a
1145 32-bit integer indicating the length of the entire chunk (including the
1146 32-bit integer indicating the length of the entire chunk (including the
1146 length field itself).
1147 length field itself).
1147
1148
1148 There is a special case chunk that has a value of 0 for the length
1149 There is a special case chunk that has a value of 0 for the length
1149 ("0x00000000"). We call this an *empty chunk*.
1150 ("0x00000000"). We call this an *empty chunk*.
1150
1151
1151 Delta Groups
1152 Delta Groups
1152 ============
1153 ============
1153
1154
1154 A *delta group* expresses the content of a revlog as a series of deltas,
1155 A *delta group* expresses the content of a revlog as a series of deltas,
1155 or patches against previous revisions.
1156 or patches against previous revisions.
1156
1157
1157 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1158 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1158 to signal the end of the delta group:
1159 to signal the end of the delta group:
1159
1160
1160 +------------------------------------------------------------------------+
1161 +------------------------------------------------------------------------+
1161 | | | | | |
1162 | | | | | |
1162 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1163 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1163 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1164 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1164 | | | | | |
1165 | | | | | |
1165 +------------------------------------------------------------------------+
1166 +------------------------------------------------------------------------+
1166
1167
1167 Each *chunk*'s data consists of the following:
1168 Each *chunk*'s data consists of the following:
1168
1169
1169 +---------------------------------------+
1170 +---------------------------------------+
1170 | | |
1171 | | |
1171 | delta header | delta data |
1172 | delta header | delta data |
1172 | (various by version) | (various) |
1173 | (various by version) | (various) |
1173 | | |
1174 | | |
1174 +---------------------------------------+
1175 +---------------------------------------+
1175
1176
1176 The *delta data* is a series of *delta*s that describe a diff from an
1177 The *delta data* is a series of *delta*s that describe a diff from an
1177 existing entry (either that the recipient already has, or previously
1178 existing entry (either that the recipient already has, or previously
1178 specified in the bundle/changegroup).
1179 specified in the bundle/changegroup).
1179
1180
1180 The *delta header* is different between versions "1", "2", and "3" of the
1181 The *delta header* is different between versions "1", "2", and "3" of the
1181 changegroup format.
1182 changegroup format.
1182
1183
1183 Version 1 (headerlen=80):
1184 Version 1 (headerlen=80):
1184
1185
1185 +------------------------------------------------------+
1186 +------------------------------------------------------+
1186 | | | | |
1187 | | | | |
1187 | node | p1 node | p2 node | link node |
1188 | node | p1 node | p2 node | link node |
1188 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1189 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1189 | | | | |
1190 | | | | |
1190 +------------------------------------------------------+
1191 +------------------------------------------------------+
1191
1192
1192 Version 2 (headerlen=100):
1193 Version 2 (headerlen=100):
1193
1194
1194 +------------------------------------------------------------------+
1195 +------------------------------------------------------------------+
1195 | | | | | |
1196 | | | | | |
1196 | node | p1 node | p2 node | base node | link node |
1197 | node | p1 node | p2 node | base node | link node |
1197 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1198 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1198 | | | | | |
1199 | | | | | |
1199 +------------------------------------------------------------------+
1200 +------------------------------------------------------------------+
1200
1201
1201 Version 3 (headerlen=102):
1202 Version 3 (headerlen=102):
1202
1203
1203 +------------------------------------------------------------------------------+
1204 +------------------------------------------------------------------------------+
1204 | | | | | | |
1205 | | | | | | |
1205 | node | p1 node | p2 node | base node | link node | flags |
1206 | node | p1 node | p2 node | base node | link node | flags |
1206 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1207 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1207 | | | | | | |
1208 | | | | | | |
1208 +------------------------------------------------------------------------------+
1209 +------------------------------------------------------------------------------+
1209
1210
1210 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1211 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1211 contain a series of *delta*s, densely packed (no separators). These deltas
1212 contain a series of *delta*s, densely packed (no separators). These deltas
1212 describe a diff from an existing entry (either that the recipient already
1213 describe a diff from an existing entry (either that the recipient already
1213 has, or previously specified in the bundle/changegroup). The format is
1214 has, or previously specified in the bundle/changegroup). The format is
1214 described more fully in "hg help internals.bdiff", but briefly:
1215 described more fully in "hg help internals.bdiff", but briefly:
1215
1216
1216 +---------------------------------------------------------------+
1217 +---------------------------------------------------------------+
1217 | | | | |
1218 | | | | |
1218 | start offset | end offset | new length | content |
1219 | start offset | end offset | new length | content |
1219 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1220 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1220 | | | | |
1221 | | | | |
1221 +---------------------------------------------------------------+
1222 +---------------------------------------------------------------+
1222
1223
1223 Please note that the length field in the delta data does *not* include
1224 Please note that the length field in the delta data does *not* include
1224 itself.
1225 itself.
1225
1226
1226 In version 1, the delta is always applied against the previous node from
1227 In version 1, the delta is always applied against the previous node from
1227 the changegroup or the first parent if this is the first entry in the
1228 the changegroup or the first parent if this is the first entry in the
1228 changegroup.
1229 changegroup.
1229
1230
1230 In version 2 and up, the delta base node is encoded in the entry in the
1231 In version 2 and up, the delta base node is encoded in the entry in the
1231 changegroup. This allows the delta to be expressed against any parent,
1232 changegroup. This allows the delta to be expressed against any parent,
1232 which can result in smaller deltas and more efficient encoding of data.
1233 which can result in smaller deltas and more efficient encoding of data.
1233
1234
1234 The *flags* field holds bitwise flags affecting the processing of revision
1235 The *flags* field holds bitwise flags affecting the processing of revision
1235 data. The following flags are defined:
1236 data. The following flags are defined:
1236
1237
1237 32768
1238 32768
1238 Censored revision. The revision's fulltext has been replaced by censor
1239 Censored revision. The revision's fulltext has been replaced by censor
1239 metadata. May only occur on file revisions.
1240 metadata. May only occur on file revisions.
1240
1241
1241 16384
1242 16384
1242 Ellipsis revision. Revision hash does not match data (likely due to
1243 Ellipsis revision. Revision hash does not match data (likely due to
1243 rewritten parents).
1244 rewritten parents).
1244
1245
1245 8192
1246 8192
1246 Externally stored. The revision fulltext contains "key:value" "\n"
1247 Externally stored. The revision fulltext contains "key:value" "\n"
1247 delimited metadata defining an object stored elsewhere. Used by the LFS
1248 delimited metadata defining an object stored elsewhere. Used by the LFS
1248 extension.
1249 extension.
1249
1250
1250 For historical reasons, the integer values are identical to revlog version
1251 For historical reasons, the integer values are identical to revlog version
1251 1 per-revision storage flags and correspond to bits being set in this
1252 1 per-revision storage flags and correspond to bits being set in this
1252 2-byte field. Bits were allocated starting from the most-significant bit,
1253 2-byte field. Bits were allocated starting from the most-significant bit,
1253 hence the reverse ordering and allocation of these flags.
1254 hence the reverse ordering and allocation of these flags.
1254
1255
1255 Changeset Segment
1256 Changeset Segment
1256 =================
1257 =================
1257
1258
1258 The *changeset segment* consists of a single *delta group* holding
1259 The *changeset segment* consists of a single *delta group* holding
1259 changelog data. The *empty chunk* at the end of the *delta group* denotes
1260 changelog data. The *empty chunk* at the end of the *delta group* denotes
1260 the boundary to the *manifest segment*.
1261 the boundary to the *manifest segment*.
1261
1262
1262 Manifest Segment
1263 Manifest Segment
1263 ================
1264 ================
1264
1265
1265 The *manifest segment* consists of a single *delta group* holding manifest
1266 The *manifest segment* consists of a single *delta group* holding manifest
1266 data. If treemanifests are in use, it contains only the manifest for the
1267 data. If treemanifests are in use, it contains only the manifest for the
1267 root directory of the repository. Otherwise, it contains the entire
1268 root directory of the repository. Otherwise, it contains the entire
1268 manifest data. The *empty chunk* at the end of the *delta group* denotes
1269 manifest data. The *empty chunk* at the end of the *delta group* denotes
1269 the boundary to the next segment (either the *treemanifests segment* or
1270 the boundary to the next segment (either the *treemanifests segment* or
1270 the *filelogs segment*, depending on version and the request options).
1271 the *filelogs segment*, depending on version and the request options).
1271
1272
1272 Treemanifests Segment
1273 Treemanifests Segment
1273 ---------------------
1274 ---------------------
1274
1275
1275 The *treemanifests segment* only exists in changegroup version "3", and
1276 The *treemanifests segment* only exists in changegroup version "3", and
1276 only if the 'treemanifest' param is part of the bundle2 changegroup part
1277 only if the 'treemanifest' param is part of the bundle2 changegroup part
1277 (it is not possible to use changegroup version 3 outside of bundle2).
1278 (it is not possible to use changegroup version 3 outside of bundle2).
1278 Aside from the filenames in the *treemanifests segment* containing a
1279 Aside from the filenames in the *treemanifests segment* containing a
1279 trailing "/" character, it behaves identically to the *filelogs segment*
1280 trailing "/" character, it behaves identically to the *filelogs segment*
1280 (see below). The final sub-segment is followed by an *empty chunk*
1281 (see below). The final sub-segment is followed by an *empty chunk*
1281 (logically, a sub-segment with filename size 0). This denotes the boundary
1282 (logically, a sub-segment with filename size 0). This denotes the boundary
1282 to the *filelogs segment*.
1283 to the *filelogs segment*.
1283
1284
1284 Filelogs Segment
1285 Filelogs Segment
1285 ================
1286 ================
1286
1287
1287 The *filelogs segment* consists of multiple sub-segments, each
1288 The *filelogs segment* consists of multiple sub-segments, each
1288 corresponding to an individual file whose data is being described:
1289 corresponding to an individual file whose data is being described:
1289
1290
1290 +--------------------------------------------------+
1291 +--------------------------------------------------+
1291 | | | | | |
1292 | | | | | |
1292 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1293 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1293 | | | | | (4 bytes) |
1294 | | | | | (4 bytes) |
1294 | | | | | |
1295 | | | | | |
1295 +--------------------------------------------------+
1296 +--------------------------------------------------+
1296
1297
1297 The final filelog sub-segment is followed by an *empty chunk* (logically,
1298 The final filelog sub-segment is followed by an *empty chunk* (logically,
1298 a sub-segment with filename size 0). This denotes the end of the segment
1299 a sub-segment with filename size 0). This denotes the end of the segment
1299 and of the overall changegroup.
1300 and of the overall changegroup.
1300
1301
1301 Each filelog sub-segment consists of the following:
1302 Each filelog sub-segment consists of the following:
1302
1303
1303 +------------------------------------------------------+
1304 +------------------------------------------------------+
1304 | | | |
1305 | | | |
1305 | filename length | filename | delta group |
1306 | filename length | filename | delta group |
1306 | (4 bytes) | (<length - 4> bytes) | (various) |
1307 | (4 bytes) | (<length - 4> bytes) | (various) |
1307 | | | |
1308 | | | |
1308 +------------------------------------------------------+
1309 +------------------------------------------------------+
1309
1310
1310 That is, a *chunk* consisting of the filename (not terminated or padded)
1311 That is, a *chunk* consisting of the filename (not terminated or padded)
1311 followed by N chunks constituting the *delta group* for this file. The
1312 followed by N chunks constituting the *delta group* for this file. The
1312 *empty chunk* at the end of each *delta group* denotes the boundary to the
1313 *empty chunk* at the end of each *delta group* denotes the boundary to the
1313 next filelog sub-segment.
1314 next filelog sub-segment.
1314
1315
1315 non-existent subtopics print an error
1316 non-existent subtopics print an error
1316
1317
1317 $ hg help internals.foo
1318 $ hg help internals.foo
1318 abort: no such help topic: internals.foo
1319 abort: no such help topic: internals.foo
1319 (try 'hg help --keyword foo')
1320 (try 'hg help --keyword foo')
1320 [255]
1321 [255]
1321
1322
1322 test advanced, deprecated and experimental options are hidden in command help
1323 test advanced, deprecated and experimental options are hidden in command help
1323 $ hg help debugoptADV
1324 $ hg help debugoptADV
1324 hg debugoptADV
1325 hg debugoptADV
1325
1326
1326 (no help text available)
1327 (no help text available)
1327
1328
1328 options:
1329 options:
1329
1330
1330 (some details hidden, use --verbose to show complete help)
1331 (some details hidden, use --verbose to show complete help)
1331 $ hg help debugoptDEP
1332 $ hg help debugoptDEP
1332 hg debugoptDEP
1333 hg debugoptDEP
1333
1334
1334 (no help text available)
1335 (no help text available)
1335
1336
1336 options:
1337 options:
1337
1338
1338 (some details hidden, use --verbose to show complete help)
1339 (some details hidden, use --verbose to show complete help)
1339
1340
1340 $ hg help debugoptEXP
1341 $ hg help debugoptEXP
1341 hg debugoptEXP
1342 hg debugoptEXP
1342
1343
1343 (no help text available)
1344 (no help text available)
1344
1345
1345 options:
1346 options:
1346
1347
1347 (some details hidden, use --verbose to show complete help)
1348 (some details hidden, use --verbose to show complete help)
1348
1349
1349 test advanced, deprecated and experimental options are shown with -v
1350 test advanced, deprecated and experimental options are shown with -v
1350 $ hg help -v debugoptADV | grep aopt
1351 $ hg help -v debugoptADV | grep aopt
1351 --aopt option is (ADVANCED)
1352 --aopt option is (ADVANCED)
1352 $ hg help -v debugoptDEP | grep dopt
1353 $ hg help -v debugoptDEP | grep dopt
1353 --dopt option is (DEPRECATED)
1354 --dopt option is (DEPRECATED)
1354 $ hg help -v debugoptEXP | grep eopt
1355 $ hg help -v debugoptEXP | grep eopt
1355 --eopt option is (EXPERIMENTAL)
1356 --eopt option is (EXPERIMENTAL)
1356
1357
1357 #if gettext
1358 #if gettext
1358 test deprecated option is hidden with translation with untranslated description
1359 test deprecated option is hidden with translation with untranslated description
1359 (use many globy for not failing on changed transaction)
1360 (use many globy for not failing on changed transaction)
1360 $ LANGUAGE=sv hg help debugoptDEP
1361 $ LANGUAGE=sv hg help debugoptDEP
1361 hg debugoptDEP
1362 hg debugoptDEP
1362
1363
1363 (*) (glob)
1364 (*) (glob)
1364
1365
1365 options:
1366 options:
1366
1367
1367 (some details hidden, use --verbose to show complete help)
1368 (some details hidden, use --verbose to show complete help)
1368 #endif
1369 #endif
1369
1370
1370 Test commands that collide with topics (issue4240)
1371 Test commands that collide with topics (issue4240)
1371
1372
1372 $ hg config -hq
1373 $ hg config -hq
1373 hg config [-u] [NAME]...
1374 hg config [-u] [NAME]...
1374
1375
1375 show combined config settings from all hgrc files
1376 show combined config settings from all hgrc files
1376 $ hg showconfig -hq
1377 $ hg showconfig -hq
1377 hg config [-u] [NAME]...
1378 hg config [-u] [NAME]...
1378
1379
1379 show combined config settings from all hgrc files
1380 show combined config settings from all hgrc files
1380
1381
1381 Test a help topic
1382 Test a help topic
1382
1383
1383 $ hg help dates
1384 $ hg help dates
1384 Date Formats
1385 Date Formats
1385 """"""""""""
1386 """"""""""""
1386
1387
1387 Some commands allow the user to specify a date, e.g.:
1388 Some commands allow the user to specify a date, e.g.:
1388
1389
1389 - backout, commit, import, tag: Specify the commit date.
1390 - backout, commit, import, tag: Specify the commit date.
1390 - log, revert, update: Select revision(s) by date.
1391 - log, revert, update: Select revision(s) by date.
1391
1392
1392 Many date formats are valid. Here are some examples:
1393 Many date formats are valid. Here are some examples:
1393
1394
1394 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1395 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1395 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1396 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1396 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1397 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1397 - "Dec 6" (midnight)
1398 - "Dec 6" (midnight)
1398 - "13:18" (today assumed)
1399 - "13:18" (today assumed)
1399 - "3:39" (3:39AM assumed)
1400 - "3:39" (3:39AM assumed)
1400 - "3:39pm" (15:39)
1401 - "3:39pm" (15:39)
1401 - "2006-12-06 13:18:29" (ISO 8601 format)
1402 - "2006-12-06 13:18:29" (ISO 8601 format)
1402 - "2006-12-6 13:18"
1403 - "2006-12-6 13:18"
1403 - "2006-12-6"
1404 - "2006-12-6"
1404 - "12-6"
1405 - "12-6"
1405 - "12/6"
1406 - "12/6"
1406 - "12/6/6" (Dec 6 2006)
1407 - "12/6/6" (Dec 6 2006)
1407 - "today" (midnight)
1408 - "today" (midnight)
1408 - "yesterday" (midnight)
1409 - "yesterday" (midnight)
1409 - "now" - right now
1410 - "now" - right now
1410
1411
1411 Lastly, there is Mercurial's internal format:
1412 Lastly, there is Mercurial's internal format:
1412
1413
1413 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1414 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1414
1415
1415 This is the internal representation format for dates. The first number is
1416 This is the internal representation format for dates. The first number is
1416 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1417 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1417 is the offset of the local timezone, in seconds west of UTC (negative if
1418 is the offset of the local timezone, in seconds west of UTC (negative if
1418 the timezone is east of UTC).
1419 the timezone is east of UTC).
1419
1420
1420 The log command also accepts date ranges:
1421 The log command also accepts date ranges:
1421
1422
1422 - "<DATE" - at or before a given date/time
1423 - "<DATE" - at or before a given date/time
1423 - ">DATE" - on or after a given date/time
1424 - ">DATE" - on or after a given date/time
1424 - "DATE to DATE" - a date range, inclusive
1425 - "DATE to DATE" - a date range, inclusive
1425 - "-DAYS" - within a given number of days of today
1426 - "-DAYS" - within a given number of days of today
1426
1427
1427 Test repeated config section name
1428 Test repeated config section name
1428
1429
1429 $ hg help config.host
1430 $ hg help config.host
1430 "http_proxy.host"
1431 "http_proxy.host"
1431 Host name and (optional) port of the proxy server, for example
1432 Host name and (optional) port of the proxy server, for example
1432 "myproxy:8000".
1433 "myproxy:8000".
1433
1434
1434 "smtp.host"
1435 "smtp.host"
1435 Host name of mail server, e.g. "mail.example.com".
1436 Host name of mail server, e.g. "mail.example.com".
1436
1437
1437
1438
1438 Test section name with dot
1439 Test section name with dot
1439
1440
1440 $ hg help config.ui.username
1441 $ hg help config.ui.username
1441 "ui.username"
1442 "ui.username"
1442 The committer of a changeset created when running "commit". Typically
1443 The committer of a changeset created when running "commit". Typically
1443 a person's name and email address, e.g. "Fred Widget
1444 a person's name and email address, e.g. "Fred Widget
1444 <fred@example.com>". Environment variables in the username are
1445 <fred@example.com>". Environment variables in the username are
1445 expanded.
1446 expanded.
1446
1447
1447 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1448 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1448 empty, e.g. if the system admin set "username =" in the system hgrc,
1449 empty, e.g. if the system admin set "username =" in the system hgrc,
1449 it has to be specified manually or in a different hgrc file)
1450 it has to be specified manually or in a different hgrc file)
1450
1451
1451
1452
1452 $ hg help config.annotate.git
1453 $ hg help config.annotate.git
1453 abort: help section not found: config.annotate.git
1454 abort: help section not found: config.annotate.git
1454 [255]
1455 [255]
1455
1456
1456 $ hg help config.update.check
1457 $ hg help config.update.check
1457 "commands.update.check"
1458 "commands.update.check"
1458 Determines what level of checking 'hg update' will perform before
1459 Determines what level of checking 'hg update' will perform before
1459 moving to a destination revision. Valid values are "abort", "none",
1460 moving to a destination revision. Valid values are "abort", "none",
1460 "linear", and "noconflict". "abort" always fails if the working
1461 "linear", and "noconflict". "abort" always fails if the working
1461 directory has uncommitted changes. "none" performs no checking, and
1462 directory has uncommitted changes. "none" performs no checking, and
1462 may result in a merge with uncommitted changes. "linear" allows any
1463 may result in a merge with uncommitted changes. "linear" allows any
1463 update as long as it follows a straight line in the revision history,
1464 update as long as it follows a straight line in the revision history,
1464 and may trigger a merge with uncommitted changes. "noconflict" will
1465 and may trigger a merge with uncommitted changes. "noconflict" will
1465 allow any update which would not trigger a merge with uncommitted
1466 allow any update which would not trigger a merge with uncommitted
1466 changes, if any are present. (default: "linear")
1467 changes, if any are present. (default: "linear")
1467
1468
1468
1469
1469 $ hg help config.commands.update.check
1470 $ hg help config.commands.update.check
1470 "commands.update.check"
1471 "commands.update.check"
1471 Determines what level of checking 'hg update' will perform before
1472 Determines what level of checking 'hg update' will perform before
1472 moving to a destination revision. Valid values are "abort", "none",
1473 moving to a destination revision. Valid values are "abort", "none",
1473 "linear", and "noconflict". "abort" always fails if the working
1474 "linear", and "noconflict". "abort" always fails if the working
1474 directory has uncommitted changes. "none" performs no checking, and
1475 directory has uncommitted changes. "none" performs no checking, and
1475 may result in a merge with uncommitted changes. "linear" allows any
1476 may result in a merge with uncommitted changes. "linear" allows any
1476 update as long as it follows a straight line in the revision history,
1477 update as long as it follows a straight line in the revision history,
1477 and may trigger a merge with uncommitted changes. "noconflict" will
1478 and may trigger a merge with uncommitted changes. "noconflict" will
1478 allow any update which would not trigger a merge with uncommitted
1479 allow any update which would not trigger a merge with uncommitted
1479 changes, if any are present. (default: "linear")
1480 changes, if any are present. (default: "linear")
1480
1481
1481
1482
1482 $ hg help config.ommands.update.check
1483 $ hg help config.ommands.update.check
1483 abort: help section not found: config.ommands.update.check
1484 abort: help section not found: config.ommands.update.check
1484 [255]
1485 [255]
1485
1486
1486 Unrelated trailing paragraphs shouldn't be included
1487 Unrelated trailing paragraphs shouldn't be included
1487
1488
1488 $ hg help config.extramsg | grep '^$'
1489 $ hg help config.extramsg | grep '^$'
1489
1490
1490
1491
1491 Test capitalized section name
1492 Test capitalized section name
1492
1493
1493 $ hg help scripting.HGPLAIN > /dev/null
1494 $ hg help scripting.HGPLAIN > /dev/null
1494
1495
1495 Help subsection:
1496 Help subsection:
1496
1497
1497 $ hg help config.charsets |grep "Email example:" > /dev/null
1498 $ hg help config.charsets |grep "Email example:" > /dev/null
1498 [1]
1499 [1]
1499
1500
1500 Show nested definitions
1501 Show nested definitions
1501 ("profiling.type"[break]"ls"[break]"stat"[break])
1502 ("profiling.type"[break]"ls"[break]"stat"[break])
1502
1503
1503 $ hg help config.type | egrep '^$'|wc -l
1504 $ hg help config.type | egrep '^$'|wc -l
1504 \s*3 (re)
1505 \s*3 (re)
1505
1506
1506 $ hg help config.profiling.type.ls
1507 $ hg help config.profiling.type.ls
1507 "profiling.type.ls"
1508 "profiling.type.ls"
1508 Use Python's built-in instrumenting profiler. This profiler works on
1509 Use Python's built-in instrumenting profiler. This profiler works on
1509 all platforms, but each line number it reports is the first line of
1510 all platforms, but each line number it reports is the first line of
1510 a function. This restriction makes it difficult to identify the
1511 a function. This restriction makes it difficult to identify the
1511 expensive parts of a non-trivial function.
1512 expensive parts of a non-trivial function.
1512
1513
1513
1514
1514 Separate sections from subsections
1515 Separate sections from subsections
1515
1516
1516 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1517 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1517 "format"
1518 "format"
1518 --------
1519 --------
1519
1520
1520 "usegeneraldelta"
1521 "usegeneraldelta"
1521
1522
1522 "dotencode"
1523 "dotencode"
1523
1524
1524 "usefncache"
1525 "usefncache"
1525
1526
1526 "usestore"
1527 "usestore"
1527
1528
1528 "sparse-revlog"
1529 "sparse-revlog"
1529
1530
1530 "revlog-compression"
1531 "revlog-compression"
1531
1532
1532 "bookmarks-in-store"
1533 "bookmarks-in-store"
1533
1534
1534 "profiling"
1535 "profiling"
1535 -----------
1536 -----------
1536
1537
1537 "format"
1538 "format"
1538
1539
1539 "progress"
1540 "progress"
1540 ----------
1541 ----------
1541
1542
1542 "format"
1543 "format"
1543
1544
1544
1545
1545 Last item in help config.*:
1546 Last item in help config.*:
1546
1547
1547 $ hg help config.`hg help config|grep '^ "'| \
1548 $ hg help config.`hg help config|grep '^ "'| \
1548 > tail -1|sed 's![ "]*!!g'`| \
1549 > tail -1|sed 's![ "]*!!g'`| \
1549 > grep 'hg help -c config' > /dev/null
1550 > grep 'hg help -c config' > /dev/null
1550 [1]
1551 [1]
1551
1552
1552 note to use help -c for general hg help config:
1553 note to use help -c for general hg help config:
1553
1554
1554 $ hg help config |grep 'hg help -c config' > /dev/null
1555 $ hg help config |grep 'hg help -c config' > /dev/null
1555
1556
1556 Test templating help
1557 Test templating help
1557
1558
1558 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1559 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1559 desc String. The text of the changeset description.
1560 desc String. The text of the changeset description.
1560 diffstat String. Statistics of changes with the following format:
1561 diffstat String. Statistics of changes with the following format:
1561 firstline Any text. Returns the first line of text.
1562 firstline Any text. Returns the first line of text.
1562 nonempty Any text. Returns '(none)' if the string is empty.
1563 nonempty Any text. Returns '(none)' if the string is empty.
1563
1564
1564 Test deprecated items
1565 Test deprecated items
1565
1566
1566 $ hg help -v templating | grep currentbookmark
1567 $ hg help -v templating | grep currentbookmark
1567 currentbookmark
1568 currentbookmark
1568 $ hg help templating | (grep currentbookmark || true)
1569 $ hg help templating | (grep currentbookmark || true)
1569
1570
1570 Test help hooks
1571 Test help hooks
1571
1572
1572 $ cat > helphook1.py <<EOF
1573 $ cat > helphook1.py <<EOF
1573 > from mercurial import help
1574 > from mercurial import help
1574 >
1575 >
1575 > def rewrite(ui, topic, doc):
1576 > def rewrite(ui, topic, doc):
1576 > return doc + b'\nhelphook1\n'
1577 > return doc + b'\nhelphook1\n'
1577 >
1578 >
1578 > def extsetup(ui):
1579 > def extsetup(ui):
1579 > help.addtopichook(b'revisions', rewrite)
1580 > help.addtopichook(b'revisions', rewrite)
1580 > EOF
1581 > EOF
1581 $ cat > helphook2.py <<EOF
1582 $ cat > helphook2.py <<EOF
1582 > from mercurial import help
1583 > from mercurial import help
1583 >
1584 >
1584 > def rewrite(ui, topic, doc):
1585 > def rewrite(ui, topic, doc):
1585 > return doc + b'\nhelphook2\n'
1586 > return doc + b'\nhelphook2\n'
1586 >
1587 >
1587 > def extsetup(ui):
1588 > def extsetup(ui):
1588 > help.addtopichook(b'revisions', rewrite)
1589 > help.addtopichook(b'revisions', rewrite)
1589 > EOF
1590 > EOF
1590 $ echo '[extensions]' >> $HGRCPATH
1591 $ echo '[extensions]' >> $HGRCPATH
1591 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1592 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1592 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1593 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1593 $ hg help revsets | grep helphook
1594 $ hg help revsets | grep helphook
1594 helphook1
1595 helphook1
1595 helphook2
1596 helphook2
1596
1597
1597 help -c should only show debug --debug
1598 help -c should only show debug --debug
1598
1599
1599 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1600 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1600 [1]
1601 [1]
1601
1602
1602 help -c should only show deprecated for -v
1603 help -c should only show deprecated for -v
1603
1604
1604 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1605 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1605 [1]
1606 [1]
1606
1607
1607 Test -s / --system
1608 Test -s / --system
1608
1609
1609 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1610 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1610 > wc -l | sed -e 's/ //g'
1611 > wc -l | sed -e 's/ //g'
1611 0
1612 0
1612 $ hg help config.files --system unix | grep 'USER' | \
1613 $ hg help config.files --system unix | grep 'USER' | \
1613 > wc -l | sed -e 's/ //g'
1614 > wc -l | sed -e 's/ //g'
1614 0
1615 0
1615
1616
1616 Test -e / -c / -k combinations
1617 Test -e / -c / -k combinations
1617
1618
1618 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1619 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1619 Commands:
1620 Commands:
1620 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1621 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1621 Extensions:
1622 Extensions:
1622 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1623 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1623 Topics:
1624 Topics:
1624 Commands:
1625 Commands:
1625 Extensions:
1626 Extensions:
1626 Extension Commands:
1627 Extension Commands:
1627 $ hg help -c schemes
1628 $ hg help -c schemes
1628 abort: no such help topic: schemes
1629 abort: no such help topic: schemes
1629 (try 'hg help --keyword schemes')
1630 (try 'hg help --keyword schemes')
1630 [255]
1631 [255]
1631 $ hg help -e schemes |head -1
1632 $ hg help -e schemes |head -1
1632 schemes extension - extend schemes with shortcuts to repository swarms
1633 schemes extension - extend schemes with shortcuts to repository swarms
1633 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1634 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1634 Commands:
1635 Commands:
1635 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1636 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1636 Extensions:
1637 Extensions:
1637 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1638 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1638 Extensions:
1639 Extensions:
1639 Commands:
1640 Commands:
1640 $ hg help -c commit > /dev/null
1641 $ hg help -c commit > /dev/null
1641 $ hg help -e -c commit > /dev/null
1642 $ hg help -e -c commit > /dev/null
1642 $ hg help -e commit
1643 $ hg help -e commit
1643 abort: no such help topic: commit
1644 abort: no such help topic: commit
1644 (try 'hg help --keyword commit')
1645 (try 'hg help --keyword commit')
1645 [255]
1646 [255]
1646
1647
1647 Test keyword search help
1648 Test keyword search help
1648
1649
1649 $ cat > prefixedname.py <<EOF
1650 $ cat > prefixedname.py <<EOF
1650 > '''matched against word "clone"
1651 > '''matched against word "clone"
1651 > '''
1652 > '''
1652 > EOF
1653 > EOF
1653 $ echo '[extensions]' >> $HGRCPATH
1654 $ echo '[extensions]' >> $HGRCPATH
1654 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1655 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1655 $ hg help -k clone
1656 $ hg help -k clone
1656 Topics:
1657 Topics:
1657
1658
1658 config Configuration Files
1659 config Configuration Files
1659 extensions Using Additional Features
1660 extensions Using Additional Features
1660 glossary Glossary
1661 glossary Glossary
1661 phases Working with Phases
1662 phases Working with Phases
1662 subrepos Subrepositories
1663 subrepos Subrepositories
1663 urls URL Paths
1664 urls URL Paths
1664
1665
1665 Commands:
1666 Commands:
1666
1667
1667 bookmarks create a new bookmark or list existing bookmarks
1668 bookmarks create a new bookmark or list existing bookmarks
1668 clone make a copy of an existing repository
1669 clone make a copy of an existing repository
1669 paths show aliases for remote repositories
1670 paths show aliases for remote repositories
1670 pull pull changes from the specified source
1671 pull pull changes from the specified source
1671 update update working directory (or switch revisions)
1672 update update working directory (or switch revisions)
1672
1673
1673 Extensions:
1674 Extensions:
1674
1675
1675 clonebundles advertise pre-generated bundles to seed clones
1676 clonebundles advertise pre-generated bundles to seed clones
1676 narrow create clones which fetch history data for subset of files
1677 narrow create clones which fetch history data for subset of files
1677 (EXPERIMENTAL)
1678 (EXPERIMENTAL)
1678 prefixedname matched against word "clone"
1679 prefixedname matched against word "clone"
1679 relink recreates hardlinks between repository clones
1680 relink recreates hardlinks between repository clones
1680
1681
1681 Extension Commands:
1682 Extension Commands:
1682
1683
1683 qclone clone main and patch repository at same time
1684 qclone clone main and patch repository at same time
1684
1685
1685 Test unfound topic
1686 Test unfound topic
1686
1687
1687 $ hg help nonexistingtopicthatwillneverexisteverever
1688 $ hg help nonexistingtopicthatwillneverexisteverever
1688 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1689 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1689 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1690 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1690 [255]
1691 [255]
1691
1692
1692 Test unfound keyword
1693 Test unfound keyword
1693
1694
1694 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1695 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1695 abort: no matches
1696 abort: no matches
1696 (try 'hg help' for a list of topics)
1697 (try 'hg help' for a list of topics)
1697 [255]
1698 [255]
1698
1699
1699 Test omit indicating for help
1700 Test omit indicating for help
1700
1701
1701 $ cat > addverboseitems.py <<EOF
1702 $ cat > addverboseitems.py <<EOF
1702 > r'''extension to test omit indicating.
1703 > r'''extension to test omit indicating.
1703 >
1704 >
1704 > This paragraph is never omitted (for extension)
1705 > This paragraph is never omitted (for extension)
1705 >
1706 >
1706 > .. container:: verbose
1707 > .. container:: verbose
1707 >
1708 >
1708 > This paragraph is omitted,
1709 > This paragraph is omitted,
1709 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1710 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1710 >
1711 >
1711 > This paragraph is never omitted, too (for extension)
1712 > This paragraph is never omitted, too (for extension)
1712 > '''
1713 > '''
1713 > from __future__ import absolute_import
1714 > from __future__ import absolute_import
1714 > from mercurial import commands, help
1715 > from mercurial import commands, help
1715 > testtopic = br"""This paragraph is never omitted (for topic).
1716 > testtopic = br"""This paragraph is never omitted (for topic).
1716 >
1717 >
1717 > .. container:: verbose
1718 > .. container:: verbose
1718 >
1719 >
1719 > This paragraph is omitted,
1720 > This paragraph is omitted,
1720 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1721 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1721 >
1722 >
1722 > This paragraph is never omitted, too (for topic)
1723 > This paragraph is never omitted, too (for topic)
1723 > """
1724 > """
1724 > def extsetup(ui):
1725 > def extsetup(ui):
1725 > help.helptable.append(([b"topic-containing-verbose"],
1726 > help.helptable.append(([b"topic-containing-verbose"],
1726 > b"This is the topic to test omit indicating.",
1727 > b"This is the topic to test omit indicating.",
1727 > lambda ui: testtopic))
1728 > lambda ui: testtopic))
1728 > EOF
1729 > EOF
1729 $ echo '[extensions]' >> $HGRCPATH
1730 $ echo '[extensions]' >> $HGRCPATH
1730 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1731 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1731 $ hg help addverboseitems
1732 $ hg help addverboseitems
1732 addverboseitems extension - extension to test omit indicating.
1733 addverboseitems extension - extension to test omit indicating.
1733
1734
1734 This paragraph is never omitted (for extension)
1735 This paragraph is never omitted (for extension)
1735
1736
1736 This paragraph is never omitted, too (for extension)
1737 This paragraph is never omitted, too (for extension)
1737
1738
1738 (some details hidden, use --verbose to show complete help)
1739 (some details hidden, use --verbose to show complete help)
1739
1740
1740 no commands defined
1741 no commands defined
1741 $ hg help -v addverboseitems
1742 $ hg help -v addverboseitems
1742 addverboseitems extension - extension to test omit indicating.
1743 addverboseitems extension - extension to test omit indicating.
1743
1744
1744 This paragraph is never omitted (for extension)
1745 This paragraph is never omitted (for extension)
1745
1746
1746 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1747 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1747 extension)
1748 extension)
1748
1749
1749 This paragraph is never omitted, too (for extension)
1750 This paragraph is never omitted, too (for extension)
1750
1751
1751 no commands defined
1752 no commands defined
1752 $ hg help topic-containing-verbose
1753 $ hg help topic-containing-verbose
1753 This is the topic to test omit indicating.
1754 This is the topic to test omit indicating.
1754 """"""""""""""""""""""""""""""""""""""""""
1755 """"""""""""""""""""""""""""""""""""""""""
1755
1756
1756 This paragraph is never omitted (for topic).
1757 This paragraph is never omitted (for topic).
1757
1758
1758 This paragraph is never omitted, too (for topic)
1759 This paragraph is never omitted, too (for topic)
1759
1760
1760 (some details hidden, use --verbose to show complete help)
1761 (some details hidden, use --verbose to show complete help)
1761 $ hg help -v topic-containing-verbose
1762 $ hg help -v topic-containing-verbose
1762 This is the topic to test omit indicating.
1763 This is the topic to test omit indicating.
1763 """"""""""""""""""""""""""""""""""""""""""
1764 """"""""""""""""""""""""""""""""""""""""""
1764
1765
1765 This paragraph is never omitted (for topic).
1766 This paragraph is never omitted (for topic).
1766
1767
1767 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1768 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1768 topic)
1769 topic)
1769
1770
1770 This paragraph is never omitted, too (for topic)
1771 This paragraph is never omitted, too (for topic)
1771
1772
1772 Test section lookup
1773 Test section lookup
1773
1774
1774 $ hg help revset.merge
1775 $ hg help revset.merge
1775 "merge()"
1776 "merge()"
1776 Changeset is a merge changeset.
1777 Changeset is a merge changeset.
1777
1778
1778 $ hg help glossary.dag
1779 $ hg help glossary.dag
1779 DAG
1780 DAG
1780 The repository of changesets of a distributed version control system
1781 The repository of changesets of a distributed version control system
1781 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1782 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1782 of nodes and edges, where nodes correspond to changesets and edges
1783 of nodes and edges, where nodes correspond to changesets and edges
1783 imply a parent -> child relation. This graph can be visualized by
1784 imply a parent -> child relation. This graph can be visualized by
1784 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1785 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1785 limited by the requirement for children to have at most two parents.
1786 limited by the requirement for children to have at most two parents.
1786
1787
1787
1788
1788 $ hg help hgrc.paths
1789 $ hg help hgrc.paths
1789 "paths"
1790 "paths"
1790 -------
1791 -------
1791
1792
1792 Assigns symbolic names and behavior to repositories.
1793 Assigns symbolic names and behavior to repositories.
1793
1794
1794 Options are symbolic names defining the URL or directory that is the
1795 Options are symbolic names defining the URL or directory that is the
1795 location of the repository. Example:
1796 location of the repository. Example:
1796
1797
1797 [paths]
1798 [paths]
1798 my_server = https://example.com/my_repo
1799 my_server = https://example.com/my_repo
1799 local_path = /home/me/repo
1800 local_path = /home/me/repo
1800
1801
1801 These symbolic names can be used from the command line. To pull from
1802 These symbolic names can be used from the command line. To pull from
1802 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1803 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1803 local_path'.
1804 local_path'.
1804
1805
1805 Options containing colons (":") denote sub-options that can influence
1806 Options containing colons (":") denote sub-options that can influence
1806 behavior for that specific path. Example:
1807 behavior for that specific path. Example:
1807
1808
1808 [paths]
1809 [paths]
1809 my_server = https://example.com/my_path
1810 my_server = https://example.com/my_path
1810 my_server:pushurl = ssh://example.com/my_path
1811 my_server:pushurl = ssh://example.com/my_path
1811
1812
1812 The following sub-options can be defined:
1813 The following sub-options can be defined:
1813
1814
1814 "pushurl"
1815 "pushurl"
1815 The URL to use for push operations. If not defined, the location
1816 The URL to use for push operations. If not defined, the location
1816 defined by the path's main entry is used.
1817 defined by the path's main entry is used.
1817
1818
1818 "pushrev"
1819 "pushrev"
1819 A revset defining which revisions to push by default.
1820 A revset defining which revisions to push by default.
1820
1821
1821 When 'hg push' is executed without a "-r" argument, the revset defined
1822 When 'hg push' is executed without a "-r" argument, the revset defined
1822 by this sub-option is evaluated to determine what to push.
1823 by this sub-option is evaluated to determine what to push.
1823
1824
1824 For example, a value of "." will push the working directory's revision
1825 For example, a value of "." will push the working directory's revision
1825 by default.
1826 by default.
1826
1827
1827 Revsets specifying bookmarks will not result in the bookmark being
1828 Revsets specifying bookmarks will not result in the bookmark being
1828 pushed.
1829 pushed.
1829
1830
1830 The following special named paths exist:
1831 The following special named paths exist:
1831
1832
1832 "default"
1833 "default"
1833 The URL or directory to use when no source or remote is specified.
1834 The URL or directory to use when no source or remote is specified.
1834
1835
1835 'hg clone' will automatically define this path to the location the
1836 'hg clone' will automatically define this path to the location the
1836 repository was cloned from.
1837 repository was cloned from.
1837
1838
1838 "default-push"
1839 "default-push"
1839 (deprecated) The URL or directory for the default 'hg push' location.
1840 (deprecated) The URL or directory for the default 'hg push' location.
1840 "default:pushurl" should be used instead.
1841 "default:pushurl" should be used instead.
1841
1842
1842 $ hg help glossary.mcguffin
1843 $ hg help glossary.mcguffin
1843 abort: help section not found: glossary.mcguffin
1844 abort: help section not found: glossary.mcguffin
1844 [255]
1845 [255]
1845
1846
1846 $ hg help glossary.mc.guffin
1847 $ hg help glossary.mc.guffin
1847 abort: help section not found: glossary.mc.guffin
1848 abort: help section not found: glossary.mc.guffin
1848 [255]
1849 [255]
1849
1850
1850 $ hg help template.files
1851 $ hg help template.files
1851 files List of strings. All files modified, added, or removed by
1852 files List of strings. All files modified, added, or removed by
1852 this changeset.
1853 this changeset.
1853 files(pattern)
1854 files(pattern)
1854 All files of the current changeset matching the pattern. See
1855 All files of the current changeset matching the pattern. See
1855 'hg help patterns'.
1856 'hg help patterns'.
1856
1857
1857 Test section lookup by translated message
1858 Test section lookup by translated message
1858
1859
1859 str.lower() instead of encoding.lower(str) on translated message might
1860 str.lower() instead of encoding.lower(str) on translated message might
1860 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1861 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1861 as the second or later byte of multi-byte character.
1862 as the second or later byte of multi-byte character.
1862
1863
1863 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1864 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1864 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1865 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1865 replacement makes message meaningless.
1866 replacement makes message meaningless.
1866
1867
1867 This tests that section lookup by translated string isn't broken by
1868 This tests that section lookup by translated string isn't broken by
1868 such str.lower().
1869 such str.lower().
1869
1870
1870 $ "$PYTHON" <<EOF
1871 $ "$PYTHON" <<EOF
1871 > def escape(s):
1872 > def escape(s):
1872 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1873 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1873 > # translation of "record" in ja_JP.cp932
1874 > # translation of "record" in ja_JP.cp932
1874 > upper = b"\x8bL\x98^"
1875 > upper = b"\x8bL\x98^"
1875 > # str.lower()-ed section name should be treated as different one
1876 > # str.lower()-ed section name should be treated as different one
1876 > lower = b"\x8bl\x98^"
1877 > lower = b"\x8bl\x98^"
1877 > with open('ambiguous.py', 'wb') as fp:
1878 > with open('ambiguous.py', 'wb') as fp:
1878 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1879 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1879 > u'''summary of extension
1880 > u'''summary of extension
1880 >
1881 >
1881 > %s
1882 > %s
1882 > ----
1883 > ----
1883 >
1884 >
1884 > Upper name should show only this message
1885 > Upper name should show only this message
1885 >
1886 >
1886 > %s
1887 > %s
1887 > ----
1888 > ----
1888 >
1889 >
1889 > Lower name should show only this message
1890 > Lower name should show only this message
1890 >
1891 >
1891 > subsequent section
1892 > subsequent section
1892 > ------------------
1893 > ------------------
1893 >
1894 >
1894 > This should be hidden at 'hg help ambiguous' with section name.
1895 > This should be hidden at 'hg help ambiguous' with section name.
1895 > '''
1896 > '''
1896 > """ % (escape(upper), escape(lower)))
1897 > """ % (escape(upper), escape(lower)))
1897 > EOF
1898 > EOF
1898
1899
1899 $ cat >> $HGRCPATH <<EOF
1900 $ cat >> $HGRCPATH <<EOF
1900 > [extensions]
1901 > [extensions]
1901 > ambiguous = ./ambiguous.py
1902 > ambiguous = ./ambiguous.py
1902 > EOF
1903 > EOF
1903
1904
1904 $ "$PYTHON" <<EOF | sh
1905 $ "$PYTHON" <<EOF | sh
1905 > from mercurial import pycompat
1906 > from mercurial import pycompat
1906 > upper = b"\x8bL\x98^"
1907 > upper = b"\x8bL\x98^"
1907 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1908 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1908 > EOF
1909 > EOF
1909 \x8bL\x98^ (esc)
1910 \x8bL\x98^ (esc)
1910 ----
1911 ----
1911
1912
1912 Upper name should show only this message
1913 Upper name should show only this message
1913
1914
1914
1915
1915 $ "$PYTHON" <<EOF | sh
1916 $ "$PYTHON" <<EOF | sh
1916 > from mercurial import pycompat
1917 > from mercurial import pycompat
1917 > lower = b"\x8bl\x98^"
1918 > lower = b"\x8bl\x98^"
1918 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1919 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1919 > EOF
1920 > EOF
1920 \x8bl\x98^ (esc)
1921 \x8bl\x98^ (esc)
1921 ----
1922 ----
1922
1923
1923 Lower name should show only this message
1924 Lower name should show only this message
1924
1925
1925
1926
1926 $ cat >> $HGRCPATH <<EOF
1927 $ cat >> $HGRCPATH <<EOF
1927 > [extensions]
1928 > [extensions]
1928 > ambiguous = !
1929 > ambiguous = !
1929 > EOF
1930 > EOF
1930
1931
1931 Show help content of disabled extensions
1932 Show help content of disabled extensions
1932
1933
1933 $ cat >> $HGRCPATH <<EOF
1934 $ cat >> $HGRCPATH <<EOF
1934 > [extensions]
1935 > [extensions]
1935 > ambiguous = !./ambiguous.py
1936 > ambiguous = !./ambiguous.py
1936 > EOF
1937 > EOF
1937 $ hg help -e ambiguous
1938 $ hg help -e ambiguous
1938 ambiguous extension - (no help text available)
1939 ambiguous extension - (no help text available)
1939
1940
1940 (use 'hg help extensions' for information on enabling extensions)
1941 (use 'hg help extensions' for information on enabling extensions)
1941
1942
1942 Test dynamic list of merge tools only shows up once
1943 Test dynamic list of merge tools only shows up once
1943 $ hg help merge-tools
1944 $ hg help merge-tools
1944 Merge Tools
1945 Merge Tools
1945 """""""""""
1946 """""""""""
1946
1947
1947 To merge files Mercurial uses merge tools.
1948 To merge files Mercurial uses merge tools.
1948
1949
1949 A merge tool combines two different versions of a file into a merged file.
1950 A merge tool combines two different versions of a file into a merged file.
1950 Merge tools are given the two files and the greatest common ancestor of
1951 Merge tools are given the two files and the greatest common ancestor of
1951 the two file versions, so they can determine the changes made on both
1952 the two file versions, so they can determine the changes made on both
1952 branches.
1953 branches.
1953
1954
1954 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1955 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1955 backout' and in several extensions.
1956 backout' and in several extensions.
1956
1957
1957 Usually, the merge tool tries to automatically reconcile the files by
1958 Usually, the merge tool tries to automatically reconcile the files by
1958 combining all non-overlapping changes that occurred separately in the two
1959 combining all non-overlapping changes that occurred separately in the two
1959 different evolutions of the same initial base file. Furthermore, some
1960 different evolutions of the same initial base file. Furthermore, some
1960 interactive merge programs make it easier to manually resolve conflicting
1961 interactive merge programs make it easier to manually resolve conflicting
1961 merges, either in a graphical way, or by inserting some conflict markers.
1962 merges, either in a graphical way, or by inserting some conflict markers.
1962 Mercurial does not include any interactive merge programs but relies on
1963 Mercurial does not include any interactive merge programs but relies on
1963 external tools for that.
1964 external tools for that.
1964
1965
1965 Available merge tools
1966 Available merge tools
1966 =====================
1967 =====================
1967
1968
1968 External merge tools and their properties are configured in the merge-
1969 External merge tools and their properties are configured in the merge-
1969 tools configuration section - see hgrc(5) - but they can often just be
1970 tools configuration section - see hgrc(5) - but they can often just be
1970 named by their executable.
1971 named by their executable.
1971
1972
1972 A merge tool is generally usable if its executable can be found on the
1973 A merge tool is generally usable if its executable can be found on the
1973 system and if it can handle the merge. The executable is found if it is an
1974 system and if it can handle the merge. The executable is found if it is an
1974 absolute or relative executable path or the name of an application in the
1975 absolute or relative executable path or the name of an application in the
1975 executable search path. The tool is assumed to be able to handle the merge
1976 executable search path. The tool is assumed to be able to handle the merge
1976 if it can handle symlinks if the file is a symlink, if it can handle
1977 if it can handle symlinks if the file is a symlink, if it can handle
1977 binary files if the file is binary, and if a GUI is available if the tool
1978 binary files if the file is binary, and if a GUI is available if the tool
1978 requires a GUI.
1979 requires a GUI.
1979
1980
1980 There are some internal merge tools which can be used. The internal merge
1981 There are some internal merge tools which can be used. The internal merge
1981 tools are:
1982 tools are:
1982
1983
1983 ":dump"
1984 ":dump"
1984 Creates three versions of the files to merge, containing the contents of
1985 Creates three versions of the files to merge, containing the contents of
1985 local, other and base. These files can then be used to perform a merge
1986 local, other and base. These files can then be used to perform a merge
1986 manually. If the file to be merged is named "a.txt", these files will
1987 manually. If the file to be merged is named "a.txt", these files will
1987 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1988 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1988 they will be placed in the same directory as "a.txt".
1989 they will be placed in the same directory as "a.txt".
1989
1990
1990 This implies premerge. Therefore, files aren't dumped, if premerge runs
1991 This implies premerge. Therefore, files aren't dumped, if premerge runs
1991 successfully. Use :forcedump to forcibly write files out.
1992 successfully. Use :forcedump to forcibly write files out.
1992
1993
1993 (actual capabilities: binary, symlink)
1994 (actual capabilities: binary, symlink)
1994
1995
1995 ":fail"
1996 ":fail"
1996 Rather than attempting to merge files that were modified on both
1997 Rather than attempting to merge files that were modified on both
1997 branches, it marks them as unresolved. The resolve command must be used
1998 branches, it marks them as unresolved. The resolve command must be used
1998 to resolve these conflicts.
1999 to resolve these conflicts.
1999
2000
2000 (actual capabilities: binary, symlink)
2001 (actual capabilities: binary, symlink)
2001
2002
2002 ":forcedump"
2003 ":forcedump"
2003 Creates three versions of the files as same as :dump, but omits
2004 Creates three versions of the files as same as :dump, but omits
2004 premerge.
2005 premerge.
2005
2006
2006 (actual capabilities: binary, symlink)
2007 (actual capabilities: binary, symlink)
2007
2008
2008 ":local"
2009 ":local"
2009 Uses the local 'p1()' version of files as the merged version.
2010 Uses the local 'p1()' version of files as the merged version.
2010
2011
2011 (actual capabilities: binary, symlink)
2012 (actual capabilities: binary, symlink)
2012
2013
2013 ":merge"
2014 ":merge"
2014 Uses the internal non-interactive simple merge algorithm for merging
2015 Uses the internal non-interactive simple merge algorithm for merging
2015 files. It will fail if there are any conflicts and leave markers in the
2016 files. It will fail if there are any conflicts and leave markers in the
2016 partially merged file. Markers will have two sections, one for each side
2017 partially merged file. Markers will have two sections, one for each side
2017 of merge.
2018 of merge.
2018
2019
2019 ":merge-local"
2020 ":merge-local"
2020 Like :merge, but resolve all conflicts non-interactively in favor of the
2021 Like :merge, but resolve all conflicts non-interactively in favor of the
2021 local 'p1()' changes.
2022 local 'p1()' changes.
2022
2023
2023 ":merge-other"
2024 ":merge-other"
2024 Like :merge, but resolve all conflicts non-interactively in favor of the
2025 Like :merge, but resolve all conflicts non-interactively in favor of the
2025 other 'p2()' changes.
2026 other 'p2()' changes.
2026
2027
2027 ":merge3"
2028 ":merge3"
2028 Uses the internal non-interactive simple merge algorithm for merging
2029 Uses the internal non-interactive simple merge algorithm for merging
2029 files. It will fail if there are any conflicts and leave markers in the
2030 files. It will fail if there are any conflicts and leave markers in the
2030 partially merged file. Marker will have three sections, one from each
2031 partially merged file. Marker will have three sections, one from each
2031 side of the merge and one for the base content.
2032 side of the merge and one for the base content.
2032
2033
2033 ":other"
2034 ":other"
2034 Uses the other 'p2()' version of files as the merged version.
2035 Uses the other 'p2()' version of files as the merged version.
2035
2036
2036 (actual capabilities: binary, symlink)
2037 (actual capabilities: binary, symlink)
2037
2038
2038 ":prompt"
2039 ":prompt"
2039 Asks the user which of the local 'p1()' or the other 'p2()' version to
2040 Asks the user which of the local 'p1()' or the other 'p2()' version to
2040 keep as the merged version.
2041 keep as the merged version.
2041
2042
2042 (actual capabilities: binary, symlink)
2043 (actual capabilities: binary, symlink)
2043
2044
2044 ":tagmerge"
2045 ":tagmerge"
2045 Uses the internal tag merge algorithm (experimental).
2046 Uses the internal tag merge algorithm (experimental).
2046
2047
2047 ":union"
2048 ":union"
2048 Uses the internal non-interactive simple merge algorithm for merging
2049 Uses the internal non-interactive simple merge algorithm for merging
2049 files. It will use both left and right sides for conflict regions. No
2050 files. It will use both left and right sides for conflict regions. No
2050 markers are inserted.
2051 markers are inserted.
2051
2052
2052 Internal tools are always available and do not require a GUI but will by
2053 Internal tools are always available and do not require a GUI but will by
2053 default not handle symlinks or binary files. See next section for detail
2054 default not handle symlinks or binary files. See next section for detail
2054 about "actual capabilities" described above.
2055 about "actual capabilities" described above.
2055
2056
2056 Choosing a merge tool
2057 Choosing a merge tool
2057 =====================
2058 =====================
2058
2059
2059 Mercurial uses these rules when deciding which merge tool to use:
2060 Mercurial uses these rules when deciding which merge tool to use:
2060
2061
2061 1. If a tool has been specified with the --tool option to merge or
2062 1. If a tool has been specified with the --tool option to merge or
2062 resolve, it is used. If it is the name of a tool in the merge-tools
2063 resolve, it is used. If it is the name of a tool in the merge-tools
2063 configuration, its configuration is used. Otherwise the specified tool
2064 configuration, its configuration is used. Otherwise the specified tool
2064 must be executable by the shell.
2065 must be executable by the shell.
2065 2. If the "HGMERGE" environment variable is present, its value is used and
2066 2. If the "HGMERGE" environment variable is present, its value is used and
2066 must be executable by the shell.
2067 must be executable by the shell.
2067 3. If the filename of the file to be merged matches any of the patterns in
2068 3. If the filename of the file to be merged matches any of the patterns in
2068 the merge-patterns configuration section, the first usable merge tool
2069 the merge-patterns configuration section, the first usable merge tool
2069 corresponding to a matching pattern is used.
2070 corresponding to a matching pattern is used.
2070 4. If ui.merge is set it will be considered next. If the value is not the
2071 4. If ui.merge is set it will be considered next. If the value is not the
2071 name of a configured tool, the specified value is used and must be
2072 name of a configured tool, the specified value is used and must be
2072 executable by the shell. Otherwise the named tool is used if it is
2073 executable by the shell. Otherwise the named tool is used if it is
2073 usable.
2074 usable.
2074 5. If any usable merge tools are present in the merge-tools configuration
2075 5. If any usable merge tools are present in the merge-tools configuration
2075 section, the one with the highest priority is used.
2076 section, the one with the highest priority is used.
2076 6. If a program named "hgmerge" can be found on the system, it is used -
2077 6. If a program named "hgmerge" can be found on the system, it is used -
2077 but it will by default not be used for symlinks and binary files.
2078 but it will by default not be used for symlinks and binary files.
2078 7. If the file to be merged is not binary and is not a symlink, then
2079 7. If the file to be merged is not binary and is not a symlink, then
2079 internal ":merge" is used.
2080 internal ":merge" is used.
2080 8. Otherwise, ":prompt" is used.
2081 8. Otherwise, ":prompt" is used.
2081
2082
2082 For historical reason, Mercurial treats merge tools as below while
2083 For historical reason, Mercurial treats merge tools as below while
2083 examining rules above.
2084 examining rules above.
2084
2085
2085 step specified via binary symlink
2086 step specified via binary symlink
2086 ----------------------------------
2087 ----------------------------------
2087 1. --tool o/o o/o
2088 1. --tool o/o o/o
2088 2. HGMERGE o/o o/o
2089 2. HGMERGE o/o o/o
2089 3. merge-patterns o/o(*) x/?(*)
2090 3. merge-patterns o/o(*) x/?(*)
2090 4. ui.merge x/?(*) x/?(*)
2091 4. ui.merge x/?(*) x/?(*)
2091
2092
2092 Each capability column indicates Mercurial behavior for internal/external
2093 Each capability column indicates Mercurial behavior for internal/external
2093 merge tools at examining each rule.
2094 merge tools at examining each rule.
2094
2095
2095 - "o": "assume that a tool has capability"
2096 - "o": "assume that a tool has capability"
2096 - "x": "assume that a tool does not have capability"
2097 - "x": "assume that a tool does not have capability"
2097 - "?": "check actual capability of a tool"
2098 - "?": "check actual capability of a tool"
2098
2099
2099 If "merge.strict-capability-check" configuration is true, Mercurial checks
2100 If "merge.strict-capability-check" configuration is true, Mercurial checks
2100 capabilities of merge tools strictly in (*) cases above (= each capability
2101 capabilities of merge tools strictly in (*) cases above (= each capability
2101 column becomes "?/?"). It is false by default for backward compatibility.
2102 column becomes "?/?"). It is false by default for backward compatibility.
2102
2103
2103 Note:
2104 Note:
2104 After selecting a merge program, Mercurial will by default attempt to
2105 After selecting a merge program, Mercurial will by default attempt to
2105 merge the files using a simple merge algorithm first. Only if it
2106 merge the files using a simple merge algorithm first. Only if it
2106 doesn't succeed because of conflicting changes will Mercurial actually
2107 doesn't succeed because of conflicting changes will Mercurial actually
2107 execute the merge program. Whether to use the simple merge algorithm
2108 execute the merge program. Whether to use the simple merge algorithm
2108 first can be controlled by the premerge setting of the merge tool.
2109 first can be controlled by the premerge setting of the merge tool.
2109 Premerge is enabled by default unless the file is binary or a symlink.
2110 Premerge is enabled by default unless the file is binary or a symlink.
2110
2111
2111 See the merge-tools and ui sections of hgrc(5) for details on the
2112 See the merge-tools and ui sections of hgrc(5) for details on the
2112 configuration of merge tools.
2113 configuration of merge tools.
2113
2114
2114 Compression engines listed in `hg help bundlespec`
2115 Compression engines listed in `hg help bundlespec`
2115
2116
2116 $ hg help bundlespec | grep gzip
2117 $ hg help bundlespec | grep gzip
2117 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2118 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2118 An algorithm that produces smaller bundles than "gzip".
2119 An algorithm that produces smaller bundles than "gzip".
2119 This engine will likely produce smaller bundles than "gzip" but will be
2120 This engine will likely produce smaller bundles than "gzip" but will be
2120 "gzip"
2121 "gzip"
2121 better compression than "gzip". It also frequently yields better (?)
2122 better compression than "gzip". It also frequently yields better (?)
2122
2123
2123 Test usage of section marks in help documents
2124 Test usage of section marks in help documents
2124
2125
2125 $ cd "$TESTDIR"/../doc
2126 $ cd "$TESTDIR"/../doc
2126 $ "$PYTHON" check-seclevel.py
2127 $ "$PYTHON" check-seclevel.py
2127 $ cd $TESTTMP
2128 $ cd $TESTTMP
2128
2129
2129 #if serve
2130 #if serve
2130
2131
2131 Test the help pages in hgweb.
2132 Test the help pages in hgweb.
2132
2133
2133 Dish up an empty repo; serve it cold.
2134 Dish up an empty repo; serve it cold.
2134
2135
2135 $ hg init "$TESTTMP/test"
2136 $ hg init "$TESTTMP/test"
2136 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2137 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2137 $ cat hg.pid >> $DAEMON_PIDS
2138 $ cat hg.pid >> $DAEMON_PIDS
2138
2139
2139 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2140 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2140 200 Script output follows
2141 200 Script output follows
2141
2142
2142 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2143 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2143 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2144 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2144 <head>
2145 <head>
2145 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2146 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2146 <meta name="robots" content="index, nofollow" />
2147 <meta name="robots" content="index, nofollow" />
2147 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2148 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2148 <script type="text/javascript" src="/static/mercurial.js"></script>
2149 <script type="text/javascript" src="/static/mercurial.js"></script>
2149
2150
2150 <title>Help: Index</title>
2151 <title>Help: Index</title>
2151 </head>
2152 </head>
2152 <body>
2153 <body>
2153
2154
2154 <div class="container">
2155 <div class="container">
2155 <div class="menu">
2156 <div class="menu">
2156 <div class="logo">
2157 <div class="logo">
2157 <a href="https://mercurial-scm.org/">
2158 <a href="https://mercurial-scm.org/">
2158 <img src="/static/hglogo.png" alt="mercurial" /></a>
2159 <img src="/static/hglogo.png" alt="mercurial" /></a>
2159 </div>
2160 </div>
2160 <ul>
2161 <ul>
2161 <li><a href="/shortlog">log</a></li>
2162 <li><a href="/shortlog">log</a></li>
2162 <li><a href="/graph">graph</a></li>
2163 <li><a href="/graph">graph</a></li>
2163 <li><a href="/tags">tags</a></li>
2164 <li><a href="/tags">tags</a></li>
2164 <li><a href="/bookmarks">bookmarks</a></li>
2165 <li><a href="/bookmarks">bookmarks</a></li>
2165 <li><a href="/branches">branches</a></li>
2166 <li><a href="/branches">branches</a></li>
2166 </ul>
2167 </ul>
2167 <ul>
2168 <ul>
2168 <li class="active">help</li>
2169 <li class="active">help</li>
2169 </ul>
2170 </ul>
2170 </div>
2171 </div>
2171
2172
2172 <div class="main">
2173 <div class="main">
2173 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2174 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2174
2175
2175 <form class="search" action="/log">
2176 <form class="search" action="/log">
2176
2177
2177 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2178 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2178 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2179 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2179 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2180 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2180 </form>
2181 </form>
2181 <table class="bigtable">
2182 <table class="bigtable">
2182 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2183 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2183
2184
2184 <tr><td>
2185 <tr><td>
2185 <a href="/help/bundlespec">
2186 <a href="/help/bundlespec">
2186 bundlespec
2187 bundlespec
2187 </a>
2188 </a>
2188 </td><td>
2189 </td><td>
2189 Bundle File Formats
2190 Bundle File Formats
2190 </td></tr>
2191 </td></tr>
2191 <tr><td>
2192 <tr><td>
2192 <a href="/help/color">
2193 <a href="/help/color">
2193 color
2194 color
2194 </a>
2195 </a>
2195 </td><td>
2196 </td><td>
2196 Colorizing Outputs
2197 Colorizing Outputs
2197 </td></tr>
2198 </td></tr>
2198 <tr><td>
2199 <tr><td>
2199 <a href="/help/config">
2200 <a href="/help/config">
2200 config
2201 config
2201 </a>
2202 </a>
2202 </td><td>
2203 </td><td>
2203 Configuration Files
2204 Configuration Files
2204 </td></tr>
2205 </td></tr>
2205 <tr><td>
2206 <tr><td>
2206 <a href="/help/dates">
2207 <a href="/help/dates">
2207 dates
2208 dates
2208 </a>
2209 </a>
2209 </td><td>
2210 </td><td>
2210 Date Formats
2211 Date Formats
2211 </td></tr>
2212 </td></tr>
2212 <tr><td>
2213 <tr><td>
2213 <a href="/help/deprecated">
2214 <a href="/help/deprecated">
2214 deprecated
2215 deprecated
2215 </a>
2216 </a>
2216 </td><td>
2217 </td><td>
2217 Deprecated Features
2218 Deprecated Features
2218 </td></tr>
2219 </td></tr>
2219 <tr><td>
2220 <tr><td>
2220 <a href="/help/diffs">
2221 <a href="/help/diffs">
2221 diffs
2222 diffs
2222 </a>
2223 </a>
2223 </td><td>
2224 </td><td>
2224 Diff Formats
2225 Diff Formats
2225 </td></tr>
2226 </td></tr>
2226 <tr><td>
2227 <tr><td>
2227 <a href="/help/environment">
2228 <a href="/help/environment">
2228 environment
2229 environment
2229 </a>
2230 </a>
2230 </td><td>
2231 </td><td>
2231 Environment Variables
2232 Environment Variables
2232 </td></tr>
2233 </td></tr>
2233 <tr><td>
2234 <tr><td>
2234 <a href="/help/extensions">
2235 <a href="/help/extensions">
2235 extensions
2236 extensions
2236 </a>
2237 </a>
2237 </td><td>
2238 </td><td>
2238 Using Additional Features
2239 Using Additional Features
2239 </td></tr>
2240 </td></tr>
2240 <tr><td>
2241 <tr><td>
2241 <a href="/help/filesets">
2242 <a href="/help/filesets">
2242 filesets
2243 filesets
2243 </a>
2244 </a>
2244 </td><td>
2245 </td><td>
2245 Specifying File Sets
2246 Specifying File Sets
2246 </td></tr>
2247 </td></tr>
2247 <tr><td>
2248 <tr><td>
2248 <a href="/help/flags">
2249 <a href="/help/flags">
2249 flags
2250 flags
2250 </a>
2251 </a>
2251 </td><td>
2252 </td><td>
2252 Command-line flags
2253 Command-line flags
2253 </td></tr>
2254 </td></tr>
2254 <tr><td>
2255 <tr><td>
2255 <a href="/help/glossary">
2256 <a href="/help/glossary">
2256 glossary
2257 glossary
2257 </a>
2258 </a>
2258 </td><td>
2259 </td><td>
2259 Glossary
2260 Glossary
2260 </td></tr>
2261 </td></tr>
2261 <tr><td>
2262 <tr><td>
2262 <a href="/help/hgignore">
2263 <a href="/help/hgignore">
2263 hgignore
2264 hgignore
2264 </a>
2265 </a>
2265 </td><td>
2266 </td><td>
2266 Syntax for Mercurial Ignore Files
2267 Syntax for Mercurial Ignore Files
2267 </td></tr>
2268 </td></tr>
2268 <tr><td>
2269 <tr><td>
2269 <a href="/help/hgweb">
2270 <a href="/help/hgweb">
2270 hgweb
2271 hgweb
2271 </a>
2272 </a>
2272 </td><td>
2273 </td><td>
2273 Configuring hgweb
2274 Configuring hgweb
2274 </td></tr>
2275 </td></tr>
2275 <tr><td>
2276 <tr><td>
2276 <a href="/help/internals">
2277 <a href="/help/internals">
2277 internals
2278 internals
2278 </a>
2279 </a>
2279 </td><td>
2280 </td><td>
2280 Technical implementation topics
2281 Technical implementation topics
2281 </td></tr>
2282 </td></tr>
2282 <tr><td>
2283 <tr><td>
2283 <a href="/help/merge-tools">
2284 <a href="/help/merge-tools">
2284 merge-tools
2285 merge-tools
2285 </a>
2286 </a>
2286 </td><td>
2287 </td><td>
2287 Merge Tools
2288 Merge Tools
2288 </td></tr>
2289 </td></tr>
2289 <tr><td>
2290 <tr><td>
2290 <a href="/help/pager">
2291 <a href="/help/pager">
2291 pager
2292 pager
2292 </a>
2293 </a>
2293 </td><td>
2294 </td><td>
2294 Pager Support
2295 Pager Support
2295 </td></tr>
2296 </td></tr>
2296 <tr><td>
2297 <tr><td>
2297 <a href="/help/patterns">
2298 <a href="/help/patterns">
2298 patterns
2299 patterns
2299 </a>
2300 </a>
2300 </td><td>
2301 </td><td>
2301 File Name Patterns
2302 File Name Patterns
2302 </td></tr>
2303 </td></tr>
2303 <tr><td>
2304 <tr><td>
2304 <a href="/help/phases">
2305 <a href="/help/phases">
2305 phases
2306 phases
2306 </a>
2307 </a>
2307 </td><td>
2308 </td><td>
2308 Working with Phases
2309 Working with Phases
2309 </td></tr>
2310 </td></tr>
2310 <tr><td>
2311 <tr><td>
2311 <a href="/help/revisions">
2312 <a href="/help/revisions">
2312 revisions
2313 revisions
2313 </a>
2314 </a>
2314 </td><td>
2315 </td><td>
2315 Specifying Revisions
2316 Specifying Revisions
2316 </td></tr>
2317 </td></tr>
2317 <tr><td>
2318 <tr><td>
2318 <a href="/help/scripting">
2319 <a href="/help/scripting">
2319 scripting
2320 scripting
2320 </a>
2321 </a>
2321 </td><td>
2322 </td><td>
2322 Using Mercurial from scripts and automation
2323 Using Mercurial from scripts and automation
2323 </td></tr>
2324 </td></tr>
2324 <tr><td>
2325 <tr><td>
2325 <a href="/help/subrepos">
2326 <a href="/help/subrepos">
2326 subrepos
2327 subrepos
2327 </a>
2328 </a>
2328 </td><td>
2329 </td><td>
2329 Subrepositories
2330 Subrepositories
2330 </td></tr>
2331 </td></tr>
2331 <tr><td>
2332 <tr><td>
2332 <a href="/help/templating">
2333 <a href="/help/templating">
2333 templating
2334 templating
2334 </a>
2335 </a>
2335 </td><td>
2336 </td><td>
2336 Template Usage
2337 Template Usage
2337 </td></tr>
2338 </td></tr>
2338 <tr><td>
2339 <tr><td>
2339 <a href="/help/urls">
2340 <a href="/help/urls">
2340 urls
2341 urls
2341 </a>
2342 </a>
2342 </td><td>
2343 </td><td>
2343 URL Paths
2344 URL Paths
2344 </td></tr>
2345 </td></tr>
2345 <tr><td>
2346 <tr><td>
2346 <a href="/help/topic-containing-verbose">
2347 <a href="/help/topic-containing-verbose">
2347 topic-containing-verbose
2348 topic-containing-verbose
2348 </a>
2349 </a>
2349 </td><td>
2350 </td><td>
2350 This is the topic to test omit indicating.
2351 This is the topic to test omit indicating.
2351 </td></tr>
2352 </td></tr>
2352
2353
2353
2354
2354 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2355 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2355
2356
2356 <tr><td>
2357 <tr><td>
2357 <a href="/help/abort">
2358 <a href="/help/abort">
2358 abort
2359 abort
2359 </a>
2360 </a>
2360 </td><td>
2361 </td><td>
2361 abort an unfinished operation (EXPERIMENTAL)
2362 abort an unfinished operation (EXPERIMENTAL)
2362 </td></tr>
2363 </td></tr>
2363 <tr><td>
2364 <tr><td>
2364 <a href="/help/add">
2365 <a href="/help/add">
2365 add
2366 add
2366 </a>
2367 </a>
2367 </td><td>
2368 </td><td>
2368 add the specified files on the next commit
2369 add the specified files on the next commit
2369 </td></tr>
2370 </td></tr>
2370 <tr><td>
2371 <tr><td>
2371 <a href="/help/annotate">
2372 <a href="/help/annotate">
2372 annotate
2373 annotate
2373 </a>
2374 </a>
2374 </td><td>
2375 </td><td>
2375 show changeset information by line for each file
2376 show changeset information by line for each file
2376 </td></tr>
2377 </td></tr>
2377 <tr><td>
2378 <tr><td>
2378 <a href="/help/clone">
2379 <a href="/help/clone">
2379 clone
2380 clone
2380 </a>
2381 </a>
2381 </td><td>
2382 </td><td>
2382 make a copy of an existing repository
2383 make a copy of an existing repository
2383 </td></tr>
2384 </td></tr>
2384 <tr><td>
2385 <tr><td>
2385 <a href="/help/commit">
2386 <a href="/help/commit">
2386 commit
2387 commit
2387 </a>
2388 </a>
2388 </td><td>
2389 </td><td>
2389 commit the specified files or all outstanding changes
2390 commit the specified files or all outstanding changes
2390 </td></tr>
2391 </td></tr>
2391 <tr><td>
2392 <tr><td>
2393 <a href="/help/continue">
2394 continue
2395 </a>
2396 </td><td>
2397 resumes an interrupted operation (EXPERIMENTAL)
2398 </td></tr>
2399 <tr><td>
2392 <a href="/help/diff">
2400 <a href="/help/diff">
2393 diff
2401 diff
2394 </a>
2402 </a>
2395 </td><td>
2403 </td><td>
2396 diff repository (or selected files)
2404 diff repository (or selected files)
2397 </td></tr>
2405 </td></tr>
2398 <tr><td>
2406 <tr><td>
2399 <a href="/help/export">
2407 <a href="/help/export">
2400 export
2408 export
2401 </a>
2409 </a>
2402 </td><td>
2410 </td><td>
2403 dump the header and diffs for one or more changesets
2411 dump the header and diffs for one or more changesets
2404 </td></tr>
2412 </td></tr>
2405 <tr><td>
2413 <tr><td>
2406 <a href="/help/forget">
2414 <a href="/help/forget">
2407 forget
2415 forget
2408 </a>
2416 </a>
2409 </td><td>
2417 </td><td>
2410 forget the specified files on the next commit
2418 forget the specified files on the next commit
2411 </td></tr>
2419 </td></tr>
2412 <tr><td>
2420 <tr><td>
2413 <a href="/help/init">
2421 <a href="/help/init">
2414 init
2422 init
2415 </a>
2423 </a>
2416 </td><td>
2424 </td><td>
2417 create a new repository in the given directory
2425 create a new repository in the given directory
2418 </td></tr>
2426 </td></tr>
2419 <tr><td>
2427 <tr><td>
2420 <a href="/help/log">
2428 <a href="/help/log">
2421 log
2429 log
2422 </a>
2430 </a>
2423 </td><td>
2431 </td><td>
2424 show revision history of entire repository or files
2432 show revision history of entire repository or files
2425 </td></tr>
2433 </td></tr>
2426 <tr><td>
2434 <tr><td>
2427 <a href="/help/merge">
2435 <a href="/help/merge">
2428 merge
2436 merge
2429 </a>
2437 </a>
2430 </td><td>
2438 </td><td>
2431 merge another revision into working directory
2439 merge another revision into working directory
2432 </td></tr>
2440 </td></tr>
2433 <tr><td>
2441 <tr><td>
2434 <a href="/help/pull">
2442 <a href="/help/pull">
2435 pull
2443 pull
2436 </a>
2444 </a>
2437 </td><td>
2445 </td><td>
2438 pull changes from the specified source
2446 pull changes from the specified source
2439 </td></tr>
2447 </td></tr>
2440 <tr><td>
2448 <tr><td>
2441 <a href="/help/push">
2449 <a href="/help/push">
2442 push
2450 push
2443 </a>
2451 </a>
2444 </td><td>
2452 </td><td>
2445 push changes to the specified destination
2453 push changes to the specified destination
2446 </td></tr>
2454 </td></tr>
2447 <tr><td>
2455 <tr><td>
2448 <a href="/help/remove">
2456 <a href="/help/remove">
2449 remove
2457 remove
2450 </a>
2458 </a>
2451 </td><td>
2459 </td><td>
2452 remove the specified files on the next commit
2460 remove the specified files on the next commit
2453 </td></tr>
2461 </td></tr>
2454 <tr><td>
2462 <tr><td>
2455 <a href="/help/serve">
2463 <a href="/help/serve">
2456 serve
2464 serve
2457 </a>
2465 </a>
2458 </td><td>
2466 </td><td>
2459 start stand-alone webserver
2467 start stand-alone webserver
2460 </td></tr>
2468 </td></tr>
2461 <tr><td>
2469 <tr><td>
2462 <a href="/help/status">
2470 <a href="/help/status">
2463 status
2471 status
2464 </a>
2472 </a>
2465 </td><td>
2473 </td><td>
2466 show changed files in the working directory
2474 show changed files in the working directory
2467 </td></tr>
2475 </td></tr>
2468 <tr><td>
2476 <tr><td>
2469 <a href="/help/summary">
2477 <a href="/help/summary">
2470 summary
2478 summary
2471 </a>
2479 </a>
2472 </td><td>
2480 </td><td>
2473 summarize working directory state
2481 summarize working directory state
2474 </td></tr>
2482 </td></tr>
2475 <tr><td>
2483 <tr><td>
2476 <a href="/help/update">
2484 <a href="/help/update">
2477 update
2485 update
2478 </a>
2486 </a>
2479 </td><td>
2487 </td><td>
2480 update working directory (or switch revisions)
2488 update working directory (or switch revisions)
2481 </td></tr>
2489 </td></tr>
2482
2490
2483
2491
2484
2492
2485 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2493 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2486
2494
2487 <tr><td>
2495 <tr><td>
2488 <a href="/help/addremove">
2496 <a href="/help/addremove">
2489 addremove
2497 addremove
2490 </a>
2498 </a>
2491 </td><td>
2499 </td><td>
2492 add all new files, delete all missing files
2500 add all new files, delete all missing files
2493 </td></tr>
2501 </td></tr>
2494 <tr><td>
2502 <tr><td>
2495 <a href="/help/archive">
2503 <a href="/help/archive">
2496 archive
2504 archive
2497 </a>
2505 </a>
2498 </td><td>
2506 </td><td>
2499 create an unversioned archive of a repository revision
2507 create an unversioned archive of a repository revision
2500 </td></tr>
2508 </td></tr>
2501 <tr><td>
2509 <tr><td>
2502 <a href="/help/backout">
2510 <a href="/help/backout">
2503 backout
2511 backout
2504 </a>
2512 </a>
2505 </td><td>
2513 </td><td>
2506 reverse effect of earlier changeset
2514 reverse effect of earlier changeset
2507 </td></tr>
2515 </td></tr>
2508 <tr><td>
2516 <tr><td>
2509 <a href="/help/bisect">
2517 <a href="/help/bisect">
2510 bisect
2518 bisect
2511 </a>
2519 </a>
2512 </td><td>
2520 </td><td>
2513 subdivision search of changesets
2521 subdivision search of changesets
2514 </td></tr>
2522 </td></tr>
2515 <tr><td>
2523 <tr><td>
2516 <a href="/help/bookmarks">
2524 <a href="/help/bookmarks">
2517 bookmarks
2525 bookmarks
2518 </a>
2526 </a>
2519 </td><td>
2527 </td><td>
2520 create a new bookmark or list existing bookmarks
2528 create a new bookmark or list existing bookmarks
2521 </td></tr>
2529 </td></tr>
2522 <tr><td>
2530 <tr><td>
2523 <a href="/help/branch">
2531 <a href="/help/branch">
2524 branch
2532 branch
2525 </a>
2533 </a>
2526 </td><td>
2534 </td><td>
2527 set or show the current branch name
2535 set or show the current branch name
2528 </td></tr>
2536 </td></tr>
2529 <tr><td>
2537 <tr><td>
2530 <a href="/help/branches">
2538 <a href="/help/branches">
2531 branches
2539 branches
2532 </a>
2540 </a>
2533 </td><td>
2541 </td><td>
2534 list repository named branches
2542 list repository named branches
2535 </td></tr>
2543 </td></tr>
2536 <tr><td>
2544 <tr><td>
2537 <a href="/help/bundle">
2545 <a href="/help/bundle">
2538 bundle
2546 bundle
2539 </a>
2547 </a>
2540 </td><td>
2548 </td><td>
2541 create a bundle file
2549 create a bundle file
2542 </td></tr>
2550 </td></tr>
2543 <tr><td>
2551 <tr><td>
2544 <a href="/help/cat">
2552 <a href="/help/cat">
2545 cat
2553 cat
2546 </a>
2554 </a>
2547 </td><td>
2555 </td><td>
2548 output the current or given revision of files
2556 output the current or given revision of files
2549 </td></tr>
2557 </td></tr>
2550 <tr><td>
2558 <tr><td>
2551 <a href="/help/config">
2559 <a href="/help/config">
2552 config
2560 config
2553 </a>
2561 </a>
2554 </td><td>
2562 </td><td>
2555 show combined config settings from all hgrc files
2563 show combined config settings from all hgrc files
2556 </td></tr>
2564 </td></tr>
2557 <tr><td>
2565 <tr><td>
2558 <a href="/help/copy">
2566 <a href="/help/copy">
2559 copy
2567 copy
2560 </a>
2568 </a>
2561 </td><td>
2569 </td><td>
2562 mark files as copied for the next commit
2570 mark files as copied for the next commit
2563 </td></tr>
2571 </td></tr>
2564 <tr><td>
2572 <tr><td>
2565 <a href="/help/files">
2573 <a href="/help/files">
2566 files
2574 files
2567 </a>
2575 </a>
2568 </td><td>
2576 </td><td>
2569 list tracked files
2577 list tracked files
2570 </td></tr>
2578 </td></tr>
2571 <tr><td>
2579 <tr><td>
2572 <a href="/help/graft">
2580 <a href="/help/graft">
2573 graft
2581 graft
2574 </a>
2582 </a>
2575 </td><td>
2583 </td><td>
2576 copy changes from other branches onto the current branch
2584 copy changes from other branches onto the current branch
2577 </td></tr>
2585 </td></tr>
2578 <tr><td>
2586 <tr><td>
2579 <a href="/help/grep">
2587 <a href="/help/grep">
2580 grep
2588 grep
2581 </a>
2589 </a>
2582 </td><td>
2590 </td><td>
2583 search revision history for a pattern in specified files
2591 search revision history for a pattern in specified files
2584 </td></tr>
2592 </td></tr>
2585 <tr><td>
2593 <tr><td>
2586 <a href="/help/hashelp">
2594 <a href="/help/hashelp">
2587 hashelp
2595 hashelp
2588 </a>
2596 </a>
2589 </td><td>
2597 </td><td>
2590 Extension command's help
2598 Extension command's help
2591 </td></tr>
2599 </td></tr>
2592 <tr><td>
2600 <tr><td>
2593 <a href="/help/heads">
2601 <a href="/help/heads">
2594 heads
2602 heads
2595 </a>
2603 </a>
2596 </td><td>
2604 </td><td>
2597 show branch heads
2605 show branch heads
2598 </td></tr>
2606 </td></tr>
2599 <tr><td>
2607 <tr><td>
2600 <a href="/help/help">
2608 <a href="/help/help">
2601 help
2609 help
2602 </a>
2610 </a>
2603 </td><td>
2611 </td><td>
2604 show help for a given topic or a help overview
2612 show help for a given topic or a help overview
2605 </td></tr>
2613 </td></tr>
2606 <tr><td>
2614 <tr><td>
2607 <a href="/help/hgalias">
2615 <a href="/help/hgalias">
2608 hgalias
2616 hgalias
2609 </a>
2617 </a>
2610 </td><td>
2618 </td><td>
2611 My doc
2619 My doc
2612 </td></tr>
2620 </td></tr>
2613 <tr><td>
2621 <tr><td>
2614 <a href="/help/hgaliasnodoc">
2622 <a href="/help/hgaliasnodoc">
2615 hgaliasnodoc
2623 hgaliasnodoc
2616 </a>
2624 </a>
2617 </td><td>
2625 </td><td>
2618 summarize working directory state
2626 summarize working directory state
2619 </td></tr>
2627 </td></tr>
2620 <tr><td>
2628 <tr><td>
2621 <a href="/help/identify">
2629 <a href="/help/identify">
2622 identify
2630 identify
2623 </a>
2631 </a>
2624 </td><td>
2632 </td><td>
2625 identify the working directory or specified revision
2633 identify the working directory or specified revision
2626 </td></tr>
2634 </td></tr>
2627 <tr><td>
2635 <tr><td>
2628 <a href="/help/import">
2636 <a href="/help/import">
2629 import
2637 import
2630 </a>
2638 </a>
2631 </td><td>
2639 </td><td>
2632 import an ordered set of patches
2640 import an ordered set of patches
2633 </td></tr>
2641 </td></tr>
2634 <tr><td>
2642 <tr><td>
2635 <a href="/help/incoming">
2643 <a href="/help/incoming">
2636 incoming
2644 incoming
2637 </a>
2645 </a>
2638 </td><td>
2646 </td><td>
2639 show new changesets found in source
2647 show new changesets found in source
2640 </td></tr>
2648 </td></tr>
2641 <tr><td>
2649 <tr><td>
2642 <a href="/help/manifest">
2650 <a href="/help/manifest">
2643 manifest
2651 manifest
2644 </a>
2652 </a>
2645 </td><td>
2653 </td><td>
2646 output the current or given revision of the project manifest
2654 output the current or given revision of the project manifest
2647 </td></tr>
2655 </td></tr>
2648 <tr><td>
2656 <tr><td>
2649 <a href="/help/nohelp">
2657 <a href="/help/nohelp">
2650 nohelp
2658 nohelp
2651 </a>
2659 </a>
2652 </td><td>
2660 </td><td>
2653 (no help text available)
2661 (no help text available)
2654 </td></tr>
2662 </td></tr>
2655 <tr><td>
2663 <tr><td>
2656 <a href="/help/outgoing">
2664 <a href="/help/outgoing">
2657 outgoing
2665 outgoing
2658 </a>
2666 </a>
2659 </td><td>
2667 </td><td>
2660 show changesets not found in the destination
2668 show changesets not found in the destination
2661 </td></tr>
2669 </td></tr>
2662 <tr><td>
2670 <tr><td>
2663 <a href="/help/paths">
2671 <a href="/help/paths">
2664 paths
2672 paths
2665 </a>
2673 </a>
2666 </td><td>
2674 </td><td>
2667 show aliases for remote repositories
2675 show aliases for remote repositories
2668 </td></tr>
2676 </td></tr>
2669 <tr><td>
2677 <tr><td>
2670 <a href="/help/phase">
2678 <a href="/help/phase">
2671 phase
2679 phase
2672 </a>
2680 </a>
2673 </td><td>
2681 </td><td>
2674 set or show the current phase name
2682 set or show the current phase name
2675 </td></tr>
2683 </td></tr>
2676 <tr><td>
2684 <tr><td>
2677 <a href="/help/recover">
2685 <a href="/help/recover">
2678 recover
2686 recover
2679 </a>
2687 </a>
2680 </td><td>
2688 </td><td>
2681 roll back an interrupted transaction
2689 roll back an interrupted transaction
2682 </td></tr>
2690 </td></tr>
2683 <tr><td>
2691 <tr><td>
2684 <a href="/help/rename">
2692 <a href="/help/rename">
2685 rename
2693 rename
2686 </a>
2694 </a>
2687 </td><td>
2695 </td><td>
2688 rename files; equivalent of copy + remove
2696 rename files; equivalent of copy + remove
2689 </td></tr>
2697 </td></tr>
2690 <tr><td>
2698 <tr><td>
2691 <a href="/help/resolve">
2699 <a href="/help/resolve">
2692 resolve
2700 resolve
2693 </a>
2701 </a>
2694 </td><td>
2702 </td><td>
2695 redo merges or set/view the merge status of files
2703 redo merges or set/view the merge status of files
2696 </td></tr>
2704 </td></tr>
2697 <tr><td>
2705 <tr><td>
2698 <a href="/help/revert">
2706 <a href="/help/revert">
2699 revert
2707 revert
2700 </a>
2708 </a>
2701 </td><td>
2709 </td><td>
2702 restore files to their checkout state
2710 restore files to their checkout state
2703 </td></tr>
2711 </td></tr>
2704 <tr><td>
2712 <tr><td>
2705 <a href="/help/root">
2713 <a href="/help/root">
2706 root
2714 root
2707 </a>
2715 </a>
2708 </td><td>
2716 </td><td>
2709 print the root (top) of the current working directory
2717 print the root (top) of the current working directory
2710 </td></tr>
2718 </td></tr>
2711 <tr><td>
2719 <tr><td>
2712 <a href="/help/shellalias">
2720 <a href="/help/shellalias">
2713 shellalias
2721 shellalias
2714 </a>
2722 </a>
2715 </td><td>
2723 </td><td>
2716 (no help text available)
2724 (no help text available)
2717 </td></tr>
2725 </td></tr>
2718 <tr><td>
2726 <tr><td>
2719 <a href="/help/shelve">
2727 <a href="/help/shelve">
2720 shelve
2728 shelve
2721 </a>
2729 </a>
2722 </td><td>
2730 </td><td>
2723 save and set aside changes from the working directory
2731 save and set aside changes from the working directory
2724 </td></tr>
2732 </td></tr>
2725 <tr><td>
2733 <tr><td>
2726 <a href="/help/tag">
2734 <a href="/help/tag">
2727 tag
2735 tag
2728 </a>
2736 </a>
2729 </td><td>
2737 </td><td>
2730 add one or more tags for the current or given revision
2738 add one or more tags for the current or given revision
2731 </td></tr>
2739 </td></tr>
2732 <tr><td>
2740 <tr><td>
2733 <a href="/help/tags">
2741 <a href="/help/tags">
2734 tags
2742 tags
2735 </a>
2743 </a>
2736 </td><td>
2744 </td><td>
2737 list repository tags
2745 list repository tags
2738 </td></tr>
2746 </td></tr>
2739 <tr><td>
2747 <tr><td>
2740 <a href="/help/unbundle">
2748 <a href="/help/unbundle">
2741 unbundle
2749 unbundle
2742 </a>
2750 </a>
2743 </td><td>
2751 </td><td>
2744 apply one or more bundle files
2752 apply one or more bundle files
2745 </td></tr>
2753 </td></tr>
2746 <tr><td>
2754 <tr><td>
2747 <a href="/help/unshelve">
2755 <a href="/help/unshelve">
2748 unshelve
2756 unshelve
2749 </a>
2757 </a>
2750 </td><td>
2758 </td><td>
2751 restore a shelved change to the working directory
2759 restore a shelved change to the working directory
2752 </td></tr>
2760 </td></tr>
2753 <tr><td>
2761 <tr><td>
2754 <a href="/help/verify">
2762 <a href="/help/verify">
2755 verify
2763 verify
2756 </a>
2764 </a>
2757 </td><td>
2765 </td><td>
2758 verify the integrity of the repository
2766 verify the integrity of the repository
2759 </td></tr>
2767 </td></tr>
2760 <tr><td>
2768 <tr><td>
2761 <a href="/help/version">
2769 <a href="/help/version">
2762 version
2770 version
2763 </a>
2771 </a>
2764 </td><td>
2772 </td><td>
2765 output version and copyright information
2773 output version and copyright information
2766 </td></tr>
2774 </td></tr>
2767
2775
2768
2776
2769 </table>
2777 </table>
2770 </div>
2778 </div>
2771 </div>
2779 </div>
2772
2780
2773
2781
2774
2782
2775 </body>
2783 </body>
2776 </html>
2784 </html>
2777
2785
2778
2786
2779 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2787 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2780 200 Script output follows
2788 200 Script output follows
2781
2789
2782 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2790 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2783 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2791 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2784 <head>
2792 <head>
2785 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2793 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2786 <meta name="robots" content="index, nofollow" />
2794 <meta name="robots" content="index, nofollow" />
2787 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2795 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2788 <script type="text/javascript" src="/static/mercurial.js"></script>
2796 <script type="text/javascript" src="/static/mercurial.js"></script>
2789
2797
2790 <title>Help: add</title>
2798 <title>Help: add</title>
2791 </head>
2799 </head>
2792 <body>
2800 <body>
2793
2801
2794 <div class="container">
2802 <div class="container">
2795 <div class="menu">
2803 <div class="menu">
2796 <div class="logo">
2804 <div class="logo">
2797 <a href="https://mercurial-scm.org/">
2805 <a href="https://mercurial-scm.org/">
2798 <img src="/static/hglogo.png" alt="mercurial" /></a>
2806 <img src="/static/hglogo.png" alt="mercurial" /></a>
2799 </div>
2807 </div>
2800 <ul>
2808 <ul>
2801 <li><a href="/shortlog">log</a></li>
2809 <li><a href="/shortlog">log</a></li>
2802 <li><a href="/graph">graph</a></li>
2810 <li><a href="/graph">graph</a></li>
2803 <li><a href="/tags">tags</a></li>
2811 <li><a href="/tags">tags</a></li>
2804 <li><a href="/bookmarks">bookmarks</a></li>
2812 <li><a href="/bookmarks">bookmarks</a></li>
2805 <li><a href="/branches">branches</a></li>
2813 <li><a href="/branches">branches</a></li>
2806 </ul>
2814 </ul>
2807 <ul>
2815 <ul>
2808 <li class="active"><a href="/help">help</a></li>
2816 <li class="active"><a href="/help">help</a></li>
2809 </ul>
2817 </ul>
2810 </div>
2818 </div>
2811
2819
2812 <div class="main">
2820 <div class="main">
2813 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2821 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2814 <h3>Help: add</h3>
2822 <h3>Help: add</h3>
2815
2823
2816 <form class="search" action="/log">
2824 <form class="search" action="/log">
2817
2825
2818 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2826 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2819 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2827 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2820 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2828 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2821 </form>
2829 </form>
2822 <div id="doc">
2830 <div id="doc">
2823 <p>
2831 <p>
2824 hg add [OPTION]... [FILE]...
2832 hg add [OPTION]... [FILE]...
2825 </p>
2833 </p>
2826 <p>
2834 <p>
2827 add the specified files on the next commit
2835 add the specified files on the next commit
2828 </p>
2836 </p>
2829 <p>
2837 <p>
2830 Schedule files to be version controlled and added to the
2838 Schedule files to be version controlled and added to the
2831 repository.
2839 repository.
2832 </p>
2840 </p>
2833 <p>
2841 <p>
2834 The files will be added to the repository at the next commit. To
2842 The files will be added to the repository at the next commit. To
2835 undo an add before that, see 'hg forget'.
2843 undo an add before that, see 'hg forget'.
2836 </p>
2844 </p>
2837 <p>
2845 <p>
2838 If no names are given, add all files to the repository (except
2846 If no names are given, add all files to the repository (except
2839 files matching &quot;.hgignore&quot;).
2847 files matching &quot;.hgignore&quot;).
2840 </p>
2848 </p>
2841 <p>
2849 <p>
2842 Examples:
2850 Examples:
2843 </p>
2851 </p>
2844 <ul>
2852 <ul>
2845 <li> New (unknown) files are added automatically by 'hg add':
2853 <li> New (unknown) files are added automatically by 'hg add':
2846 <pre>
2854 <pre>
2847 \$ ls (re)
2855 \$ ls (re)
2848 foo.c
2856 foo.c
2849 \$ hg status (re)
2857 \$ hg status (re)
2850 ? foo.c
2858 ? foo.c
2851 \$ hg add (re)
2859 \$ hg add (re)
2852 adding foo.c
2860 adding foo.c
2853 \$ hg status (re)
2861 \$ hg status (re)
2854 A foo.c
2862 A foo.c
2855 </pre>
2863 </pre>
2856 <li> Specific files to be added can be specified:
2864 <li> Specific files to be added can be specified:
2857 <pre>
2865 <pre>
2858 \$ ls (re)
2866 \$ ls (re)
2859 bar.c foo.c
2867 bar.c foo.c
2860 \$ hg status (re)
2868 \$ hg status (re)
2861 ? bar.c
2869 ? bar.c
2862 ? foo.c
2870 ? foo.c
2863 \$ hg add bar.c (re)
2871 \$ hg add bar.c (re)
2864 \$ hg status (re)
2872 \$ hg status (re)
2865 A bar.c
2873 A bar.c
2866 ? foo.c
2874 ? foo.c
2867 </pre>
2875 </pre>
2868 </ul>
2876 </ul>
2869 <p>
2877 <p>
2870 Returns 0 if all files are successfully added.
2878 Returns 0 if all files are successfully added.
2871 </p>
2879 </p>
2872 <p>
2880 <p>
2873 options ([+] can be repeated):
2881 options ([+] can be repeated):
2874 </p>
2882 </p>
2875 <table>
2883 <table>
2876 <tr><td>-I</td>
2884 <tr><td>-I</td>
2877 <td>--include PATTERN [+]</td>
2885 <td>--include PATTERN [+]</td>
2878 <td>include names matching the given patterns</td></tr>
2886 <td>include names matching the given patterns</td></tr>
2879 <tr><td>-X</td>
2887 <tr><td>-X</td>
2880 <td>--exclude PATTERN [+]</td>
2888 <td>--exclude PATTERN [+]</td>
2881 <td>exclude names matching the given patterns</td></tr>
2889 <td>exclude names matching the given patterns</td></tr>
2882 <tr><td>-S</td>
2890 <tr><td>-S</td>
2883 <td>--subrepos</td>
2891 <td>--subrepos</td>
2884 <td>recurse into subrepositories</td></tr>
2892 <td>recurse into subrepositories</td></tr>
2885 <tr><td>-n</td>
2893 <tr><td>-n</td>
2886 <td>--dry-run</td>
2894 <td>--dry-run</td>
2887 <td>do not perform actions, just print output</td></tr>
2895 <td>do not perform actions, just print output</td></tr>
2888 </table>
2896 </table>
2889 <p>
2897 <p>
2890 global options ([+] can be repeated):
2898 global options ([+] can be repeated):
2891 </p>
2899 </p>
2892 <table>
2900 <table>
2893 <tr><td>-R</td>
2901 <tr><td>-R</td>
2894 <td>--repository REPO</td>
2902 <td>--repository REPO</td>
2895 <td>repository root directory or name of overlay bundle file</td></tr>
2903 <td>repository root directory or name of overlay bundle file</td></tr>
2896 <tr><td></td>
2904 <tr><td></td>
2897 <td>--cwd DIR</td>
2905 <td>--cwd DIR</td>
2898 <td>change working directory</td></tr>
2906 <td>change working directory</td></tr>
2899 <tr><td>-y</td>
2907 <tr><td>-y</td>
2900 <td>--noninteractive</td>
2908 <td>--noninteractive</td>
2901 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2909 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2902 <tr><td>-q</td>
2910 <tr><td>-q</td>
2903 <td>--quiet</td>
2911 <td>--quiet</td>
2904 <td>suppress output</td></tr>
2912 <td>suppress output</td></tr>
2905 <tr><td>-v</td>
2913 <tr><td>-v</td>
2906 <td>--verbose</td>
2914 <td>--verbose</td>
2907 <td>enable additional output</td></tr>
2915 <td>enable additional output</td></tr>
2908 <tr><td></td>
2916 <tr><td></td>
2909 <td>--color TYPE</td>
2917 <td>--color TYPE</td>
2910 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2918 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2911 <tr><td></td>
2919 <tr><td></td>
2912 <td>--config CONFIG [+]</td>
2920 <td>--config CONFIG [+]</td>
2913 <td>set/override config option (use 'section.name=value')</td></tr>
2921 <td>set/override config option (use 'section.name=value')</td></tr>
2914 <tr><td></td>
2922 <tr><td></td>
2915 <td>--debug</td>
2923 <td>--debug</td>
2916 <td>enable debugging output</td></tr>
2924 <td>enable debugging output</td></tr>
2917 <tr><td></td>
2925 <tr><td></td>
2918 <td>--debugger</td>
2926 <td>--debugger</td>
2919 <td>start debugger</td></tr>
2927 <td>start debugger</td></tr>
2920 <tr><td></td>
2928 <tr><td></td>
2921 <td>--encoding ENCODE</td>
2929 <td>--encoding ENCODE</td>
2922 <td>set the charset encoding (default: ascii)</td></tr>
2930 <td>set the charset encoding (default: ascii)</td></tr>
2923 <tr><td></td>
2931 <tr><td></td>
2924 <td>--encodingmode MODE</td>
2932 <td>--encodingmode MODE</td>
2925 <td>set the charset encoding mode (default: strict)</td></tr>
2933 <td>set the charset encoding mode (default: strict)</td></tr>
2926 <tr><td></td>
2934 <tr><td></td>
2927 <td>--traceback</td>
2935 <td>--traceback</td>
2928 <td>always print a traceback on exception</td></tr>
2936 <td>always print a traceback on exception</td></tr>
2929 <tr><td></td>
2937 <tr><td></td>
2930 <td>--time</td>
2938 <td>--time</td>
2931 <td>time how long the command takes</td></tr>
2939 <td>time how long the command takes</td></tr>
2932 <tr><td></td>
2940 <tr><td></td>
2933 <td>--profile</td>
2941 <td>--profile</td>
2934 <td>print command execution profile</td></tr>
2942 <td>print command execution profile</td></tr>
2935 <tr><td></td>
2943 <tr><td></td>
2936 <td>--version</td>
2944 <td>--version</td>
2937 <td>output version information and exit</td></tr>
2945 <td>output version information and exit</td></tr>
2938 <tr><td>-h</td>
2946 <tr><td>-h</td>
2939 <td>--help</td>
2947 <td>--help</td>
2940 <td>display help and exit</td></tr>
2948 <td>display help and exit</td></tr>
2941 <tr><td></td>
2949 <tr><td></td>
2942 <td>--hidden</td>
2950 <td>--hidden</td>
2943 <td>consider hidden changesets</td></tr>
2951 <td>consider hidden changesets</td></tr>
2944 <tr><td></td>
2952 <tr><td></td>
2945 <td>--pager TYPE</td>
2953 <td>--pager TYPE</td>
2946 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2954 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2947 </table>
2955 </table>
2948
2956
2949 </div>
2957 </div>
2950 </div>
2958 </div>
2951 </div>
2959 </div>
2952
2960
2953
2961
2954
2962
2955 </body>
2963 </body>
2956 </html>
2964 </html>
2957
2965
2958
2966
2959 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2967 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2960 200 Script output follows
2968 200 Script output follows
2961
2969
2962 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2970 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2963 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2971 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2964 <head>
2972 <head>
2965 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2973 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2966 <meta name="robots" content="index, nofollow" />
2974 <meta name="robots" content="index, nofollow" />
2967 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2975 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2968 <script type="text/javascript" src="/static/mercurial.js"></script>
2976 <script type="text/javascript" src="/static/mercurial.js"></script>
2969
2977
2970 <title>Help: remove</title>
2978 <title>Help: remove</title>
2971 </head>
2979 </head>
2972 <body>
2980 <body>
2973
2981
2974 <div class="container">
2982 <div class="container">
2975 <div class="menu">
2983 <div class="menu">
2976 <div class="logo">
2984 <div class="logo">
2977 <a href="https://mercurial-scm.org/">
2985 <a href="https://mercurial-scm.org/">
2978 <img src="/static/hglogo.png" alt="mercurial" /></a>
2986 <img src="/static/hglogo.png" alt="mercurial" /></a>
2979 </div>
2987 </div>
2980 <ul>
2988 <ul>
2981 <li><a href="/shortlog">log</a></li>
2989 <li><a href="/shortlog">log</a></li>
2982 <li><a href="/graph">graph</a></li>
2990 <li><a href="/graph">graph</a></li>
2983 <li><a href="/tags">tags</a></li>
2991 <li><a href="/tags">tags</a></li>
2984 <li><a href="/bookmarks">bookmarks</a></li>
2992 <li><a href="/bookmarks">bookmarks</a></li>
2985 <li><a href="/branches">branches</a></li>
2993 <li><a href="/branches">branches</a></li>
2986 </ul>
2994 </ul>
2987 <ul>
2995 <ul>
2988 <li class="active"><a href="/help">help</a></li>
2996 <li class="active"><a href="/help">help</a></li>
2989 </ul>
2997 </ul>
2990 </div>
2998 </div>
2991
2999
2992 <div class="main">
3000 <div class="main">
2993 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3001 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2994 <h3>Help: remove</h3>
3002 <h3>Help: remove</h3>
2995
3003
2996 <form class="search" action="/log">
3004 <form class="search" action="/log">
2997
3005
2998 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3006 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2999 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3007 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3000 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3008 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3001 </form>
3009 </form>
3002 <div id="doc">
3010 <div id="doc">
3003 <p>
3011 <p>
3004 hg remove [OPTION]... FILE...
3012 hg remove [OPTION]... FILE...
3005 </p>
3013 </p>
3006 <p>
3014 <p>
3007 aliases: rm
3015 aliases: rm
3008 </p>
3016 </p>
3009 <p>
3017 <p>
3010 remove the specified files on the next commit
3018 remove the specified files on the next commit
3011 </p>
3019 </p>
3012 <p>
3020 <p>
3013 Schedule the indicated files for removal from the current branch.
3021 Schedule the indicated files for removal from the current branch.
3014 </p>
3022 </p>
3015 <p>
3023 <p>
3016 This command schedules the files to be removed at the next commit.
3024 This command schedules the files to be removed at the next commit.
3017 To undo a remove before that, see 'hg revert'. To undo added
3025 To undo a remove before that, see 'hg revert'. To undo added
3018 files, see 'hg forget'.
3026 files, see 'hg forget'.
3019 </p>
3027 </p>
3020 <p>
3028 <p>
3021 -A/--after can be used to remove only files that have already
3029 -A/--after can be used to remove only files that have already
3022 been deleted, -f/--force can be used to force deletion, and -Af
3030 been deleted, -f/--force can be used to force deletion, and -Af
3023 can be used to remove files from the next revision without
3031 can be used to remove files from the next revision without
3024 deleting them from the working directory.
3032 deleting them from the working directory.
3025 </p>
3033 </p>
3026 <p>
3034 <p>
3027 The following table details the behavior of remove for different
3035 The following table details the behavior of remove for different
3028 file states (columns) and option combinations (rows). The file
3036 file states (columns) and option combinations (rows). The file
3029 states are Added [A], Clean [C], Modified [M] and Missing [!]
3037 states are Added [A], Clean [C], Modified [M] and Missing [!]
3030 (as reported by 'hg status'). The actions are Warn, Remove
3038 (as reported by 'hg status'). The actions are Warn, Remove
3031 (from branch) and Delete (from disk):
3039 (from branch) and Delete (from disk):
3032 </p>
3040 </p>
3033 <table>
3041 <table>
3034 <tr><td>opt/state</td>
3042 <tr><td>opt/state</td>
3035 <td>A</td>
3043 <td>A</td>
3036 <td>C</td>
3044 <td>C</td>
3037 <td>M</td>
3045 <td>M</td>
3038 <td>!</td></tr>
3046 <td>!</td></tr>
3039 <tr><td>none</td>
3047 <tr><td>none</td>
3040 <td>W</td>
3048 <td>W</td>
3041 <td>RD</td>
3049 <td>RD</td>
3042 <td>W</td>
3050 <td>W</td>
3043 <td>R</td></tr>
3051 <td>R</td></tr>
3044 <tr><td>-f</td>
3052 <tr><td>-f</td>
3045 <td>R</td>
3053 <td>R</td>
3046 <td>RD</td>
3054 <td>RD</td>
3047 <td>RD</td>
3055 <td>RD</td>
3048 <td>R</td></tr>
3056 <td>R</td></tr>
3049 <tr><td>-A</td>
3057 <tr><td>-A</td>
3050 <td>W</td>
3058 <td>W</td>
3051 <td>W</td>
3059 <td>W</td>
3052 <td>W</td>
3060 <td>W</td>
3053 <td>R</td></tr>
3061 <td>R</td></tr>
3054 <tr><td>-Af</td>
3062 <tr><td>-Af</td>
3055 <td>R</td>
3063 <td>R</td>
3056 <td>R</td>
3064 <td>R</td>
3057 <td>R</td>
3065 <td>R</td>
3058 <td>R</td></tr>
3066 <td>R</td></tr>
3059 </table>
3067 </table>
3060 <p>
3068 <p>
3061 <b>Note:</b>
3069 <b>Note:</b>
3062 </p>
3070 </p>
3063 <p>
3071 <p>
3064 'hg remove' never deletes files in Added [A] state from the
3072 'hg remove' never deletes files in Added [A] state from the
3065 working directory, not even if &quot;--force&quot; is specified.
3073 working directory, not even if &quot;--force&quot; is specified.
3066 </p>
3074 </p>
3067 <p>
3075 <p>
3068 Returns 0 on success, 1 if any warnings encountered.
3076 Returns 0 on success, 1 if any warnings encountered.
3069 </p>
3077 </p>
3070 <p>
3078 <p>
3071 options ([+] can be repeated):
3079 options ([+] can be repeated):
3072 </p>
3080 </p>
3073 <table>
3081 <table>
3074 <tr><td>-A</td>
3082 <tr><td>-A</td>
3075 <td>--after</td>
3083 <td>--after</td>
3076 <td>record delete for missing files</td></tr>
3084 <td>record delete for missing files</td></tr>
3077 <tr><td>-f</td>
3085 <tr><td>-f</td>
3078 <td>--force</td>
3086 <td>--force</td>
3079 <td>forget added files, delete modified files</td></tr>
3087 <td>forget added files, delete modified files</td></tr>
3080 <tr><td>-S</td>
3088 <tr><td>-S</td>
3081 <td>--subrepos</td>
3089 <td>--subrepos</td>
3082 <td>recurse into subrepositories</td></tr>
3090 <td>recurse into subrepositories</td></tr>
3083 <tr><td>-I</td>
3091 <tr><td>-I</td>
3084 <td>--include PATTERN [+]</td>
3092 <td>--include PATTERN [+]</td>
3085 <td>include names matching the given patterns</td></tr>
3093 <td>include names matching the given patterns</td></tr>
3086 <tr><td>-X</td>
3094 <tr><td>-X</td>
3087 <td>--exclude PATTERN [+]</td>
3095 <td>--exclude PATTERN [+]</td>
3088 <td>exclude names matching the given patterns</td></tr>
3096 <td>exclude names matching the given patterns</td></tr>
3089 <tr><td>-n</td>
3097 <tr><td>-n</td>
3090 <td>--dry-run</td>
3098 <td>--dry-run</td>
3091 <td>do not perform actions, just print output</td></tr>
3099 <td>do not perform actions, just print output</td></tr>
3092 </table>
3100 </table>
3093 <p>
3101 <p>
3094 global options ([+] can be repeated):
3102 global options ([+] can be repeated):
3095 </p>
3103 </p>
3096 <table>
3104 <table>
3097 <tr><td>-R</td>
3105 <tr><td>-R</td>
3098 <td>--repository REPO</td>
3106 <td>--repository REPO</td>
3099 <td>repository root directory or name of overlay bundle file</td></tr>
3107 <td>repository root directory or name of overlay bundle file</td></tr>
3100 <tr><td></td>
3108 <tr><td></td>
3101 <td>--cwd DIR</td>
3109 <td>--cwd DIR</td>
3102 <td>change working directory</td></tr>
3110 <td>change working directory</td></tr>
3103 <tr><td>-y</td>
3111 <tr><td>-y</td>
3104 <td>--noninteractive</td>
3112 <td>--noninteractive</td>
3105 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3113 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3106 <tr><td>-q</td>
3114 <tr><td>-q</td>
3107 <td>--quiet</td>
3115 <td>--quiet</td>
3108 <td>suppress output</td></tr>
3116 <td>suppress output</td></tr>
3109 <tr><td>-v</td>
3117 <tr><td>-v</td>
3110 <td>--verbose</td>
3118 <td>--verbose</td>
3111 <td>enable additional output</td></tr>
3119 <td>enable additional output</td></tr>
3112 <tr><td></td>
3120 <tr><td></td>
3113 <td>--color TYPE</td>
3121 <td>--color TYPE</td>
3114 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3122 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3115 <tr><td></td>
3123 <tr><td></td>
3116 <td>--config CONFIG [+]</td>
3124 <td>--config CONFIG [+]</td>
3117 <td>set/override config option (use 'section.name=value')</td></tr>
3125 <td>set/override config option (use 'section.name=value')</td></tr>
3118 <tr><td></td>
3126 <tr><td></td>
3119 <td>--debug</td>
3127 <td>--debug</td>
3120 <td>enable debugging output</td></tr>
3128 <td>enable debugging output</td></tr>
3121 <tr><td></td>
3129 <tr><td></td>
3122 <td>--debugger</td>
3130 <td>--debugger</td>
3123 <td>start debugger</td></tr>
3131 <td>start debugger</td></tr>
3124 <tr><td></td>
3132 <tr><td></td>
3125 <td>--encoding ENCODE</td>
3133 <td>--encoding ENCODE</td>
3126 <td>set the charset encoding (default: ascii)</td></tr>
3134 <td>set the charset encoding (default: ascii)</td></tr>
3127 <tr><td></td>
3135 <tr><td></td>
3128 <td>--encodingmode MODE</td>
3136 <td>--encodingmode MODE</td>
3129 <td>set the charset encoding mode (default: strict)</td></tr>
3137 <td>set the charset encoding mode (default: strict)</td></tr>
3130 <tr><td></td>
3138 <tr><td></td>
3131 <td>--traceback</td>
3139 <td>--traceback</td>
3132 <td>always print a traceback on exception</td></tr>
3140 <td>always print a traceback on exception</td></tr>
3133 <tr><td></td>
3141 <tr><td></td>
3134 <td>--time</td>
3142 <td>--time</td>
3135 <td>time how long the command takes</td></tr>
3143 <td>time how long the command takes</td></tr>
3136 <tr><td></td>
3144 <tr><td></td>
3137 <td>--profile</td>
3145 <td>--profile</td>
3138 <td>print command execution profile</td></tr>
3146 <td>print command execution profile</td></tr>
3139 <tr><td></td>
3147 <tr><td></td>
3140 <td>--version</td>
3148 <td>--version</td>
3141 <td>output version information and exit</td></tr>
3149 <td>output version information and exit</td></tr>
3142 <tr><td>-h</td>
3150 <tr><td>-h</td>
3143 <td>--help</td>
3151 <td>--help</td>
3144 <td>display help and exit</td></tr>
3152 <td>display help and exit</td></tr>
3145 <tr><td></td>
3153 <tr><td></td>
3146 <td>--hidden</td>
3154 <td>--hidden</td>
3147 <td>consider hidden changesets</td></tr>
3155 <td>consider hidden changesets</td></tr>
3148 <tr><td></td>
3156 <tr><td></td>
3149 <td>--pager TYPE</td>
3157 <td>--pager TYPE</td>
3150 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3158 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3151 </table>
3159 </table>
3152
3160
3153 </div>
3161 </div>
3154 </div>
3162 </div>
3155 </div>
3163 </div>
3156
3164
3157
3165
3158
3166
3159 </body>
3167 </body>
3160 </html>
3168 </html>
3161
3169
3162
3170
3163 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3171 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3164 200 Script output follows
3172 200 Script output follows
3165
3173
3166 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3174 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3167 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3175 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3168 <head>
3176 <head>
3169 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3177 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3170 <meta name="robots" content="index, nofollow" />
3178 <meta name="robots" content="index, nofollow" />
3171 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3179 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3172 <script type="text/javascript" src="/static/mercurial.js"></script>
3180 <script type="text/javascript" src="/static/mercurial.js"></script>
3173
3181
3174 <title>Help: dates</title>
3182 <title>Help: dates</title>
3175 </head>
3183 </head>
3176 <body>
3184 <body>
3177
3185
3178 <div class="container">
3186 <div class="container">
3179 <div class="menu">
3187 <div class="menu">
3180 <div class="logo">
3188 <div class="logo">
3181 <a href="https://mercurial-scm.org/">
3189 <a href="https://mercurial-scm.org/">
3182 <img src="/static/hglogo.png" alt="mercurial" /></a>
3190 <img src="/static/hglogo.png" alt="mercurial" /></a>
3183 </div>
3191 </div>
3184 <ul>
3192 <ul>
3185 <li><a href="/shortlog">log</a></li>
3193 <li><a href="/shortlog">log</a></li>
3186 <li><a href="/graph">graph</a></li>
3194 <li><a href="/graph">graph</a></li>
3187 <li><a href="/tags">tags</a></li>
3195 <li><a href="/tags">tags</a></li>
3188 <li><a href="/bookmarks">bookmarks</a></li>
3196 <li><a href="/bookmarks">bookmarks</a></li>
3189 <li><a href="/branches">branches</a></li>
3197 <li><a href="/branches">branches</a></li>
3190 </ul>
3198 </ul>
3191 <ul>
3199 <ul>
3192 <li class="active"><a href="/help">help</a></li>
3200 <li class="active"><a href="/help">help</a></li>
3193 </ul>
3201 </ul>
3194 </div>
3202 </div>
3195
3203
3196 <div class="main">
3204 <div class="main">
3197 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3205 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3198 <h3>Help: dates</h3>
3206 <h3>Help: dates</h3>
3199
3207
3200 <form class="search" action="/log">
3208 <form class="search" action="/log">
3201
3209
3202 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3210 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3203 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3211 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3204 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3212 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3205 </form>
3213 </form>
3206 <div id="doc">
3214 <div id="doc">
3207 <h1>Date Formats</h1>
3215 <h1>Date Formats</h1>
3208 <p>
3216 <p>
3209 Some commands allow the user to specify a date, e.g.:
3217 Some commands allow the user to specify a date, e.g.:
3210 </p>
3218 </p>
3211 <ul>
3219 <ul>
3212 <li> backout, commit, import, tag: Specify the commit date.
3220 <li> backout, commit, import, tag: Specify the commit date.
3213 <li> log, revert, update: Select revision(s) by date.
3221 <li> log, revert, update: Select revision(s) by date.
3214 </ul>
3222 </ul>
3215 <p>
3223 <p>
3216 Many date formats are valid. Here are some examples:
3224 Many date formats are valid. Here are some examples:
3217 </p>
3225 </p>
3218 <ul>
3226 <ul>
3219 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3227 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3220 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3228 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3221 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3229 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3222 <li> &quot;Dec 6&quot; (midnight)
3230 <li> &quot;Dec 6&quot; (midnight)
3223 <li> &quot;13:18&quot; (today assumed)
3231 <li> &quot;13:18&quot; (today assumed)
3224 <li> &quot;3:39&quot; (3:39AM assumed)
3232 <li> &quot;3:39&quot; (3:39AM assumed)
3225 <li> &quot;3:39pm&quot; (15:39)
3233 <li> &quot;3:39pm&quot; (15:39)
3226 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3234 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3227 <li> &quot;2006-12-6 13:18&quot;
3235 <li> &quot;2006-12-6 13:18&quot;
3228 <li> &quot;2006-12-6&quot;
3236 <li> &quot;2006-12-6&quot;
3229 <li> &quot;12-6&quot;
3237 <li> &quot;12-6&quot;
3230 <li> &quot;12/6&quot;
3238 <li> &quot;12/6&quot;
3231 <li> &quot;12/6/6&quot; (Dec 6 2006)
3239 <li> &quot;12/6/6&quot; (Dec 6 2006)
3232 <li> &quot;today&quot; (midnight)
3240 <li> &quot;today&quot; (midnight)
3233 <li> &quot;yesterday&quot; (midnight)
3241 <li> &quot;yesterday&quot; (midnight)
3234 <li> &quot;now&quot; - right now
3242 <li> &quot;now&quot; - right now
3235 </ul>
3243 </ul>
3236 <p>
3244 <p>
3237 Lastly, there is Mercurial's internal format:
3245 Lastly, there is Mercurial's internal format:
3238 </p>
3246 </p>
3239 <ul>
3247 <ul>
3240 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3248 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3241 </ul>
3249 </ul>
3242 <p>
3250 <p>
3243 This is the internal representation format for dates. The first number
3251 This is the internal representation format for dates. The first number
3244 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3252 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3245 second is the offset of the local timezone, in seconds west of UTC
3253 second is the offset of the local timezone, in seconds west of UTC
3246 (negative if the timezone is east of UTC).
3254 (negative if the timezone is east of UTC).
3247 </p>
3255 </p>
3248 <p>
3256 <p>
3249 The log command also accepts date ranges:
3257 The log command also accepts date ranges:
3250 </p>
3258 </p>
3251 <ul>
3259 <ul>
3252 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3260 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3253 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3261 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3254 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3262 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3255 <li> &quot;-DAYS&quot; - within a given number of days of today
3263 <li> &quot;-DAYS&quot; - within a given number of days of today
3256 </ul>
3264 </ul>
3257
3265
3258 </div>
3266 </div>
3259 </div>
3267 </div>
3260 </div>
3268 </div>
3261
3269
3262
3270
3263
3271
3264 </body>
3272 </body>
3265 </html>
3273 </html>
3266
3274
3267
3275
3268 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3276 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3269 200 Script output follows
3277 200 Script output follows
3270
3278
3271 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3279 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3272 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3280 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3273 <head>
3281 <head>
3274 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3282 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3275 <meta name="robots" content="index, nofollow" />
3283 <meta name="robots" content="index, nofollow" />
3276 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3284 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3277 <script type="text/javascript" src="/static/mercurial.js"></script>
3285 <script type="text/javascript" src="/static/mercurial.js"></script>
3278
3286
3279 <title>Help: pager</title>
3287 <title>Help: pager</title>
3280 </head>
3288 </head>
3281 <body>
3289 <body>
3282
3290
3283 <div class="container">
3291 <div class="container">
3284 <div class="menu">
3292 <div class="menu">
3285 <div class="logo">
3293 <div class="logo">
3286 <a href="https://mercurial-scm.org/">
3294 <a href="https://mercurial-scm.org/">
3287 <img src="/static/hglogo.png" alt="mercurial" /></a>
3295 <img src="/static/hglogo.png" alt="mercurial" /></a>
3288 </div>
3296 </div>
3289 <ul>
3297 <ul>
3290 <li><a href="/shortlog">log</a></li>
3298 <li><a href="/shortlog">log</a></li>
3291 <li><a href="/graph">graph</a></li>
3299 <li><a href="/graph">graph</a></li>
3292 <li><a href="/tags">tags</a></li>
3300 <li><a href="/tags">tags</a></li>
3293 <li><a href="/bookmarks">bookmarks</a></li>
3301 <li><a href="/bookmarks">bookmarks</a></li>
3294 <li><a href="/branches">branches</a></li>
3302 <li><a href="/branches">branches</a></li>
3295 </ul>
3303 </ul>
3296 <ul>
3304 <ul>
3297 <li class="active"><a href="/help">help</a></li>
3305 <li class="active"><a href="/help">help</a></li>
3298 </ul>
3306 </ul>
3299 </div>
3307 </div>
3300
3308
3301 <div class="main">
3309 <div class="main">
3302 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3310 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3303 <h3>Help: pager</h3>
3311 <h3>Help: pager</h3>
3304
3312
3305 <form class="search" action="/log">
3313 <form class="search" action="/log">
3306
3314
3307 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3315 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3308 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3316 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3309 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3317 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3310 </form>
3318 </form>
3311 <div id="doc">
3319 <div id="doc">
3312 <h1>Pager Support</h1>
3320 <h1>Pager Support</h1>
3313 <p>
3321 <p>
3314 Some Mercurial commands can produce a lot of output, and Mercurial will
3322 Some Mercurial commands can produce a lot of output, and Mercurial will
3315 attempt to use a pager to make those commands more pleasant.
3323 attempt to use a pager to make those commands more pleasant.
3316 </p>
3324 </p>
3317 <p>
3325 <p>
3318 To set the pager that should be used, set the application variable:
3326 To set the pager that should be used, set the application variable:
3319 </p>
3327 </p>
3320 <pre>
3328 <pre>
3321 [pager]
3329 [pager]
3322 pager = less -FRX
3330 pager = less -FRX
3323 </pre>
3331 </pre>
3324 <p>
3332 <p>
3325 If no pager is set in the user or repository configuration, Mercurial uses the
3333 If no pager is set in the user or repository configuration, Mercurial uses the
3326 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3334 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3327 or system configuration is used. If none of these are set, a default pager will
3335 or system configuration is used. If none of these are set, a default pager will
3328 be used, typically 'less' on Unix and 'more' on Windows.
3336 be used, typically 'less' on Unix and 'more' on Windows.
3329 </p>
3337 </p>
3330 <p>
3338 <p>
3331 You can disable the pager for certain commands by adding them to the
3339 You can disable the pager for certain commands by adding them to the
3332 pager.ignore list:
3340 pager.ignore list:
3333 </p>
3341 </p>
3334 <pre>
3342 <pre>
3335 [pager]
3343 [pager]
3336 ignore = version, help, update
3344 ignore = version, help, update
3337 </pre>
3345 </pre>
3338 <p>
3346 <p>
3339 To ignore global commands like 'hg version' or 'hg help', you have
3347 To ignore global commands like 'hg version' or 'hg help', you have
3340 to specify them in your user configuration file.
3348 to specify them in your user configuration file.
3341 </p>
3349 </p>
3342 <p>
3350 <p>
3343 To control whether the pager is used at all for an individual command,
3351 To control whether the pager is used at all for an individual command,
3344 you can use --pager=&lt;value&gt;:
3352 you can use --pager=&lt;value&gt;:
3345 </p>
3353 </p>
3346 <ul>
3354 <ul>
3347 <li> use as needed: 'auto'.
3355 <li> use as needed: 'auto'.
3348 <li> require the pager: 'yes' or 'on'.
3356 <li> require the pager: 'yes' or 'on'.
3349 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3357 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3350 </ul>
3358 </ul>
3351 <p>
3359 <p>
3352 To globally turn off all attempts to use a pager, set:
3360 To globally turn off all attempts to use a pager, set:
3353 </p>
3361 </p>
3354 <pre>
3362 <pre>
3355 [ui]
3363 [ui]
3356 paginate = never
3364 paginate = never
3357 </pre>
3365 </pre>
3358 <p>
3366 <p>
3359 which will prevent the pager from running.
3367 which will prevent the pager from running.
3360 </p>
3368 </p>
3361
3369
3362 </div>
3370 </div>
3363 </div>
3371 </div>
3364 </div>
3372 </div>
3365
3373
3366
3374
3367
3375
3368 </body>
3376 </body>
3369 </html>
3377 </html>
3370
3378
3371
3379
3372 Sub-topic indexes rendered properly
3380 Sub-topic indexes rendered properly
3373
3381
3374 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3382 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3375 200 Script output follows
3383 200 Script output follows
3376
3384
3377 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3385 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3378 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3386 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3379 <head>
3387 <head>
3380 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3388 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3381 <meta name="robots" content="index, nofollow" />
3389 <meta name="robots" content="index, nofollow" />
3382 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3390 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3383 <script type="text/javascript" src="/static/mercurial.js"></script>
3391 <script type="text/javascript" src="/static/mercurial.js"></script>
3384
3392
3385 <title>Help: internals</title>
3393 <title>Help: internals</title>
3386 </head>
3394 </head>
3387 <body>
3395 <body>
3388
3396
3389 <div class="container">
3397 <div class="container">
3390 <div class="menu">
3398 <div class="menu">
3391 <div class="logo">
3399 <div class="logo">
3392 <a href="https://mercurial-scm.org/">
3400 <a href="https://mercurial-scm.org/">
3393 <img src="/static/hglogo.png" alt="mercurial" /></a>
3401 <img src="/static/hglogo.png" alt="mercurial" /></a>
3394 </div>
3402 </div>
3395 <ul>
3403 <ul>
3396 <li><a href="/shortlog">log</a></li>
3404 <li><a href="/shortlog">log</a></li>
3397 <li><a href="/graph">graph</a></li>
3405 <li><a href="/graph">graph</a></li>
3398 <li><a href="/tags">tags</a></li>
3406 <li><a href="/tags">tags</a></li>
3399 <li><a href="/bookmarks">bookmarks</a></li>
3407 <li><a href="/bookmarks">bookmarks</a></li>
3400 <li><a href="/branches">branches</a></li>
3408 <li><a href="/branches">branches</a></li>
3401 </ul>
3409 </ul>
3402 <ul>
3410 <ul>
3403 <li><a href="/help">help</a></li>
3411 <li><a href="/help">help</a></li>
3404 </ul>
3412 </ul>
3405 </div>
3413 </div>
3406
3414
3407 <div class="main">
3415 <div class="main">
3408 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3416 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3409
3417
3410 <form class="search" action="/log">
3418 <form class="search" action="/log">
3411
3419
3412 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3420 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3413 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3421 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3414 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3422 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3415 </form>
3423 </form>
3416 <table class="bigtable">
3424 <table class="bigtable">
3417 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3425 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3418
3426
3419 <tr><td>
3427 <tr><td>
3420 <a href="/help/internals.bundle2">
3428 <a href="/help/internals.bundle2">
3421 bundle2
3429 bundle2
3422 </a>
3430 </a>
3423 </td><td>
3431 </td><td>
3424 Bundle2
3432 Bundle2
3425 </td></tr>
3433 </td></tr>
3426 <tr><td>
3434 <tr><td>
3427 <a href="/help/internals.bundles">
3435 <a href="/help/internals.bundles">
3428 bundles
3436 bundles
3429 </a>
3437 </a>
3430 </td><td>
3438 </td><td>
3431 Bundles
3439 Bundles
3432 </td></tr>
3440 </td></tr>
3433 <tr><td>
3441 <tr><td>
3434 <a href="/help/internals.cbor">
3442 <a href="/help/internals.cbor">
3435 cbor
3443 cbor
3436 </a>
3444 </a>
3437 </td><td>
3445 </td><td>
3438 CBOR
3446 CBOR
3439 </td></tr>
3447 </td></tr>
3440 <tr><td>
3448 <tr><td>
3441 <a href="/help/internals.censor">
3449 <a href="/help/internals.censor">
3442 censor
3450 censor
3443 </a>
3451 </a>
3444 </td><td>
3452 </td><td>
3445 Censor
3453 Censor
3446 </td></tr>
3454 </td></tr>
3447 <tr><td>
3455 <tr><td>
3448 <a href="/help/internals.changegroups">
3456 <a href="/help/internals.changegroups">
3449 changegroups
3457 changegroups
3450 </a>
3458 </a>
3451 </td><td>
3459 </td><td>
3452 Changegroups
3460 Changegroups
3453 </td></tr>
3461 </td></tr>
3454 <tr><td>
3462 <tr><td>
3455 <a href="/help/internals.config">
3463 <a href="/help/internals.config">
3456 config
3464 config
3457 </a>
3465 </a>
3458 </td><td>
3466 </td><td>
3459 Config Registrar
3467 Config Registrar
3460 </td></tr>
3468 </td></tr>
3461 <tr><td>
3469 <tr><td>
3462 <a href="/help/internals.extensions">
3470 <a href="/help/internals.extensions">
3463 extensions
3471 extensions
3464 </a>
3472 </a>
3465 </td><td>
3473 </td><td>
3466 Extension API
3474 Extension API
3467 </td></tr>
3475 </td></tr>
3468 <tr><td>
3476 <tr><td>
3469 <a href="/help/internals.mergestate">
3477 <a href="/help/internals.mergestate">
3470 mergestate
3478 mergestate
3471 </a>
3479 </a>
3472 </td><td>
3480 </td><td>
3473 Mergestate
3481 Mergestate
3474 </td></tr>
3482 </td></tr>
3475 <tr><td>
3483 <tr><td>
3476 <a href="/help/internals.requirements">
3484 <a href="/help/internals.requirements">
3477 requirements
3485 requirements
3478 </a>
3486 </a>
3479 </td><td>
3487 </td><td>
3480 Repository Requirements
3488 Repository Requirements
3481 </td></tr>
3489 </td></tr>
3482 <tr><td>
3490 <tr><td>
3483 <a href="/help/internals.revlogs">
3491 <a href="/help/internals.revlogs">
3484 revlogs
3492 revlogs
3485 </a>
3493 </a>
3486 </td><td>
3494 </td><td>
3487 Revision Logs
3495 Revision Logs
3488 </td></tr>
3496 </td></tr>
3489 <tr><td>
3497 <tr><td>
3490 <a href="/help/internals.wireprotocol">
3498 <a href="/help/internals.wireprotocol">
3491 wireprotocol
3499 wireprotocol
3492 </a>
3500 </a>
3493 </td><td>
3501 </td><td>
3494 Wire Protocol
3502 Wire Protocol
3495 </td></tr>
3503 </td></tr>
3496 <tr><td>
3504 <tr><td>
3497 <a href="/help/internals.wireprotocolrpc">
3505 <a href="/help/internals.wireprotocolrpc">
3498 wireprotocolrpc
3506 wireprotocolrpc
3499 </a>
3507 </a>
3500 </td><td>
3508 </td><td>
3501 Wire Protocol RPC
3509 Wire Protocol RPC
3502 </td></tr>
3510 </td></tr>
3503 <tr><td>
3511 <tr><td>
3504 <a href="/help/internals.wireprotocolv2">
3512 <a href="/help/internals.wireprotocolv2">
3505 wireprotocolv2
3513 wireprotocolv2
3506 </a>
3514 </a>
3507 </td><td>
3515 </td><td>
3508 Wire Protocol Version 2
3516 Wire Protocol Version 2
3509 </td></tr>
3517 </td></tr>
3510
3518
3511
3519
3512
3520
3513
3521
3514
3522
3515 </table>
3523 </table>
3516 </div>
3524 </div>
3517 </div>
3525 </div>
3518
3526
3519
3527
3520
3528
3521 </body>
3529 </body>
3522 </html>
3530 </html>
3523
3531
3524
3532
3525 Sub-topic topics rendered properly
3533 Sub-topic topics rendered properly
3526
3534
3527 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3535 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3528 200 Script output follows
3536 200 Script output follows
3529
3537
3530 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3538 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3531 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3539 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3532 <head>
3540 <head>
3533 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3541 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3534 <meta name="robots" content="index, nofollow" />
3542 <meta name="robots" content="index, nofollow" />
3535 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3543 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3536 <script type="text/javascript" src="/static/mercurial.js"></script>
3544 <script type="text/javascript" src="/static/mercurial.js"></script>
3537
3545
3538 <title>Help: internals.changegroups</title>
3546 <title>Help: internals.changegroups</title>
3539 </head>
3547 </head>
3540 <body>
3548 <body>
3541
3549
3542 <div class="container">
3550 <div class="container">
3543 <div class="menu">
3551 <div class="menu">
3544 <div class="logo">
3552 <div class="logo">
3545 <a href="https://mercurial-scm.org/">
3553 <a href="https://mercurial-scm.org/">
3546 <img src="/static/hglogo.png" alt="mercurial" /></a>
3554 <img src="/static/hglogo.png" alt="mercurial" /></a>
3547 </div>
3555 </div>
3548 <ul>
3556 <ul>
3549 <li><a href="/shortlog">log</a></li>
3557 <li><a href="/shortlog">log</a></li>
3550 <li><a href="/graph">graph</a></li>
3558 <li><a href="/graph">graph</a></li>
3551 <li><a href="/tags">tags</a></li>
3559 <li><a href="/tags">tags</a></li>
3552 <li><a href="/bookmarks">bookmarks</a></li>
3560 <li><a href="/bookmarks">bookmarks</a></li>
3553 <li><a href="/branches">branches</a></li>
3561 <li><a href="/branches">branches</a></li>
3554 </ul>
3562 </ul>
3555 <ul>
3563 <ul>
3556 <li class="active"><a href="/help">help</a></li>
3564 <li class="active"><a href="/help">help</a></li>
3557 </ul>
3565 </ul>
3558 </div>
3566 </div>
3559
3567
3560 <div class="main">
3568 <div class="main">
3561 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3569 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3562 <h3>Help: internals.changegroups</h3>
3570 <h3>Help: internals.changegroups</h3>
3563
3571
3564 <form class="search" action="/log">
3572 <form class="search" action="/log">
3565
3573
3566 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3574 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3567 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3575 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3568 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3576 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3569 </form>
3577 </form>
3570 <div id="doc">
3578 <div id="doc">
3571 <h1>Changegroups</h1>
3579 <h1>Changegroups</h1>
3572 <p>
3580 <p>
3573 Changegroups are representations of repository revlog data, specifically
3581 Changegroups are representations of repository revlog data, specifically
3574 the changelog data, root/flat manifest data, treemanifest data, and
3582 the changelog data, root/flat manifest data, treemanifest data, and
3575 filelogs.
3583 filelogs.
3576 </p>
3584 </p>
3577 <p>
3585 <p>
3578 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3586 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3579 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3587 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3580 only difference being an additional item in the *delta header*. Version
3588 only difference being an additional item in the *delta header*. Version
3581 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3589 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3582 exchanging treemanifests (enabled by setting an option on the
3590 exchanging treemanifests (enabled by setting an option on the
3583 &quot;changegroup&quot; part in the bundle2).
3591 &quot;changegroup&quot; part in the bundle2).
3584 </p>
3592 </p>
3585 <p>
3593 <p>
3586 Changegroups when not exchanging treemanifests consist of 3 logical
3594 Changegroups when not exchanging treemanifests consist of 3 logical
3587 segments:
3595 segments:
3588 </p>
3596 </p>
3589 <pre>
3597 <pre>
3590 +---------------------------------+
3598 +---------------------------------+
3591 | | | |
3599 | | | |
3592 | changeset | manifest | filelogs |
3600 | changeset | manifest | filelogs |
3593 | | | |
3601 | | | |
3594 | | | |
3602 | | | |
3595 +---------------------------------+
3603 +---------------------------------+
3596 </pre>
3604 </pre>
3597 <p>
3605 <p>
3598 When exchanging treemanifests, there are 4 logical segments:
3606 When exchanging treemanifests, there are 4 logical segments:
3599 </p>
3607 </p>
3600 <pre>
3608 <pre>
3601 +-------------------------------------------------+
3609 +-------------------------------------------------+
3602 | | | | |
3610 | | | | |
3603 | changeset | root | treemanifests | filelogs |
3611 | changeset | root | treemanifests | filelogs |
3604 | | manifest | | |
3612 | | manifest | | |
3605 | | | | |
3613 | | | | |
3606 +-------------------------------------------------+
3614 +-------------------------------------------------+
3607 </pre>
3615 </pre>
3608 <p>
3616 <p>
3609 The principle building block of each segment is a *chunk*. A *chunk*
3617 The principle building block of each segment is a *chunk*. A *chunk*
3610 is a framed piece of data:
3618 is a framed piece of data:
3611 </p>
3619 </p>
3612 <pre>
3620 <pre>
3613 +---------------------------------------+
3621 +---------------------------------------+
3614 | | |
3622 | | |
3615 | length | data |
3623 | length | data |
3616 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3624 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3617 | | |
3625 | | |
3618 +---------------------------------------+
3626 +---------------------------------------+
3619 </pre>
3627 </pre>
3620 <p>
3628 <p>
3621 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3629 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3622 integer indicating the length of the entire chunk (including the length field
3630 integer indicating the length of the entire chunk (including the length field
3623 itself).
3631 itself).
3624 </p>
3632 </p>
3625 <p>
3633 <p>
3626 There is a special case chunk that has a value of 0 for the length
3634 There is a special case chunk that has a value of 0 for the length
3627 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3635 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3628 </p>
3636 </p>
3629 <h2>Delta Groups</h2>
3637 <h2>Delta Groups</h2>
3630 <p>
3638 <p>
3631 A *delta group* expresses the content of a revlog as a series of deltas,
3639 A *delta group* expresses the content of a revlog as a series of deltas,
3632 or patches against previous revisions.
3640 or patches against previous revisions.
3633 </p>
3641 </p>
3634 <p>
3642 <p>
3635 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3643 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3636 to signal the end of the delta group:
3644 to signal the end of the delta group:
3637 </p>
3645 </p>
3638 <pre>
3646 <pre>
3639 +------------------------------------------------------------------------+
3647 +------------------------------------------------------------------------+
3640 | | | | | |
3648 | | | | | |
3641 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3649 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3642 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3650 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3643 | | | | | |
3651 | | | | | |
3644 +------------------------------------------------------------------------+
3652 +------------------------------------------------------------------------+
3645 </pre>
3653 </pre>
3646 <p>
3654 <p>
3647 Each *chunk*'s data consists of the following:
3655 Each *chunk*'s data consists of the following:
3648 </p>
3656 </p>
3649 <pre>
3657 <pre>
3650 +---------------------------------------+
3658 +---------------------------------------+
3651 | | |
3659 | | |
3652 | delta header | delta data |
3660 | delta header | delta data |
3653 | (various by version) | (various) |
3661 | (various by version) | (various) |
3654 | | |
3662 | | |
3655 +---------------------------------------+
3663 +---------------------------------------+
3656 </pre>
3664 </pre>
3657 <p>
3665 <p>
3658 The *delta data* is a series of *delta*s that describe a diff from an existing
3666 The *delta data* is a series of *delta*s that describe a diff from an existing
3659 entry (either that the recipient already has, or previously specified in the
3667 entry (either that the recipient already has, or previously specified in the
3660 bundle/changegroup).
3668 bundle/changegroup).
3661 </p>
3669 </p>
3662 <p>
3670 <p>
3663 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3671 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3664 &quot;3&quot; of the changegroup format.
3672 &quot;3&quot; of the changegroup format.
3665 </p>
3673 </p>
3666 <p>
3674 <p>
3667 Version 1 (headerlen=80):
3675 Version 1 (headerlen=80):
3668 </p>
3676 </p>
3669 <pre>
3677 <pre>
3670 +------------------------------------------------------+
3678 +------------------------------------------------------+
3671 | | | | |
3679 | | | | |
3672 | node | p1 node | p2 node | link node |
3680 | node | p1 node | p2 node | link node |
3673 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3681 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3674 | | | | |
3682 | | | | |
3675 +------------------------------------------------------+
3683 +------------------------------------------------------+
3676 </pre>
3684 </pre>
3677 <p>
3685 <p>
3678 Version 2 (headerlen=100):
3686 Version 2 (headerlen=100):
3679 </p>
3687 </p>
3680 <pre>
3688 <pre>
3681 +------------------------------------------------------------------+
3689 +------------------------------------------------------------------+
3682 | | | | | |
3690 | | | | | |
3683 | node | p1 node | p2 node | base node | link node |
3691 | node | p1 node | p2 node | base node | link node |
3684 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3692 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3685 | | | | | |
3693 | | | | | |
3686 +------------------------------------------------------------------+
3694 +------------------------------------------------------------------+
3687 </pre>
3695 </pre>
3688 <p>
3696 <p>
3689 Version 3 (headerlen=102):
3697 Version 3 (headerlen=102):
3690 </p>
3698 </p>
3691 <pre>
3699 <pre>
3692 +------------------------------------------------------------------------------+
3700 +------------------------------------------------------------------------------+
3693 | | | | | | |
3701 | | | | | | |
3694 | node | p1 node | p2 node | base node | link node | flags |
3702 | node | p1 node | p2 node | base node | link node | flags |
3695 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3703 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3696 | | | | | | |
3704 | | | | | | |
3697 +------------------------------------------------------------------------------+
3705 +------------------------------------------------------------------------------+
3698 </pre>
3706 </pre>
3699 <p>
3707 <p>
3700 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3708 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3701 series of *delta*s, densely packed (no separators). These deltas describe a diff
3709 series of *delta*s, densely packed (no separators). These deltas describe a diff
3702 from an existing entry (either that the recipient already has, or previously
3710 from an existing entry (either that the recipient already has, or previously
3703 specified in the bundle/changegroup). The format is described more fully in
3711 specified in the bundle/changegroup). The format is described more fully in
3704 &quot;hg help internals.bdiff&quot;, but briefly:
3712 &quot;hg help internals.bdiff&quot;, but briefly:
3705 </p>
3713 </p>
3706 <pre>
3714 <pre>
3707 +---------------------------------------------------------------+
3715 +---------------------------------------------------------------+
3708 | | | | |
3716 | | | | |
3709 | start offset | end offset | new length | content |
3717 | start offset | end offset | new length | content |
3710 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3718 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3711 | | | | |
3719 | | | | |
3712 +---------------------------------------------------------------+
3720 +---------------------------------------------------------------+
3713 </pre>
3721 </pre>
3714 <p>
3722 <p>
3715 Please note that the length field in the delta data does *not* include itself.
3723 Please note that the length field in the delta data does *not* include itself.
3716 </p>
3724 </p>
3717 <p>
3725 <p>
3718 In version 1, the delta is always applied against the previous node from
3726 In version 1, the delta is always applied against the previous node from
3719 the changegroup or the first parent if this is the first entry in the
3727 the changegroup or the first parent if this is the first entry in the
3720 changegroup.
3728 changegroup.
3721 </p>
3729 </p>
3722 <p>
3730 <p>
3723 In version 2 and up, the delta base node is encoded in the entry in the
3731 In version 2 and up, the delta base node is encoded in the entry in the
3724 changegroup. This allows the delta to be expressed against any parent,
3732 changegroup. This allows the delta to be expressed against any parent,
3725 which can result in smaller deltas and more efficient encoding of data.
3733 which can result in smaller deltas and more efficient encoding of data.
3726 </p>
3734 </p>
3727 <p>
3735 <p>
3728 The *flags* field holds bitwise flags affecting the processing of revision
3736 The *flags* field holds bitwise flags affecting the processing of revision
3729 data. The following flags are defined:
3737 data. The following flags are defined:
3730 </p>
3738 </p>
3731 <dl>
3739 <dl>
3732 <dt>32768
3740 <dt>32768
3733 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3741 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3734 <dt>16384
3742 <dt>16384
3735 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3743 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3736 <dt>8192
3744 <dt>8192
3737 <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.
3745 <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.
3738 </dl>
3746 </dl>
3739 <p>
3747 <p>
3740 For historical reasons, the integer values are identical to revlog version 1
3748 For historical reasons, the integer values are identical to revlog version 1
3741 per-revision storage flags and correspond to bits being set in this 2-byte
3749 per-revision storage flags and correspond to bits being set in this 2-byte
3742 field. Bits were allocated starting from the most-significant bit, hence the
3750 field. Bits were allocated starting from the most-significant bit, hence the
3743 reverse ordering and allocation of these flags.
3751 reverse ordering and allocation of these flags.
3744 </p>
3752 </p>
3745 <h2>Changeset Segment</h2>
3753 <h2>Changeset Segment</h2>
3746 <p>
3754 <p>
3747 The *changeset segment* consists of a single *delta group* holding
3755 The *changeset segment* consists of a single *delta group* holding
3748 changelog data. The *empty chunk* at the end of the *delta group* denotes
3756 changelog data. The *empty chunk* at the end of the *delta group* denotes
3749 the boundary to the *manifest segment*.
3757 the boundary to the *manifest segment*.
3750 </p>
3758 </p>
3751 <h2>Manifest Segment</h2>
3759 <h2>Manifest Segment</h2>
3752 <p>
3760 <p>
3753 The *manifest segment* consists of a single *delta group* holding manifest
3761 The *manifest segment* consists of a single *delta group* holding manifest
3754 data. If treemanifests are in use, it contains only the manifest for the
3762 data. If treemanifests are in use, it contains only the manifest for the
3755 root directory of the repository. Otherwise, it contains the entire
3763 root directory of the repository. Otherwise, it contains the entire
3756 manifest data. The *empty chunk* at the end of the *delta group* denotes
3764 manifest data. The *empty chunk* at the end of the *delta group* denotes
3757 the boundary to the next segment (either the *treemanifests segment* or the
3765 the boundary to the next segment (either the *treemanifests segment* or the
3758 *filelogs segment*, depending on version and the request options).
3766 *filelogs segment*, depending on version and the request options).
3759 </p>
3767 </p>
3760 <h3>Treemanifests Segment</h3>
3768 <h3>Treemanifests Segment</h3>
3761 <p>
3769 <p>
3762 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3770 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3763 only if the 'treemanifest' param is part of the bundle2 changegroup part
3771 only if the 'treemanifest' param is part of the bundle2 changegroup part
3764 (it is not possible to use changegroup version 3 outside of bundle2).
3772 (it is not possible to use changegroup version 3 outside of bundle2).
3765 Aside from the filenames in the *treemanifests segment* containing a
3773 Aside from the filenames in the *treemanifests segment* containing a
3766 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3774 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3767 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3775 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3768 a sub-segment with filename size 0). This denotes the boundary to the
3776 a sub-segment with filename size 0). This denotes the boundary to the
3769 *filelogs segment*.
3777 *filelogs segment*.
3770 </p>
3778 </p>
3771 <h2>Filelogs Segment</h2>
3779 <h2>Filelogs Segment</h2>
3772 <p>
3780 <p>
3773 The *filelogs segment* consists of multiple sub-segments, each
3781 The *filelogs segment* consists of multiple sub-segments, each
3774 corresponding to an individual file whose data is being described:
3782 corresponding to an individual file whose data is being described:
3775 </p>
3783 </p>
3776 <pre>
3784 <pre>
3777 +--------------------------------------------------+
3785 +--------------------------------------------------+
3778 | | | | | |
3786 | | | | | |
3779 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3787 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3780 | | | | | (4 bytes) |
3788 | | | | | (4 bytes) |
3781 | | | | | |
3789 | | | | | |
3782 +--------------------------------------------------+
3790 +--------------------------------------------------+
3783 </pre>
3791 </pre>
3784 <p>
3792 <p>
3785 The final filelog sub-segment is followed by an *empty chunk* (logically,
3793 The final filelog sub-segment is followed by an *empty chunk* (logically,
3786 a sub-segment with filename size 0). This denotes the end of the segment
3794 a sub-segment with filename size 0). This denotes the end of the segment
3787 and of the overall changegroup.
3795 and of the overall changegroup.
3788 </p>
3796 </p>
3789 <p>
3797 <p>
3790 Each filelog sub-segment consists of the following:
3798 Each filelog sub-segment consists of the following:
3791 </p>
3799 </p>
3792 <pre>
3800 <pre>
3793 +------------------------------------------------------+
3801 +------------------------------------------------------+
3794 | | | |
3802 | | | |
3795 | filename length | filename | delta group |
3803 | filename length | filename | delta group |
3796 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3804 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3797 | | | |
3805 | | | |
3798 +------------------------------------------------------+
3806 +------------------------------------------------------+
3799 </pre>
3807 </pre>
3800 <p>
3808 <p>
3801 That is, a *chunk* consisting of the filename (not terminated or padded)
3809 That is, a *chunk* consisting of the filename (not terminated or padded)
3802 followed by N chunks constituting the *delta group* for this file. The
3810 followed by N chunks constituting the *delta group* for this file. The
3803 *empty chunk* at the end of each *delta group* denotes the boundary to the
3811 *empty chunk* at the end of each *delta group* denotes the boundary to the
3804 next filelog sub-segment.
3812 next filelog sub-segment.
3805 </p>
3813 </p>
3806
3814
3807 </div>
3815 </div>
3808 </div>
3816 </div>
3809 </div>
3817 </div>
3810
3818
3811
3819
3812
3820
3813 </body>
3821 </body>
3814 </html>
3822 </html>
3815
3823
3816
3824
3817 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3825 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3818 404 Not Found
3826 404 Not Found
3819
3827
3820 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3828 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3821 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3829 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3822 <head>
3830 <head>
3823 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3831 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3824 <meta name="robots" content="index, nofollow" />
3832 <meta name="robots" content="index, nofollow" />
3825 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3833 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3826 <script type="text/javascript" src="/static/mercurial.js"></script>
3834 <script type="text/javascript" src="/static/mercurial.js"></script>
3827
3835
3828 <title>test: error</title>
3836 <title>test: error</title>
3829 </head>
3837 </head>
3830 <body>
3838 <body>
3831
3839
3832 <div class="container">
3840 <div class="container">
3833 <div class="menu">
3841 <div class="menu">
3834 <div class="logo">
3842 <div class="logo">
3835 <a href="https://mercurial-scm.org/">
3843 <a href="https://mercurial-scm.org/">
3836 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3844 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3837 </div>
3845 </div>
3838 <ul>
3846 <ul>
3839 <li><a href="/shortlog">log</a></li>
3847 <li><a href="/shortlog">log</a></li>
3840 <li><a href="/graph">graph</a></li>
3848 <li><a href="/graph">graph</a></li>
3841 <li><a href="/tags">tags</a></li>
3849 <li><a href="/tags">tags</a></li>
3842 <li><a href="/bookmarks">bookmarks</a></li>
3850 <li><a href="/bookmarks">bookmarks</a></li>
3843 <li><a href="/branches">branches</a></li>
3851 <li><a href="/branches">branches</a></li>
3844 </ul>
3852 </ul>
3845 <ul>
3853 <ul>
3846 <li><a href="/help">help</a></li>
3854 <li><a href="/help">help</a></li>
3847 </ul>
3855 </ul>
3848 </div>
3856 </div>
3849
3857
3850 <div class="main">
3858 <div class="main">
3851
3859
3852 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3860 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3853 <h3>error</h3>
3861 <h3>error</h3>
3854
3862
3855
3863
3856 <form class="search" action="/log">
3864 <form class="search" action="/log">
3857
3865
3858 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3866 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3859 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3867 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3860 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3868 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3861 </form>
3869 </form>
3862
3870
3863 <div class="description">
3871 <div class="description">
3864 <p>
3872 <p>
3865 An error occurred while processing your request:
3873 An error occurred while processing your request:
3866 </p>
3874 </p>
3867 <p>
3875 <p>
3868 Not Found
3876 Not Found
3869 </p>
3877 </p>
3870 </div>
3878 </div>
3871 </div>
3879 </div>
3872 </div>
3880 </div>
3873
3881
3874
3882
3875
3883
3876 </body>
3884 </body>
3877 </html>
3885 </html>
3878
3886
3879 [1]
3887 [1]
3880
3888
3881 $ killdaemons.py
3889 $ killdaemons.py
3882
3890
3883 #endif
3891 #endif
@@ -1,2232 +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)",
1899 "topic": "continue"
1900 },
1901 {
1898 "summary": "diff repository (or selected files)",
1902 "summary": "diff repository (or selected files)",
1899 "topic": "diff"
1903 "topic": "diff"
1900 },
1904 },
1901 {
1905 {
1902 "summary": "dump the header and diffs for one or more changesets",
1906 "summary": "dump the header and diffs for one or more changesets",
1903 "topic": "export"
1907 "topic": "export"
1904 },
1908 },
1905 {
1909 {
1906 "summary": "forget the specified files on the next commit",
1910 "summary": "forget the specified files on the next commit",
1907 "topic": "forget"
1911 "topic": "forget"
1908 },
1912 },
1909 {
1913 {
1910 "summary": "create a new repository in the given directory",
1914 "summary": "create a new repository in the given directory",
1911 "topic": "init"
1915 "topic": "init"
1912 },
1916 },
1913 {
1917 {
1914 "summary": "show revision history of entire repository or files",
1918 "summary": "show revision history of entire repository or files",
1915 "topic": "log"
1919 "topic": "log"
1916 },
1920 },
1917 {
1921 {
1918 "summary": "merge another revision into working directory",
1922 "summary": "merge another revision into working directory",
1919 "topic": "merge"
1923 "topic": "merge"
1920 },
1924 },
1921 {
1925 {
1922 "summary": "pull changes from the specified source",
1926 "summary": "pull changes from the specified source",
1923 "topic": "pull"
1927 "topic": "pull"
1924 },
1928 },
1925 {
1929 {
1926 "summary": "push changes to the specified destination",
1930 "summary": "push changes to the specified destination",
1927 "topic": "push"
1931 "topic": "push"
1928 },
1932 },
1929 {
1933 {
1930 "summary": "remove the specified files on the next commit",
1934 "summary": "remove the specified files on the next commit",
1931 "topic": "remove"
1935 "topic": "remove"
1932 },
1936 },
1933 {
1937 {
1934 "summary": "start stand-alone webserver",
1938 "summary": "start stand-alone webserver",
1935 "topic": "serve"
1939 "topic": "serve"
1936 },
1940 },
1937 {
1941 {
1938 "summary": "show changed files in the working directory",
1942 "summary": "show changed files in the working directory",
1939 "topic": "status"
1943 "topic": "status"
1940 },
1944 },
1941 {
1945 {
1942 "summary": "summarize working directory state",
1946 "summary": "summarize working directory state",
1943 "topic": "summary"
1947 "topic": "summary"
1944 },
1948 },
1945 {
1949 {
1946 "summary": "update working directory (or switch revisions)",
1950 "summary": "update working directory (or switch revisions)",
1947 "topic": "update"
1951 "topic": "update"
1948 }
1952 }
1949 ],
1953 ],
1950 "othercommands": [
1954 "othercommands": [
1951 {
1955 {
1952 "summary": "add all new files, delete all missing files",
1956 "summary": "add all new files, delete all missing files",
1953 "topic": "addremove"
1957 "topic": "addremove"
1954 },
1958 },
1955 {
1959 {
1956 "summary": "create an unversioned archive of a repository revision",
1960 "summary": "create an unversioned archive of a repository revision",
1957 "topic": "archive"
1961 "topic": "archive"
1958 },
1962 },
1959 {
1963 {
1960 "summary": "reverse effect of earlier changeset",
1964 "summary": "reverse effect of earlier changeset",
1961 "topic": "backout"
1965 "topic": "backout"
1962 },
1966 },
1963 {
1967 {
1964 "summary": "subdivision search of changesets",
1968 "summary": "subdivision search of changesets",
1965 "topic": "bisect"
1969 "topic": "bisect"
1966 },
1970 },
1967 {
1971 {
1968 "summary": "create a new bookmark or list existing bookmarks",
1972 "summary": "create a new bookmark or list existing bookmarks",
1969 "topic": "bookmarks"
1973 "topic": "bookmarks"
1970 },
1974 },
1971 {
1975 {
1972 "summary": "set or show the current branch name",
1976 "summary": "set or show the current branch name",
1973 "topic": "branch"
1977 "topic": "branch"
1974 },
1978 },
1975 {
1979 {
1976 "summary": "list repository named branches",
1980 "summary": "list repository named branches",
1977 "topic": "branches"
1981 "topic": "branches"
1978 },
1982 },
1979 {
1983 {
1980 "summary": "create a bundle file",
1984 "summary": "create a bundle file",
1981 "topic": "bundle"
1985 "topic": "bundle"
1982 },
1986 },
1983 {
1987 {
1984 "summary": "output the current or given revision of files",
1988 "summary": "output the current or given revision of files",
1985 "topic": "cat"
1989 "topic": "cat"
1986 },
1990 },
1987 {
1991 {
1988 "summary": "show combined config settings from all hgrc files",
1992 "summary": "show combined config settings from all hgrc files",
1989 "topic": "config"
1993 "topic": "config"
1990 },
1994 },
1991 {
1995 {
1992 "summary": "mark files as copied for the next commit",
1996 "summary": "mark files as copied for the next commit",
1993 "topic": "copy"
1997 "topic": "copy"
1994 },
1998 },
1995 {
1999 {
1996 "summary": "list tracked files",
2000 "summary": "list tracked files",
1997 "topic": "files"
2001 "topic": "files"
1998 },
2002 },
1999 {
2003 {
2000 "summary": "copy changes from other branches onto the current branch",
2004 "summary": "copy changes from other branches onto the current branch",
2001 "topic": "graft"
2005 "topic": "graft"
2002 },
2006 },
2003 {
2007 {
2004 "summary": "search revision history for a pattern in specified files",
2008 "summary": "search revision history for a pattern in specified files",
2005 "topic": "grep"
2009 "topic": "grep"
2006 },
2010 },
2007 {
2011 {
2008 "summary": "show branch heads",
2012 "summary": "show branch heads",
2009 "topic": "heads"
2013 "topic": "heads"
2010 },
2014 },
2011 {
2015 {
2012 "summary": "show help for a given topic or a help overview",
2016 "summary": "show help for a given topic or a help overview",
2013 "topic": "help"
2017 "topic": "help"
2014 },
2018 },
2015 {
2019 {
2016 "summary": "identify the working directory or specified revision",
2020 "summary": "identify the working directory or specified revision",
2017 "topic": "identify"
2021 "topic": "identify"
2018 },
2022 },
2019 {
2023 {
2020 "summary": "import an ordered set of patches",
2024 "summary": "import an ordered set of patches",
2021 "topic": "import"
2025 "topic": "import"
2022 },
2026 },
2023 {
2027 {
2024 "summary": "show new changesets found in source",
2028 "summary": "show new changesets found in source",
2025 "topic": "incoming"
2029 "topic": "incoming"
2026 },
2030 },
2027 {
2031 {
2028 "summary": "output the current or given revision of the project manifest",
2032 "summary": "output the current or given revision of the project manifest",
2029 "topic": "manifest"
2033 "topic": "manifest"
2030 },
2034 },
2031 {
2035 {
2032 "summary": "show changesets not found in the destination",
2036 "summary": "show changesets not found in the destination",
2033 "topic": "outgoing"
2037 "topic": "outgoing"
2034 },
2038 },
2035 {
2039 {
2036 "summary": "show aliases for remote repositories",
2040 "summary": "show aliases for remote repositories",
2037 "topic": "paths"
2041 "topic": "paths"
2038 },
2042 },
2039 {
2043 {
2040 "summary": "set or show the current phase name",
2044 "summary": "set or show the current phase name",
2041 "topic": "phase"
2045 "topic": "phase"
2042 },
2046 },
2043 {
2047 {
2044 "summary": "roll back an interrupted transaction",
2048 "summary": "roll back an interrupted transaction",
2045 "topic": "recover"
2049 "topic": "recover"
2046 },
2050 },
2047 {
2051 {
2048 "summary": "rename files; equivalent of copy + remove",
2052 "summary": "rename files; equivalent of copy + remove",
2049 "topic": "rename"
2053 "topic": "rename"
2050 },
2054 },
2051 {
2055 {
2052 "summary": "redo merges or set/view the merge status of files",
2056 "summary": "redo merges or set/view the merge status of files",
2053 "topic": "resolve"
2057 "topic": "resolve"
2054 },
2058 },
2055 {
2059 {
2056 "summary": "restore files to their checkout state",
2060 "summary": "restore files to their checkout state",
2057 "topic": "revert"
2061 "topic": "revert"
2058 },
2062 },
2059 {
2063 {
2060 "summary": "print the root (top) of the current working directory",
2064 "summary": "print the root (top) of the current working directory",
2061 "topic": "root"
2065 "topic": "root"
2062 },
2066 },
2063 {
2067 {
2064 "summary": "save and set aside changes from the working directory",
2068 "summary": "save and set aside changes from the working directory",
2065 "topic": "shelve"
2069 "topic": "shelve"
2066 },
2070 },
2067 {
2071 {
2068 "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",
2069 "topic": "tag"
2073 "topic": "tag"
2070 },
2074 },
2071 {
2075 {
2072 "summary": "list repository tags",
2076 "summary": "list repository tags",
2073 "topic": "tags"
2077 "topic": "tags"
2074 },
2078 },
2075 {
2079 {
2076 "summary": "apply one or more bundle files",
2080 "summary": "apply one or more bundle files",
2077 "topic": "unbundle"
2081 "topic": "unbundle"
2078 },
2082 },
2079 {
2083 {
2080 "summary": "restore a shelved change to the working directory",
2084 "summary": "restore a shelved change to the working directory",
2081 "topic": "unshelve"
2085 "topic": "unshelve"
2082 },
2086 },
2083 {
2087 {
2084 "summary": "verify the integrity of the repository",
2088 "summary": "verify the integrity of the repository",
2085 "topic": "verify"
2089 "topic": "verify"
2086 },
2090 },
2087 {
2091 {
2088 "summary": "output version and copyright information",
2092 "summary": "output version and copyright information",
2089 "topic": "version"
2093 "topic": "version"
2090 }
2094 }
2091 ],
2095 ],
2092 "topics": [
2096 "topics": [
2093 {
2097 {
2094 "summary": "Bundle File Formats",
2098 "summary": "Bundle File Formats",
2095 "topic": "bundlespec"
2099 "topic": "bundlespec"
2096 },
2100 },
2097 {
2101 {
2098 "summary": "Colorizing Outputs",
2102 "summary": "Colorizing Outputs",
2099 "topic": "color"
2103 "topic": "color"
2100 },
2104 },
2101 {
2105 {
2102 "summary": "Configuration Files",
2106 "summary": "Configuration Files",
2103 "topic": "config"
2107 "topic": "config"
2104 },
2108 },
2105 {
2109 {
2106 "summary": "Date Formats",
2110 "summary": "Date Formats",
2107 "topic": "dates"
2111 "topic": "dates"
2108 },
2112 },
2109 {
2113 {
2110 "summary": "Deprecated Features",
2114 "summary": "Deprecated Features",
2111 "topic": "deprecated"
2115 "topic": "deprecated"
2112 },
2116 },
2113 {
2117 {
2114 "summary": "Diff Formats",
2118 "summary": "Diff Formats",
2115 "topic": "diffs"
2119 "topic": "diffs"
2116 },
2120 },
2117 {
2121 {
2118 "summary": "Environment Variables",
2122 "summary": "Environment Variables",
2119 "topic": "environment"
2123 "topic": "environment"
2120 },
2124 },
2121 {
2125 {
2122 "summary": "Using Additional Features",
2126 "summary": "Using Additional Features",
2123 "topic": "extensions"
2127 "topic": "extensions"
2124 },
2128 },
2125 {
2129 {
2126 "summary": "Specifying File Sets",
2130 "summary": "Specifying File Sets",
2127 "topic": "filesets"
2131 "topic": "filesets"
2128 },
2132 },
2129 {
2133 {
2130 "summary": "Command-line flags",
2134 "summary": "Command-line flags",
2131 "topic": "flags"
2135 "topic": "flags"
2132 },
2136 },
2133 {
2137 {
2134 "summary": "Glossary",
2138 "summary": "Glossary",
2135 "topic": "glossary"
2139 "topic": "glossary"
2136 },
2140 },
2137 {
2141 {
2138 "summary": "Syntax for Mercurial Ignore Files",
2142 "summary": "Syntax for Mercurial Ignore Files",
2139 "topic": "hgignore"
2143 "topic": "hgignore"
2140 },
2144 },
2141 {
2145 {
2142 "summary": "Configuring hgweb",
2146 "summary": "Configuring hgweb",
2143 "topic": "hgweb"
2147 "topic": "hgweb"
2144 },
2148 },
2145 {
2149 {
2146 "summary": "Technical implementation topics",
2150 "summary": "Technical implementation topics",
2147 "topic": "internals"
2151 "topic": "internals"
2148 },
2152 },
2149 {
2153 {
2150 "summary": "Merge Tools",
2154 "summary": "Merge Tools",
2151 "topic": "merge-tools"
2155 "topic": "merge-tools"
2152 },
2156 },
2153 {
2157 {
2154 "summary": "Pager Support",
2158 "summary": "Pager Support",
2155 "topic": "pager"
2159 "topic": "pager"
2156 },
2160 },
2157 {
2161 {
2158 "summary": "File Name Patterns",
2162 "summary": "File Name Patterns",
2159 "topic": "patterns"
2163 "topic": "patterns"
2160 },
2164 },
2161 {
2165 {
2162 "summary": "Working with Phases",
2166 "summary": "Working with Phases",
2163 "topic": "phases"
2167 "topic": "phases"
2164 },
2168 },
2165 {
2169 {
2166 "summary": "Specifying Revisions",
2170 "summary": "Specifying Revisions",
2167 "topic": "revisions"
2171 "topic": "revisions"
2168 },
2172 },
2169 {
2173 {
2170 "summary": "Using Mercurial from scripts and automation",
2174 "summary": "Using Mercurial from scripts and automation",
2171 "topic": "scripting"
2175 "topic": "scripting"
2172 },
2176 },
2173 {
2177 {
2174 "summary": "Subrepositories",
2178 "summary": "Subrepositories",
2175 "topic": "subrepos"
2179 "topic": "subrepos"
2176 },
2180 },
2177 {
2181 {
2178 "summary": "Template Usage",
2182 "summary": "Template Usage",
2179 "topic": "templating"
2183 "topic": "templating"
2180 },
2184 },
2181 {
2185 {
2182 "summary": "URL Paths",
2186 "summary": "URL Paths",
2183 "topic": "urls"
2187 "topic": "urls"
2184 }
2188 }
2185 ]
2189 ]
2186 }
2190 }
2187
2191
2188 help/{topic} shows an individual help topic
2192 help/{topic} shows an individual help topic
2189
2193
2190 $ request json-help/phases
2194 $ request json-help/phases
2191 200 Script output follows
2195 200 Script output follows
2192
2196
2193 {
2197 {
2194 "rawdoc": "Working with Phases\n*", (glob)
2198 "rawdoc": "Working with Phases\n*", (glob)
2195 "topic": "phases"
2199 "topic": "phases"
2196 }
2200 }
2197
2201
2198 Error page shouldn't crash
2202 Error page shouldn't crash
2199
2203
2200 $ request json-changeset/deadbeef
2204 $ request json-changeset/deadbeef
2201 404 Not Found
2205 404 Not Found
2202
2206
2203 {
2207 {
2204 "error": "unknown revision 'deadbeef'"
2208 "error": "unknown revision 'deadbeef'"
2205 }
2209 }
2206 [1]
2210 [1]
2207
2211
2208 Commit message with Japanese Kanji 'Noh', which ends with '\x5c'
2212 Commit message with Japanese Kanji 'Noh', which ends with '\x5c'
2209
2213
2210 $ echo foo >> da/foo
2214 $ echo foo >> da/foo
2211 >>> open('msg', 'wb').write(b'\x94\x5c\x0a') and None
2215 >>> open('msg', 'wb').write(b'\x94\x5c\x0a') and None
2212 $ HGENCODING=cp932 hg ci -l msg
2216 $ HGENCODING=cp932 hg ci -l msg
2213
2217
2214 Commit message with null character
2218 Commit message with null character
2215
2219
2216 $ echo foo >> da/foo
2220 $ echo foo >> da/foo
2217 >>> 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
2218 $ hg ci -l msg
2222 $ hg ci -l msg
2219 $ rm msg
2223 $ rm msg
2220
2224
2221 Stop and restart with HGENCODING=cp932
2225 Stop and restart with HGENCODING=cp932
2222
2226
2223 $ killdaemons.py
2227 $ killdaemons.py
2224 $ HGENCODING=cp932 hg serve -p $HGPORT -d --pid-file=hg.pid \
2228 $ HGENCODING=cp932 hg serve -p $HGPORT -d --pid-file=hg.pid \
2225 > -A access.log -E error.log
2229 > -A access.log -E error.log
2226 $ cat hg.pid >> $DAEMON_PIDS
2230 $ cat hg.pid >> $DAEMON_PIDS
2227
2231
2228 Test json escape of multibyte characters
2232 Test json escape of multibyte characters
2229
2233
2230 $ request json-filelog/tip/da/foo?revcount=2 | grep '"desc":'
2234 $ request json-filelog/tip/da/foo?revcount=2 | grep '"desc":'
2231 "desc": "commit with null character: \u0000",
2235 "desc": "commit with null character: \u0000",
2232 "desc": "\u80fd",
2236 "desc": "\u80fd",
General Comments 0
You need to be logged in to leave comments. Login now