##// END OF EJS Templates
abort: added logic for of hg abort...
Taapas Agrawal -
r42784:bb135a78 default
parent child Browse files
Show More
@@ -1,6370 +1,6395 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',
135 dryrunopts, helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
136 helpbasic=True)
137 def abort(ui, repo, **opts):
138 """abort an unfinished operation (EXPERIMENTAL)
139
140 Aborts a multistep operation like graft, histedit, rebase, merge,
141 and unshelve if they are in an unfinished state.
142
143 use --dry-run/-n to dry run the command.
144 A new operation can be added to this by registering the operation and
145 abort logic in the unfinishedstates list under statemod.
146 """
147 dryrun = opts.get(r'dry_run')
148 abortstate = cmdutil.getunfinishedstate(repo)
149 if not abortstate:
150 raise error.Abort(_('no operation in progress'))
151 if not abortstate.abortfunc:
152 raise error.Abort((_("%s in progress but does not support 'hg abort'") %
153 (abortstate._opname)), hint=abortstate.hint())
154 if dryrun:
155 ui.status(_('%s in progress, will be aborted\n') % (abortstate._opname))
156 return
157 return abortstate.abortfunc(ui, repo)
158
134 @command('add',
159 @command('add',
135 walkopts + subrepoopts + dryrunopts,
160 walkopts + subrepoopts + dryrunopts,
136 _('[OPTION]... [FILE]...'),
161 _('[OPTION]... [FILE]...'),
137 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
162 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
138 helpbasic=True, inferrepo=True)
163 helpbasic=True, inferrepo=True)
139 def add(ui, repo, *pats, **opts):
164 def add(ui, repo, *pats, **opts):
140 """add the specified files on the next commit
165 """add the specified files on the next commit
141
166
142 Schedule files to be version controlled and added to the
167 Schedule files to be version controlled and added to the
143 repository.
168 repository.
144
169
145 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
146 undo an add before that, see :hg:`forget`.
171 undo an add before that, see :hg:`forget`.
147
172
148 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
149 files matching ``.hgignore``).
174 files matching ``.hgignore``).
150
175
151 .. container:: verbose
176 .. container:: verbose
152
177
153 Examples:
178 Examples:
154
179
155 - New (unknown) files are added
180 - New (unknown) files are added
156 automatically by :hg:`add`::
181 automatically by :hg:`add`::
157
182
158 $ ls
183 $ ls
159 foo.c
184 foo.c
160 $ hg status
185 $ hg status
161 ? foo.c
186 ? foo.c
162 $ hg add
187 $ hg add
163 adding foo.c
188 adding foo.c
164 $ hg status
189 $ hg status
165 A foo.c
190 A foo.c
166
191
167 - Specific files to be added can be specified::
192 - Specific files to be added can be specified::
168
193
169 $ ls
194 $ ls
170 bar.c foo.c
195 bar.c foo.c
171 $ hg status
196 $ hg status
172 ? bar.c
197 ? bar.c
173 ? foo.c
198 ? foo.c
174 $ hg add bar.c
199 $ hg add bar.c
175 $ hg status
200 $ hg status
176 A bar.c
201 A bar.c
177 ? foo.c
202 ? foo.c
178
203
179 Returns 0 if all files are successfully added.
204 Returns 0 if all files are successfully added.
180 """
205 """
181
206
182 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
207 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
183 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
208 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
184 rejected = cmdutil.add(ui, repo, m, "", uipathfn, False, **opts)
209 rejected = cmdutil.add(ui, repo, m, "", uipathfn, False, **opts)
185 return rejected and 1 or 0
210 return rejected and 1 or 0
186
211
187 @command('addremove',
212 @command('addremove',
188 similarityopts + subrepoopts + walkopts + dryrunopts,
213 similarityopts + subrepoopts + walkopts + dryrunopts,
189 _('[OPTION]... [FILE]...'),
214 _('[OPTION]... [FILE]...'),
190 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
215 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
191 inferrepo=True)
216 inferrepo=True)
192 def addremove(ui, repo, *pats, **opts):
217 def addremove(ui, repo, *pats, **opts):
193 """add all new files, delete all missing files
218 """add all new files, delete all missing files
194
219
195 Add all new files and remove all missing files from the
220 Add all new files and remove all missing files from the
196 repository.
221 repository.
197
222
198 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
199 the patterns in ``.hgignore``. As with add, these changes take
224 the patterns in ``.hgignore``. As with add, these changes take
200 effect at the next commit.
225 effect at the next commit.
201
226
202 Use the -s/--similarity option to detect renamed files. This
227 Use the -s/--similarity option to detect renamed files. This
203 option takes a percentage between 0 (disabled) and 100 (files must
228 option takes a percentage between 0 (disabled) and 100 (files must
204 be identical) as its parameter. With a parameter greater than 0,
229 be identical) as its parameter. With a parameter greater than 0,
205 this compares every removed file with every added file and records
230 this compares every removed file with every added file and records
206 those similar enough as renames. Detecting renamed files this way
231 those similar enough as renames. Detecting renamed files this way
207 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
208 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
209 not specified, -s/--similarity defaults to 100 and only renames of
234 not specified, -s/--similarity defaults to 100 and only renames of
210 identical files are detected.
235 identical files are detected.
211
236
212 .. container:: verbose
237 .. container:: verbose
213
238
214 Examples:
239 Examples:
215
240
216 - A number of files (bar.c and foo.c) are new,
241 - A number of files (bar.c and foo.c) are new,
217 while foobar.c has been removed (without using :hg:`remove`)
242 while foobar.c has been removed (without using :hg:`remove`)
218 from the repository::
243 from the repository::
219
244
220 $ ls
245 $ ls
221 bar.c foo.c
246 bar.c foo.c
222 $ hg status
247 $ hg status
223 ! foobar.c
248 ! foobar.c
224 ? bar.c
249 ? bar.c
225 ? foo.c
250 ? foo.c
226 $ hg addremove
251 $ hg addremove
227 adding bar.c
252 adding bar.c
228 adding foo.c
253 adding foo.c
229 removing foobar.c
254 removing foobar.c
230 $ hg status
255 $ hg status
231 A bar.c
256 A bar.c
232 A foo.c
257 A foo.c
233 R foobar.c
258 R foobar.c
234
259
235 - 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`.
236 Afterwards, it was edited slightly::
261 Afterwards, it was edited slightly::
237
262
238 $ ls
263 $ ls
239 foo.c
264 foo.c
240 $ hg status
265 $ hg status
241 ! foobar.c
266 ! foobar.c
242 ? foo.c
267 ? foo.c
243 $ hg addremove --similarity 90
268 $ hg addremove --similarity 90
244 removing foobar.c
269 removing foobar.c
245 adding foo.c
270 adding foo.c
246 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)
247 $ hg status -C
272 $ hg status -C
248 A foo.c
273 A foo.c
249 foobar.c
274 foobar.c
250 R foobar.c
275 R foobar.c
251
276
252 Returns 0 if all files are successfully added.
277 Returns 0 if all files are successfully added.
253 """
278 """
254 opts = pycompat.byteskwargs(opts)
279 opts = pycompat.byteskwargs(opts)
255 if not opts.get('similarity'):
280 if not opts.get('similarity'):
256 opts['similarity'] = '100'
281 opts['similarity'] = '100'
257 matcher = scmutil.match(repo[None], pats, opts)
282 matcher = scmutil.match(repo[None], pats, opts)
258 relative = scmutil.anypats(pats, opts)
283 relative = scmutil.anypats(pats, opts)
259 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
284 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
260 return scmutil.addremove(repo, matcher, "", uipathfn, opts)
285 return scmutil.addremove(repo, matcher, "", uipathfn, opts)
261
286
262 @command('annotate|blame',
287 @command('annotate|blame',
263 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
288 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
264 ('', 'follow', None,
289 ('', 'follow', None,
265 _('follow copies/renames and list the filename (DEPRECATED)')),
290 _('follow copies/renames and list the filename (DEPRECATED)')),
266 ('', 'no-follow', None, _("don't follow copies and renames")),
291 ('', 'no-follow', None, _("don't follow copies and renames")),
267 ('a', 'text', None, _('treat all files as text')),
292 ('a', 'text', None, _('treat all files as text')),
268 ('u', 'user', None, _('list the author (long with -v)')),
293 ('u', 'user', None, _('list the author (long with -v)')),
269 ('f', 'file', None, _('list the filename')),
294 ('f', 'file', None, _('list the filename')),
270 ('d', 'date', None, _('list the date (short with -q)')),
295 ('d', 'date', None, _('list the date (short with -q)')),
271 ('n', 'number', None, _('list the revision number (default)')),
296 ('n', 'number', None, _('list the revision number (default)')),
272 ('c', 'changeset', None, _('list the changeset')),
297 ('c', 'changeset', None, _('list the changeset')),
273 ('l', 'line-number', None, _('show line number at the first appearance')),
298 ('l', 'line-number', None, _('show line number at the first appearance')),
274 ('', 'skip', [], _('revision to not display (EXPERIMENTAL)'), _('REV')),
299 ('', 'skip', [], _('revision to not display (EXPERIMENTAL)'), _('REV')),
275 ] + diffwsopts + walkopts + formatteropts,
300 ] + diffwsopts + walkopts + formatteropts,
276 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
301 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
277 helpcategory=command.CATEGORY_FILE_CONTENTS,
302 helpcategory=command.CATEGORY_FILE_CONTENTS,
278 helpbasic=True, inferrepo=True)
303 helpbasic=True, inferrepo=True)
279 def annotate(ui, repo, *pats, **opts):
304 def annotate(ui, repo, *pats, **opts):
280 """show changeset information by line for each file
305 """show changeset information by line for each file
281
306
282 List changes in files, showing the revision id responsible for
307 List changes in files, showing the revision id responsible for
283 each line.
308 each line.
284
309
285 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
286 by whom.
311 by whom.
287
312
288 If you include --file, --user, or --date, the revision number is
313 If you include --file, --user, or --date, the revision number is
289 suppressed unless you also include --number.
314 suppressed unless you also include --number.
290
315
291 Without the -a/--text option, annotate will avoid processing files
316 Without the -a/--text option, annotate will avoid processing files
292 it detects as binary. With -a, annotate will annotate the file
317 it detects as binary. With -a, annotate will annotate the file
293 anyway, although the results will probably be neither useful
318 anyway, although the results will probably be neither useful
294 nor desirable.
319 nor desirable.
295
320
296 .. container:: verbose
321 .. container:: verbose
297
322
298 Template:
323 Template:
299
324
300 The following keywords are supported in addition to the common template
325 The following keywords are supported in addition to the common template
301 keywords and functions. See also :hg:`help templates`.
326 keywords and functions. See also :hg:`help templates`.
302
327
303 :lines: List of lines with annotation data.
328 :lines: List of lines with annotation data.
304 :path: String. Repository-absolute path of the specified file.
329 :path: String. Repository-absolute path of the specified file.
305
330
306 And each entry of ``{lines}`` provides the following sub-keywords in
331 And each entry of ``{lines}`` provides the following sub-keywords in
307 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
332 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
308
333
309 :line: String. Line content.
334 :line: String. Line content.
310 :lineno: Integer. Line number at that revision.
335 :lineno: Integer. Line number at that revision.
311 :path: String. Repository-absolute path of the file at that revision.
336 :path: String. Repository-absolute path of the file at that revision.
312
337
313 See :hg:`help templates.operators` for the list expansion syntax.
338 See :hg:`help templates.operators` for the list expansion syntax.
314
339
315 Returns 0 on success.
340 Returns 0 on success.
316 """
341 """
317 opts = pycompat.byteskwargs(opts)
342 opts = pycompat.byteskwargs(opts)
318 if not pats:
343 if not pats:
319 raise error.Abort(_('at least one filename or pattern is required'))
344 raise error.Abort(_('at least one filename or pattern is required'))
320
345
321 if opts.get('follow'):
346 if opts.get('follow'):
322 # --follow is deprecated and now just an alias for -f/--file
347 # --follow is deprecated and now just an alias for -f/--file
323 # to mimic the behavior of Mercurial before version 1.5
348 # to mimic the behavior of Mercurial before version 1.5
324 opts['file'] = True
349 opts['file'] = True
325
350
326 if (not opts.get('user') and not opts.get('changeset')
351 if (not opts.get('user') and not opts.get('changeset')
327 and not opts.get('date') and not opts.get('file')):
352 and not opts.get('date') and not opts.get('file')):
328 opts['number'] = True
353 opts['number'] = True
329
354
330 linenumber = opts.get('line_number') is not None
355 linenumber = opts.get('line_number') is not None
331 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')):
332 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'))
333
358
334 rev = opts.get('rev')
359 rev = opts.get('rev')
335 if rev:
360 if rev:
336 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
361 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
337 ctx = scmutil.revsingle(repo, rev)
362 ctx = scmutil.revsingle(repo, rev)
338
363
339 ui.pager('annotate')
364 ui.pager('annotate')
340 rootfm = ui.formatter('annotate', opts)
365 rootfm = ui.formatter('annotate', opts)
341 if ui.debugflag:
366 if ui.debugflag:
342 shorthex = pycompat.identity
367 shorthex = pycompat.identity
343 else:
368 else:
344 def shorthex(h):
369 def shorthex(h):
345 return h[:12]
370 return h[:12]
346 if ui.quiet:
371 if ui.quiet:
347 datefunc = dateutil.shortdate
372 datefunc = dateutil.shortdate
348 else:
373 else:
349 datefunc = dateutil.datestr
374 datefunc = dateutil.datestr
350 if ctx.rev() is None:
375 if ctx.rev() is None:
351 if opts.get('changeset'):
376 if opts.get('changeset'):
352 # omit "+" suffix which is appended to node hex
377 # omit "+" suffix which is appended to node hex
353 def formatrev(rev):
378 def formatrev(rev):
354 if rev == wdirrev:
379 if rev == wdirrev:
355 return '%d' % ctx.p1().rev()
380 return '%d' % ctx.p1().rev()
356 else:
381 else:
357 return '%d' % rev
382 return '%d' % rev
358 else:
383 else:
359 def formatrev(rev):
384 def formatrev(rev):
360 if rev == wdirrev:
385 if rev == wdirrev:
361 return '%d+' % ctx.p1().rev()
386 return '%d+' % ctx.p1().rev()
362 else:
387 else:
363 return '%d ' % rev
388 return '%d ' % rev
364 def formathex(h):
389 def formathex(h):
365 if h == wdirhex:
390 if h == wdirhex:
366 return '%s+' % shorthex(hex(ctx.p1().node()))
391 return '%s+' % shorthex(hex(ctx.p1().node()))
367 else:
392 else:
368 return '%s ' % shorthex(h)
393 return '%s ' % shorthex(h)
369 else:
394 else:
370 formatrev = b'%d'.__mod__
395 formatrev = b'%d'.__mod__
371 formathex = shorthex
396 formathex = shorthex
372
397
373 opmap = [
398 opmap = [
374 ('user', ' ', lambda x: x.fctx.user(), ui.shortuser),
399 ('user', ' ', lambda x: x.fctx.user(), ui.shortuser),
375 ('rev', ' ', lambda x: scmutil.intrev(x.fctx), formatrev),
400 ('rev', ' ', lambda x: scmutil.intrev(x.fctx), formatrev),
376 ('node', ' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
401 ('node', ' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
377 ('date', ' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
402 ('date', ' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
378 ('path', ' ', lambda x: x.fctx.path(), pycompat.bytestr),
403 ('path', ' ', lambda x: x.fctx.path(), pycompat.bytestr),
379 ('lineno', ':', lambda x: x.lineno, pycompat.bytestr),
404 ('lineno', ':', lambda x: x.lineno, pycompat.bytestr),
380 ]
405 ]
381 opnamemap = {
406 opnamemap = {
382 'rev': 'number',
407 'rev': 'number',
383 'node': 'changeset',
408 'node': 'changeset',
384 'path': 'file',
409 'path': 'file',
385 'lineno': 'line_number',
410 'lineno': 'line_number',
386 }
411 }
387
412
388 if rootfm.isplain():
413 if rootfm.isplain():
389 def makefunc(get, fmt):
414 def makefunc(get, fmt):
390 return lambda x: fmt(get(x))
415 return lambda x: fmt(get(x))
391 else:
416 else:
392 def makefunc(get, fmt):
417 def makefunc(get, fmt):
393 return get
418 return get
394 datahint = rootfm.datahint()
419 datahint = rootfm.datahint()
395 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
396 if opts.get(opnamemap.get(fn, fn)) or fn in datahint]
421 if opts.get(opnamemap.get(fn, fn)) or fn in datahint]
397 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
398 fields = ' '.join(fn for fn, sep, get, fmt in opmap
423 fields = ' '.join(fn for fn, sep, get, fmt in opmap
399 if opts.get(opnamemap.get(fn, fn)) or fn in datahint)
424 if opts.get(opnamemap.get(fn, fn)) or fn in datahint)
400
425
401 def bad(x, y):
426 def bad(x, y):
402 raise error.Abort("%s: %s" % (x, y))
427 raise error.Abort("%s: %s" % (x, y))
403
428
404 m = scmutil.match(ctx, pats, opts, badfn=bad)
429 m = scmutil.match(ctx, pats, opts, badfn=bad)
405
430
406 follow = not opts.get('no_follow')
431 follow = not opts.get('no_follow')
407 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
432 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
408 whitespace=True)
433 whitespace=True)
409 skiprevs = opts.get('skip')
434 skiprevs = opts.get('skip')
410 if skiprevs:
435 if skiprevs:
411 skiprevs = scmutil.revrange(repo, skiprevs)
436 skiprevs = scmutil.revrange(repo, skiprevs)
412
437
413 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
438 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
414 for abs in ctx.walk(m):
439 for abs in ctx.walk(m):
415 fctx = ctx[abs]
440 fctx = ctx[abs]
416 rootfm.startitem()
441 rootfm.startitem()
417 rootfm.data(path=abs)
442 rootfm.data(path=abs)
418 if not opts.get('text') and fctx.isbinary():
443 if not opts.get('text') and fctx.isbinary():
419 rootfm.plain(_("%s: binary file\n") % uipathfn(abs))
444 rootfm.plain(_("%s: binary file\n") % uipathfn(abs))
420 continue
445 continue
421
446
422 fm = rootfm.nested('lines', tmpl='{rev}: {line}')
447 fm = rootfm.nested('lines', tmpl='{rev}: {line}')
423 lines = fctx.annotate(follow=follow, skiprevs=skiprevs,
448 lines = fctx.annotate(follow=follow, skiprevs=skiprevs,
424 diffopts=diffopts)
449 diffopts=diffopts)
425 if not lines:
450 if not lines:
426 fm.end()
451 fm.end()
427 continue
452 continue
428 formats = []
453 formats = []
429 pieces = []
454 pieces = []
430
455
431 for f, sep in funcmap:
456 for f, sep in funcmap:
432 l = [f(n) for n in lines]
457 l = [f(n) for n in lines]
433 if fm.isplain():
458 if fm.isplain():
434 sizes = [encoding.colwidth(x) for x in l]
459 sizes = [encoding.colwidth(x) for x in l]
435 ml = max(sizes)
460 ml = max(sizes)
436 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
461 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
437 else:
462 else:
438 formats.append(['%s' for x in l])
463 formats.append(['%s' for x in l])
439 pieces.append(l)
464 pieces.append(l)
440
465
441 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
466 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
442 fm.startitem()
467 fm.startitem()
443 fm.context(fctx=n.fctx)
468 fm.context(fctx=n.fctx)
444 fm.write(fields, "".join(f), *p)
469 fm.write(fields, "".join(f), *p)
445 if n.skip:
470 if n.skip:
446 fmt = "* %s"
471 fmt = "* %s"
447 else:
472 else:
448 fmt = ": %s"
473 fmt = ": %s"
449 fm.write('line', fmt, n.text)
474 fm.write('line', fmt, n.text)
450
475
451 if not lines[-1].text.endswith('\n'):
476 if not lines[-1].text.endswith('\n'):
452 fm.plain('\n')
477 fm.plain('\n')
453 fm.end()
478 fm.end()
454
479
455 rootfm.end()
480 rootfm.end()
456
481
457 @command('archive',
482 @command('archive',
458 [('', 'no-decode', None, _('do not pass files through decoders')),
483 [('', 'no-decode', None, _('do not pass files through decoders')),
459 ('p', 'prefix', '', _('directory prefix for files in archive'),
484 ('p', 'prefix', '', _('directory prefix for files in archive'),
460 _('PREFIX')),
485 _('PREFIX')),
461 ('r', 'rev', '', _('revision to distribute'), _('REV')),
486 ('r', 'rev', '', _('revision to distribute'), _('REV')),
462 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
487 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
463 ] + subrepoopts + walkopts,
488 ] + subrepoopts + walkopts,
464 _('[OPTION]... DEST'),
489 _('[OPTION]... DEST'),
465 helpcategory=command.CATEGORY_IMPORT_EXPORT)
490 helpcategory=command.CATEGORY_IMPORT_EXPORT)
466 def archive(ui, repo, dest, **opts):
491 def archive(ui, repo, dest, **opts):
467 '''create an unversioned archive of a repository revision
492 '''create an unversioned archive of a repository revision
468
493
469 By default, the revision used is the parent of the working
494 By default, the revision used is the parent of the working
470 directory; use -r/--rev to specify a different revision.
495 directory; use -r/--rev to specify a different revision.
471
496
472 The archive type is automatically detected based on file
497 The archive type is automatically detected based on file
473 extension (to override, use -t/--type).
498 extension (to override, use -t/--type).
474
499
475 .. container:: verbose
500 .. container:: verbose
476
501
477 Examples:
502 Examples:
478
503
479 - create a zip file containing the 1.0 release::
504 - create a zip file containing the 1.0 release::
480
505
481 hg archive -r 1.0 project-1.0.zip
506 hg archive -r 1.0 project-1.0.zip
482
507
483 - create a tarball excluding .hg files::
508 - create a tarball excluding .hg files::
484
509
485 hg archive project.tar.gz -X ".hg*"
510 hg archive project.tar.gz -X ".hg*"
486
511
487 Valid types are:
512 Valid types are:
488
513
489 :``files``: a directory full of files (default)
514 :``files``: a directory full of files (default)
490 :``tar``: tar archive, uncompressed
515 :``tar``: tar archive, uncompressed
491 :``tbz2``: tar archive, compressed using bzip2
516 :``tbz2``: tar archive, compressed using bzip2
492 :``tgz``: tar archive, compressed using gzip
517 :``tgz``: tar archive, compressed using gzip
493 :``uzip``: zip archive, uncompressed
518 :``uzip``: zip archive, uncompressed
494 :``zip``: zip archive, compressed using deflate
519 :``zip``: zip archive, compressed using deflate
495
520
496 The exact name of the destination archive or directory is given
521 The exact name of the destination archive or directory is given
497 using a format string; see :hg:`help export` for details.
522 using a format string; see :hg:`help export` for details.
498
523
499 Each member added to an archive file has a directory prefix
524 Each member added to an archive file has a directory prefix
500 prepended. Use -p/--prefix to specify a format string for the
525 prepended. Use -p/--prefix to specify a format string for the
501 prefix. The default is the basename of the archive, with suffixes
526 prefix. The default is the basename of the archive, with suffixes
502 removed.
527 removed.
503
528
504 Returns 0 on success.
529 Returns 0 on success.
505 '''
530 '''
506
531
507 opts = pycompat.byteskwargs(opts)
532 opts = pycompat.byteskwargs(opts)
508 rev = opts.get('rev')
533 rev = opts.get('rev')
509 if rev:
534 if rev:
510 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
535 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
511 ctx = scmutil.revsingle(repo, rev)
536 ctx = scmutil.revsingle(repo, rev)
512 if not ctx:
537 if not ctx:
513 raise error.Abort(_('no working directory: please specify a revision'))
538 raise error.Abort(_('no working directory: please specify a revision'))
514 node = ctx.node()
539 node = ctx.node()
515 dest = cmdutil.makefilename(ctx, dest)
540 dest = cmdutil.makefilename(ctx, dest)
516 if os.path.realpath(dest) == repo.root:
541 if os.path.realpath(dest) == repo.root:
517 raise error.Abort(_('repository root cannot be destination'))
542 raise error.Abort(_('repository root cannot be destination'))
518
543
519 kind = opts.get('type') or archival.guesskind(dest) or 'files'
544 kind = opts.get('type') or archival.guesskind(dest) or 'files'
520 prefix = opts.get('prefix')
545 prefix = opts.get('prefix')
521
546
522 if dest == '-':
547 if dest == '-':
523 if kind == 'files':
548 if kind == 'files':
524 raise error.Abort(_('cannot archive plain files to stdout'))
549 raise error.Abort(_('cannot archive plain files to stdout'))
525 dest = cmdutil.makefileobj(ctx, dest)
550 dest = cmdutil.makefileobj(ctx, dest)
526 if not prefix:
551 if not prefix:
527 prefix = os.path.basename(repo.root) + '-%h'
552 prefix = os.path.basename(repo.root) + '-%h'
528
553
529 prefix = cmdutil.makefilename(ctx, prefix)
554 prefix = cmdutil.makefilename(ctx, prefix)
530 match = scmutil.match(ctx, [], opts)
555 match = scmutil.match(ctx, [], opts)
531 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
556 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
532 match, prefix, subrepos=opts.get('subrepos'))
557 match, prefix, subrepos=opts.get('subrepos'))
533
558
534 @command('backout',
559 @command('backout',
535 [('', 'merge', None, _('merge with old dirstate parent after backout')),
560 [('', 'merge', None, _('merge with old dirstate parent after backout')),
536 ('', 'commit', None,
561 ('', 'commit', None,
537 _('commit if no conflicts were encountered (DEPRECATED)')),
562 _('commit if no conflicts were encountered (DEPRECATED)')),
538 ('', 'no-commit', None, _('do not commit')),
563 ('', 'no-commit', None, _('do not commit')),
539 ('', 'parent', '',
564 ('', 'parent', '',
540 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
565 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
541 ('r', 'rev', '', _('revision to backout'), _('REV')),
566 ('r', 'rev', '', _('revision to backout'), _('REV')),
542 ('e', 'edit', False, _('invoke editor on commit messages')),
567 ('e', 'edit', False, _('invoke editor on commit messages')),
543 ] + mergetoolopts + walkopts + commitopts + commitopts2,
568 ] + mergetoolopts + walkopts + commitopts + commitopts2,
544 _('[OPTION]... [-r] REV'),
569 _('[OPTION]... [-r] REV'),
545 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
570 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
546 def backout(ui, repo, node=None, rev=None, **opts):
571 def backout(ui, repo, node=None, rev=None, **opts):
547 '''reverse effect of earlier changeset
572 '''reverse effect of earlier changeset
548
573
549 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
550 current working directory. If no conflicts were encountered,
575 current working directory. If no conflicts were encountered,
551 it will be committed immediately.
576 it will be committed immediately.
552
577
553 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
554 is committed automatically (unless --no-commit is specified).
579 is committed automatically (unless --no-commit is specified).
555
580
556 .. note::
581 .. note::
557
582
558 :hg:`backout` cannot be used to fix either an unwanted or
583 :hg:`backout` cannot be used to fix either an unwanted or
559 incorrect merge.
584 incorrect merge.
560
585
561 .. container:: verbose
586 .. container:: verbose
562
587
563 Examples:
588 Examples:
564
589
565 - Reverse the effect of the parent of the working directory.
590 - Reverse the effect of the parent of the working directory.
566 This backout will be committed immediately::
591 This backout will be committed immediately::
567
592
568 hg backout -r .
593 hg backout -r .
569
594
570 - Reverse the effect of previous bad revision 23::
595 - Reverse the effect of previous bad revision 23::
571
596
572 hg backout -r 23
597 hg backout -r 23
573
598
574 - Reverse the effect of previous bad revision 23 and
599 - Reverse the effect of previous bad revision 23 and
575 leave changes uncommitted::
600 leave changes uncommitted::
576
601
577 hg backout -r 23 --no-commit
602 hg backout -r 23 --no-commit
578 hg commit -m "Backout revision 23"
603 hg commit -m "Backout revision 23"
579
604
580 By default, the pending changeset will have one parent,
605 By default, the pending changeset will have one parent,
581 maintaining a linear history. With --merge, the pending
606 maintaining a linear history. With --merge, the pending
582 changeset will instead have two parents: the old parent of the
607 changeset will instead have two parents: the old parent of the
583 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.
584
609
585 Before version 1.7, the behavior without --merge was equivalent
610 Before version 1.7, the behavior without --merge was equivalent
586 to specifying --merge followed by :hg:`update --clean .` to
611 to specifying --merge followed by :hg:`update --clean .` to
587 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
588 merged separately.
613 merged separately.
589
614
590 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.
591
616
592 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
593 of another revision.
618 of another revision.
594
619
595 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
596 files.
621 files.
597 '''
622 '''
598 with repo.wlock(), repo.lock():
623 with repo.wlock(), repo.lock():
599 return _dobackout(ui, repo, node, rev, **opts)
624 return _dobackout(ui, repo, node, rev, **opts)
600
625
601 def _dobackout(ui, repo, node=None, rev=None, **opts):
626 def _dobackout(ui, repo, node=None, rev=None, **opts):
602 opts = pycompat.byteskwargs(opts)
627 opts = pycompat.byteskwargs(opts)
603 if opts.get('commit') and opts.get('no_commit'):
628 if opts.get('commit') and opts.get('no_commit'):
604 raise error.Abort(_("cannot use --commit with --no-commit"))
629 raise error.Abort(_("cannot use --commit with --no-commit"))
605 if opts.get('merge') and opts.get('no_commit'):
630 if opts.get('merge') and opts.get('no_commit'):
606 raise error.Abort(_("cannot use --merge with --no-commit"))
631 raise error.Abort(_("cannot use --merge with --no-commit"))
607
632
608 if rev and node:
633 if rev and node:
609 raise error.Abort(_("please specify just one revision"))
634 raise error.Abort(_("please specify just one revision"))
610
635
611 if not rev:
636 if not rev:
612 rev = node
637 rev = node
613
638
614 if not rev:
639 if not rev:
615 raise error.Abort(_("please specify a revision to backout"))
640 raise error.Abort(_("please specify a revision to backout"))
616
641
617 date = opts.get('date')
642 date = opts.get('date')
618 if date:
643 if date:
619 opts['date'] = dateutil.parsedate(date)
644 opts['date'] = dateutil.parsedate(date)
620
645
621 cmdutil.checkunfinished(repo)
646 cmdutil.checkunfinished(repo)
622 cmdutil.bailifchanged(repo)
647 cmdutil.bailifchanged(repo)
623 node = scmutil.revsingle(repo, rev).node()
648 node = scmutil.revsingle(repo, rev).node()
624
649
625 op1, op2 = repo.dirstate.parents()
650 op1, op2 = repo.dirstate.parents()
626 if not repo.changelog.isancestor(node, op1):
651 if not repo.changelog.isancestor(node, op1):
627 raise error.Abort(_('cannot backout change that is not an ancestor'))
652 raise error.Abort(_('cannot backout change that is not an ancestor'))
628
653
629 p1, p2 = repo.changelog.parents(node)
654 p1, p2 = repo.changelog.parents(node)
630 if p1 == nullid:
655 if p1 == nullid:
631 raise error.Abort(_('cannot backout a change with no parents'))
656 raise error.Abort(_('cannot backout a change with no parents'))
632 if p2 != nullid:
657 if p2 != nullid:
633 if not opts.get('parent'):
658 if not opts.get('parent'):
634 raise error.Abort(_('cannot backout a merge changeset'))
659 raise error.Abort(_('cannot backout a merge changeset'))
635 p = repo.lookup(opts['parent'])
660 p = repo.lookup(opts['parent'])
636 if p not in (p1, p2):
661 if p not in (p1, p2):
637 raise error.Abort(_('%s is not a parent of %s') %
662 raise error.Abort(_('%s is not a parent of %s') %
638 (short(p), short(node)))
663 (short(p), short(node)))
639 parent = p
664 parent = p
640 else:
665 else:
641 if opts.get('parent'):
666 if opts.get('parent'):
642 raise error.Abort(_('cannot use --parent on non-merge changeset'))
667 raise error.Abort(_('cannot use --parent on non-merge changeset'))
643 parent = p1
668 parent = p1
644
669
645 # the backout should appear on the same branch
670 # the backout should appear on the same branch
646 branch = repo.dirstate.branch()
671 branch = repo.dirstate.branch()
647 bheads = repo.branchheads(branch)
672 bheads = repo.branchheads(branch)
648 rctx = scmutil.revsingle(repo, hex(parent))
673 rctx = scmutil.revsingle(repo, hex(parent))
649 if not opts.get('merge') and op1 != node:
674 if not opts.get('merge') and op1 != node:
650 with dirstateguard.dirstateguard(repo, 'backout'):
675 with dirstateguard.dirstateguard(repo, 'backout'):
651 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
676 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
652 with ui.configoverride(overrides, 'backout'):
677 with ui.configoverride(overrides, 'backout'):
653 stats = mergemod.update(repo, parent, branchmerge=True,
678 stats = mergemod.update(repo, parent, branchmerge=True,
654 force=True, ancestor=node,
679 force=True, ancestor=node,
655 mergeancestor=False)
680 mergeancestor=False)
656 repo.setparents(op1, op2)
681 repo.setparents(op1, op2)
657 hg._showstats(repo, stats)
682 hg._showstats(repo, stats)
658 if stats.unresolvedcount:
683 if stats.unresolvedcount:
659 repo.ui.status(_("use 'hg resolve' to retry unresolved "
684 repo.ui.status(_("use 'hg resolve' to retry unresolved "
660 "file merges\n"))
685 "file merges\n"))
661 return 1
686 return 1
662 else:
687 else:
663 hg.clean(repo, node, show_stats=False)
688 hg.clean(repo, node, show_stats=False)
664 repo.dirstate.setbranch(branch)
689 repo.dirstate.setbranch(branch)
665 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
690 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
666
691
667 if opts.get('no_commit'):
692 if opts.get('no_commit'):
668 msg = _("changeset %s backed out, "
693 msg = _("changeset %s backed out, "
669 "don't forget to commit.\n")
694 "don't forget to commit.\n")
670 ui.status(msg % short(node))
695 ui.status(msg % short(node))
671 return 0
696 return 0
672
697
673 def commitfunc(ui, repo, message, match, opts):
698 def commitfunc(ui, repo, message, match, opts):
674 editform = 'backout'
699 editform = 'backout'
675 e = cmdutil.getcommiteditor(editform=editform,
700 e = cmdutil.getcommiteditor(editform=editform,
676 **pycompat.strkwargs(opts))
701 **pycompat.strkwargs(opts))
677 if not message:
702 if not message:
678 # we don't translate commit messages
703 # we don't translate commit messages
679 message = "Backed out changeset %s" % short(node)
704 message = "Backed out changeset %s" % short(node)
680 e = cmdutil.getcommiteditor(edit=True, editform=editform)
705 e = cmdutil.getcommiteditor(edit=True, editform=editform)
681 return repo.commit(message, opts.get('user'), opts.get('date'),
706 return repo.commit(message, opts.get('user'), opts.get('date'),
682 match, editor=e)
707 match, editor=e)
683 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
708 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
684 if not newnode:
709 if not newnode:
685 ui.status(_("nothing changed\n"))
710 ui.status(_("nothing changed\n"))
686 return 1
711 return 1
687 cmdutil.commitstatus(repo, newnode, branch, bheads)
712 cmdutil.commitstatus(repo, newnode, branch, bheads)
688
713
689 def nice(node):
714 def nice(node):
690 return '%d:%s' % (repo.changelog.rev(node), short(node))
715 return '%d:%s' % (repo.changelog.rev(node), short(node))
691 ui.status(_('changeset %s backs out changeset %s\n') %
716 ui.status(_('changeset %s backs out changeset %s\n') %
692 (nice(repo.changelog.tip()), nice(node)))
717 (nice(repo.changelog.tip()), nice(node)))
693 if opts.get('merge') and op1 != node:
718 if opts.get('merge') and op1 != node:
694 hg.clean(repo, op1, show_stats=False)
719 hg.clean(repo, op1, show_stats=False)
695 ui.status(_('merging with changeset %s\n')
720 ui.status(_('merging with changeset %s\n')
696 % nice(repo.changelog.tip()))
721 % nice(repo.changelog.tip()))
697 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
722 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
698 with ui.configoverride(overrides, 'backout'):
723 with ui.configoverride(overrides, 'backout'):
699 return hg.merge(repo, hex(repo.changelog.tip()))
724 return hg.merge(repo, hex(repo.changelog.tip()))
700 return 0
725 return 0
701
726
702 @command('bisect',
727 @command('bisect',
703 [('r', 'reset', False, _('reset bisect state')),
728 [('r', 'reset', False, _('reset bisect state')),
704 ('g', 'good', False, _('mark changeset good')),
729 ('g', 'good', False, _('mark changeset good')),
705 ('b', 'bad', False, _('mark changeset bad')),
730 ('b', 'bad', False, _('mark changeset bad')),
706 ('s', 'skip', False, _('skip testing changeset')),
731 ('s', 'skip', False, _('skip testing changeset')),
707 ('e', 'extend', False, _('extend the bisect range')),
732 ('e', 'extend', False, _('extend the bisect range')),
708 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
733 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
709 ('U', 'noupdate', False, _('do not update to target'))],
734 ('U', 'noupdate', False, _('do not update to target'))],
710 _("[-gbsr] [-U] [-c CMD] [REV]"),
735 _("[-gbsr] [-U] [-c CMD] [REV]"),
711 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
736 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
712 def bisect(ui, repo, rev=None, extra=None, command=None,
737 def bisect(ui, repo, rev=None, extra=None, command=None,
713 reset=None, good=None, bad=None, skip=None, extend=None,
738 reset=None, good=None, bad=None, skip=None, extend=None,
714 noupdate=None):
739 noupdate=None):
715 """subdivision search of changesets
740 """subdivision search of changesets
716
741
717 This command helps to find changesets which introduce problems. To
742 This command helps to find changesets which introduce problems. To
718 use, mark the earliest changeset you know exhibits the problem as
743 use, mark the earliest changeset you know exhibits the problem as
719 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
720 as good. Bisect will update your working directory to a revision
745 as good. Bisect will update your working directory to a revision
721 for testing (unless the -U/--noupdate option is specified). Once
746 for testing (unless the -U/--noupdate option is specified). Once
722 you have performed tests, mark the working directory as good or
747 you have performed tests, mark the working directory as good or
723 bad, and bisect will either update to another candidate changeset
748 bad, and bisect will either update to another candidate changeset
724 or announce that it has found the bad revision.
749 or announce that it has found the bad revision.
725
750
726 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
727 revision as good or bad without checking it out first.
752 revision as good or bad without checking it out first.
728
753
729 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.
730 The environment variable HG_NODE will contain the ID of the
755 The environment variable HG_NODE will contain the ID of the
731 changeset being tested. The exit status of the command will be
756 changeset being tested. The exit status of the command will be
732 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
733 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
734 bisection, and any other non-zero exit status means the revision
759 bisection, and any other non-zero exit status means the revision
735 is bad.
760 is bad.
736
761
737 .. container:: verbose
762 .. container:: verbose
738
763
739 Some examples:
764 Some examples:
740
765
741 - 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::
742
767
743 hg bisect --bad 34
768 hg bisect --bad 34
744 hg bisect --good 12
769 hg bisect --good 12
745
770
746 - advance the current bisection by marking current revision as good or
771 - advance the current bisection by marking current revision as good or
747 bad::
772 bad::
748
773
749 hg bisect --good
774 hg bisect --good
750 hg bisect --bad
775 hg bisect --bad
751
776
752 - 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
753 that revision is not usable because of another issue)::
778 that revision is not usable because of another issue)::
754
779
755 hg bisect --skip
780 hg bisect --skip
756 hg bisect --skip 23
781 hg bisect --skip 23
757
782
758 - skip all revisions that do not touch directories ``foo`` or ``bar``::
783 - skip all revisions that do not touch directories ``foo`` or ``bar``::
759
784
760 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
785 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
761
786
762 - forget the current bisection::
787 - forget the current bisection::
763
788
764 hg bisect --reset
789 hg bisect --reset
765
790
766 - use 'make && make tests' to automatically find the first broken
791 - use 'make && make tests' to automatically find the first broken
767 revision::
792 revision::
768
793
769 hg bisect --reset
794 hg bisect --reset
770 hg bisect --bad 34
795 hg bisect --bad 34
771 hg bisect --good 12
796 hg bisect --good 12
772 hg bisect --command "make && make tests"
797 hg bisect --command "make && make tests"
773
798
774 - see all changesets whose states are already known in the current
799 - see all changesets whose states are already known in the current
775 bisection::
800 bisection::
776
801
777 hg log -r "bisect(pruned)"
802 hg log -r "bisect(pruned)"
778
803
779 - see the changeset currently being bisected (especially useful
804 - see the changeset currently being bisected (especially useful
780 if running with -U/--noupdate)::
805 if running with -U/--noupdate)::
781
806
782 hg log -r "bisect(current)"
807 hg log -r "bisect(current)"
783
808
784 - see all changesets that took part in the current bisection::
809 - see all changesets that took part in the current bisection::
785
810
786 hg log -r "bisect(range)"
811 hg log -r "bisect(range)"
787
812
788 - you can even get a nice graph::
813 - you can even get a nice graph::
789
814
790 hg log --graph -r "bisect(range)"
815 hg log --graph -r "bisect(range)"
791
816
792 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
817 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
793
818
794 Returns 0 on success.
819 Returns 0 on success.
795 """
820 """
796 # backward compatibility
821 # backward compatibility
797 if rev in "good bad reset init".split():
822 if rev in "good bad reset init".split():
798 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
823 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
799 cmd, rev, extra = rev, extra, None
824 cmd, rev, extra = rev, extra, None
800 if cmd == "good":
825 if cmd == "good":
801 good = True
826 good = True
802 elif cmd == "bad":
827 elif cmd == "bad":
803 bad = True
828 bad = True
804 else:
829 else:
805 reset = True
830 reset = True
806 elif extra:
831 elif extra:
807 raise error.Abort(_('incompatible arguments'))
832 raise error.Abort(_('incompatible arguments'))
808
833
809 incompatibles = {
834 incompatibles = {
810 '--bad': bad,
835 '--bad': bad,
811 '--command': bool(command),
836 '--command': bool(command),
812 '--extend': extend,
837 '--extend': extend,
813 '--good': good,
838 '--good': good,
814 '--reset': reset,
839 '--reset': reset,
815 '--skip': skip,
840 '--skip': skip,
816 }
841 }
817
842
818 enabled = [x for x in incompatibles if incompatibles[x]]
843 enabled = [x for x in incompatibles if incompatibles[x]]
819
844
820 if len(enabled) > 1:
845 if len(enabled) > 1:
821 raise error.Abort(_('%s and %s are incompatible') %
846 raise error.Abort(_('%s and %s are incompatible') %
822 tuple(sorted(enabled)[0:2]))
847 tuple(sorted(enabled)[0:2]))
823
848
824 if reset:
849 if reset:
825 hbisect.resetstate(repo)
850 hbisect.resetstate(repo)
826 return
851 return
827
852
828 state = hbisect.load_state(repo)
853 state = hbisect.load_state(repo)
829
854
830 # update state
855 # update state
831 if good or bad or skip:
856 if good or bad or skip:
832 if rev:
857 if rev:
833 nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
858 nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
834 else:
859 else:
835 nodes = [repo.lookup('.')]
860 nodes = [repo.lookup('.')]
836 if good:
861 if good:
837 state['good'] += nodes
862 state['good'] += nodes
838 elif bad:
863 elif bad:
839 state['bad'] += nodes
864 state['bad'] += nodes
840 elif skip:
865 elif skip:
841 state['skip'] += nodes
866 state['skip'] += nodes
842 hbisect.save_state(repo, state)
867 hbisect.save_state(repo, state)
843 if not (state['good'] and state['bad']):
868 if not (state['good'] and state['bad']):
844 return
869 return
845
870
846 def mayupdate(repo, node, show_stats=True):
871 def mayupdate(repo, node, show_stats=True):
847 """common used update sequence"""
872 """common used update sequence"""
848 if noupdate:
873 if noupdate:
849 return
874 return
850 cmdutil.checkunfinished(repo)
875 cmdutil.checkunfinished(repo)
851 cmdutil.bailifchanged(repo)
876 cmdutil.bailifchanged(repo)
852 return hg.clean(repo, node, show_stats=show_stats)
877 return hg.clean(repo, node, show_stats=show_stats)
853
878
854 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
879 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
855
880
856 if command:
881 if command:
857 changesets = 1
882 changesets = 1
858 if noupdate:
883 if noupdate:
859 try:
884 try:
860 node = state['current'][0]
885 node = state['current'][0]
861 except LookupError:
886 except LookupError:
862 raise error.Abort(_('current bisect revision is unknown - '
887 raise error.Abort(_('current bisect revision is unknown - '
863 'start a new bisect to fix'))
888 'start a new bisect to fix'))
864 else:
889 else:
865 node, p2 = repo.dirstate.parents()
890 node, p2 = repo.dirstate.parents()
866 if p2 != nullid:
891 if p2 != nullid:
867 raise error.Abort(_('current bisect revision is a merge'))
892 raise error.Abort(_('current bisect revision is a merge'))
868 if rev:
893 if rev:
869 node = repo[scmutil.revsingle(repo, rev, node)].node()
894 node = repo[scmutil.revsingle(repo, rev, node)].node()
870 try:
895 try:
871 while changesets:
896 while changesets:
872 # update state
897 # update state
873 state['current'] = [node]
898 state['current'] = [node]
874 hbisect.save_state(repo, state)
899 hbisect.save_state(repo, state)
875 status = ui.system(command, environ={'HG_NODE': hex(node)},
900 status = ui.system(command, environ={'HG_NODE': hex(node)},
876 blockedtag='bisect_check')
901 blockedtag='bisect_check')
877 if status == 125:
902 if status == 125:
878 transition = "skip"
903 transition = "skip"
879 elif status == 0:
904 elif status == 0:
880 transition = "good"
905 transition = "good"
881 # status < 0 means process was killed
906 # status < 0 means process was killed
882 elif status == 127:
907 elif status == 127:
883 raise error.Abort(_("failed to execute %s") % command)
908 raise error.Abort(_("failed to execute %s") % command)
884 elif status < 0:
909 elif status < 0:
885 raise error.Abort(_("%s killed") % command)
910 raise error.Abort(_("%s killed") % command)
886 else:
911 else:
887 transition = "bad"
912 transition = "bad"
888 state[transition].append(node)
913 state[transition].append(node)
889 ctx = repo[node]
914 ctx = repo[node]
890 ui.status(_('changeset %d:%s: %s\n') % (ctx.rev(), ctx,
915 ui.status(_('changeset %d:%s: %s\n') % (ctx.rev(), ctx,
891 transition))
916 transition))
892 hbisect.checkstate(state)
917 hbisect.checkstate(state)
893 # bisect
918 # bisect
894 nodes, changesets, bgood = hbisect.bisect(repo, state)
919 nodes, changesets, bgood = hbisect.bisect(repo, state)
895 # update to next check
920 # update to next check
896 node = nodes[0]
921 node = nodes[0]
897 mayupdate(repo, node, show_stats=False)
922 mayupdate(repo, node, show_stats=False)
898 finally:
923 finally:
899 state['current'] = [node]
924 state['current'] = [node]
900 hbisect.save_state(repo, state)
925 hbisect.save_state(repo, state)
901 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
926 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
902 return
927 return
903
928
904 hbisect.checkstate(state)
929 hbisect.checkstate(state)
905
930
906 # actually bisect
931 # actually bisect
907 nodes, changesets, good = hbisect.bisect(repo, state)
932 nodes, changesets, good = hbisect.bisect(repo, state)
908 if extend:
933 if extend:
909 if not changesets:
934 if not changesets:
910 extendnode = hbisect.extendrange(repo, state, nodes, good)
935 extendnode = hbisect.extendrange(repo, state, nodes, good)
911 if extendnode is not None:
936 if extendnode is not None:
912 ui.write(_("Extending search to changeset %d:%s\n")
937 ui.write(_("Extending search to changeset %d:%s\n")
913 % (extendnode.rev(), extendnode))
938 % (extendnode.rev(), extendnode))
914 state['current'] = [extendnode.node()]
939 state['current'] = [extendnode.node()]
915 hbisect.save_state(repo, state)
940 hbisect.save_state(repo, state)
916 return mayupdate(repo, extendnode.node())
941 return mayupdate(repo, extendnode.node())
917 raise error.Abort(_("nothing to extend"))
942 raise error.Abort(_("nothing to extend"))
918
943
919 if changesets == 0:
944 if changesets == 0:
920 hbisect.printresult(ui, repo, state, displayer, nodes, good)
945 hbisect.printresult(ui, repo, state, displayer, nodes, good)
921 else:
946 else:
922 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
923 node = nodes[0]
948 node = nodes[0]
924 # compute the approximate number of remaining tests
949 # compute the approximate number of remaining tests
925 tests, size = 0, 2
950 tests, size = 0, 2
926 while size <= changesets:
951 while size <= changesets:
927 tests, size = tests + 1, size * 2
952 tests, size = tests + 1, size * 2
928 rev = repo.changelog.rev(node)
953 rev = repo.changelog.rev(node)
929 ui.write(_("Testing changeset %d:%s "
954 ui.write(_("Testing changeset %d:%s "
930 "(%d changesets remaining, ~%d tests)\n")
955 "(%d changesets remaining, ~%d tests)\n")
931 % (rev, short(node), changesets, tests))
956 % (rev, short(node), changesets, tests))
932 state['current'] = [node]
957 state['current'] = [node]
933 hbisect.save_state(repo, state)
958 hbisect.save_state(repo, state)
934 return mayupdate(repo, node)
959 return mayupdate(repo, node)
935
960
936 @command('bookmarks|bookmark',
961 @command('bookmarks|bookmark',
937 [('f', 'force', False, _('force')),
962 [('f', 'force', False, _('force')),
938 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
963 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
939 ('d', 'delete', False, _('delete a given bookmark')),
964 ('d', 'delete', False, _('delete a given bookmark')),
940 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
965 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
941 ('i', 'inactive', False, _('mark a bookmark inactive')),
966 ('i', 'inactive', False, _('mark a bookmark inactive')),
942 ('l', 'list', False, _('list existing bookmarks')),
967 ('l', 'list', False, _('list existing bookmarks')),
943 ] + formatteropts,
968 ] + formatteropts,
944 _('hg bookmarks [OPTIONS]... [NAME]...'),
969 _('hg bookmarks [OPTIONS]... [NAME]...'),
945 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
970 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
946 def bookmark(ui, repo, *names, **opts):
971 def bookmark(ui, repo, *names, **opts):
947 '''create a new bookmark or list existing bookmarks
972 '''create a new bookmark or list existing bookmarks
948
973
949 Bookmarks are labels on changesets to help track lines of development.
974 Bookmarks are labels on changesets to help track lines of development.
950 Bookmarks are unversioned and can be moved, renamed and deleted.
975 Bookmarks are unversioned and can be moved, renamed and deleted.
951 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.
952
977
953 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'.
954 The active bookmark is indicated with a '*'.
979 The active bookmark is indicated with a '*'.
955 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.
956 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.
957 Updating away from a bookmark will cause it to be deactivated.
982 Updating away from a bookmark will cause it to be deactivated.
958
983
959 Bookmarks can be pushed and pulled between repositories (see
984 Bookmarks can be pushed and pulled between repositories (see
960 :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
961 diverged, a new 'divergent bookmark' of the form 'name@path' will
986 diverged, a new 'divergent bookmark' of the form 'name@path' will
962 be created. Using :hg:`merge` will resolve the divergence.
987 be created. Using :hg:`merge` will resolve the divergence.
963
988
964 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
965 the active bookmark's name.
990 the active bookmark's name.
966
991
967 A bookmark named '@' has the special property that :hg:`clone` will
992 A bookmark named '@' has the special property that :hg:`clone` will
968 check it out by default if it exists.
993 check it out by default if it exists.
969
994
970 .. container:: verbose
995 .. container:: verbose
971
996
972 Template:
997 Template:
973
998
974 The following keywords are supported in addition to the common template
999 The following keywords are supported in addition to the common template
975 keywords and functions such as ``{bookmark}``. See also
1000 keywords and functions such as ``{bookmark}``. See also
976 :hg:`help templates`.
1001 :hg:`help templates`.
977
1002
978 :active: Boolean. True if the bookmark is active.
1003 :active: Boolean. True if the bookmark is active.
979
1004
980 Examples:
1005 Examples:
981
1006
982 - create an active bookmark for a new line of development::
1007 - create an active bookmark for a new line of development::
983
1008
984 hg book new-feature
1009 hg book new-feature
985
1010
986 - create an inactive bookmark as a place marker::
1011 - create an inactive bookmark as a place marker::
987
1012
988 hg book -i reviewed
1013 hg book -i reviewed
989
1014
990 - create an inactive bookmark on another changeset::
1015 - create an inactive bookmark on another changeset::
991
1016
992 hg book -r .^ tested
1017 hg book -r .^ tested
993
1018
994 - rename bookmark turkey to dinner::
1019 - rename bookmark turkey to dinner::
995
1020
996 hg book -m turkey dinner
1021 hg book -m turkey dinner
997
1022
998 - move the '@' bookmark from another branch::
1023 - move the '@' bookmark from another branch::
999
1024
1000 hg book -f @
1025 hg book -f @
1001
1026
1002 - print only the active bookmark name::
1027 - print only the active bookmark name::
1003
1028
1004 hg book -ql .
1029 hg book -ql .
1005 '''
1030 '''
1006 opts = pycompat.byteskwargs(opts)
1031 opts = pycompat.byteskwargs(opts)
1007 force = opts.get('force')
1032 force = opts.get('force')
1008 rev = opts.get('rev')
1033 rev = opts.get('rev')
1009 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark
1034 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark
1010
1035
1011 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)]
1012 if len(selactions) > 1:
1037 if len(selactions) > 1:
1013 raise error.Abort(_('--%s and --%s are incompatible')
1038 raise error.Abort(_('--%s and --%s are incompatible')
1014 % tuple(selactions[:2]))
1039 % tuple(selactions[:2]))
1015 if selactions:
1040 if selactions:
1016 action = selactions[0]
1041 action = selactions[0]
1017 elif names or rev:
1042 elif names or rev:
1018 action = 'add'
1043 action = 'add'
1019 elif inactive:
1044 elif inactive:
1020 action = 'inactive' # meaning deactivate
1045 action = 'inactive' # meaning deactivate
1021 else:
1046 else:
1022 action = 'list'
1047 action = 'list'
1023
1048
1024 if rev and action in {'delete', 'rename', 'list'}:
1049 if rev and action in {'delete', 'rename', 'list'}:
1025 raise error.Abort(_("--rev is incompatible with --%s") % action)
1050 raise error.Abort(_("--rev is incompatible with --%s") % action)
1026 if inactive and action in {'delete', 'list'}:
1051 if inactive and action in {'delete', 'list'}:
1027 raise error.Abort(_("--inactive is incompatible with --%s") % action)
1052 raise error.Abort(_("--inactive is incompatible with --%s") % action)
1028 if not names and action in {'add', 'delete'}:
1053 if not names and action in {'add', 'delete'}:
1029 raise error.Abort(_("bookmark name required"))
1054 raise error.Abort(_("bookmark name required"))
1030
1055
1031 if action in {'add', 'delete', 'rename', 'inactive'}:
1056 if action in {'add', 'delete', 'rename', 'inactive'}:
1032 with repo.wlock(), repo.lock(), repo.transaction('bookmark') as tr:
1057 with repo.wlock(), repo.lock(), repo.transaction('bookmark') as tr:
1033 if action == 'delete':
1058 if action == 'delete':
1034 names = pycompat.maplist(repo._bookmarks.expandname, names)
1059 names = pycompat.maplist(repo._bookmarks.expandname, names)
1035 bookmarks.delete(repo, tr, names)
1060 bookmarks.delete(repo, tr, names)
1036 elif action == 'rename':
1061 elif action == 'rename':
1037 if not names:
1062 if not names:
1038 raise error.Abort(_("new bookmark name required"))
1063 raise error.Abort(_("new bookmark name required"))
1039 elif len(names) > 1:
1064 elif len(names) > 1:
1040 raise error.Abort(_("only one new bookmark name allowed"))
1065 raise error.Abort(_("only one new bookmark name allowed"))
1041 oldname = repo._bookmarks.expandname(opts['rename'])
1066 oldname = repo._bookmarks.expandname(opts['rename'])
1042 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1067 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1043 elif action == 'add':
1068 elif action == 'add':
1044 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1069 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1045 elif action == 'inactive':
1070 elif action == 'inactive':
1046 if len(repo._bookmarks) == 0:
1071 if len(repo._bookmarks) == 0:
1047 ui.status(_("no bookmarks set\n"))
1072 ui.status(_("no bookmarks set\n"))
1048 elif not repo._activebookmark:
1073 elif not repo._activebookmark:
1049 ui.status(_("no active bookmark\n"))
1074 ui.status(_("no active bookmark\n"))
1050 else:
1075 else:
1051 bookmarks.deactivate(repo)
1076 bookmarks.deactivate(repo)
1052 elif action == 'list':
1077 elif action == 'list':
1053 names = pycompat.maplist(repo._bookmarks.expandname, names)
1078 names = pycompat.maplist(repo._bookmarks.expandname, names)
1054 with ui.formatter('bookmarks', opts) as fm:
1079 with ui.formatter('bookmarks', opts) as fm:
1055 bookmarks.printbookmarks(ui, repo, fm, names)
1080 bookmarks.printbookmarks(ui, repo, fm, names)
1056 else:
1081 else:
1057 raise error.ProgrammingError('invalid action: %s' % action)
1082 raise error.ProgrammingError('invalid action: %s' % action)
1058
1083
1059 @command('branch',
1084 @command('branch',
1060 [('f', 'force', None,
1085 [('f', 'force', None,
1061 _('set branch name even if it shadows an existing branch')),
1086 _('set branch name even if it shadows an existing branch')),
1062 ('C', 'clean', None, _('reset branch name to parent branch name')),
1087 ('C', 'clean', None, _('reset branch name to parent branch name')),
1063 ('r', 'rev', [], _('change branches of the given revs (EXPERIMENTAL)')),
1088 ('r', 'rev', [], _('change branches of the given revs (EXPERIMENTAL)')),
1064 ],
1089 ],
1065 _('[-fC] [NAME]'),
1090 _('[-fC] [NAME]'),
1066 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
1091 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
1067 def branch(ui, repo, label=None, **opts):
1092 def branch(ui, repo, label=None, **opts):
1068 """set or show the current branch name
1093 """set or show the current branch name
1069
1094
1070 .. note::
1095 .. note::
1071
1096
1072 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
1073 light-weight bookmark instead. See :hg:`help glossary` for more
1098 light-weight bookmark instead. See :hg:`help glossary` for more
1074 information about named branches and bookmarks.
1099 information about named branches and bookmarks.
1075
1100
1076 With no argument, show the current branch name. With one argument,
1101 With no argument, show the current branch name. With one argument,
1077 set the working directory branch name (the branch will not exist
1102 set the working directory branch name (the branch will not exist
1078 in the repository until the next commit). Standard practice
1103 in the repository until the next commit). Standard practice
1079 recommends that primary development take place on the 'default'
1104 recommends that primary development take place on the 'default'
1080 branch.
1105 branch.
1081
1106
1082 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
1083 branch name that already exists.
1108 branch name that already exists.
1084
1109
1085 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
1086 the parent of the working directory, negating a previous branch
1111 the parent of the working directory, negating a previous branch
1087 change.
1112 change.
1088
1113
1089 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
1090 :hg:`commit --close-branch` to mark this branch head as closed.
1115 :hg:`commit --close-branch` to mark this branch head as closed.
1091 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
1092 considered closed.
1117 considered closed.
1093
1118
1094 Returns 0 on success.
1119 Returns 0 on success.
1095 """
1120 """
1096 opts = pycompat.byteskwargs(opts)
1121 opts = pycompat.byteskwargs(opts)
1097 revs = opts.get('rev')
1122 revs = opts.get('rev')
1098 if label:
1123 if label:
1099 label = label.strip()
1124 label = label.strip()
1100
1125
1101 if not opts.get('clean') and not label:
1126 if not opts.get('clean') and not label:
1102 if revs:
1127 if revs:
1103 raise error.Abort(_("no branch name specified for the revisions"))
1128 raise error.Abort(_("no branch name specified for the revisions"))
1104 ui.write("%s\n" % repo.dirstate.branch())
1129 ui.write("%s\n" % repo.dirstate.branch())
1105 return
1130 return
1106
1131
1107 with repo.wlock():
1132 with repo.wlock():
1108 if opts.get('clean'):
1133 if opts.get('clean'):
1109 label = repo['.'].branch()
1134 label = repo['.'].branch()
1110 repo.dirstate.setbranch(label)
1135 repo.dirstate.setbranch(label)
1111 ui.status(_('reset working directory to branch %s\n') % label)
1136 ui.status(_('reset working directory to branch %s\n') % label)
1112 elif label:
1137 elif label:
1113
1138
1114 scmutil.checknewlabel(repo, label, 'branch')
1139 scmutil.checknewlabel(repo, label, 'branch')
1115 if revs:
1140 if revs:
1116 return cmdutil.changebranch(ui, repo, revs, label)
1141 return cmdutil.changebranch(ui, repo, revs, label)
1117
1142
1118 if not opts.get('force') and label in repo.branchmap():
1143 if not opts.get('force') and label in repo.branchmap():
1119 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()]:
1120 raise error.Abort(_('a branch of the same name already'
1145 raise error.Abort(_('a branch of the same name already'
1121 ' exists'),
1146 ' exists'),
1122 # i18n: "it" refers to an existing branch
1147 # i18n: "it" refers to an existing branch
1123 hint=_("use 'hg update' to switch to it"))
1148 hint=_("use 'hg update' to switch to it"))
1124
1149
1125 repo.dirstate.setbranch(label)
1150 repo.dirstate.setbranch(label)
1126 ui.status(_('marked working directory as branch %s\n') % label)
1151 ui.status(_('marked working directory as branch %s\n') % label)
1127
1152
1128 # find any open named branches aside from default
1153 # find any open named branches aside from default
1129 for n, h, t, c in repo.branchmap().iterbranches():
1154 for n, h, t, c in repo.branchmap().iterbranches():
1130 if n != "default" and not c:
1155 if n != "default" and not c:
1131 return 0
1156 return 0
1132 ui.status(_('(branches are permanent and global, '
1157 ui.status(_('(branches are permanent and global, '
1133 'did you want a bookmark?)\n'))
1158 'did you want a bookmark?)\n'))
1134
1159
1135 @command('branches',
1160 @command('branches',
1136 [('a', 'active', False,
1161 [('a', 'active', False,
1137 _('show only branches that have unmerged heads (DEPRECATED)')),
1162 _('show only branches that have unmerged heads (DEPRECATED)')),
1138 ('c', 'closed', False, _('show normal and closed branches')),
1163 ('c', 'closed', False, _('show normal and closed branches')),
1139 ('r', 'rev', [], _('show branch name(s) of the given rev'))
1164 ('r', 'rev', [], _('show branch name(s) of the given rev'))
1140 ] + formatteropts,
1165 ] + formatteropts,
1141 _('[-c]'),
1166 _('[-c]'),
1142 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1167 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1143 intents={INTENT_READONLY})
1168 intents={INTENT_READONLY})
1144 def branches(ui, repo, active=False, closed=False, **opts):
1169 def branches(ui, repo, active=False, closed=False, **opts):
1145 """list repository named branches
1170 """list repository named branches
1146
1171
1147 List the repository's named branches, indicating which ones are
1172 List the repository's named branches, indicating which ones are
1148 inactive. If -c/--closed is specified, also list branches which have
1173 inactive. If -c/--closed is specified, also list branches which have
1149 been marked closed (see :hg:`commit --close-branch`).
1174 been marked closed (see :hg:`commit --close-branch`).
1150
1175
1151 Use the command :hg:`update` to switch to an existing branch.
1176 Use the command :hg:`update` to switch to an existing branch.
1152
1177
1153 .. container:: verbose
1178 .. container:: verbose
1154
1179
1155 Template:
1180 Template:
1156
1181
1157 The following keywords are supported in addition to the common template
1182 The following keywords are supported in addition to the common template
1158 keywords and functions such as ``{branch}``. See also
1183 keywords and functions such as ``{branch}``. See also
1159 :hg:`help templates`.
1184 :hg:`help templates`.
1160
1185
1161 :active: Boolean. True if the branch is active.
1186 :active: Boolean. True if the branch is active.
1162 :closed: Boolean. True if the branch is closed.
1187 :closed: Boolean. True if the branch is closed.
1163 :current: Boolean. True if it is the current branch.
1188 :current: Boolean. True if it is the current branch.
1164
1189
1165 Returns 0.
1190 Returns 0.
1166 """
1191 """
1167
1192
1168 opts = pycompat.byteskwargs(opts)
1193 opts = pycompat.byteskwargs(opts)
1169 revs = opts.get('rev')
1194 revs = opts.get('rev')
1170 selectedbranches = None
1195 selectedbranches = None
1171 if revs:
1196 if revs:
1172 revs = scmutil.revrange(repo, revs)
1197 revs = scmutil.revrange(repo, revs)
1173 getbi = repo.revbranchcache().branchinfo
1198 getbi = repo.revbranchcache().branchinfo
1174 selectedbranches = {getbi(r)[0] for r in revs}
1199 selectedbranches = {getbi(r)[0] for r in revs}
1175
1200
1176 ui.pager('branches')
1201 ui.pager('branches')
1177 fm = ui.formatter('branches', opts)
1202 fm = ui.formatter('branches', opts)
1178 hexfunc = fm.hexfunc
1203 hexfunc = fm.hexfunc
1179
1204
1180 allheads = set(repo.heads())
1205 allheads = set(repo.heads())
1181 branches = []
1206 branches = []
1182 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1207 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1183 if selectedbranches is not None and tag not in selectedbranches:
1208 if selectedbranches is not None and tag not in selectedbranches:
1184 continue
1209 continue
1185 isactive = False
1210 isactive = False
1186 if not isclosed:
1211 if not isclosed:
1187 openheads = set(repo.branchmap().iteropen(heads))
1212 openheads = set(repo.branchmap().iteropen(heads))
1188 isactive = bool(openheads & allheads)
1213 isactive = bool(openheads & allheads)
1189 branches.append((tag, repo[tip], isactive, not isclosed))
1214 branches.append((tag, repo[tip], isactive, not isclosed))
1190 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]),
1191 reverse=True)
1216 reverse=True)
1192
1217
1193 for tag, ctx, isactive, isopen in branches:
1218 for tag, ctx, isactive, isopen in branches:
1194 if active and not isactive:
1219 if active and not isactive:
1195 continue
1220 continue
1196 if isactive:
1221 if isactive:
1197 label = 'branches.active'
1222 label = 'branches.active'
1198 notice = ''
1223 notice = ''
1199 elif not isopen:
1224 elif not isopen:
1200 if not closed:
1225 if not closed:
1201 continue
1226 continue
1202 label = 'branches.closed'
1227 label = 'branches.closed'
1203 notice = _(' (closed)')
1228 notice = _(' (closed)')
1204 else:
1229 else:
1205 label = 'branches.inactive'
1230 label = 'branches.inactive'
1206 notice = _(' (inactive)')
1231 notice = _(' (inactive)')
1207 current = (tag == repo.dirstate.branch())
1232 current = (tag == repo.dirstate.branch())
1208 if current:
1233 if current:
1209 label = 'branches.current'
1234 label = 'branches.current'
1210
1235
1211 fm.startitem()
1236 fm.startitem()
1212 fm.write('branch', '%s', tag, label=label)
1237 fm.write('branch', '%s', tag, label=label)
1213 rev = ctx.rev()
1238 rev = ctx.rev()
1214 padsize = max(31 - len("%d" % rev) - encoding.colwidth(tag), 0)
1239 padsize = max(31 - len("%d" % rev) - encoding.colwidth(tag), 0)
1215 fmt = ' ' * padsize + ' %d:%s'
1240 fmt = ' ' * padsize + ' %d:%s'
1216 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()),
1217 label='log.changeset changeset.%s' % ctx.phasestr())
1242 label='log.changeset changeset.%s' % ctx.phasestr())
1218 fm.context(ctx=ctx)
1243 fm.context(ctx=ctx)
1219 fm.data(active=isactive, closed=not isopen, current=current)
1244 fm.data(active=isactive, closed=not isopen, current=current)
1220 if not ui.quiet:
1245 if not ui.quiet:
1221 fm.plain(notice)
1246 fm.plain(notice)
1222 fm.plain('\n')
1247 fm.plain('\n')
1223 fm.end()
1248 fm.end()
1224
1249
1225 @command('bundle',
1250 @command('bundle',
1226 [('f', 'force', None, _('run even when the destination is unrelated')),
1251 [('f', 'force', None, _('run even when the destination is unrelated')),
1227 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1252 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1228 _('REV')),
1253 _('REV')),
1229 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1254 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1230 _('BRANCH')),
1255 _('BRANCH')),
1231 ('', 'base', [],
1256 ('', 'base', [],
1232 _('a base changeset assumed to be available at the destination'),
1257 _('a base changeset assumed to be available at the destination'),
1233 _('REV')),
1258 _('REV')),
1234 ('a', 'all', None, _('bundle all changesets in the repository')),
1259 ('a', 'all', None, _('bundle all changesets in the repository')),
1235 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1260 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1236 ] + remoteopts,
1261 ] + remoteopts,
1237 _('[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1262 _('[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1238 helpcategory=command.CATEGORY_IMPORT_EXPORT)
1263 helpcategory=command.CATEGORY_IMPORT_EXPORT)
1239 def bundle(ui, repo, fname, dest=None, **opts):
1264 def bundle(ui, repo, fname, dest=None, **opts):
1240 """create a bundle file
1265 """create a bundle file
1241
1266
1242 Generate a bundle file containing data to be transferred to another
1267 Generate a bundle file containing data to be transferred to another
1243 repository.
1268 repository.
1244
1269
1245 To create a bundle containing all changesets, use -a/--all
1270 To create a bundle containing all changesets, use -a/--all
1246 (or --base null). Otherwise, hg assumes the destination will have
1271 (or --base null). Otherwise, hg assumes the destination will have
1247 all the nodes you specify with --base parameters. Otherwise, hg
1272 all the nodes you specify with --base parameters. Otherwise, hg
1248 will assume the repository has all the nodes in destination, or
1273 will assume the repository has all the nodes in destination, or
1249 default-push/default if no destination is specified, where destination
1274 default-push/default if no destination is specified, where destination
1250 is the repository you provide through DEST option.
1275 is the repository you provide through DEST option.
1251
1276
1252 You can change bundle format with the -t/--type option. See
1277 You can change bundle format with the -t/--type option. See
1253 :hg:`help bundlespec` for documentation on this format. By default,
1278 :hg:`help bundlespec` for documentation on this format. By default,
1254 the most appropriate format is used and compression defaults to
1279 the most appropriate format is used and compression defaults to
1255 bzip2.
1280 bzip2.
1256
1281
1257 The bundle file can then be transferred using conventional means
1282 The bundle file can then be transferred using conventional means
1258 and applied to another repository with the unbundle or pull
1283 and applied to another repository with the unbundle or pull
1259 command. This is useful when direct push and pull are not
1284 command. This is useful when direct push and pull are not
1260 available or when exporting an entire repository is undesirable.
1285 available or when exporting an entire repository is undesirable.
1261
1286
1262 Applying bundles preserves all changeset contents including
1287 Applying bundles preserves all changeset contents including
1263 permissions, copy/rename information, and revision history.
1288 permissions, copy/rename information, and revision history.
1264
1289
1265 Returns 0 on success, 1 if no changes found.
1290 Returns 0 on success, 1 if no changes found.
1266 """
1291 """
1267 opts = pycompat.byteskwargs(opts)
1292 opts = pycompat.byteskwargs(opts)
1268 revs = None
1293 revs = None
1269 if 'rev' in opts:
1294 if 'rev' in opts:
1270 revstrings = opts['rev']
1295 revstrings = opts['rev']
1271 revs = scmutil.revrange(repo, revstrings)
1296 revs = scmutil.revrange(repo, revstrings)
1272 if revstrings and not revs:
1297 if revstrings and not revs:
1273 raise error.Abort(_('no commits to bundle'))
1298 raise error.Abort(_('no commits to bundle'))
1274
1299
1275 bundletype = opts.get('type', 'bzip2').lower()
1300 bundletype = opts.get('type', 'bzip2').lower()
1276 try:
1301 try:
1277 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
1302 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
1278 except error.UnsupportedBundleSpecification as e:
1303 except error.UnsupportedBundleSpecification as e:
1279 raise error.Abort(pycompat.bytestr(e),
1304 raise error.Abort(pycompat.bytestr(e),
1280 hint=_("see 'hg help bundlespec' for supported "
1305 hint=_("see 'hg help bundlespec' for supported "
1281 "values for --type"))
1306 "values for --type"))
1282 cgversion = bundlespec.contentopts["cg.version"]
1307 cgversion = bundlespec.contentopts["cg.version"]
1283
1308
1284 # Packed bundles are a pseudo bundle format for now.
1309 # Packed bundles are a pseudo bundle format for now.
1285 if cgversion == 's1':
1310 if cgversion == 's1':
1286 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1311 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1287 hint=_("use 'hg debugcreatestreamclonebundle'"))
1312 hint=_("use 'hg debugcreatestreamclonebundle'"))
1288
1313
1289 if opts.get('all'):
1314 if opts.get('all'):
1290 if dest:
1315 if dest:
1291 raise error.Abort(_("--all is incompatible with specifying "
1316 raise error.Abort(_("--all is incompatible with specifying "
1292 "a destination"))
1317 "a destination"))
1293 if opts.get('base'):
1318 if opts.get('base'):
1294 ui.warn(_("ignoring --base because --all was specified\n"))
1319 ui.warn(_("ignoring --base because --all was specified\n"))
1295 base = [nullrev]
1320 base = [nullrev]
1296 else:
1321 else:
1297 base = scmutil.revrange(repo, opts.get('base'))
1322 base = scmutil.revrange(repo, opts.get('base'))
1298 if cgversion not in changegroup.supportedoutgoingversions(repo):
1323 if cgversion not in changegroup.supportedoutgoingversions(repo):
1299 raise error.Abort(_("repository does not support bundle version %s") %
1324 raise error.Abort(_("repository does not support bundle version %s") %
1300 cgversion)
1325 cgversion)
1301
1326
1302 if base:
1327 if base:
1303 if dest:
1328 if dest:
1304 raise error.Abort(_("--base is incompatible with specifying "
1329 raise error.Abort(_("--base is incompatible with specifying "
1305 "a destination"))
1330 "a destination"))
1306 common = [repo[rev].node() for rev in base]
1331 common = [repo[rev].node() for rev in base]
1307 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
1308 outgoing = discovery.outgoing(repo, common, heads)
1333 outgoing = discovery.outgoing(repo, common, heads)
1309 else:
1334 else:
1310 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1335 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1311 dest, branches = hg.parseurl(dest, opts.get('branch'))
1336 dest, branches = hg.parseurl(dest, opts.get('branch'))
1312 other = hg.peer(repo, opts, dest)
1337 other = hg.peer(repo, opts, dest)
1313 revs = [repo[r].hex() for r in revs]
1338 revs = [repo[r].hex() for r in revs]
1314 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1339 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1315 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1340 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1316 outgoing = discovery.findcommonoutgoing(repo, other,
1341 outgoing = discovery.findcommonoutgoing(repo, other,
1317 onlyheads=heads,
1342 onlyheads=heads,
1318 force=opts.get('force'),
1343 force=opts.get('force'),
1319 portable=True)
1344 portable=True)
1320
1345
1321 if not outgoing.missing:
1346 if not outgoing.missing:
1322 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1347 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1323 return 1
1348 return 1
1324
1349
1325 if cgversion == '01': #bundle1
1350 if cgversion == '01': #bundle1
1326 bversion = 'HG10' + bundlespec.wirecompression
1351 bversion = 'HG10' + bundlespec.wirecompression
1327 bcompression = None
1352 bcompression = None
1328 elif cgversion in ('02', '03'):
1353 elif cgversion in ('02', '03'):
1329 bversion = 'HG20'
1354 bversion = 'HG20'
1330 bcompression = bundlespec.wirecompression
1355 bcompression = bundlespec.wirecompression
1331 else:
1356 else:
1332 raise error.ProgrammingError(
1357 raise error.ProgrammingError(
1333 'bundle: unexpected changegroup version %s' % cgversion)
1358 'bundle: unexpected changegroup version %s' % cgversion)
1334
1359
1335 # TODO compression options should be derived from bundlespec parsing.
1360 # TODO compression options should be derived from bundlespec parsing.
1336 # This is a temporary hack to allow adjusting bundle compression
1361 # This is a temporary hack to allow adjusting bundle compression
1337 # level without a) formalizing the bundlespec changes to declare it
1362 # level without a) formalizing the bundlespec changes to declare it
1338 # b) introducing a command flag.
1363 # b) introducing a command flag.
1339 compopts = {}
1364 compopts = {}
1340 complevel = ui.configint('experimental',
1365 complevel = ui.configint('experimental',
1341 'bundlecomplevel.' + bundlespec.compression)
1366 'bundlecomplevel.' + bundlespec.compression)
1342 if complevel is None:
1367 if complevel is None:
1343 complevel = ui.configint('experimental', 'bundlecomplevel')
1368 complevel = ui.configint('experimental', 'bundlecomplevel')
1344 if complevel is not None:
1369 if complevel is not None:
1345 compopts['level'] = complevel
1370 compopts['level'] = complevel
1346
1371
1347 # Allow overriding the bundling of obsmarker in phases through
1372 # Allow overriding the bundling of obsmarker in phases through
1348 # 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
1349 if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'):
1374 if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'):
1350 bundlespec.contentopts['obsolescence'] = True
1375 bundlespec.contentopts['obsolescence'] = True
1351 if repo.ui.configbool('experimental', 'bundle-phases'):
1376 if repo.ui.configbool('experimental', 'bundle-phases'):
1352 bundlespec.contentopts['phases'] = True
1377 bundlespec.contentopts['phases'] = True
1353
1378
1354 bundle2.writenewbundle(ui, repo, 'bundle', fname, bversion, outgoing,
1379 bundle2.writenewbundle(ui, repo, 'bundle', fname, bversion, outgoing,
1355 bundlespec.contentopts, compression=bcompression,
1380 bundlespec.contentopts, compression=bcompression,
1356 compopts=compopts)
1381 compopts=compopts)
1357
1382
1358 @command('cat',
1383 @command('cat',
1359 [('o', 'output', '',
1384 [('o', 'output', '',
1360 _('print output to file with formatted name'), _('FORMAT')),
1385 _('print output to file with formatted name'), _('FORMAT')),
1361 ('r', 'rev', '', _('print the given revision'), _('REV')),
1386 ('r', 'rev', '', _('print the given revision'), _('REV')),
1362 ('', 'decode', None, _('apply any matching decode filter')),
1387 ('', 'decode', None, _('apply any matching decode filter')),
1363 ] + walkopts + formatteropts,
1388 ] + walkopts + formatteropts,
1364 _('[OPTION]... FILE...'),
1389 _('[OPTION]... FILE...'),
1365 helpcategory=command.CATEGORY_FILE_CONTENTS,
1390 helpcategory=command.CATEGORY_FILE_CONTENTS,
1366 inferrepo=True,
1391 inferrepo=True,
1367 intents={INTENT_READONLY})
1392 intents={INTENT_READONLY})
1368 def cat(ui, repo, file1, *pats, **opts):
1393 def cat(ui, repo, file1, *pats, **opts):
1369 """output the current or given revision of files
1394 """output the current or given revision of files
1370
1395
1371 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
1372 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.
1373
1398
1374 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
1375 given using a template string. See :hg:`help templates`. In addition
1400 given using a template string. See :hg:`help templates`. In addition
1376 to the common template keywords, the following formatting rules are
1401 to the common template keywords, the following formatting rules are
1377 supported:
1402 supported:
1378
1403
1379 :``%%``: literal "%" character
1404 :``%%``: literal "%" character
1380 :``%s``: basename of file being printed
1405 :``%s``: basename of file being printed
1381 :``%d``: dirname of file being printed, or '.' if in repository root
1406 :``%d``: dirname of file being printed, or '.' if in repository root
1382 :``%p``: root-relative path name of file being printed
1407 :``%p``: root-relative path name of file being printed
1383 :``%H``: changeset hash (40 hexadecimal digits)
1408 :``%H``: changeset hash (40 hexadecimal digits)
1384 :``%R``: changeset revision number
1409 :``%R``: changeset revision number
1385 :``%h``: short-form changeset hash (12 hexadecimal digits)
1410 :``%h``: short-form changeset hash (12 hexadecimal digits)
1386 :``%r``: zero-padded changeset revision number
1411 :``%r``: zero-padded changeset revision number
1387 :``%b``: basename of the exporting repository
1412 :``%b``: basename of the exporting repository
1388 :``\\``: literal "\\" character
1413 :``\\``: literal "\\" character
1389
1414
1390 .. container:: verbose
1415 .. container:: verbose
1391
1416
1392 Template:
1417 Template:
1393
1418
1394 The following keywords are supported in addition to the common template
1419 The following keywords are supported in addition to the common template
1395 keywords and functions. See also :hg:`help templates`.
1420 keywords and functions. See also :hg:`help templates`.
1396
1421
1397 :data: String. File content.
1422 :data: String. File content.
1398 :path: String. Repository-absolute path of the file.
1423 :path: String. Repository-absolute path of the file.
1399
1424
1400 Returns 0 on success.
1425 Returns 0 on success.
1401 """
1426 """
1402 opts = pycompat.byteskwargs(opts)
1427 opts = pycompat.byteskwargs(opts)
1403 rev = opts.get('rev')
1428 rev = opts.get('rev')
1404 if rev:
1429 if rev:
1405 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
1430 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
1406 ctx = scmutil.revsingle(repo, rev)
1431 ctx = scmutil.revsingle(repo, rev)
1407 m = scmutil.match(ctx, (file1,) + pats, opts)
1432 m = scmutil.match(ctx, (file1,) + pats, opts)
1408 fntemplate = opts.pop('output', '')
1433 fntemplate = opts.pop('output', '')
1409 if cmdutil.isstdiofilename(fntemplate):
1434 if cmdutil.isstdiofilename(fntemplate):
1410 fntemplate = ''
1435 fntemplate = ''
1411
1436
1412 if fntemplate:
1437 if fntemplate:
1413 fm = formatter.nullformatter(ui, 'cat', opts)
1438 fm = formatter.nullformatter(ui, 'cat', opts)
1414 else:
1439 else:
1415 ui.pager('cat')
1440 ui.pager('cat')
1416 fm = ui.formatter('cat', opts)
1441 fm = ui.formatter('cat', opts)
1417 with fm:
1442 with fm:
1418 return cmdutil.cat(ui, repo, ctx, m, fm, fntemplate, '',
1443 return cmdutil.cat(ui, repo, ctx, m, fm, fntemplate, '',
1419 **pycompat.strkwargs(opts))
1444 **pycompat.strkwargs(opts))
1420
1445
1421 @command('clone',
1446 @command('clone',
1422 [('U', 'noupdate', None, _('the clone will include an empty working '
1447 [('U', 'noupdate', None, _('the clone will include an empty working '
1423 'directory (only a repository)')),
1448 'directory (only a repository)')),
1424 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1449 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1425 _('REV')),
1450 _('REV')),
1426 ('r', 'rev', [], _('do not clone everything, but include this changeset'
1451 ('r', 'rev', [], _('do not clone everything, but include this changeset'
1427 ' and its ancestors'), _('REV')),
1452 ' and its ancestors'), _('REV')),
1428 ('b', 'branch', [], _('do not clone everything, but include this branch\'s'
1453 ('b', 'branch', [], _('do not clone everything, but include this branch\'s'
1429 ' changesets and their ancestors'), _('BRANCH')),
1454 ' changesets and their ancestors'), _('BRANCH')),
1430 ('', 'pull', None, _('use pull protocol to copy metadata')),
1455 ('', 'pull', None, _('use pull protocol to copy metadata')),
1431 ('', 'uncompressed', None,
1456 ('', 'uncompressed', None,
1432 _('an alias to --stream (DEPRECATED)')),
1457 _('an alias to --stream (DEPRECATED)')),
1433 ('', 'stream', None,
1458 ('', 'stream', None,
1434 _('clone with minimal data processing')),
1459 _('clone with minimal data processing')),
1435 ] + remoteopts,
1460 ] + remoteopts,
1436 _('[OPTION]... SOURCE [DEST]'),
1461 _('[OPTION]... SOURCE [DEST]'),
1437 helpcategory=command.CATEGORY_REPO_CREATION,
1462 helpcategory=command.CATEGORY_REPO_CREATION,
1438 helpbasic=True, norepo=True)
1463 helpbasic=True, norepo=True)
1439 def clone(ui, source, dest=None, **opts):
1464 def clone(ui, source, dest=None, **opts):
1440 """make a copy of an existing repository
1465 """make a copy of an existing repository
1441
1466
1442 Create a copy of an existing repository in a new directory.
1467 Create a copy of an existing repository in a new directory.
1443
1468
1444 If no destination directory name is specified, it defaults to the
1469 If no destination directory name is specified, it defaults to the
1445 basename of the source.
1470 basename of the source.
1446
1471
1447 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
1448 ``.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.
1449
1474
1450 Only local paths and ``ssh://`` URLs are supported as
1475 Only local paths and ``ssh://`` URLs are supported as
1451 destinations. For ``ssh://`` destinations, no working directory or
1476 destinations. For ``ssh://`` destinations, no working directory or
1452 ``.hg/hgrc`` will be created on the remote side.
1477 ``.hg/hgrc`` will be created on the remote side.
1453
1478
1454 If the source repository has a bookmark called '@' set, that
1479 If the source repository has a bookmark called '@' set, that
1455 revision will be checked out in the new repository by default.
1480 revision will be checked out in the new repository by default.
1456
1481
1457 To check out a particular version, use -u/--update, or
1482 To check out a particular version, use -u/--update, or
1458 -U/--noupdate to create a clone with no working directory.
1483 -U/--noupdate to create a clone with no working directory.
1459
1484
1460 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
1461 identifiers with -r/--rev or branches with -b/--branch. The
1486 identifiers with -r/--rev or branches with -b/--branch. The
1462 resulting clone will contain only the specified changesets and
1487 resulting clone will contain only the specified changesets and
1463 their ancestors. These options (or 'clone src#rev dest') imply
1488 their ancestors. These options (or 'clone src#rev dest') imply
1464 --pull, even for local source repositories.
1489 --pull, even for local source repositories.
1465
1490
1466 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
1467 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
1468 storage format. --stream activates a different clone mode that essentially
1493 storage format. --stream activates a different clone mode that essentially
1469 copies repository files from the remote with minimal data processing. This
1494 copies repository files from the remote with minimal data processing. This
1470 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.
1471 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
1472 result in substantially faster clones where I/O throughput is plentiful,
1497 result in substantially faster clones where I/O throughput is plentiful,
1473 especially for larger repositories. A side-effect of --stream clones is
1498 especially for larger repositories. A side-effect of --stream clones is
1474 that storage settings and requirements on the remote are applied locally:
1499 that storage settings and requirements on the remote are applied locally:
1475 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
1476 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
1477 modern Mercurial remote.
1502 modern Mercurial remote.
1478
1503
1479 .. note::
1504 .. note::
1480
1505
1481 Specifying a tag will include the tagged changeset but not the
1506 Specifying a tag will include the tagged changeset but not the
1482 changeset containing the tag.
1507 changeset containing the tag.
1483
1508
1484 .. container:: verbose
1509 .. container:: verbose
1485
1510
1486 For efficiency, hardlinks are used for cloning whenever the
1511 For efficiency, hardlinks are used for cloning whenever the
1487 source and destination are on the same filesystem (note this
1512 source and destination are on the same filesystem (note this
1488 applies only to the repository data, not to the working
1513 applies only to the repository data, not to the working
1489 directory). Some filesystems, such as AFS, implement hardlinking
1514 directory). Some filesystems, such as AFS, implement hardlinking
1490 incorrectly, but do not report errors. In these cases, use the
1515 incorrectly, but do not report errors. In these cases, use the
1491 --pull option to avoid hardlinking.
1516 --pull option to avoid hardlinking.
1492
1517
1493 Mercurial will update the working directory to the first applicable
1518 Mercurial will update the working directory to the first applicable
1494 revision from this list:
1519 revision from this list:
1495
1520
1496 a) null if -U or the source repository has no changesets
1521 a) null if -U or the source repository has no changesets
1497 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
1498 the source repository's working directory
1523 the source repository's working directory
1499 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
1500 latest head of that branch)
1525 latest head of that branch)
1501 d) the changeset specified with -r
1526 d) the changeset specified with -r
1502 e) the tipmost head specified with -b
1527 e) the tipmost head specified with -b
1503 f) the tipmost head specified with the url#branch source syntax
1528 f) the tipmost head specified with the url#branch source syntax
1504 g) the revision marked with the '@' bookmark, if present
1529 g) the revision marked with the '@' bookmark, if present
1505 h) the tipmost head of the default branch
1530 h) the tipmost head of the default branch
1506 i) tip
1531 i) tip
1507
1532
1508 When cloning from servers that support it, Mercurial may fetch
1533 When cloning from servers that support it, Mercurial may fetch
1509 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
1510 same stream. When this is done, hooks operating on incoming changesets
1535 same stream. When this is done, hooks operating on incoming changesets
1511 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
1512 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,
1513 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
1514 clone. This behavior may change in future releases.
1539 clone. This behavior may change in future releases.
1515 See :hg:`help -e clonebundles` for more.
1540 See :hg:`help -e clonebundles` for more.
1516
1541
1517 Examples:
1542 Examples:
1518
1543
1519 - clone a remote repository to a new directory named hg/::
1544 - clone a remote repository to a new directory named hg/::
1520
1545
1521 hg clone https://www.mercurial-scm.org/repo/hg/
1546 hg clone https://www.mercurial-scm.org/repo/hg/
1522
1547
1523 - create a lightweight local clone::
1548 - create a lightweight local clone::
1524
1549
1525 hg clone project/ project-feature/
1550 hg clone project/ project-feature/
1526
1551
1527 - 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)::
1528
1553
1529 hg clone ssh://user@server//home/projects/alpha/
1554 hg clone ssh://user@server//home/projects/alpha/
1530
1555
1531 - do a streaming clone while checking out a specified version::
1556 - do a streaming clone while checking out a specified version::
1532
1557
1533 hg clone --stream http://server/repo -u 1.5
1558 hg clone --stream http://server/repo -u 1.5
1534
1559
1535 - create a repository without changesets after a particular revision::
1560 - create a repository without changesets after a particular revision::
1536
1561
1537 hg clone -r 04e544 experimental/ good/
1562 hg clone -r 04e544 experimental/ good/
1538
1563
1539 - clone (and track) a particular named branch::
1564 - clone (and track) a particular named branch::
1540
1565
1541 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1566 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1542
1567
1543 See :hg:`help urls` for details on specifying URLs.
1568 See :hg:`help urls` for details on specifying URLs.
1544
1569
1545 Returns 0 on success.
1570 Returns 0 on success.
1546 """
1571 """
1547 opts = pycompat.byteskwargs(opts)
1572 opts = pycompat.byteskwargs(opts)
1548 if opts.get('noupdate') and opts.get('updaterev'):
1573 if opts.get('noupdate') and opts.get('updaterev'):
1549 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1574 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1550
1575
1551 # --include/--exclude can come from narrow or sparse.
1576 # --include/--exclude can come from narrow or sparse.
1552 includepats, excludepats = None, None
1577 includepats, excludepats = None, None
1553
1578
1554 # 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
1555 # patterns are sets if narrow is requested without patterns.
1580 # patterns are sets if narrow is requested without patterns.
1556 if opts.get('narrow'):
1581 if opts.get('narrow'):
1557 includepats = set()
1582 includepats = set()
1558 excludepats = set()
1583 excludepats = set()
1559
1584
1560 if opts.get('include'):
1585 if opts.get('include'):
1561 includepats = narrowspec.parsepatterns(opts.get('include'))
1586 includepats = narrowspec.parsepatterns(opts.get('include'))
1562 if opts.get('exclude'):
1587 if opts.get('exclude'):
1563 excludepats = narrowspec.parsepatterns(opts.get('exclude'))
1588 excludepats = narrowspec.parsepatterns(opts.get('exclude'))
1564
1589
1565 r = hg.clone(ui, opts, source, dest,
1590 r = hg.clone(ui, opts, source, dest,
1566 pull=opts.get('pull'),
1591 pull=opts.get('pull'),
1567 stream=opts.get('stream') or opts.get('uncompressed'),
1592 stream=opts.get('stream') or opts.get('uncompressed'),
1568 revs=opts.get('rev'),
1593 revs=opts.get('rev'),
1569 update=opts.get('updaterev') or not opts.get('noupdate'),
1594 update=opts.get('updaterev') or not opts.get('noupdate'),
1570 branch=opts.get('branch'),
1595 branch=opts.get('branch'),
1571 shareopts=opts.get('shareopts'),
1596 shareopts=opts.get('shareopts'),
1572 storeincludepats=includepats,
1597 storeincludepats=includepats,
1573 storeexcludepats=excludepats,
1598 storeexcludepats=excludepats,
1574 depth=opts.get('depth') or None)
1599 depth=opts.get('depth') or None)
1575
1600
1576 return r is None
1601 return r is None
1577
1602
1578 @command('commit|ci',
1603 @command('commit|ci',
1579 [('A', 'addremove', None,
1604 [('A', 'addremove', None,
1580 _('mark new/missing files as added/removed before committing')),
1605 _('mark new/missing files as added/removed before committing')),
1581 ('', 'close-branch', None,
1606 ('', 'close-branch', None,
1582 _('mark a branch head as closed')),
1607 _('mark a branch head as closed')),
1583 ('', 'amend', None, _('amend the parent of the working directory')),
1608 ('', 'amend', None, _('amend the parent of the working directory')),
1584 ('s', 'secret', None, _('use the secret phase for committing')),
1609 ('s', 'secret', None, _('use the secret phase for committing')),
1585 ('e', 'edit', None, _('invoke editor on commit messages')),
1610 ('e', 'edit', None, _('invoke editor on commit messages')),
1586 ('', 'force-close-branch', None,
1611 ('', 'force-close-branch', None,
1587 _('forcibly close branch from a non-head changeset (ADVANCED)')),
1612 _('forcibly close branch from a non-head changeset (ADVANCED)')),
1588 ('i', 'interactive', None, _('use interactive mode')),
1613 ('i', 'interactive', None, _('use interactive mode')),
1589 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1614 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1590 _('[OPTION]... [FILE]...'),
1615 _('[OPTION]... [FILE]...'),
1591 helpcategory=command.CATEGORY_COMMITTING, helpbasic=True,
1616 helpcategory=command.CATEGORY_COMMITTING, helpbasic=True,
1592 inferrepo=True)
1617 inferrepo=True)
1593 def commit(ui, repo, *pats, **opts):
1618 def commit(ui, repo, *pats, **opts):
1594 """commit the specified files or all outstanding changes
1619 """commit the specified files or all outstanding changes
1595
1620
1596 Commit changes to the given files into the repository. Unlike a
1621 Commit changes to the given files into the repository. Unlike a
1597 centralized SCM, this operation is a local operation. See
1622 centralized SCM, this operation is a local operation. See
1598 :hg:`push` for a way to actively distribute your changes.
1623 :hg:`push` for a way to actively distribute your changes.
1599
1624
1600 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`
1601 will be committed.
1626 will be committed.
1602
1627
1603 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
1604 filenames or -I/-X filters.
1629 filenames or -I/-X filters.
1605
1630
1606 If no commit message is specified, Mercurial starts your
1631 If no commit message is specified, Mercurial starts your
1607 configured editor where you can enter a message. In case your
1632 configured editor where you can enter a message. In case your
1608 commit fails, you will find a backup of your message in
1633 commit fails, you will find a backup of your message in
1609 ``.hg/last-message.txt``.
1634 ``.hg/last-message.txt``.
1610
1635
1611 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
1612 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
1613 will be considered closed and no longer listed.
1638 will be considered closed and no longer listed.
1614
1639
1615 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
1616 working directory with a new commit that contains the changes
1641 working directory with a new commit that contains the changes
1617 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`,
1618 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
1619 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1644 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1620 on how to restore it).
1645 on how to restore it).
1621
1646
1622 Message, user and date are taken from the amended commit unless
1647 Message, user and date are taken from the amended commit unless
1623 specified. When a message isn't specified on the command line,
1648 specified. When a message isn't specified on the command line,
1624 the editor will open with the message of the amended commit.
1649 the editor will open with the message of the amended commit.
1625
1650
1626 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`)
1627 or changesets that have children.
1652 or changesets that have children.
1628
1653
1629 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.
1630
1655
1631 Returns 0 on success, 1 if nothing changed.
1656 Returns 0 on success, 1 if nothing changed.
1632
1657
1633 .. container:: verbose
1658 .. container:: verbose
1634
1659
1635 Examples:
1660 Examples:
1636
1661
1637 - commit all files ending in .py::
1662 - commit all files ending in .py::
1638
1663
1639 hg commit --include "set:**.py"
1664 hg commit --include "set:**.py"
1640
1665
1641 - commit all non-binary files::
1666 - commit all non-binary files::
1642
1667
1643 hg commit --exclude "set:binary()"
1668 hg commit --exclude "set:binary()"
1644
1669
1645 - amend the current commit and set the date to now::
1670 - amend the current commit and set the date to now::
1646
1671
1647 hg commit --amend --date now
1672 hg commit --amend --date now
1648 """
1673 """
1649 with repo.wlock(), repo.lock():
1674 with repo.wlock(), repo.lock():
1650 return _docommit(ui, repo, *pats, **opts)
1675 return _docommit(ui, repo, *pats, **opts)
1651
1676
1652 def _docommit(ui, repo, *pats, **opts):
1677 def _docommit(ui, repo, *pats, **opts):
1653 if opts.get(r'interactive'):
1678 if opts.get(r'interactive'):
1654 opts.pop(r'interactive')
1679 opts.pop(r'interactive')
1655 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1680 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1656 cmdutil.recordfilter, *pats,
1681 cmdutil.recordfilter, *pats,
1657 **opts)
1682 **opts)
1658 # 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
1659 # commit(), 1 if nothing changed or None on success.
1684 # commit(), 1 if nothing changed or None on success.
1660 return 1 if ret == 0 else ret
1685 return 1 if ret == 0 else ret
1661
1686
1662 opts = pycompat.byteskwargs(opts)
1687 opts = pycompat.byteskwargs(opts)
1663 if opts.get('subrepos'):
1688 if opts.get('subrepos'):
1664 if opts.get('amend'):
1689 if opts.get('amend'):
1665 raise error.Abort(_('cannot amend with --subrepos'))
1690 raise error.Abort(_('cannot amend with --subrepos'))
1666 # Let --subrepos on the command line override config setting.
1691 # Let --subrepos on the command line override config setting.
1667 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1692 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1668
1693
1669 cmdutil.checkunfinished(repo, commit=True)
1694 cmdutil.checkunfinished(repo, commit=True)
1670
1695
1671 branch = repo[None].branch()
1696 branch = repo[None].branch()
1672 bheads = repo.branchheads(branch)
1697 bheads = repo.branchheads(branch)
1673
1698
1674 extra = {}
1699 extra = {}
1675 if opts.get('close_branch') or opts.get('force_close_branch'):
1700 if opts.get('close_branch') or opts.get('force_close_branch'):
1676 extra['close'] = '1'
1701 extra['close'] = '1'
1677
1702
1678 if repo['.'].closesbranch():
1703 if repo['.'].closesbranch():
1679 raise error.Abort(_('current revision is already a branch closing'
1704 raise error.Abort(_('current revision is already a branch closing'
1680 ' head'))
1705 ' head'))
1681 elif not bheads:
1706 elif not bheads:
1682 raise error.Abort(_('branch "%s" has no heads to close') % branch)
1707 raise error.Abort(_('branch "%s" has no heads to close') % branch)
1683 elif (branch == repo['.'].branch() and repo['.'].node() not in bheads
1708 elif (branch == repo['.'].branch() and repo['.'].node() not in bheads
1684 and not opts.get('force_close_branch')):
1709 and not opts.get('force_close_branch')):
1685 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'
1686 ' changeset')
1711 ' changeset')
1687 raise error.Abort(_('can only close branch heads'), hint=hint)
1712 raise error.Abort(_('can only close branch heads'), hint=hint)
1688 elif opts.get('amend'):
1713 elif opts.get('amend'):
1689 if (repo['.'].p1().branch() != branch and
1714 if (repo['.'].p1().branch() != branch and
1690 repo['.'].p2().branch() != branch):
1715 repo['.'].p2().branch() != branch):
1691 raise error.Abort(_('can only close branch heads'))
1716 raise error.Abort(_('can only close branch heads'))
1692
1717
1693 if opts.get('amend'):
1718 if opts.get('amend'):
1694 if ui.configbool('ui', 'commitsubrepos'):
1719 if ui.configbool('ui', 'commitsubrepos'):
1695 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1720 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1696
1721
1697 old = repo['.']
1722 old = repo['.']
1698 rewriteutil.precheck(repo, [old.rev()], 'amend')
1723 rewriteutil.precheck(repo, [old.rev()], 'amend')
1699
1724
1700 # Currently histedit gets confused if an amend happens while histedit
1725 # Currently histedit gets confused if an amend happens while histedit
1701 # is in progress. Since we have a checkunfinished command, we are
1726 # is in progress. Since we have a checkunfinished command, we are
1702 # temporarily honoring it.
1727 # temporarily honoring it.
1703 #
1728 #
1704 # Note: eventually this guard will be removed. Please do not expect
1729 # Note: eventually this guard will be removed. Please do not expect
1705 # this behavior to remain.
1730 # this behavior to remain.
1706 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1731 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1707 cmdutil.checkunfinished(repo)
1732 cmdutil.checkunfinished(repo)
1708
1733
1709 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
1734 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
1710 if node == old.node():
1735 if node == old.node():
1711 ui.status(_("nothing changed\n"))
1736 ui.status(_("nothing changed\n"))
1712 return 1
1737 return 1
1713 else:
1738 else:
1714 def commitfunc(ui, repo, message, match, opts):
1739 def commitfunc(ui, repo, message, match, opts):
1715 overrides = {}
1740 overrides = {}
1716 if opts.get('secret'):
1741 if opts.get('secret'):
1717 overrides[('phases', 'new-commit')] = 'secret'
1742 overrides[('phases', 'new-commit')] = 'secret'
1718
1743
1719 baseui = repo.baseui
1744 baseui = repo.baseui
1720 with baseui.configoverride(overrides, 'commit'):
1745 with baseui.configoverride(overrides, 'commit'):
1721 with ui.configoverride(overrides, 'commit'):
1746 with ui.configoverride(overrides, 'commit'):
1722 editform = cmdutil.mergeeditform(repo[None],
1747 editform = cmdutil.mergeeditform(repo[None],
1723 'commit.normal')
1748 'commit.normal')
1724 editor = cmdutil.getcommiteditor(
1749 editor = cmdutil.getcommiteditor(
1725 editform=editform, **pycompat.strkwargs(opts))
1750 editform=editform, **pycompat.strkwargs(opts))
1726 return repo.commit(message,
1751 return repo.commit(message,
1727 opts.get('user'),
1752 opts.get('user'),
1728 opts.get('date'),
1753 opts.get('date'),
1729 match,
1754 match,
1730 editor=editor,
1755 editor=editor,
1731 extra=extra)
1756 extra=extra)
1732
1757
1733 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1758 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1734
1759
1735 if not node:
1760 if not node:
1736 stat = cmdutil.postcommitstatus(repo, pats, opts)
1761 stat = cmdutil.postcommitstatus(repo, pats, opts)
1737 if stat[3]:
1762 if stat[3]:
1738 ui.status(_("nothing changed (%d missing files, see "
1763 ui.status(_("nothing changed (%d missing files, see "
1739 "'hg status')\n") % len(stat[3]))
1764 "'hg status')\n") % len(stat[3]))
1740 else:
1765 else:
1741 ui.status(_("nothing changed\n"))
1766 ui.status(_("nothing changed\n"))
1742 return 1
1767 return 1
1743
1768
1744 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1769 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1745
1770
1746 if not ui.quiet and ui.configbool('commands', 'commit.post-status'):
1771 if not ui.quiet and ui.configbool('commands', 'commit.post-status'):
1747 status(ui, repo, modified=True, added=True, removed=True, deleted=True,
1772 status(ui, repo, modified=True, added=True, removed=True, deleted=True,
1748 unknown=True, subrepos=opts.get('subrepos'))
1773 unknown=True, subrepos=opts.get('subrepos'))
1749
1774
1750 @command('config|showconfig|debugconfig',
1775 @command('config|showconfig|debugconfig',
1751 [('u', 'untrusted', None, _('show untrusted configuration options')),
1776 [('u', 'untrusted', None, _('show untrusted configuration options')),
1752 ('e', 'edit', None, _('edit user config')),
1777 ('e', 'edit', None, _('edit user config')),
1753 ('l', 'local', None, _('edit repository config')),
1778 ('l', 'local', None, _('edit repository config')),
1754 ('g', 'global', None, _('edit global config'))] + formatteropts,
1779 ('g', 'global', None, _('edit global config'))] + formatteropts,
1755 _('[-u] [NAME]...'),
1780 _('[-u] [NAME]...'),
1756 helpcategory=command.CATEGORY_HELP,
1781 helpcategory=command.CATEGORY_HELP,
1757 optionalrepo=True,
1782 optionalrepo=True,
1758 intents={INTENT_READONLY})
1783 intents={INTENT_READONLY})
1759 def config(ui, repo, *values, **opts):
1784 def config(ui, repo, *values, **opts):
1760 """show combined config settings from all hgrc files
1785 """show combined config settings from all hgrc files
1761
1786
1762 With no arguments, print names and values of all config items.
1787 With no arguments, print names and values of all config items.
1763
1788
1764 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
1765 of that config item.
1790 of that config item.
1766
1791
1767 With multiple arguments, print names and values of all config
1792 With multiple arguments, print names and values of all config
1768 items with matching section names or section.names.
1793 items with matching section names or section.names.
1769
1794
1770 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
1771 --global, edit the system-wide config file. With --local, edit the
1796 --global, edit the system-wide config file. With --local, edit the
1772 repository-level config file.
1797 repository-level config file.
1773
1798
1774 With --debug, the source (filename and line number) is printed
1799 With --debug, the source (filename and line number) is printed
1775 for each config item.
1800 for each config item.
1776
1801
1777 See :hg:`help config` for more information about config files.
1802 See :hg:`help config` for more information about config files.
1778
1803
1779 .. container:: verbose
1804 .. container:: verbose
1780
1805
1781 Template:
1806 Template:
1782
1807
1783 The following keywords are supported. See also :hg:`help templates`.
1808 The following keywords are supported. See also :hg:`help templates`.
1784
1809
1785 :name: String. Config name.
1810 :name: String. Config name.
1786 :source: String. Filename and line number where the item is defined.
1811 :source: String. Filename and line number where the item is defined.
1787 :value: String. Config value.
1812 :value: String. Config value.
1788
1813
1789 Returns 0 on success, 1 if NAME does not exist.
1814 Returns 0 on success, 1 if NAME does not exist.
1790
1815
1791 """
1816 """
1792
1817
1793 opts = pycompat.byteskwargs(opts)
1818 opts = pycompat.byteskwargs(opts)
1794 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'):
1795 if opts.get('local') and opts.get('global'):
1820 if opts.get('local') and opts.get('global'):
1796 raise error.Abort(_("can't use --local and --global together"))
1821 raise error.Abort(_("can't use --local and --global together"))
1797
1822
1798 if opts.get('local'):
1823 if opts.get('local'):
1799 if not repo:
1824 if not repo:
1800 raise error.Abort(_("can't use --local outside a repository"))
1825 raise error.Abort(_("can't use --local outside a repository"))
1801 paths = [repo.vfs.join('hgrc')]
1826 paths = [repo.vfs.join('hgrc')]
1802 elif opts.get('global'):
1827 elif opts.get('global'):
1803 paths = rcutil.systemrcpath()
1828 paths = rcutil.systemrcpath()
1804 else:
1829 else:
1805 paths = rcutil.userrcpath()
1830 paths = rcutil.userrcpath()
1806
1831
1807 for f in paths:
1832 for f in paths:
1808 if os.path.exists(f):
1833 if os.path.exists(f):
1809 break
1834 break
1810 else:
1835 else:
1811 if opts.get('global'):
1836 if opts.get('global'):
1812 samplehgrc = uimod.samplehgrcs['global']
1837 samplehgrc = uimod.samplehgrcs['global']
1813 elif opts.get('local'):
1838 elif opts.get('local'):
1814 samplehgrc = uimod.samplehgrcs['local']
1839 samplehgrc = uimod.samplehgrcs['local']
1815 else:
1840 else:
1816 samplehgrc = uimod.samplehgrcs['user']
1841 samplehgrc = uimod.samplehgrcs['user']
1817
1842
1818 f = paths[0]
1843 f = paths[0]
1819 fp = open(f, "wb")
1844 fp = open(f, "wb")
1820 fp.write(util.tonativeeol(samplehgrc))
1845 fp.write(util.tonativeeol(samplehgrc))
1821 fp.close()
1846 fp.close()
1822
1847
1823 editor = ui.geteditor()
1848 editor = ui.geteditor()
1824 ui.system("%s \"%s\"" % (editor, f),
1849 ui.system("%s \"%s\"" % (editor, f),
1825 onerr=error.Abort, errprefix=_("edit failed"),
1850 onerr=error.Abort, errprefix=_("edit failed"),
1826 blockedtag='config_edit')
1851 blockedtag='config_edit')
1827 return
1852 return
1828 ui.pager('config')
1853 ui.pager('config')
1829 fm = ui.formatter('config', opts)
1854 fm = ui.formatter('config', opts)
1830 for t, f in rcutil.rccomponents():
1855 for t, f in rcutil.rccomponents():
1831 if t == 'path':
1856 if t == 'path':
1832 ui.debug('read config from: %s\n' % f)
1857 ui.debug('read config from: %s\n' % f)
1833 elif t == 'items':
1858 elif t == 'items':
1834 for section, name, value, source in f:
1859 for section, name, value, source in f:
1835 ui.debug('set config by: %s\n' % source)
1860 ui.debug('set config by: %s\n' % source)
1836 else:
1861 else:
1837 raise error.ProgrammingError('unknown rctype: %s' % t)
1862 raise error.ProgrammingError('unknown rctype: %s' % t)
1838 untrusted = bool(opts.get('untrusted'))
1863 untrusted = bool(opts.get('untrusted'))
1839
1864
1840 selsections = selentries = []
1865 selsections = selentries = []
1841 if values:
1866 if values:
1842 selsections = [v for v in values if '.' not in v]
1867 selsections = [v for v in values if '.' not in v]
1843 selentries = [v for v in values if '.' in v]
1868 selentries = [v for v in values if '.' in v]
1844 uniquesel = (len(selentries) == 1 and not selsections)
1869 uniquesel = (len(selentries) == 1 and not selsections)
1845 selsections = set(selsections)
1870 selsections = set(selsections)
1846 selentries = set(selentries)
1871 selentries = set(selentries)
1847
1872
1848 matched = False
1873 matched = False
1849 for section, name, value in ui.walkconfig(untrusted=untrusted):
1874 for section, name, value in ui.walkconfig(untrusted=untrusted):
1850 source = ui.configsource(section, name, untrusted)
1875 source = ui.configsource(section, name, untrusted)
1851 value = pycompat.bytestr(value)
1876 value = pycompat.bytestr(value)
1852 if fm.isplain():
1877 if fm.isplain():
1853 source = source or 'none'
1878 source = source or 'none'
1854 value = value.replace('\n', '\\n')
1879 value = value.replace('\n', '\\n')
1855 entryname = section + '.' + name
1880 entryname = section + '.' + name
1856 if values and not (section in selsections or entryname in selentries):
1881 if values and not (section in selsections or entryname in selentries):
1857 continue
1882 continue
1858 fm.startitem()
1883 fm.startitem()
1859 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1884 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1860 if uniquesel:
1885 if uniquesel:
1861 fm.data(name=entryname)
1886 fm.data(name=entryname)
1862 fm.write('value', '%s\n', value)
1887 fm.write('value', '%s\n', value)
1863 else:
1888 else:
1864 fm.write('name value', '%s=%s\n', entryname, value)
1889 fm.write('name value', '%s=%s\n', entryname, value)
1865 matched = True
1890 matched = True
1866 fm.end()
1891 fm.end()
1867 if matched:
1892 if matched:
1868 return 0
1893 return 0
1869 return 1
1894 return 1
1870
1895
1871 @command('copy|cp',
1896 @command('copy|cp',
1872 [('A', 'after', None, _('record a copy that has already occurred')),
1897 [('A', 'after', None, _('record a copy that has already occurred')),
1873 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1898 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1874 ] + walkopts + dryrunopts,
1899 ] + walkopts + dryrunopts,
1875 _('[OPTION]... SOURCE... DEST'),
1900 _('[OPTION]... SOURCE... DEST'),
1876 helpcategory=command.CATEGORY_FILE_CONTENTS)
1901 helpcategory=command.CATEGORY_FILE_CONTENTS)
1877 def copy(ui, repo, *pats, **opts):
1902 def copy(ui, repo, *pats, **opts):
1878 """mark files as copied for the next commit
1903 """mark files as copied for the next commit
1879
1904
1880 Mark dest as having copies of source files. If dest is a
1905 Mark dest as having copies of source files. If dest is a
1881 directory, copies are put in that directory. If dest is a file,
1906 directory, copies are put in that directory. If dest is a file,
1882 the source must be a single file.
1907 the source must be a single file.
1883
1908
1884 By default, this command copies the contents of files as they
1909 By default, this command copies the contents of files as they
1885 exist in the working directory. If invoked with -A/--after, the
1910 exist in the working directory. If invoked with -A/--after, the
1886 operation is recorded, but no copying is performed.
1911 operation is recorded, but no copying is performed.
1887
1912
1888 This command takes effect with the next commit. To undo a copy
1913 This command takes effect with the next commit. To undo a copy
1889 before that, see :hg:`revert`.
1914 before that, see :hg:`revert`.
1890
1915
1891 Returns 0 on success, 1 if errors are encountered.
1916 Returns 0 on success, 1 if errors are encountered.
1892 """
1917 """
1893 opts = pycompat.byteskwargs(opts)
1918 opts = pycompat.byteskwargs(opts)
1894 with repo.wlock(False):
1919 with repo.wlock(False):
1895 return cmdutil.copy(ui, repo, pats, opts)
1920 return cmdutil.copy(ui, repo, pats, opts)
1896
1921
1897 @command(
1922 @command(
1898 'debugcommands', [], _('[COMMAND]'),
1923 'debugcommands', [], _('[COMMAND]'),
1899 helpcategory=command.CATEGORY_HELP,
1924 helpcategory=command.CATEGORY_HELP,
1900 norepo=True)
1925 norepo=True)
1901 def debugcommands(ui, cmd='', *args):
1926 def debugcommands(ui, cmd='', *args):
1902 """list all available commands and options"""
1927 """list all available commands and options"""
1903 for cmd, vals in sorted(table.iteritems()):
1928 for cmd, vals in sorted(table.iteritems()):
1904 cmd = cmd.split('|')[0]
1929 cmd = cmd.split('|')[0]
1905 opts = ', '.join([i[1] for i in vals[1]])
1930 opts = ', '.join([i[1] for i in vals[1]])
1906 ui.write('%s: %s\n' % (cmd, opts))
1931 ui.write('%s: %s\n' % (cmd, opts))
1907
1932
1908 @command('debugcomplete',
1933 @command('debugcomplete',
1909 [('o', 'options', None, _('show the command options'))],
1934 [('o', 'options', None, _('show the command options'))],
1910 _('[-o] CMD'),
1935 _('[-o] CMD'),
1911 helpcategory=command.CATEGORY_HELP,
1936 helpcategory=command.CATEGORY_HELP,
1912 norepo=True)
1937 norepo=True)
1913 def debugcomplete(ui, cmd='', **opts):
1938 def debugcomplete(ui, cmd='', **opts):
1914 """returns the completion list associated with the given command"""
1939 """returns the completion list associated with the given command"""
1915
1940
1916 if opts.get(r'options'):
1941 if opts.get(r'options'):
1917 options = []
1942 options = []
1918 otables = [globalopts]
1943 otables = [globalopts]
1919 if cmd:
1944 if cmd:
1920 aliases, entry = cmdutil.findcmd(cmd, table, False)
1945 aliases, entry = cmdutil.findcmd(cmd, table, False)
1921 otables.append(entry[1])
1946 otables.append(entry[1])
1922 for t in otables:
1947 for t in otables:
1923 for o in t:
1948 for o in t:
1924 if "(DEPRECATED)" in o[3]:
1949 if "(DEPRECATED)" in o[3]:
1925 continue
1950 continue
1926 if o[0]:
1951 if o[0]:
1927 options.append('-%s' % o[0])
1952 options.append('-%s' % o[0])
1928 options.append('--%s' % o[1])
1953 options.append('--%s' % o[1])
1929 ui.write("%s\n" % "\n".join(options))
1954 ui.write("%s\n" % "\n".join(options))
1930 return
1955 return
1931
1956
1932 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
1957 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
1933 if ui.verbose:
1958 if ui.verbose:
1934 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1959 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1935 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1960 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1936
1961
1937 @command('diff',
1962 @command('diff',
1938 [('r', 'rev', [], _('revision'), _('REV')),
1963 [('r', 'rev', [], _('revision'), _('REV')),
1939 ('c', 'change', '', _('change made by revision'), _('REV'))
1964 ('c', 'change', '', _('change made by revision'), _('REV'))
1940 ] + diffopts + diffopts2 + walkopts + subrepoopts,
1965 ] + diffopts + diffopts2 + walkopts + subrepoopts,
1941 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1966 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1942 helpcategory=command.CATEGORY_FILE_CONTENTS,
1967 helpcategory=command.CATEGORY_FILE_CONTENTS,
1943 helpbasic=True, inferrepo=True, intents={INTENT_READONLY})
1968 helpbasic=True, inferrepo=True, intents={INTENT_READONLY})
1944 def diff(ui, repo, *pats, **opts):
1969 def diff(ui, repo, *pats, **opts):
1945 """diff repository (or selected files)
1970 """diff repository (or selected files)
1946
1971
1947 Show differences between revisions for the specified files.
1972 Show differences between revisions for the specified files.
1948
1973
1949 Differences between files are shown using the unified diff format.
1974 Differences between files are shown using the unified diff format.
1950
1975
1951 .. note::
1976 .. note::
1952
1977
1953 :hg:`diff` may generate unexpected results for merges, as it will
1978 :hg:`diff` may generate unexpected results for merges, as it will
1954 default to comparing against the working directory's first
1979 default to comparing against the working directory's first
1955 parent changeset if no revisions are specified.
1980 parent changeset if no revisions are specified.
1956
1981
1957 When two revision arguments are given, then changes are shown
1982 When two revision arguments are given, then changes are shown
1958 between those revisions. If only one revision is specified then
1983 between those revisions. If only one revision is specified then
1959 that revision is compared to the working directory, and, when no
1984 that revision is compared to the working directory, and, when no
1960 revisions are specified, the working directory files are compared
1985 revisions are specified, the working directory files are compared
1961 to its first parent.
1986 to its first parent.
1962
1987
1963 Alternatively you can specify -c/--change with a revision to see
1988 Alternatively you can specify -c/--change with a revision to see
1964 the changes in that changeset relative to its first parent.
1989 the changes in that changeset relative to its first parent.
1965
1990
1966 Without the -a/--text option, diff will avoid generating diffs of
1991 Without the -a/--text option, diff will avoid generating diffs of
1967 files it detects as binary. With -a, diff will generate a diff
1992 files it detects as binary. With -a, diff will generate a diff
1968 anyway, probably with undesirable results.
1993 anyway, probably with undesirable results.
1969
1994
1970 Use the -g/--git option to generate diffs in the git extended diff
1995 Use the -g/--git option to generate diffs in the git extended diff
1971 format. For more information, read :hg:`help diffs`.
1996 format. For more information, read :hg:`help diffs`.
1972
1997
1973 .. container:: verbose
1998 .. container:: verbose
1974
1999
1975 Examples:
2000 Examples:
1976
2001
1977 - compare a file in the current working directory to its parent::
2002 - compare a file in the current working directory to its parent::
1978
2003
1979 hg diff foo.c
2004 hg diff foo.c
1980
2005
1981 - compare two historical versions of a directory, with rename info::
2006 - compare two historical versions of a directory, with rename info::
1982
2007
1983 hg diff --git -r 1.0:1.2 lib/
2008 hg diff --git -r 1.0:1.2 lib/
1984
2009
1985 - get change stats relative to the last change on some date::
2010 - get change stats relative to the last change on some date::
1986
2011
1987 hg diff --stat -r "date('may 2')"
2012 hg diff --stat -r "date('may 2')"
1988
2013
1989 - diff all newly-added files that contain a keyword::
2014 - diff all newly-added files that contain a keyword::
1990
2015
1991 hg diff "set:added() and grep(GNU)"
2016 hg diff "set:added() and grep(GNU)"
1992
2017
1993 - compare a revision and its parents::
2018 - compare a revision and its parents::
1994
2019
1995 hg diff -c 9353 # compare against first parent
2020 hg diff -c 9353 # compare against first parent
1996 hg diff -r 9353^:9353 # same using revset syntax
2021 hg diff -r 9353^:9353 # same using revset syntax
1997 hg diff -r 9353^2:9353 # compare against the second parent
2022 hg diff -r 9353^2:9353 # compare against the second parent
1998
2023
1999 Returns 0 on success.
2024 Returns 0 on success.
2000 """
2025 """
2001
2026
2002 opts = pycompat.byteskwargs(opts)
2027 opts = pycompat.byteskwargs(opts)
2003 revs = opts.get('rev')
2028 revs = opts.get('rev')
2004 change = opts.get('change')
2029 change = opts.get('change')
2005 stat = opts.get('stat')
2030 stat = opts.get('stat')
2006 reverse = opts.get('reverse')
2031 reverse = opts.get('reverse')
2007
2032
2008 if revs and change:
2033 if revs and change:
2009 msg = _('cannot specify --rev and --change at the same time')
2034 msg = _('cannot specify --rev and --change at the same time')
2010 raise error.Abort(msg)
2035 raise error.Abort(msg)
2011 elif change:
2036 elif change:
2012 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
2037 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
2013 ctx2 = scmutil.revsingle(repo, change, None)
2038 ctx2 = scmutil.revsingle(repo, change, None)
2014 ctx1 = ctx2.p1()
2039 ctx1 = ctx2.p1()
2015 else:
2040 else:
2016 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
2041 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
2017 ctx1, ctx2 = scmutil.revpair(repo, revs)
2042 ctx1, ctx2 = scmutil.revpair(repo, revs)
2018 node1, node2 = ctx1.node(), ctx2.node()
2043 node1, node2 = ctx1.node(), ctx2.node()
2019
2044
2020 if reverse:
2045 if reverse:
2021 node1, node2 = node2, node1
2046 node1, node2 = node2, node1
2022
2047
2023 diffopts = patch.diffallopts(ui, opts)
2048 diffopts = patch.diffallopts(ui, opts)
2024 m = scmutil.match(ctx2, pats, opts)
2049 m = scmutil.match(ctx2, pats, opts)
2025 m = repo.narrowmatch(m)
2050 m = repo.narrowmatch(m)
2026 ui.pager('diff')
2051 ui.pager('diff')
2027 logcmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2052 logcmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2028 listsubrepos=opts.get('subrepos'),
2053 listsubrepos=opts.get('subrepos'),
2029 root=opts.get('root'))
2054 root=opts.get('root'))
2030
2055
2031 @command('export',
2056 @command('export',
2032 [('B', 'bookmark', '',
2057 [('B', 'bookmark', '',
2033 _('export changes only reachable by given bookmark'), _('BOOKMARK')),
2058 _('export changes only reachable by given bookmark'), _('BOOKMARK')),
2034 ('o', 'output', '',
2059 ('o', 'output', '',
2035 _('print output to file with formatted name'), _('FORMAT')),
2060 _('print output to file with formatted name'), _('FORMAT')),
2036 ('', 'switch-parent', None, _('diff against the second parent')),
2061 ('', 'switch-parent', None, _('diff against the second parent')),
2037 ('r', 'rev', [], _('revisions to export'), _('REV')),
2062 ('r', 'rev', [], _('revisions to export'), _('REV')),
2038 ] + diffopts + formatteropts,
2063 ] + diffopts + formatteropts,
2039 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2064 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2040 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2065 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2041 helpbasic=True, intents={INTENT_READONLY})
2066 helpbasic=True, intents={INTENT_READONLY})
2042 def export(ui, repo, *changesets, **opts):
2067 def export(ui, repo, *changesets, **opts):
2043 """dump the header and diffs for one or more changesets
2068 """dump the header and diffs for one or more changesets
2044
2069
2045 Print the changeset header and diffs for one or more revisions.
2070 Print the changeset header and diffs for one or more revisions.
2046 If no revision is given, the parent of the working directory is used.
2071 If no revision is given, the parent of the working directory is used.
2047
2072
2048 The information shown in the changeset header is: author, date,
2073 The information shown in the changeset header is: author, date,
2049 branch name (if non-default), changeset hash, parent(s) and commit
2074 branch name (if non-default), changeset hash, parent(s) and commit
2050 comment.
2075 comment.
2051
2076
2052 .. note::
2077 .. note::
2053
2078
2054 :hg:`export` may generate unexpected diff output for merge
2079 :hg:`export` may generate unexpected diff output for merge
2055 changesets, as it will compare the merge changeset against its
2080 changesets, as it will compare the merge changeset against its
2056 first parent only.
2081 first parent only.
2057
2082
2058 Output may be to a file, in which case the name of the file is
2083 Output may be to a file, in which case the name of the file is
2059 given using a template string. See :hg:`help templates`. In addition
2084 given using a template string. See :hg:`help templates`. In addition
2060 to the common template keywords, the following formatting rules are
2085 to the common template keywords, the following formatting rules are
2061 supported:
2086 supported:
2062
2087
2063 :``%%``: literal "%" character
2088 :``%%``: literal "%" character
2064 :``%H``: changeset hash (40 hexadecimal digits)
2089 :``%H``: changeset hash (40 hexadecimal digits)
2065 :``%N``: number of patches being generated
2090 :``%N``: number of patches being generated
2066 :``%R``: changeset revision number
2091 :``%R``: changeset revision number
2067 :``%b``: basename of the exporting repository
2092 :``%b``: basename of the exporting repository
2068 :``%h``: short-form changeset hash (12 hexadecimal digits)
2093 :``%h``: short-form changeset hash (12 hexadecimal digits)
2069 :``%m``: first line of the commit message (only alphanumeric characters)
2094 :``%m``: first line of the commit message (only alphanumeric characters)
2070 :``%n``: zero-padded sequence number, starting at 1
2095 :``%n``: zero-padded sequence number, starting at 1
2071 :``%r``: zero-padded changeset revision number
2096 :``%r``: zero-padded changeset revision number
2072 :``\\``: literal "\\" character
2097 :``\\``: literal "\\" character
2073
2098
2074 Without the -a/--text option, export will avoid generating diffs
2099 Without the -a/--text option, export will avoid generating diffs
2075 of files it detects as binary. With -a, export will generate a
2100 of files it detects as binary. With -a, export will generate a
2076 diff anyway, probably with undesirable results.
2101 diff anyway, probably with undesirable results.
2077
2102
2078 With -B/--bookmark changesets reachable by the given bookmark are
2103 With -B/--bookmark changesets reachable by the given bookmark are
2079 selected.
2104 selected.
2080
2105
2081 Use the -g/--git option to generate diffs in the git extended diff
2106 Use the -g/--git option to generate diffs in the git extended diff
2082 format. See :hg:`help diffs` for more information.
2107 format. See :hg:`help diffs` for more information.
2083
2108
2084 With the --switch-parent option, the diff will be against the
2109 With the --switch-parent option, the diff will be against the
2085 second parent. It can be useful to review a merge.
2110 second parent. It can be useful to review a merge.
2086
2111
2087 .. container:: verbose
2112 .. container:: verbose
2088
2113
2089 Template:
2114 Template:
2090
2115
2091 The following keywords are supported in addition to the common template
2116 The following keywords are supported in addition to the common template
2092 keywords and functions. See also :hg:`help templates`.
2117 keywords and functions. See also :hg:`help templates`.
2093
2118
2094 :diff: String. Diff content.
2119 :diff: String. Diff content.
2095 :parents: List of strings. Parent nodes of the changeset.
2120 :parents: List of strings. Parent nodes of the changeset.
2096
2121
2097 Examples:
2122 Examples:
2098
2123
2099 - use export and import to transplant a bugfix to the current
2124 - use export and import to transplant a bugfix to the current
2100 branch::
2125 branch::
2101
2126
2102 hg export -r 9353 | hg import -
2127 hg export -r 9353 | hg import -
2103
2128
2104 - export all the changesets between two revisions to a file with
2129 - export all the changesets between two revisions to a file with
2105 rename information::
2130 rename information::
2106
2131
2107 hg export --git -r 123:150 > changes.txt
2132 hg export --git -r 123:150 > changes.txt
2108
2133
2109 - split outgoing changes into a series of patches with
2134 - split outgoing changes into a series of patches with
2110 descriptive names::
2135 descriptive names::
2111
2136
2112 hg export -r "outgoing()" -o "%n-%m.patch"
2137 hg export -r "outgoing()" -o "%n-%m.patch"
2113
2138
2114 Returns 0 on success.
2139 Returns 0 on success.
2115 """
2140 """
2116 opts = pycompat.byteskwargs(opts)
2141 opts = pycompat.byteskwargs(opts)
2117 bookmark = opts.get('bookmark')
2142 bookmark = opts.get('bookmark')
2118 changesets += tuple(opts.get('rev', []))
2143 changesets += tuple(opts.get('rev', []))
2119
2144
2120 if bookmark and changesets:
2145 if bookmark and changesets:
2121 raise error.Abort(_("-r and -B are mutually exclusive"))
2146 raise error.Abort(_("-r and -B are mutually exclusive"))
2122
2147
2123 if bookmark:
2148 if bookmark:
2124 if bookmark not in repo._bookmarks:
2149 if bookmark not in repo._bookmarks:
2125 raise error.Abort(_("bookmark '%s' not found") % bookmark)
2150 raise error.Abort(_("bookmark '%s' not found") % bookmark)
2126
2151
2127 revs = scmutil.bookmarkrevs(repo, bookmark)
2152 revs = scmutil.bookmarkrevs(repo, bookmark)
2128 else:
2153 else:
2129 if not changesets:
2154 if not changesets:
2130 changesets = ['.']
2155 changesets = ['.']
2131
2156
2132 repo = scmutil.unhidehashlikerevs(repo, changesets, 'nowarn')
2157 repo = scmutil.unhidehashlikerevs(repo, changesets, 'nowarn')
2133 revs = scmutil.revrange(repo, changesets)
2158 revs = scmutil.revrange(repo, changesets)
2134
2159
2135 if not revs:
2160 if not revs:
2136 raise error.Abort(_("export requires at least one changeset"))
2161 raise error.Abort(_("export requires at least one changeset"))
2137 if len(revs) > 1:
2162 if len(revs) > 1:
2138 ui.note(_('exporting patches:\n'))
2163 ui.note(_('exporting patches:\n'))
2139 else:
2164 else:
2140 ui.note(_('exporting patch:\n'))
2165 ui.note(_('exporting patch:\n'))
2141
2166
2142 fntemplate = opts.get('output')
2167 fntemplate = opts.get('output')
2143 if cmdutil.isstdiofilename(fntemplate):
2168 if cmdutil.isstdiofilename(fntemplate):
2144 fntemplate = ''
2169 fntemplate = ''
2145
2170
2146 if fntemplate:
2171 if fntemplate:
2147 fm = formatter.nullformatter(ui, 'export', opts)
2172 fm = formatter.nullformatter(ui, 'export', opts)
2148 else:
2173 else:
2149 ui.pager('export')
2174 ui.pager('export')
2150 fm = ui.formatter('export', opts)
2175 fm = ui.formatter('export', opts)
2151 with fm:
2176 with fm:
2152 cmdutil.export(repo, revs, fm, fntemplate=fntemplate,
2177 cmdutil.export(repo, revs, fm, fntemplate=fntemplate,
2153 switch_parent=opts.get('switch_parent'),
2178 switch_parent=opts.get('switch_parent'),
2154 opts=patch.diffallopts(ui, opts))
2179 opts=patch.diffallopts(ui, opts))
2155
2180
2156 @command('files',
2181 @command('files',
2157 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2182 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2158 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2183 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2159 ] + walkopts + formatteropts + subrepoopts,
2184 ] + walkopts + formatteropts + subrepoopts,
2160 _('[OPTION]... [FILE]...'),
2185 _('[OPTION]... [FILE]...'),
2161 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2186 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2162 intents={INTENT_READONLY})
2187 intents={INTENT_READONLY})
2163 def files(ui, repo, *pats, **opts):
2188 def files(ui, repo, *pats, **opts):
2164 """list tracked files
2189 """list tracked files
2165
2190
2166 Print files under Mercurial control in the working directory or
2191 Print files under Mercurial control in the working directory or
2167 specified revision for given files (excluding removed files).
2192 specified revision for given files (excluding removed files).
2168 Files can be specified as filenames or filesets.
2193 Files can be specified as filenames or filesets.
2169
2194
2170 If no files are given to match, this command prints the names
2195 If no files are given to match, this command prints the names
2171 of all files under Mercurial control.
2196 of all files under Mercurial control.
2172
2197
2173 .. container:: verbose
2198 .. container:: verbose
2174
2199
2175 Template:
2200 Template:
2176
2201
2177 The following keywords are supported in addition to the common template
2202 The following keywords are supported in addition to the common template
2178 keywords and functions. See also :hg:`help templates`.
2203 keywords and functions. See also :hg:`help templates`.
2179
2204
2180 :flags: String. Character denoting file's symlink and executable bits.
2205 :flags: String. Character denoting file's symlink and executable bits.
2181 :path: String. Repository-absolute path of the file.
2206 :path: String. Repository-absolute path of the file.
2182 :size: Integer. Size of the file in bytes.
2207 :size: Integer. Size of the file in bytes.
2183
2208
2184 Examples:
2209 Examples:
2185
2210
2186 - list all files under the current directory::
2211 - list all files under the current directory::
2187
2212
2188 hg files .
2213 hg files .
2189
2214
2190 - shows sizes and flags for current revision::
2215 - shows sizes and flags for current revision::
2191
2216
2192 hg files -vr .
2217 hg files -vr .
2193
2218
2194 - list all files named README::
2219 - list all files named README::
2195
2220
2196 hg files -I "**/README"
2221 hg files -I "**/README"
2197
2222
2198 - list all binary files::
2223 - list all binary files::
2199
2224
2200 hg files "set:binary()"
2225 hg files "set:binary()"
2201
2226
2202 - find files containing a regular expression::
2227 - find files containing a regular expression::
2203
2228
2204 hg files "set:grep('bob')"
2229 hg files "set:grep('bob')"
2205
2230
2206 - search tracked file contents with xargs and grep::
2231 - search tracked file contents with xargs and grep::
2207
2232
2208 hg files -0 | xargs -0 grep foo
2233 hg files -0 | xargs -0 grep foo
2209
2234
2210 See :hg:`help patterns` and :hg:`help filesets` for more information
2235 See :hg:`help patterns` and :hg:`help filesets` for more information
2211 on specifying file patterns.
2236 on specifying file patterns.
2212
2237
2213 Returns 0 if a match is found, 1 otherwise.
2238 Returns 0 if a match is found, 1 otherwise.
2214
2239
2215 """
2240 """
2216
2241
2217 opts = pycompat.byteskwargs(opts)
2242 opts = pycompat.byteskwargs(opts)
2218 rev = opts.get('rev')
2243 rev = opts.get('rev')
2219 if rev:
2244 if rev:
2220 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
2245 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
2221 ctx = scmutil.revsingle(repo, rev, None)
2246 ctx = scmutil.revsingle(repo, rev, None)
2222
2247
2223 end = '\n'
2248 end = '\n'
2224 if opts.get('print0'):
2249 if opts.get('print0'):
2225 end = '\0'
2250 end = '\0'
2226 fmt = '%s' + end
2251 fmt = '%s' + end
2227
2252
2228 m = scmutil.match(ctx, pats, opts)
2253 m = scmutil.match(ctx, pats, opts)
2229 ui.pager('files')
2254 ui.pager('files')
2230 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2255 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2231 with ui.formatter('files', opts) as fm:
2256 with ui.formatter('files', opts) as fm:
2232 return cmdutil.files(ui, ctx, m, uipathfn, fm, fmt,
2257 return cmdutil.files(ui, ctx, m, uipathfn, fm, fmt,
2233 opts.get('subrepos'))
2258 opts.get('subrepos'))
2234
2259
2235 @command(
2260 @command(
2236 'forget',
2261 'forget',
2237 [('i', 'interactive', None, _('use interactive mode')),
2262 [('i', 'interactive', None, _('use interactive mode')),
2238 ] + walkopts + dryrunopts,
2263 ] + walkopts + dryrunopts,
2239 _('[OPTION]... FILE...'),
2264 _('[OPTION]... FILE...'),
2240 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2265 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2241 helpbasic=True, inferrepo=True)
2266 helpbasic=True, inferrepo=True)
2242 def forget(ui, repo, *pats, **opts):
2267 def forget(ui, repo, *pats, **opts):
2243 """forget the specified files on the next commit
2268 """forget the specified files on the next commit
2244
2269
2245 Mark the specified files so they will no longer be tracked
2270 Mark the specified files so they will no longer be tracked
2246 after the next commit.
2271 after the next commit.
2247
2272
2248 This only removes files from the current branch, not from the
2273 This only removes files from the current branch, not from the
2249 entire project history, and it does not delete them from the
2274 entire project history, and it does not delete them from the
2250 working directory.
2275 working directory.
2251
2276
2252 To delete the file from the working directory, see :hg:`remove`.
2277 To delete the file from the working directory, see :hg:`remove`.
2253
2278
2254 To undo a forget before the next commit, see :hg:`add`.
2279 To undo a forget before the next commit, see :hg:`add`.
2255
2280
2256 .. container:: verbose
2281 .. container:: verbose
2257
2282
2258 Examples:
2283 Examples:
2259
2284
2260 - forget newly-added binary files::
2285 - forget newly-added binary files::
2261
2286
2262 hg forget "set:added() and binary()"
2287 hg forget "set:added() and binary()"
2263
2288
2264 - forget files that would be excluded by .hgignore::
2289 - forget files that would be excluded by .hgignore::
2265
2290
2266 hg forget "set:hgignore()"
2291 hg forget "set:hgignore()"
2267
2292
2268 Returns 0 on success.
2293 Returns 0 on success.
2269 """
2294 """
2270
2295
2271 opts = pycompat.byteskwargs(opts)
2296 opts = pycompat.byteskwargs(opts)
2272 if not pats:
2297 if not pats:
2273 raise error.Abort(_('no files specified'))
2298 raise error.Abort(_('no files specified'))
2274
2299
2275 m = scmutil.match(repo[None], pats, opts)
2300 m = scmutil.match(repo[None], pats, opts)
2276 dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
2301 dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
2277 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2302 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2278 rejected = cmdutil.forget(ui, repo, m, prefix="", uipathfn=uipathfn,
2303 rejected = cmdutil.forget(ui, repo, m, prefix="", uipathfn=uipathfn,
2279 explicitonly=False, dryrun=dryrun,
2304 explicitonly=False, dryrun=dryrun,
2280 interactive=interactive)[0]
2305 interactive=interactive)[0]
2281 return rejected and 1 or 0
2306 return rejected and 1 or 0
2282
2307
2283 @command(
2308 @command(
2284 'graft',
2309 'graft',
2285 [('r', 'rev', [], _('revisions to graft'), _('REV')),
2310 [('r', 'rev', [], _('revisions to graft'), _('REV')),
2286 ('', 'base', '',
2311 ('', 'base', '',
2287 _('base revision when doing the graft merge (ADVANCED)'), _('REV')),
2312 _('base revision when doing the graft merge (ADVANCED)'), _('REV')),
2288 ('c', 'continue', False, _('resume interrupted graft')),
2313 ('c', 'continue', False, _('resume interrupted graft')),
2289 ('', 'stop', False, _('stop interrupted graft')),
2314 ('', 'stop', False, _('stop interrupted graft')),
2290 ('', 'abort', False, _('abort interrupted graft')),
2315 ('', 'abort', False, _('abort interrupted graft')),
2291 ('e', 'edit', False, _('invoke editor on commit messages')),
2316 ('e', 'edit', False, _('invoke editor on commit messages')),
2292 ('', 'log', None, _('append graft info to log message')),
2317 ('', 'log', None, _('append graft info to log message')),
2293 ('', 'no-commit', None,
2318 ('', 'no-commit', None,
2294 _("don't commit, just apply the changes in working directory")),
2319 _("don't commit, just apply the changes in working directory")),
2295 ('f', 'force', False, _('force graft')),
2320 ('f', 'force', False, _('force graft')),
2296 ('D', 'currentdate', False,
2321 ('D', 'currentdate', False,
2297 _('record the current date as commit date')),
2322 _('record the current date as commit date')),
2298 ('U', 'currentuser', False,
2323 ('U', 'currentuser', False,
2299 _('record the current user as committer'))]
2324 _('record the current user as committer'))]
2300 + commitopts2 + mergetoolopts + dryrunopts,
2325 + commitopts2 + mergetoolopts + dryrunopts,
2301 _('[OPTION]... [-r REV]... REV...'),
2326 _('[OPTION]... [-r REV]... REV...'),
2302 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
2327 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
2303 def graft(ui, repo, *revs, **opts):
2328 def graft(ui, repo, *revs, **opts):
2304 '''copy changes from other branches onto the current branch
2329 '''copy changes from other branches onto the current branch
2305
2330
2306 This command uses Mercurial's merge logic to copy individual
2331 This command uses Mercurial's merge logic to copy individual
2307 changes from other branches without merging branches in the
2332 changes from other branches without merging branches in the
2308 history graph. This is sometimes known as 'backporting' or
2333 history graph. This is sometimes known as 'backporting' or
2309 'cherry-picking'. By default, graft will copy user, date, and
2334 'cherry-picking'. By default, graft will copy user, date, and
2310 description from the source changesets.
2335 description from the source changesets.
2311
2336
2312 Changesets that are ancestors of the current revision, that have
2337 Changesets that are ancestors of the current revision, that have
2313 already been grafted, or that are merges will be skipped.
2338 already been grafted, or that are merges will be skipped.
2314
2339
2315 If --log is specified, log messages will have a comment appended
2340 If --log is specified, log messages will have a comment appended
2316 of the form::
2341 of the form::
2317
2342
2318 (grafted from CHANGESETHASH)
2343 (grafted from CHANGESETHASH)
2319
2344
2320 If --force is specified, revisions will be grafted even if they
2345 If --force is specified, revisions will be grafted even if they
2321 are already ancestors of, or have been grafted to, the destination.
2346 are already ancestors of, or have been grafted to, the destination.
2322 This is useful when the revisions have since been backed out.
2347 This is useful when the revisions have since been backed out.
2323
2348
2324 If a graft merge results in conflicts, the graft process is
2349 If a graft merge results in conflicts, the graft process is
2325 interrupted so that the current merge can be manually resolved.
2350 interrupted so that the current merge can be manually resolved.
2326 Once all conflicts are addressed, the graft process can be
2351 Once all conflicts are addressed, the graft process can be
2327 continued with the -c/--continue option.
2352 continued with the -c/--continue option.
2328
2353
2329 The -c/--continue option reapplies all the earlier options.
2354 The -c/--continue option reapplies all the earlier options.
2330
2355
2331 .. container:: verbose
2356 .. container:: verbose
2332
2357
2333 The --base option exposes more of how graft internally uses merge with a
2358 The --base option exposes more of how graft internally uses merge with a
2334 custom base revision. --base can be used to specify another ancestor than
2359 custom base revision. --base can be used to specify another ancestor than
2335 the first and only parent.
2360 the first and only parent.
2336
2361
2337 The command::
2362 The command::
2338
2363
2339 hg graft -r 345 --base 234
2364 hg graft -r 345 --base 234
2340
2365
2341 is thus pretty much the same as::
2366 is thus pretty much the same as::
2342
2367
2343 hg diff -r 234 -r 345 | hg import
2368 hg diff -r 234 -r 345 | hg import
2344
2369
2345 but using merge to resolve conflicts and track moved files.
2370 but using merge to resolve conflicts and track moved files.
2346
2371
2347 The result of a merge can thus be backported as a single commit by
2372 The result of a merge can thus be backported as a single commit by
2348 specifying one of the merge parents as base, and thus effectively
2373 specifying one of the merge parents as base, and thus effectively
2349 grafting the changes from the other side.
2374 grafting the changes from the other side.
2350
2375
2351 It is also possible to collapse multiple changesets and clean up history
2376 It is also possible to collapse multiple changesets and clean up history
2352 by specifying another ancestor as base, much like rebase --collapse
2377 by specifying another ancestor as base, much like rebase --collapse
2353 --keep.
2378 --keep.
2354
2379
2355 The commit message can be tweaked after the fact using commit --amend .
2380 The commit message can be tweaked after the fact using commit --amend .
2356
2381
2357 For using non-ancestors as the base to backout changes, see the backout
2382 For using non-ancestors as the base to backout changes, see the backout
2358 command and the hidden --parent option.
2383 command and the hidden --parent option.
2359
2384
2360 .. container:: verbose
2385 .. container:: verbose
2361
2386
2362 Examples:
2387 Examples:
2363
2388
2364 - copy a single change to the stable branch and edit its description::
2389 - copy a single change to the stable branch and edit its description::
2365
2390
2366 hg update stable
2391 hg update stable
2367 hg graft --edit 9393
2392 hg graft --edit 9393
2368
2393
2369 - graft a range of changesets with one exception, updating dates::
2394 - graft a range of changesets with one exception, updating dates::
2370
2395
2371 hg graft -D "2085::2093 and not 2091"
2396 hg graft -D "2085::2093 and not 2091"
2372
2397
2373 - continue a graft after resolving conflicts::
2398 - continue a graft after resolving conflicts::
2374
2399
2375 hg graft -c
2400 hg graft -c
2376
2401
2377 - show the source of a grafted changeset::
2402 - show the source of a grafted changeset::
2378
2403
2379 hg log --debug -r .
2404 hg log --debug -r .
2380
2405
2381 - show revisions sorted by date::
2406 - show revisions sorted by date::
2382
2407
2383 hg log -r "sort(all(), date)"
2408 hg log -r "sort(all(), date)"
2384
2409
2385 - backport the result of a merge as a single commit::
2410 - backport the result of a merge as a single commit::
2386
2411
2387 hg graft -r 123 --base 123^
2412 hg graft -r 123 --base 123^
2388
2413
2389 - land a feature branch as one changeset::
2414 - land a feature branch as one changeset::
2390
2415
2391 hg up -cr default
2416 hg up -cr default
2392 hg graft -r featureX --base "ancestor('featureX', 'default')"
2417 hg graft -r featureX --base "ancestor('featureX', 'default')"
2393
2418
2394 See :hg:`help revisions` for more about specifying revisions.
2419 See :hg:`help revisions` for more about specifying revisions.
2395
2420
2396 Returns 0 on successful completion.
2421 Returns 0 on successful completion.
2397 '''
2422 '''
2398 with repo.wlock():
2423 with repo.wlock():
2399 return _dograft(ui, repo, *revs, **opts)
2424 return _dograft(ui, repo, *revs, **opts)
2400
2425
2401 def _dograft(ui, repo, *revs, **opts):
2426 def _dograft(ui, repo, *revs, **opts):
2402 opts = pycompat.byteskwargs(opts)
2427 opts = pycompat.byteskwargs(opts)
2403 if revs and opts.get('rev'):
2428 if revs and opts.get('rev'):
2404 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
2429 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
2405 'revision ordering!\n'))
2430 'revision ordering!\n'))
2406
2431
2407 revs = list(revs)
2432 revs = list(revs)
2408 revs.extend(opts.get('rev'))
2433 revs.extend(opts.get('rev'))
2409 basectx = None
2434 basectx = None
2410 if opts.get('base'):
2435 if opts.get('base'):
2411 basectx = scmutil.revsingle(repo, opts['base'], None)
2436 basectx = scmutil.revsingle(repo, opts['base'], None)
2412 # a dict of data to be stored in state file
2437 # a dict of data to be stored in state file
2413 statedata = {}
2438 statedata = {}
2414 # list of new nodes created by ongoing graft
2439 # list of new nodes created by ongoing graft
2415 statedata['newnodes'] = []
2440 statedata['newnodes'] = []
2416
2441
2417 if opts.get('user') and opts.get('currentuser'):
2442 if opts.get('user') and opts.get('currentuser'):
2418 raise error.Abort(_('--user and --currentuser are mutually exclusive'))
2443 raise error.Abort(_('--user and --currentuser are mutually exclusive'))
2419 if opts.get('date') and opts.get('currentdate'):
2444 if opts.get('date') and opts.get('currentdate'):
2420 raise error.Abort(_('--date and --currentdate are mutually exclusive'))
2445 raise error.Abort(_('--date and --currentdate are mutually exclusive'))
2421 if not opts.get('user') and opts.get('currentuser'):
2446 if not opts.get('user') and opts.get('currentuser'):
2422 opts['user'] = ui.username()
2447 opts['user'] = ui.username()
2423 if not opts.get('date') and opts.get('currentdate'):
2448 if not opts.get('date') and opts.get('currentdate'):
2424 opts['date'] = "%d %d" % dateutil.makedate()
2449 opts['date'] = "%d %d" % dateutil.makedate()
2425
2450
2426 editor = cmdutil.getcommiteditor(editform='graft',
2451 editor = cmdutil.getcommiteditor(editform='graft',
2427 **pycompat.strkwargs(opts))
2452 **pycompat.strkwargs(opts))
2428
2453
2429 cont = False
2454 cont = False
2430 if opts.get('no_commit'):
2455 if opts.get('no_commit'):
2431 if opts.get('edit'):
2456 if opts.get('edit'):
2432 raise error.Abort(_("cannot specify --no-commit and "
2457 raise error.Abort(_("cannot specify --no-commit and "
2433 "--edit together"))
2458 "--edit together"))
2434 if opts.get('currentuser'):
2459 if opts.get('currentuser'):
2435 raise error.Abort(_("cannot specify --no-commit and "
2460 raise error.Abort(_("cannot specify --no-commit and "
2436 "--currentuser together"))
2461 "--currentuser together"))
2437 if opts.get('currentdate'):
2462 if opts.get('currentdate'):
2438 raise error.Abort(_("cannot specify --no-commit and "
2463 raise error.Abort(_("cannot specify --no-commit and "
2439 "--currentdate together"))
2464 "--currentdate together"))
2440 if opts.get('log'):
2465 if opts.get('log'):
2441 raise error.Abort(_("cannot specify --no-commit and "
2466 raise error.Abort(_("cannot specify --no-commit and "
2442 "--log together"))
2467 "--log together"))
2443
2468
2444 graftstate = statemod.cmdstate(repo, 'graftstate')
2469 graftstate = statemod.cmdstate(repo, 'graftstate')
2445
2470
2446 if opts.get('stop'):
2471 if opts.get('stop'):
2447 if opts.get('continue'):
2472 if opts.get('continue'):
2448 raise error.Abort(_("cannot use '--continue' and "
2473 raise error.Abort(_("cannot use '--continue' and "
2449 "'--stop' together"))
2474 "'--stop' together"))
2450 if opts.get('abort'):
2475 if opts.get('abort'):
2451 raise error.Abort(_("cannot use '--abort' and '--stop' together"))
2476 raise error.Abort(_("cannot use '--abort' and '--stop' together"))
2452
2477
2453 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2478 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2454 opts.get('date'), opts.get('currentdate'),
2479 opts.get('date'), opts.get('currentdate'),
2455 opts.get('currentuser'), opts.get('rev'))):
2480 opts.get('currentuser'), opts.get('rev'))):
2456 raise error.Abort(_("cannot specify any other flag with '--stop'"))
2481 raise error.Abort(_("cannot specify any other flag with '--stop'"))
2457 return _stopgraft(ui, repo, graftstate)
2482 return _stopgraft(ui, repo, graftstate)
2458 elif opts.get('abort'):
2483 elif opts.get('abort'):
2459 if opts.get('continue'):
2484 if opts.get('continue'):
2460 raise error.Abort(_("cannot use '--continue' and "
2485 raise error.Abort(_("cannot use '--continue' and "
2461 "'--abort' together"))
2486 "'--abort' together"))
2462 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2487 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2463 opts.get('date'), opts.get('currentdate'),
2488 opts.get('date'), opts.get('currentdate'),
2464 opts.get('currentuser'), opts.get('rev'))):
2489 opts.get('currentuser'), opts.get('rev'))):
2465 raise error.Abort(_("cannot specify any other flag with '--abort'"))
2490 raise error.Abort(_("cannot specify any other flag with '--abort'"))
2466
2491
2467 return cmdutil.abortgraft(ui, repo, graftstate)
2492 return cmdutil.abortgraft(ui, repo, graftstate)
2468 elif opts.get('continue'):
2493 elif opts.get('continue'):
2469 cont = True
2494 cont = True
2470 if revs:
2495 if revs:
2471 raise error.Abort(_("can't specify --continue and revisions"))
2496 raise error.Abort(_("can't specify --continue and revisions"))
2472 # read in unfinished revisions
2497 # read in unfinished revisions
2473 if graftstate.exists():
2498 if graftstate.exists():
2474 statedata = cmdutil.readgraftstate(repo, graftstate)
2499 statedata = cmdutil.readgraftstate(repo, graftstate)
2475 if statedata.get('date'):
2500 if statedata.get('date'):
2476 opts['date'] = statedata['date']
2501 opts['date'] = statedata['date']
2477 if statedata.get('user'):
2502 if statedata.get('user'):
2478 opts['user'] = statedata['user']
2503 opts['user'] = statedata['user']
2479 if statedata.get('log'):
2504 if statedata.get('log'):
2480 opts['log'] = True
2505 opts['log'] = True
2481 if statedata.get('no_commit'):
2506 if statedata.get('no_commit'):
2482 opts['no_commit'] = statedata.get('no_commit')
2507 opts['no_commit'] = statedata.get('no_commit')
2483 nodes = statedata['nodes']
2508 nodes = statedata['nodes']
2484 revs = [repo[node].rev() for node in nodes]
2509 revs = [repo[node].rev() for node in nodes]
2485 else:
2510 else:
2486 cmdutil.wrongtooltocontinue(repo, _('graft'))
2511 cmdutil.wrongtooltocontinue(repo, _('graft'))
2487 else:
2512 else:
2488 if not revs:
2513 if not revs:
2489 raise error.Abort(_('no revisions specified'))
2514 raise error.Abort(_('no revisions specified'))
2490 cmdutil.checkunfinished(repo)
2515 cmdutil.checkunfinished(repo)
2491 cmdutil.bailifchanged(repo)
2516 cmdutil.bailifchanged(repo)
2492 revs = scmutil.revrange(repo, revs)
2517 revs = scmutil.revrange(repo, revs)
2493
2518
2494 skipped = set()
2519 skipped = set()
2495 if basectx is None:
2520 if basectx is None:
2496 # check for merges
2521 # check for merges
2497 for rev in repo.revs('%ld and merge()', revs):
2522 for rev in repo.revs('%ld and merge()', revs):
2498 ui.warn(_('skipping ungraftable merge revision %d\n') % rev)
2523 ui.warn(_('skipping ungraftable merge revision %d\n') % rev)
2499 skipped.add(rev)
2524 skipped.add(rev)
2500 revs = [r for r in revs if r not in skipped]
2525 revs = [r for r in revs if r not in skipped]
2501 if not revs:
2526 if not revs:
2502 return -1
2527 return -1
2503 if basectx is not None and len(revs) != 1:
2528 if basectx is not None and len(revs) != 1:
2504 raise error.Abort(_('only one revision allowed with --base '))
2529 raise error.Abort(_('only one revision allowed with --base '))
2505
2530
2506 # Don't check in the --continue case, in effect retaining --force across
2531 # Don't check in the --continue case, in effect retaining --force across
2507 # --continues. That's because without --force, any revisions we decided to
2532 # --continues. That's because without --force, any revisions we decided to
2508 # skip would have been filtered out here, so they wouldn't have made their
2533 # skip would have been filtered out here, so they wouldn't have made their
2509 # way to the graftstate. With --force, any revisions we would have otherwise
2534 # way to the graftstate. With --force, any revisions we would have otherwise
2510 # skipped would not have been filtered out, and if they hadn't been applied
2535 # skipped would not have been filtered out, and if they hadn't been applied
2511 # already, they'd have been in the graftstate.
2536 # already, they'd have been in the graftstate.
2512 if not (cont or opts.get('force')) and basectx is None:
2537 if not (cont or opts.get('force')) and basectx is None:
2513 # check for ancestors of dest branch
2538 # check for ancestors of dest branch
2514 crev = repo['.'].rev()
2539 crev = repo['.'].rev()
2515 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2540 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2516 # XXX make this lazy in the future
2541 # XXX make this lazy in the future
2517 # don't mutate while iterating, create a copy
2542 # don't mutate while iterating, create a copy
2518 for rev in list(revs):
2543 for rev in list(revs):
2519 if rev in ancestors:
2544 if rev in ancestors:
2520 ui.warn(_('skipping ancestor revision %d:%s\n') %
2545 ui.warn(_('skipping ancestor revision %d:%s\n') %
2521 (rev, repo[rev]))
2546 (rev, repo[rev]))
2522 # XXX remove on list is slow
2547 # XXX remove on list is slow
2523 revs.remove(rev)
2548 revs.remove(rev)
2524 if not revs:
2549 if not revs:
2525 return -1
2550 return -1
2526
2551
2527 # analyze revs for earlier grafts
2552 # analyze revs for earlier grafts
2528 ids = {}
2553 ids = {}
2529 for ctx in repo.set("%ld", revs):
2554 for ctx in repo.set("%ld", revs):
2530 ids[ctx.hex()] = ctx.rev()
2555 ids[ctx.hex()] = ctx.rev()
2531 n = ctx.extra().get('source')
2556 n = ctx.extra().get('source')
2532 if n:
2557 if n:
2533 ids[n] = ctx.rev()
2558 ids[n] = ctx.rev()
2534
2559
2535 # check ancestors for earlier grafts
2560 # check ancestors for earlier grafts
2536 ui.debug('scanning for duplicate grafts\n')
2561 ui.debug('scanning for duplicate grafts\n')
2537
2562
2538 # The only changesets we can be sure doesn't contain grafts of any
2563 # The only changesets we can be sure doesn't contain grafts of any
2539 # revs, are the ones that are common ancestors of *all* revs:
2564 # revs, are the ones that are common ancestors of *all* revs:
2540 for rev in repo.revs('only(%d,ancestor(%ld))', crev, revs):
2565 for rev in repo.revs('only(%d,ancestor(%ld))', crev, revs):
2541 ctx = repo[rev]
2566 ctx = repo[rev]
2542 n = ctx.extra().get('source')
2567 n = ctx.extra().get('source')
2543 if n in ids:
2568 if n in ids:
2544 try:
2569 try:
2545 r = repo[n].rev()
2570 r = repo[n].rev()
2546 except error.RepoLookupError:
2571 except error.RepoLookupError:
2547 r = None
2572 r = None
2548 if r in revs:
2573 if r in revs:
2549 ui.warn(_('skipping revision %d:%s '
2574 ui.warn(_('skipping revision %d:%s '
2550 '(already grafted to %d:%s)\n')
2575 '(already grafted to %d:%s)\n')
2551 % (r, repo[r], rev, ctx))
2576 % (r, repo[r], rev, ctx))
2552 revs.remove(r)
2577 revs.remove(r)
2553 elif ids[n] in revs:
2578 elif ids[n] in revs:
2554 if r is None:
2579 if r is None:
2555 ui.warn(_('skipping already grafted revision %d:%s '
2580 ui.warn(_('skipping already grafted revision %d:%s '
2556 '(%d:%s also has unknown origin %s)\n')
2581 '(%d:%s also has unknown origin %s)\n')
2557 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
2582 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
2558 else:
2583 else:
2559 ui.warn(_('skipping already grafted revision %d:%s '
2584 ui.warn(_('skipping already grafted revision %d:%s '
2560 '(%d:%s also has origin %d:%s)\n')
2585 '(%d:%s also has origin %d:%s)\n')
2561 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
2586 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
2562 revs.remove(ids[n])
2587 revs.remove(ids[n])
2563 elif ctx.hex() in ids:
2588 elif ctx.hex() in ids:
2564 r = ids[ctx.hex()]
2589 r = ids[ctx.hex()]
2565 if r in revs:
2590 if r in revs:
2566 ui.warn(_('skipping already grafted revision %d:%s '
2591 ui.warn(_('skipping already grafted revision %d:%s '
2567 '(was grafted from %d:%s)\n') %
2592 '(was grafted from %d:%s)\n') %
2568 (r, repo[r], rev, ctx))
2593 (r, repo[r], rev, ctx))
2569 revs.remove(r)
2594 revs.remove(r)
2570 if not revs:
2595 if not revs:
2571 return -1
2596 return -1
2572
2597
2573 if opts.get('no_commit'):
2598 if opts.get('no_commit'):
2574 statedata['no_commit'] = True
2599 statedata['no_commit'] = True
2575 for pos, ctx in enumerate(repo.set("%ld", revs)):
2600 for pos, ctx in enumerate(repo.set("%ld", revs)):
2576 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
2601 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
2577 ctx.description().split('\n', 1)[0])
2602 ctx.description().split('\n', 1)[0])
2578 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2603 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2579 if names:
2604 if names:
2580 desc += ' (%s)' % ' '.join(names)
2605 desc += ' (%s)' % ' '.join(names)
2581 ui.status(_('grafting %s\n') % desc)
2606 ui.status(_('grafting %s\n') % desc)
2582 if opts.get('dry_run'):
2607 if opts.get('dry_run'):
2583 continue
2608 continue
2584
2609
2585 source = ctx.extra().get('source')
2610 source = ctx.extra().get('source')
2586 extra = {}
2611 extra = {}
2587 if source:
2612 if source:
2588 extra['source'] = source
2613 extra['source'] = source
2589 extra['intermediate-source'] = ctx.hex()
2614 extra['intermediate-source'] = ctx.hex()
2590 else:
2615 else:
2591 extra['source'] = ctx.hex()
2616 extra['source'] = ctx.hex()
2592 user = ctx.user()
2617 user = ctx.user()
2593 if opts.get('user'):
2618 if opts.get('user'):
2594 user = opts['user']
2619 user = opts['user']
2595 statedata['user'] = user
2620 statedata['user'] = user
2596 date = ctx.date()
2621 date = ctx.date()
2597 if opts.get('date'):
2622 if opts.get('date'):
2598 date = opts['date']
2623 date = opts['date']
2599 statedata['date'] = date
2624 statedata['date'] = date
2600 message = ctx.description()
2625 message = ctx.description()
2601 if opts.get('log'):
2626 if opts.get('log'):
2602 message += '\n(grafted from %s)' % ctx.hex()
2627 message += '\n(grafted from %s)' % ctx.hex()
2603 statedata['log'] = True
2628 statedata['log'] = True
2604
2629
2605 # we don't merge the first commit when continuing
2630 # we don't merge the first commit when continuing
2606 if not cont:
2631 if not cont:
2607 # perform the graft merge with p1(rev) as 'ancestor'
2632 # perform the graft merge with p1(rev) as 'ancestor'
2608 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
2633 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
2609 base = ctx.p1() if basectx is None else basectx
2634 base = ctx.p1() if basectx is None else basectx
2610 with ui.configoverride(overrides, 'graft'):
2635 with ui.configoverride(overrides, 'graft'):
2611 stats = mergemod.graft(repo, ctx, base, ['local', 'graft'])
2636 stats = mergemod.graft(repo, ctx, base, ['local', 'graft'])
2612 # report any conflicts
2637 # report any conflicts
2613 if stats.unresolvedcount > 0:
2638 if stats.unresolvedcount > 0:
2614 # write out state for --continue
2639 # write out state for --continue
2615 nodes = [repo[rev].hex() for rev in revs[pos:]]
2640 nodes = [repo[rev].hex() for rev in revs[pos:]]
2616 statedata['nodes'] = nodes
2641 statedata['nodes'] = nodes
2617 stateversion = 1
2642 stateversion = 1
2618 graftstate.save(stateversion, statedata)
2643 graftstate.save(stateversion, statedata)
2619 hint = _("use 'hg resolve' and 'hg graft --continue'")
2644 hint = _("use 'hg resolve' and 'hg graft --continue'")
2620 raise error.Abort(
2645 raise error.Abort(
2621 _("unresolved conflicts, can't continue"),
2646 _("unresolved conflicts, can't continue"),
2622 hint=hint)
2647 hint=hint)
2623 else:
2648 else:
2624 cont = False
2649 cont = False
2625
2650
2626 # commit if --no-commit is false
2651 # commit if --no-commit is false
2627 if not opts.get('no_commit'):
2652 if not opts.get('no_commit'):
2628 node = repo.commit(text=message, user=user, date=date, extra=extra,
2653 node = repo.commit(text=message, user=user, date=date, extra=extra,
2629 editor=editor)
2654 editor=editor)
2630 if node is None:
2655 if node is None:
2631 ui.warn(
2656 ui.warn(
2632 _('note: graft of %d:%s created no changes to commit\n') %
2657 _('note: graft of %d:%s created no changes to commit\n') %
2633 (ctx.rev(), ctx))
2658 (ctx.rev(), ctx))
2634 # checking that newnodes exist because old state files won't have it
2659 # checking that newnodes exist because old state files won't have it
2635 elif statedata.get('newnodes') is not None:
2660 elif statedata.get('newnodes') is not None:
2636 statedata['newnodes'].append(node)
2661 statedata['newnodes'].append(node)
2637
2662
2638 # remove state when we complete successfully
2663 # remove state when we complete successfully
2639 if not opts.get('dry_run'):
2664 if not opts.get('dry_run'):
2640 graftstate.delete()
2665 graftstate.delete()
2641
2666
2642 return 0
2667 return 0
2643
2668
2644 def _stopgraft(ui, repo, graftstate):
2669 def _stopgraft(ui, repo, graftstate):
2645 """stop the interrupted graft"""
2670 """stop the interrupted graft"""
2646 if not graftstate.exists():
2671 if not graftstate.exists():
2647 raise error.Abort(_("no interrupted graft found"))
2672 raise error.Abort(_("no interrupted graft found"))
2648 pctx = repo['.']
2673 pctx = repo['.']
2649 hg.updaterepo(repo, pctx.node(), overwrite=True)
2674 hg.updaterepo(repo, pctx.node(), overwrite=True)
2650 graftstate.delete()
2675 graftstate.delete()
2651 ui.status(_("stopped the interrupted graft\n"))
2676 ui.status(_("stopped the interrupted graft\n"))
2652 ui.status(_("working directory is now at %s\n") % pctx.hex()[:12])
2677 ui.status(_("working directory is now at %s\n") % pctx.hex()[:12])
2653 return 0
2678 return 0
2654
2679
2655 @command('grep',
2680 @command('grep',
2656 [('0', 'print0', None, _('end fields with NUL')),
2681 [('0', 'print0', None, _('end fields with NUL')),
2657 ('', 'all', None, _('print all revisions that match (DEPRECATED) ')),
2682 ('', 'all', None, _('print all revisions that match (DEPRECATED) ')),
2658 ('', 'diff', None, _('print all revisions when the term was introduced '
2683 ('', 'diff', None, _('print all revisions when the term was introduced '
2659 'or removed')),
2684 'or removed')),
2660 ('a', 'text', None, _('treat all files as text')),
2685 ('a', 'text', None, _('treat all files as text')),
2661 ('f', 'follow', None,
2686 ('f', 'follow', None,
2662 _('follow changeset history,'
2687 _('follow changeset history,'
2663 ' or file history across copies and renames')),
2688 ' or file history across copies and renames')),
2664 ('i', 'ignore-case', None, _('ignore case when matching')),
2689 ('i', 'ignore-case', None, _('ignore case when matching')),
2665 ('l', 'files-with-matches', None,
2690 ('l', 'files-with-matches', None,
2666 _('print only filenames and revisions that match')),
2691 _('print only filenames and revisions that match')),
2667 ('n', 'line-number', None, _('print matching line numbers')),
2692 ('n', 'line-number', None, _('print matching line numbers')),
2668 ('r', 'rev', [],
2693 ('r', 'rev', [],
2669 _('only search files changed within revision range'), _('REV')),
2694 _('only search files changed within revision range'), _('REV')),
2670 ('', 'all-files', None,
2695 ('', 'all-files', None,
2671 _('include all files in the changeset while grepping (EXPERIMENTAL)')),
2696 _('include all files in the changeset while grepping (EXPERIMENTAL)')),
2672 ('u', 'user', None, _('list the author (long with -v)')),
2697 ('u', 'user', None, _('list the author (long with -v)')),
2673 ('d', 'date', None, _('list the date (short with -q)')),
2698 ('d', 'date', None, _('list the date (short with -q)')),
2674 ] + formatteropts + walkopts,
2699 ] + formatteropts + walkopts,
2675 _('[OPTION]... PATTERN [FILE]...'),
2700 _('[OPTION]... PATTERN [FILE]...'),
2676 helpcategory=command.CATEGORY_FILE_CONTENTS,
2701 helpcategory=command.CATEGORY_FILE_CONTENTS,
2677 inferrepo=True,
2702 inferrepo=True,
2678 intents={INTENT_READONLY})
2703 intents={INTENT_READONLY})
2679 def grep(ui, repo, pattern, *pats, **opts):
2704 def grep(ui, repo, pattern, *pats, **opts):
2680 """search revision history for a pattern in specified files
2705 """search revision history for a pattern in specified files
2681
2706
2682 Search revision history for a regular expression in the specified
2707 Search revision history for a regular expression in the specified
2683 files or the entire project.
2708 files or the entire project.
2684
2709
2685 By default, grep prints the most recent revision number for each
2710 By default, grep prints the most recent revision number for each
2686 file in which it finds a match. To get it to print every revision
2711 file in which it finds a match. To get it to print every revision
2687 that contains a change in match status ("-" for a match that becomes
2712 that contains a change in match status ("-" for a match that becomes
2688 a non-match, or "+" for a non-match that becomes a match), use the
2713 a non-match, or "+" for a non-match that becomes a match), use the
2689 --diff flag.
2714 --diff flag.
2690
2715
2691 PATTERN can be any Python (roughly Perl-compatible) regular
2716 PATTERN can be any Python (roughly Perl-compatible) regular
2692 expression.
2717 expression.
2693
2718
2694 If no FILEs are specified (and -f/--follow isn't set), all files in
2719 If no FILEs are specified (and -f/--follow isn't set), all files in
2695 the repository are searched, including those that don't exist in the
2720 the repository are searched, including those that don't exist in the
2696 current branch or have been deleted in a prior changeset.
2721 current branch or have been deleted in a prior changeset.
2697
2722
2698 .. container:: verbose
2723 .. container:: verbose
2699
2724
2700 Template:
2725 Template:
2701
2726
2702 The following keywords are supported in addition to the common template
2727 The following keywords are supported in addition to the common template
2703 keywords and functions. See also :hg:`help templates`.
2728 keywords and functions. See also :hg:`help templates`.
2704
2729
2705 :change: String. Character denoting insertion ``+`` or removal ``-``.
2730 :change: String. Character denoting insertion ``+`` or removal ``-``.
2706 Available if ``--diff`` is specified.
2731 Available if ``--diff`` is specified.
2707 :lineno: Integer. Line number of the match.
2732 :lineno: Integer. Line number of the match.
2708 :path: String. Repository-absolute path of the file.
2733 :path: String. Repository-absolute path of the file.
2709 :texts: List of text chunks.
2734 :texts: List of text chunks.
2710
2735
2711 And each entry of ``{texts}`` provides the following sub-keywords.
2736 And each entry of ``{texts}`` provides the following sub-keywords.
2712
2737
2713 :matched: Boolean. True if the chunk matches the specified pattern.
2738 :matched: Boolean. True if the chunk matches the specified pattern.
2714 :text: String. Chunk content.
2739 :text: String. Chunk content.
2715
2740
2716 See :hg:`help templates.operators` for the list expansion syntax.
2741 See :hg:`help templates.operators` for the list expansion syntax.
2717
2742
2718 Returns 0 if a match is found, 1 otherwise.
2743 Returns 0 if a match is found, 1 otherwise.
2719 """
2744 """
2720 opts = pycompat.byteskwargs(opts)
2745 opts = pycompat.byteskwargs(opts)
2721 diff = opts.get('all') or opts.get('diff')
2746 diff = opts.get('all') or opts.get('diff')
2722 all_files = opts.get('all_files')
2747 all_files = opts.get('all_files')
2723 if diff and opts.get('all_files'):
2748 if diff and opts.get('all_files'):
2724 raise error.Abort(_('--diff and --all-files are mutually exclusive'))
2749 raise error.Abort(_('--diff and --all-files are mutually exclusive'))
2725 # TODO: remove "not opts.get('rev')" if --all-files -rMULTIREV gets working
2750 # TODO: remove "not opts.get('rev')" if --all-files -rMULTIREV gets working
2726 if opts.get('all_files') is None and not opts.get('rev') and not diff:
2751 if opts.get('all_files') is None and not opts.get('rev') and not diff:
2727 # experimental config: commands.grep.all-files
2752 # experimental config: commands.grep.all-files
2728 opts['all_files'] = ui.configbool('commands', 'grep.all-files')
2753 opts['all_files'] = ui.configbool('commands', 'grep.all-files')
2729 plaingrep = opts.get('all_files') and not opts.get('rev')
2754 plaingrep = opts.get('all_files') and not opts.get('rev')
2730 if plaingrep:
2755 if plaingrep:
2731 opts['rev'] = ['wdir()']
2756 opts['rev'] = ['wdir()']
2732
2757
2733 reflags = re.M
2758 reflags = re.M
2734 if opts.get('ignore_case'):
2759 if opts.get('ignore_case'):
2735 reflags |= re.I
2760 reflags |= re.I
2736 try:
2761 try:
2737 regexp = util.re.compile(pattern, reflags)
2762 regexp = util.re.compile(pattern, reflags)
2738 except re.error as inst:
2763 except re.error as inst:
2739 ui.warn(_("grep: invalid match pattern: %s\n") % pycompat.bytestr(inst))
2764 ui.warn(_("grep: invalid match pattern: %s\n") % pycompat.bytestr(inst))
2740 return 1
2765 return 1
2741 sep, eol = ':', '\n'
2766 sep, eol = ':', '\n'
2742 if opts.get('print0'):
2767 if opts.get('print0'):
2743 sep = eol = '\0'
2768 sep = eol = '\0'
2744
2769
2745 getfile = util.lrucachefunc(repo.file)
2770 getfile = util.lrucachefunc(repo.file)
2746
2771
2747 def matchlines(body):
2772 def matchlines(body):
2748 begin = 0
2773 begin = 0
2749 linenum = 0
2774 linenum = 0
2750 while begin < len(body):
2775 while begin < len(body):
2751 match = regexp.search(body, begin)
2776 match = regexp.search(body, begin)
2752 if not match:
2777 if not match:
2753 break
2778 break
2754 mstart, mend = match.span()
2779 mstart, mend = match.span()
2755 linenum += body.count('\n', begin, mstart) + 1
2780 linenum += body.count('\n', begin, mstart) + 1
2756 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2781 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2757 begin = body.find('\n', mend) + 1 or len(body) + 1
2782 begin = body.find('\n', mend) + 1 or len(body) + 1
2758 lend = begin - 1
2783 lend = begin - 1
2759 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2784 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2760
2785
2761 class linestate(object):
2786 class linestate(object):
2762 def __init__(self, line, linenum, colstart, colend):
2787 def __init__(self, line, linenum, colstart, colend):
2763 self.line = line
2788 self.line = line
2764 self.linenum = linenum
2789 self.linenum = linenum
2765 self.colstart = colstart
2790 self.colstart = colstart
2766 self.colend = colend
2791 self.colend = colend
2767
2792
2768 def __hash__(self):
2793 def __hash__(self):
2769 return hash((self.linenum, self.line))
2794 return hash((self.linenum, self.line))
2770
2795
2771 def __eq__(self, other):
2796 def __eq__(self, other):
2772 return self.line == other.line
2797 return self.line == other.line
2773
2798
2774 def findpos(self):
2799 def findpos(self):
2775 """Iterate all (start, end) indices of matches"""
2800 """Iterate all (start, end) indices of matches"""
2776 yield self.colstart, self.colend
2801 yield self.colstart, self.colend
2777 p = self.colend
2802 p = self.colend
2778 while p < len(self.line):
2803 while p < len(self.line):
2779 m = regexp.search(self.line, p)
2804 m = regexp.search(self.line, p)
2780 if not m:
2805 if not m:
2781 break
2806 break
2782 yield m.span()
2807 yield m.span()
2783 p = m.end()
2808 p = m.end()
2784
2809
2785 matches = {}
2810 matches = {}
2786 copies = {}
2811 copies = {}
2787 def grepbody(fn, rev, body):
2812 def grepbody(fn, rev, body):
2788 matches[rev].setdefault(fn, [])
2813 matches[rev].setdefault(fn, [])
2789 m = matches[rev][fn]
2814 m = matches[rev][fn]
2790 for lnum, cstart, cend, line in matchlines(body):
2815 for lnum, cstart, cend, line in matchlines(body):
2791 s = linestate(line, lnum, cstart, cend)
2816 s = linestate(line, lnum, cstart, cend)
2792 m.append(s)
2817 m.append(s)
2793
2818
2794 def difflinestates(a, b):
2819 def difflinestates(a, b):
2795 sm = difflib.SequenceMatcher(None, a, b)
2820 sm = difflib.SequenceMatcher(None, a, b)
2796 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2821 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2797 if tag == r'insert':
2822 if tag == r'insert':
2798 for i in pycompat.xrange(blo, bhi):
2823 for i in pycompat.xrange(blo, bhi):
2799 yield ('+', b[i])
2824 yield ('+', b[i])
2800 elif tag == r'delete':
2825 elif tag == r'delete':
2801 for i in pycompat.xrange(alo, ahi):
2826 for i in pycompat.xrange(alo, ahi):
2802 yield ('-', a[i])
2827 yield ('-', a[i])
2803 elif tag == r'replace':
2828 elif tag == r'replace':
2804 for i in pycompat.xrange(alo, ahi):
2829 for i in pycompat.xrange(alo, ahi):
2805 yield ('-', a[i])
2830 yield ('-', a[i])
2806 for i in pycompat.xrange(blo, bhi):
2831 for i in pycompat.xrange(blo, bhi):
2807 yield ('+', b[i])
2832 yield ('+', b[i])
2808
2833
2809 uipathfn = scmutil.getuipathfn(repo)
2834 uipathfn = scmutil.getuipathfn(repo)
2810 def display(fm, fn, ctx, pstates, states):
2835 def display(fm, fn, ctx, pstates, states):
2811 rev = scmutil.intrev(ctx)
2836 rev = scmutil.intrev(ctx)
2812 if fm.isplain():
2837 if fm.isplain():
2813 formatuser = ui.shortuser
2838 formatuser = ui.shortuser
2814 else:
2839 else:
2815 formatuser = pycompat.bytestr
2840 formatuser = pycompat.bytestr
2816 if ui.quiet:
2841 if ui.quiet:
2817 datefmt = '%Y-%m-%d'
2842 datefmt = '%Y-%m-%d'
2818 else:
2843 else:
2819 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2844 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2820 found = False
2845 found = False
2821 @util.cachefunc
2846 @util.cachefunc
2822 def binary():
2847 def binary():
2823 flog = getfile(fn)
2848 flog = getfile(fn)
2824 try:
2849 try:
2825 return stringutil.binary(flog.read(ctx.filenode(fn)))
2850 return stringutil.binary(flog.read(ctx.filenode(fn)))
2826 except error.WdirUnsupported:
2851 except error.WdirUnsupported:
2827 return ctx[fn].isbinary()
2852 return ctx[fn].isbinary()
2828
2853
2829 fieldnamemap = {'linenumber': 'lineno'}
2854 fieldnamemap = {'linenumber': 'lineno'}
2830 if diff:
2855 if diff:
2831 iter = difflinestates(pstates, states)
2856 iter = difflinestates(pstates, states)
2832 else:
2857 else:
2833 iter = [('', l) for l in states]
2858 iter = [('', l) for l in states]
2834 for change, l in iter:
2859 for change, l in iter:
2835 fm.startitem()
2860 fm.startitem()
2836 fm.context(ctx=ctx)
2861 fm.context(ctx=ctx)
2837 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
2862 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
2838 fm.plain(uipathfn(fn), label='grep.filename')
2863 fm.plain(uipathfn(fn), label='grep.filename')
2839
2864
2840 cols = [
2865 cols = [
2841 ('rev', '%d', rev, not plaingrep, ''),
2866 ('rev', '%d', rev, not plaingrep, ''),
2842 ('linenumber', '%d', l.linenum, opts.get('line_number'), ''),
2867 ('linenumber', '%d', l.linenum, opts.get('line_number'), ''),
2843 ]
2868 ]
2844 if diff:
2869 if diff:
2845 cols.append(
2870 cols.append(
2846 ('change', '%s', change, True,
2871 ('change', '%s', change, True,
2847 'grep.inserted ' if change == '+' else 'grep.deleted ')
2872 'grep.inserted ' if change == '+' else 'grep.deleted ')
2848 )
2873 )
2849 cols.extend([
2874 cols.extend([
2850 ('user', '%s', formatuser(ctx.user()), opts.get('user'), ''),
2875 ('user', '%s', formatuser(ctx.user()), opts.get('user'), ''),
2851 ('date', '%s', fm.formatdate(ctx.date(), datefmt),
2876 ('date', '%s', fm.formatdate(ctx.date(), datefmt),
2852 opts.get('date'), ''),
2877 opts.get('date'), ''),
2853 ])
2878 ])
2854 for name, fmt, data, cond, extra_label in cols:
2879 for name, fmt, data, cond, extra_label in cols:
2855 if cond:
2880 if cond:
2856 fm.plain(sep, label='grep.sep')
2881 fm.plain(sep, label='grep.sep')
2857 field = fieldnamemap.get(name, name)
2882 field = fieldnamemap.get(name, name)
2858 label = extra_label + ('grep.%s' % name)
2883 label = extra_label + ('grep.%s' % name)
2859 fm.condwrite(cond, field, fmt, data, label=label)
2884 fm.condwrite(cond, field, fmt, data, label=label)
2860 if not opts.get('files_with_matches'):
2885 if not opts.get('files_with_matches'):
2861 fm.plain(sep, label='grep.sep')
2886 fm.plain(sep, label='grep.sep')
2862 if not opts.get('text') and binary():
2887 if not opts.get('text') and binary():
2863 fm.plain(_(" Binary file matches"))
2888 fm.plain(_(" Binary file matches"))
2864 else:
2889 else:
2865 displaymatches(fm.nested('texts', tmpl='{text}'), l)
2890 displaymatches(fm.nested('texts', tmpl='{text}'), l)
2866 fm.plain(eol)
2891 fm.plain(eol)
2867 found = True
2892 found = True
2868 if opts.get('files_with_matches'):
2893 if opts.get('files_with_matches'):
2869 break
2894 break
2870 return found
2895 return found
2871
2896
2872 def displaymatches(fm, l):
2897 def displaymatches(fm, l):
2873 p = 0
2898 p = 0
2874 for s, e in l.findpos():
2899 for s, e in l.findpos():
2875 if p < s:
2900 if p < s:
2876 fm.startitem()
2901 fm.startitem()
2877 fm.write('text', '%s', l.line[p:s])
2902 fm.write('text', '%s', l.line[p:s])
2878 fm.data(matched=False)
2903 fm.data(matched=False)
2879 fm.startitem()
2904 fm.startitem()
2880 fm.write('text', '%s', l.line[s:e], label='grep.match')
2905 fm.write('text', '%s', l.line[s:e], label='grep.match')
2881 fm.data(matched=True)
2906 fm.data(matched=True)
2882 p = e
2907 p = e
2883 if p < len(l.line):
2908 if p < len(l.line):
2884 fm.startitem()
2909 fm.startitem()
2885 fm.write('text', '%s', l.line[p:])
2910 fm.write('text', '%s', l.line[p:])
2886 fm.data(matched=False)
2911 fm.data(matched=False)
2887 fm.end()
2912 fm.end()
2888
2913
2889 skip = set()
2914 skip = set()
2890 revfiles = {}
2915 revfiles = {}
2891 match = scmutil.match(repo[None], pats, opts)
2916 match = scmutil.match(repo[None], pats, opts)
2892 found = False
2917 found = False
2893 follow = opts.get('follow')
2918 follow = opts.get('follow')
2894
2919
2895 getrenamed = scmutil.getrenamedfn(repo)
2920 getrenamed = scmutil.getrenamedfn(repo)
2896 def prep(ctx, fns):
2921 def prep(ctx, fns):
2897 rev = ctx.rev()
2922 rev = ctx.rev()
2898 pctx = ctx.p1()
2923 pctx = ctx.p1()
2899 parent = pctx.rev()
2924 parent = pctx.rev()
2900 matches.setdefault(rev, {})
2925 matches.setdefault(rev, {})
2901 matches.setdefault(parent, {})
2926 matches.setdefault(parent, {})
2902 files = revfiles.setdefault(rev, [])
2927 files = revfiles.setdefault(rev, [])
2903 for fn in fns:
2928 for fn in fns:
2904 flog = getfile(fn)
2929 flog = getfile(fn)
2905 try:
2930 try:
2906 fnode = ctx.filenode(fn)
2931 fnode = ctx.filenode(fn)
2907 except error.LookupError:
2932 except error.LookupError:
2908 continue
2933 continue
2909
2934
2910 copy = None
2935 copy = None
2911 if follow:
2936 if follow:
2912 copy = getrenamed(fn, rev)
2937 copy = getrenamed(fn, rev)
2913 if copy:
2938 if copy:
2914 copies.setdefault(rev, {})[fn] = copy
2939 copies.setdefault(rev, {})[fn] = copy
2915 if fn in skip:
2940 if fn in skip:
2916 skip.add(copy)
2941 skip.add(copy)
2917 if fn in skip:
2942 if fn in skip:
2918 continue
2943 continue
2919 files.append(fn)
2944 files.append(fn)
2920
2945
2921 if fn not in matches[rev]:
2946 if fn not in matches[rev]:
2922 try:
2947 try:
2923 content = flog.read(fnode)
2948 content = flog.read(fnode)
2924 except error.WdirUnsupported:
2949 except error.WdirUnsupported:
2925 content = ctx[fn].data()
2950 content = ctx[fn].data()
2926 grepbody(fn, rev, content)
2951 grepbody(fn, rev, content)
2927
2952
2928 pfn = copy or fn
2953 pfn = copy or fn
2929 if pfn not in matches[parent]:
2954 if pfn not in matches[parent]:
2930 try:
2955 try:
2931 fnode = pctx.filenode(pfn)
2956 fnode = pctx.filenode(pfn)
2932 grepbody(pfn, parent, flog.read(fnode))
2957 grepbody(pfn, parent, flog.read(fnode))
2933 except error.LookupError:
2958 except error.LookupError:
2934 pass
2959 pass
2935
2960
2936 ui.pager('grep')
2961 ui.pager('grep')
2937 fm = ui.formatter('grep', opts)
2962 fm = ui.formatter('grep', opts)
2938 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
2963 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
2939 rev = ctx.rev()
2964 rev = ctx.rev()
2940 parent = ctx.p1().rev()
2965 parent = ctx.p1().rev()
2941 for fn in sorted(revfiles.get(rev, [])):
2966 for fn in sorted(revfiles.get(rev, [])):
2942 states = matches[rev][fn]
2967 states = matches[rev][fn]
2943 copy = copies.get(rev, {}).get(fn)
2968 copy = copies.get(rev, {}).get(fn)
2944 if fn in skip:
2969 if fn in skip:
2945 if copy:
2970 if copy:
2946 skip.add(copy)
2971 skip.add(copy)
2947 continue
2972 continue
2948 pstates = matches.get(parent, {}).get(copy or fn, [])
2973 pstates = matches.get(parent, {}).get(copy or fn, [])
2949 if pstates or states:
2974 if pstates or states:
2950 r = display(fm, fn, ctx, pstates, states)
2975 r = display(fm, fn, ctx, pstates, states)
2951 found = found or r
2976 found = found or r
2952 if r and not diff and not all_files:
2977 if r and not diff and not all_files:
2953 skip.add(fn)
2978 skip.add(fn)
2954 if copy:
2979 if copy:
2955 skip.add(copy)
2980 skip.add(copy)
2956 del revfiles[rev]
2981 del revfiles[rev]
2957 # We will keep the matches dict for the duration of the window
2982 # We will keep the matches dict for the duration of the window
2958 # clear the matches dict once the window is over
2983 # clear the matches dict once the window is over
2959 if not revfiles:
2984 if not revfiles:
2960 matches.clear()
2985 matches.clear()
2961 fm.end()
2986 fm.end()
2962
2987
2963 return not found
2988 return not found
2964
2989
2965 @command('heads',
2990 @command('heads',
2966 [('r', 'rev', '',
2991 [('r', 'rev', '',
2967 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2992 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2968 ('t', 'topo', False, _('show topological heads only')),
2993 ('t', 'topo', False, _('show topological heads only')),
2969 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2994 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2970 ('c', 'closed', False, _('show normal and closed branch heads')),
2995 ('c', 'closed', False, _('show normal and closed branch heads')),
2971 ] + templateopts,
2996 ] + templateopts,
2972 _('[-ct] [-r STARTREV] [REV]...'),
2997 _('[-ct] [-r STARTREV] [REV]...'),
2973 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
2998 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
2974 intents={INTENT_READONLY})
2999 intents={INTENT_READONLY})
2975 def heads(ui, repo, *branchrevs, **opts):
3000 def heads(ui, repo, *branchrevs, **opts):
2976 """show branch heads
3001 """show branch heads
2977
3002
2978 With no arguments, show all open branch heads in the repository.
3003 With no arguments, show all open branch heads in the repository.
2979 Branch heads are changesets that have no descendants on the
3004 Branch heads are changesets that have no descendants on the
2980 same branch. They are where development generally takes place and
3005 same branch. They are where development generally takes place and
2981 are the usual targets for update and merge operations.
3006 are the usual targets for update and merge operations.
2982
3007
2983 If one or more REVs are given, only open branch heads on the
3008 If one or more REVs are given, only open branch heads on the
2984 branches associated with the specified changesets are shown. This
3009 branches associated with the specified changesets are shown. This
2985 means that you can use :hg:`heads .` to see the heads on the
3010 means that you can use :hg:`heads .` to see the heads on the
2986 currently checked-out branch.
3011 currently checked-out branch.
2987
3012
2988 If -c/--closed is specified, also show branch heads marked closed
3013 If -c/--closed is specified, also show branch heads marked closed
2989 (see :hg:`commit --close-branch`).
3014 (see :hg:`commit --close-branch`).
2990
3015
2991 If STARTREV is specified, only those heads that are descendants of
3016 If STARTREV is specified, only those heads that are descendants of
2992 STARTREV will be displayed.
3017 STARTREV will be displayed.
2993
3018
2994 If -t/--topo is specified, named branch mechanics will be ignored and only
3019 If -t/--topo is specified, named branch mechanics will be ignored and only
2995 topological heads (changesets with no children) will be shown.
3020 topological heads (changesets with no children) will be shown.
2996
3021
2997 Returns 0 if matching heads are found, 1 if not.
3022 Returns 0 if matching heads are found, 1 if not.
2998 """
3023 """
2999
3024
3000 opts = pycompat.byteskwargs(opts)
3025 opts = pycompat.byteskwargs(opts)
3001 start = None
3026 start = None
3002 rev = opts.get('rev')
3027 rev = opts.get('rev')
3003 if rev:
3028 if rev:
3004 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3029 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3005 start = scmutil.revsingle(repo, rev, None).node()
3030 start = scmutil.revsingle(repo, rev, None).node()
3006
3031
3007 if opts.get('topo'):
3032 if opts.get('topo'):
3008 heads = [repo[h] for h in repo.heads(start)]
3033 heads = [repo[h] for h in repo.heads(start)]
3009 else:
3034 else:
3010 heads = []
3035 heads = []
3011 for branch in repo.branchmap():
3036 for branch in repo.branchmap():
3012 heads += repo.branchheads(branch, start, opts.get('closed'))
3037 heads += repo.branchheads(branch, start, opts.get('closed'))
3013 heads = [repo[h] for h in heads]
3038 heads = [repo[h] for h in heads]
3014
3039
3015 if branchrevs:
3040 if branchrevs:
3016 branches = set(repo[r].branch()
3041 branches = set(repo[r].branch()
3017 for r in scmutil.revrange(repo, branchrevs))
3042 for r in scmutil.revrange(repo, branchrevs))
3018 heads = [h for h in heads if h.branch() in branches]
3043 heads = [h for h in heads if h.branch() in branches]
3019
3044
3020 if opts.get('active') and branchrevs:
3045 if opts.get('active') and branchrevs:
3021 dagheads = repo.heads(start)
3046 dagheads = repo.heads(start)
3022 heads = [h for h in heads if h.node() in dagheads]
3047 heads = [h for h in heads if h.node() in dagheads]
3023
3048
3024 if branchrevs:
3049 if branchrevs:
3025 haveheads = set(h.branch() for h in heads)
3050 haveheads = set(h.branch() for h in heads)
3026 if branches - haveheads:
3051 if branches - haveheads:
3027 headless = ', '.join(b for b in branches - haveheads)
3052 headless = ', '.join(b for b in branches - haveheads)
3028 msg = _('no open branch heads found on branches %s')
3053 msg = _('no open branch heads found on branches %s')
3029 if opts.get('rev'):
3054 if opts.get('rev'):
3030 msg += _(' (started at %s)') % opts['rev']
3055 msg += _(' (started at %s)') % opts['rev']
3031 ui.warn((msg + '\n') % headless)
3056 ui.warn((msg + '\n') % headless)
3032
3057
3033 if not heads:
3058 if not heads:
3034 return 1
3059 return 1
3035
3060
3036 ui.pager('heads')
3061 ui.pager('heads')
3037 heads = sorted(heads, key=lambda x: -x.rev())
3062 heads = sorted(heads, key=lambda x: -x.rev())
3038 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3063 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3039 for ctx in heads:
3064 for ctx in heads:
3040 displayer.show(ctx)
3065 displayer.show(ctx)
3041 displayer.close()
3066 displayer.close()
3042
3067
3043 @command('help',
3068 @command('help',
3044 [('e', 'extension', None, _('show only help for extensions')),
3069 [('e', 'extension', None, _('show only help for extensions')),
3045 ('c', 'command', None, _('show only help for commands')),
3070 ('c', 'command', None, _('show only help for commands')),
3046 ('k', 'keyword', None, _('show topics matching keyword')),
3071 ('k', 'keyword', None, _('show topics matching keyword')),
3047 ('s', 'system', [],
3072 ('s', 'system', [],
3048 _('show help for specific platform(s)'), _('PLATFORM')),
3073 _('show help for specific platform(s)'), _('PLATFORM')),
3049 ],
3074 ],
3050 _('[-eck] [-s PLATFORM] [TOPIC]'),
3075 _('[-eck] [-s PLATFORM] [TOPIC]'),
3051 helpcategory=command.CATEGORY_HELP,
3076 helpcategory=command.CATEGORY_HELP,
3052 norepo=True,
3077 norepo=True,
3053 intents={INTENT_READONLY})
3078 intents={INTENT_READONLY})
3054 def help_(ui, name=None, **opts):
3079 def help_(ui, name=None, **opts):
3055 """show help for a given topic or a help overview
3080 """show help for a given topic or a help overview
3056
3081
3057 With no arguments, print a list of commands with short help messages.
3082 With no arguments, print a list of commands with short help messages.
3058
3083
3059 Given a topic, extension, or command name, print help for that
3084 Given a topic, extension, or command name, print help for that
3060 topic.
3085 topic.
3061
3086
3062 Returns 0 if successful.
3087 Returns 0 if successful.
3063 """
3088 """
3064
3089
3065 keep = opts.get(r'system') or []
3090 keep = opts.get(r'system') or []
3066 if len(keep) == 0:
3091 if len(keep) == 0:
3067 if pycompat.sysplatform.startswith('win'):
3092 if pycompat.sysplatform.startswith('win'):
3068 keep.append('windows')
3093 keep.append('windows')
3069 elif pycompat.sysplatform == 'OpenVMS':
3094 elif pycompat.sysplatform == 'OpenVMS':
3070 keep.append('vms')
3095 keep.append('vms')
3071 elif pycompat.sysplatform == 'plan9':
3096 elif pycompat.sysplatform == 'plan9':
3072 keep.append('plan9')
3097 keep.append('plan9')
3073 else:
3098 else:
3074 keep.append('unix')
3099 keep.append('unix')
3075 keep.append(pycompat.sysplatform.lower())
3100 keep.append(pycompat.sysplatform.lower())
3076 if ui.verbose:
3101 if ui.verbose:
3077 keep.append('verbose')
3102 keep.append('verbose')
3078
3103
3079 commands = sys.modules[__name__]
3104 commands = sys.modules[__name__]
3080 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3105 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3081 ui.pager('help')
3106 ui.pager('help')
3082 ui.write(formatted)
3107 ui.write(formatted)
3083
3108
3084
3109
3085 @command('identify|id',
3110 @command('identify|id',
3086 [('r', 'rev', '',
3111 [('r', 'rev', '',
3087 _('identify the specified revision'), _('REV')),
3112 _('identify the specified revision'), _('REV')),
3088 ('n', 'num', None, _('show local revision number')),
3113 ('n', 'num', None, _('show local revision number')),
3089 ('i', 'id', None, _('show global revision id')),
3114 ('i', 'id', None, _('show global revision id')),
3090 ('b', 'branch', None, _('show branch')),
3115 ('b', 'branch', None, _('show branch')),
3091 ('t', 'tags', None, _('show tags')),
3116 ('t', 'tags', None, _('show tags')),
3092 ('B', 'bookmarks', None, _('show bookmarks')),
3117 ('B', 'bookmarks', None, _('show bookmarks')),
3093 ] + remoteopts + formatteropts,
3118 ] + remoteopts + formatteropts,
3094 _('[-nibtB] [-r REV] [SOURCE]'),
3119 _('[-nibtB] [-r REV] [SOURCE]'),
3095 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3120 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3096 optionalrepo=True,
3121 optionalrepo=True,
3097 intents={INTENT_READONLY})
3122 intents={INTENT_READONLY})
3098 def identify(ui, repo, source=None, rev=None,
3123 def identify(ui, repo, source=None, rev=None,
3099 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3124 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3100 """identify the working directory or specified revision
3125 """identify the working directory or specified revision
3101
3126
3102 Print a summary identifying the repository state at REV using one or
3127 Print a summary identifying the repository state at REV using one or
3103 two parent hash identifiers, followed by a "+" if the working
3128 two parent hash identifiers, followed by a "+" if the working
3104 directory has uncommitted changes, the branch name (if not default),
3129 directory has uncommitted changes, the branch name (if not default),
3105 a list of tags, and a list of bookmarks.
3130 a list of tags, and a list of bookmarks.
3106
3131
3107 When REV is not given, print a summary of the current state of the
3132 When REV is not given, print a summary of the current state of the
3108 repository including the working directory. Specify -r. to get information
3133 repository including the working directory. Specify -r. to get information
3109 of the working directory parent without scanning uncommitted changes.
3134 of the working directory parent without scanning uncommitted changes.
3110
3135
3111 Specifying a path to a repository root or Mercurial bundle will
3136 Specifying a path to a repository root or Mercurial bundle will
3112 cause lookup to operate on that repository/bundle.
3137 cause lookup to operate on that repository/bundle.
3113
3138
3114 .. container:: verbose
3139 .. container:: verbose
3115
3140
3116 Template:
3141 Template:
3117
3142
3118 The following keywords are supported in addition to the common template
3143 The following keywords are supported in addition to the common template
3119 keywords and functions. See also :hg:`help templates`.
3144 keywords and functions. See also :hg:`help templates`.
3120
3145
3121 :dirty: String. Character ``+`` denoting if the working directory has
3146 :dirty: String. Character ``+`` denoting if the working directory has
3122 uncommitted changes.
3147 uncommitted changes.
3123 :id: String. One or two nodes, optionally followed by ``+``.
3148 :id: String. One or two nodes, optionally followed by ``+``.
3124 :parents: List of strings. Parent nodes of the changeset.
3149 :parents: List of strings. Parent nodes of the changeset.
3125
3150
3126 Examples:
3151 Examples:
3127
3152
3128 - generate a build identifier for the working directory::
3153 - generate a build identifier for the working directory::
3129
3154
3130 hg id --id > build-id.dat
3155 hg id --id > build-id.dat
3131
3156
3132 - find the revision corresponding to a tag::
3157 - find the revision corresponding to a tag::
3133
3158
3134 hg id -n -r 1.3
3159 hg id -n -r 1.3
3135
3160
3136 - check the most recent revision of a remote repository::
3161 - check the most recent revision of a remote repository::
3137
3162
3138 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3163 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3139
3164
3140 See :hg:`log` for generating more information about specific revisions,
3165 See :hg:`log` for generating more information about specific revisions,
3141 including full hash identifiers.
3166 including full hash identifiers.
3142
3167
3143 Returns 0 if successful.
3168 Returns 0 if successful.
3144 """
3169 """
3145
3170
3146 opts = pycompat.byteskwargs(opts)
3171 opts = pycompat.byteskwargs(opts)
3147 if not repo and not source:
3172 if not repo and not source:
3148 raise error.Abort(_("there is no Mercurial repository here "
3173 raise error.Abort(_("there is no Mercurial repository here "
3149 "(.hg not found)"))
3174 "(.hg not found)"))
3150
3175
3151 default = not (num or id or branch or tags or bookmarks)
3176 default = not (num or id or branch or tags or bookmarks)
3152 output = []
3177 output = []
3153 revs = []
3178 revs = []
3154
3179
3155 if source:
3180 if source:
3156 source, branches = hg.parseurl(ui.expandpath(source))
3181 source, branches = hg.parseurl(ui.expandpath(source))
3157 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3182 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3158 repo = peer.local()
3183 repo = peer.local()
3159 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3184 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3160
3185
3161 fm = ui.formatter('identify', opts)
3186 fm = ui.formatter('identify', opts)
3162 fm.startitem()
3187 fm.startitem()
3163
3188
3164 if not repo:
3189 if not repo:
3165 if num or branch or tags:
3190 if num or branch or tags:
3166 raise error.Abort(
3191 raise error.Abort(
3167 _("can't query remote revision number, branch, or tags"))
3192 _("can't query remote revision number, branch, or tags"))
3168 if not rev and revs:
3193 if not rev and revs:
3169 rev = revs[0]
3194 rev = revs[0]
3170 if not rev:
3195 if not rev:
3171 rev = "tip"
3196 rev = "tip"
3172
3197
3173 remoterev = peer.lookup(rev)
3198 remoterev = peer.lookup(rev)
3174 hexrev = fm.hexfunc(remoterev)
3199 hexrev = fm.hexfunc(remoterev)
3175 if default or id:
3200 if default or id:
3176 output = [hexrev]
3201 output = [hexrev]
3177 fm.data(id=hexrev)
3202 fm.data(id=hexrev)
3178
3203
3179 @util.cachefunc
3204 @util.cachefunc
3180 def getbms():
3205 def getbms():
3181 bms = []
3206 bms = []
3182
3207
3183 if 'bookmarks' in peer.listkeys('namespaces'):
3208 if 'bookmarks' in peer.listkeys('namespaces'):
3184 hexremoterev = hex(remoterev)
3209 hexremoterev = hex(remoterev)
3185 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3210 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3186 if bmr == hexremoterev]
3211 if bmr == hexremoterev]
3187
3212
3188 return sorted(bms)
3213 return sorted(bms)
3189
3214
3190 if fm.isplain():
3215 if fm.isplain():
3191 if bookmarks:
3216 if bookmarks:
3192 output.extend(getbms())
3217 output.extend(getbms())
3193 elif default and not ui.quiet:
3218 elif default and not ui.quiet:
3194 # multiple bookmarks for a single parent separated by '/'
3219 # multiple bookmarks for a single parent separated by '/'
3195 bm = '/'.join(getbms())
3220 bm = '/'.join(getbms())
3196 if bm:
3221 if bm:
3197 output.append(bm)
3222 output.append(bm)
3198 else:
3223 else:
3199 fm.data(node=hex(remoterev))
3224 fm.data(node=hex(remoterev))
3200 if bookmarks or 'bookmarks' in fm.datahint():
3225 if bookmarks or 'bookmarks' in fm.datahint():
3201 fm.data(bookmarks=fm.formatlist(getbms(), name='bookmark'))
3226 fm.data(bookmarks=fm.formatlist(getbms(), name='bookmark'))
3202 else:
3227 else:
3203 if rev:
3228 if rev:
3204 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3229 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3205 ctx = scmutil.revsingle(repo, rev, None)
3230 ctx = scmutil.revsingle(repo, rev, None)
3206
3231
3207 if ctx.rev() is None:
3232 if ctx.rev() is None:
3208 ctx = repo[None]
3233 ctx = repo[None]
3209 parents = ctx.parents()
3234 parents = ctx.parents()
3210 taglist = []
3235 taglist = []
3211 for p in parents:
3236 for p in parents:
3212 taglist.extend(p.tags())
3237 taglist.extend(p.tags())
3213
3238
3214 dirty = ""
3239 dirty = ""
3215 if ctx.dirty(missing=True, merge=False, branch=False):
3240 if ctx.dirty(missing=True, merge=False, branch=False):
3216 dirty = '+'
3241 dirty = '+'
3217 fm.data(dirty=dirty)
3242 fm.data(dirty=dirty)
3218
3243
3219 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3244 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3220 if default or id:
3245 if default or id:
3221 output = ["%s%s" % ('+'.join(hexoutput), dirty)]
3246 output = ["%s%s" % ('+'.join(hexoutput), dirty)]
3222 fm.data(id="%s%s" % ('+'.join(hexoutput), dirty))
3247 fm.data(id="%s%s" % ('+'.join(hexoutput), dirty))
3223
3248
3224 if num:
3249 if num:
3225 numoutput = ["%d" % p.rev() for p in parents]
3250 numoutput = ["%d" % p.rev() for p in parents]
3226 output.append("%s%s" % ('+'.join(numoutput), dirty))
3251 output.append("%s%s" % ('+'.join(numoutput), dirty))
3227
3252
3228 fm.data(parents=fm.formatlist([fm.hexfunc(p.node())
3253 fm.data(parents=fm.formatlist([fm.hexfunc(p.node())
3229 for p in parents], name='node'))
3254 for p in parents], name='node'))
3230 else:
3255 else:
3231 hexoutput = fm.hexfunc(ctx.node())
3256 hexoutput = fm.hexfunc(ctx.node())
3232 if default or id:
3257 if default or id:
3233 output = [hexoutput]
3258 output = [hexoutput]
3234 fm.data(id=hexoutput)
3259 fm.data(id=hexoutput)
3235
3260
3236 if num:
3261 if num:
3237 output.append(pycompat.bytestr(ctx.rev()))
3262 output.append(pycompat.bytestr(ctx.rev()))
3238 taglist = ctx.tags()
3263 taglist = ctx.tags()
3239
3264
3240 if default and not ui.quiet:
3265 if default and not ui.quiet:
3241 b = ctx.branch()
3266 b = ctx.branch()
3242 if b != 'default':
3267 if b != 'default':
3243 output.append("(%s)" % b)
3268 output.append("(%s)" % b)
3244
3269
3245 # multiple tags for a single parent separated by '/'
3270 # multiple tags for a single parent separated by '/'
3246 t = '/'.join(taglist)
3271 t = '/'.join(taglist)
3247 if t:
3272 if t:
3248 output.append(t)
3273 output.append(t)
3249
3274
3250 # multiple bookmarks for a single parent separated by '/'
3275 # multiple bookmarks for a single parent separated by '/'
3251 bm = '/'.join(ctx.bookmarks())
3276 bm = '/'.join(ctx.bookmarks())
3252 if bm:
3277 if bm:
3253 output.append(bm)
3278 output.append(bm)
3254 else:
3279 else:
3255 if branch:
3280 if branch:
3256 output.append(ctx.branch())
3281 output.append(ctx.branch())
3257
3282
3258 if tags:
3283 if tags:
3259 output.extend(taglist)
3284 output.extend(taglist)
3260
3285
3261 if bookmarks:
3286 if bookmarks:
3262 output.extend(ctx.bookmarks())
3287 output.extend(ctx.bookmarks())
3263
3288
3264 fm.data(node=ctx.hex())
3289 fm.data(node=ctx.hex())
3265 fm.data(branch=ctx.branch())
3290 fm.data(branch=ctx.branch())
3266 fm.data(tags=fm.formatlist(taglist, name='tag', sep=':'))
3291 fm.data(tags=fm.formatlist(taglist, name='tag', sep=':'))
3267 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'))
3292 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'))
3268 fm.context(ctx=ctx)
3293 fm.context(ctx=ctx)
3269
3294
3270 fm.plain("%s\n" % ' '.join(output))
3295 fm.plain("%s\n" % ' '.join(output))
3271 fm.end()
3296 fm.end()
3272
3297
3273 @command('import|patch',
3298 @command('import|patch',
3274 [('p', 'strip', 1,
3299 [('p', 'strip', 1,
3275 _('directory strip option for patch. This has the same '
3300 _('directory strip option for patch. This has the same '
3276 'meaning as the corresponding patch option'), _('NUM')),
3301 'meaning as the corresponding patch option'), _('NUM')),
3277 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3302 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3278 ('e', 'edit', False, _('invoke editor on commit messages')),
3303 ('e', 'edit', False, _('invoke editor on commit messages')),
3279 ('f', 'force', None,
3304 ('f', 'force', None,
3280 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3305 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3281 ('', 'no-commit', None,
3306 ('', 'no-commit', None,
3282 _("don't commit, just update the working directory")),
3307 _("don't commit, just update the working directory")),
3283 ('', 'bypass', None,
3308 ('', 'bypass', None,
3284 _("apply patch without touching the working directory")),
3309 _("apply patch without touching the working directory")),
3285 ('', 'partial', None,
3310 ('', 'partial', None,
3286 _('commit even if some hunks fail')),
3311 _('commit even if some hunks fail')),
3287 ('', 'exact', None,
3312 ('', 'exact', None,
3288 _('abort if patch would apply lossily')),
3313 _('abort if patch would apply lossily')),
3289 ('', 'prefix', '',
3314 ('', 'prefix', '',
3290 _('apply patch to subdirectory'), _('DIR')),
3315 _('apply patch to subdirectory'), _('DIR')),
3291 ('', 'import-branch', None,
3316 ('', 'import-branch', None,
3292 _('use any branch information in patch (implied by --exact)'))] +
3317 _('use any branch information in patch (implied by --exact)'))] +
3293 commitopts + commitopts2 + similarityopts,
3318 commitopts + commitopts2 + similarityopts,
3294 _('[OPTION]... PATCH...'),
3319 _('[OPTION]... PATCH...'),
3295 helpcategory=command.CATEGORY_IMPORT_EXPORT)
3320 helpcategory=command.CATEGORY_IMPORT_EXPORT)
3296 def import_(ui, repo, patch1=None, *patches, **opts):
3321 def import_(ui, repo, patch1=None, *patches, **opts):
3297 """import an ordered set of patches
3322 """import an ordered set of patches
3298
3323
3299 Import a list of patches and commit them individually (unless
3324 Import a list of patches and commit them individually (unless
3300 --no-commit is specified).
3325 --no-commit is specified).
3301
3326
3302 To read a patch from standard input (stdin), use "-" as the patch
3327 To read a patch from standard input (stdin), use "-" as the patch
3303 name. If a URL is specified, the patch will be downloaded from
3328 name. If a URL is specified, the patch will be downloaded from
3304 there.
3329 there.
3305
3330
3306 Import first applies changes to the working directory (unless
3331 Import first applies changes to the working directory (unless
3307 --bypass is specified), import will abort if there are outstanding
3332 --bypass is specified), import will abort if there are outstanding
3308 changes.
3333 changes.
3309
3334
3310 Use --bypass to apply and commit patches directly to the
3335 Use --bypass to apply and commit patches directly to the
3311 repository, without affecting the working directory. Without
3336 repository, without affecting the working directory. Without
3312 --exact, patches will be applied on top of the working directory
3337 --exact, patches will be applied on top of the working directory
3313 parent revision.
3338 parent revision.
3314
3339
3315 You can import a patch straight from a mail message. Even patches
3340 You can import a patch straight from a mail message. Even patches
3316 as attachments work (to use the body part, it must have type
3341 as attachments work (to use the body part, it must have type
3317 text/plain or text/x-patch). From and Subject headers of email
3342 text/plain or text/x-patch). From and Subject headers of email
3318 message are used as default committer and commit message. All
3343 message are used as default committer and commit message. All
3319 text/plain body parts before first diff are added to the commit
3344 text/plain body parts before first diff are added to the commit
3320 message.
3345 message.
3321
3346
3322 If the imported patch was generated by :hg:`export`, user and
3347 If the imported patch was generated by :hg:`export`, user and
3323 description from patch override values from message headers and
3348 description from patch override values from message headers and
3324 body. Values given on command line with -m/--message and -u/--user
3349 body. Values given on command line with -m/--message and -u/--user
3325 override these.
3350 override these.
3326
3351
3327 If --exact is specified, import will set the working directory to
3352 If --exact is specified, import will set the working directory to
3328 the parent of each patch before applying it, and will abort if the
3353 the parent of each patch before applying it, and will abort if the
3329 resulting changeset has a different ID than the one recorded in
3354 resulting changeset has a different ID than the one recorded in
3330 the patch. This will guard against various ways that portable
3355 the patch. This will guard against various ways that portable
3331 patch formats and mail systems might fail to transfer Mercurial
3356 patch formats and mail systems might fail to transfer Mercurial
3332 data or metadata. See :hg:`bundle` for lossless transmission.
3357 data or metadata. See :hg:`bundle` for lossless transmission.
3333
3358
3334 Use --partial to ensure a changeset will be created from the patch
3359 Use --partial to ensure a changeset will be created from the patch
3335 even if some hunks fail to apply. Hunks that fail to apply will be
3360 even if some hunks fail to apply. Hunks that fail to apply will be
3336 written to a <target-file>.rej file. Conflicts can then be resolved
3361 written to a <target-file>.rej file. Conflicts can then be resolved
3337 by hand before :hg:`commit --amend` is run to update the created
3362 by hand before :hg:`commit --amend` is run to update the created
3338 changeset. This flag exists to let people import patches that
3363 changeset. This flag exists to let people import patches that
3339 partially apply without losing the associated metadata (author,
3364 partially apply without losing the associated metadata (author,
3340 date, description, ...).
3365 date, description, ...).
3341
3366
3342 .. note::
3367 .. note::
3343
3368
3344 When no hunks apply cleanly, :hg:`import --partial` will create
3369 When no hunks apply cleanly, :hg:`import --partial` will create
3345 an empty changeset, importing only the patch metadata.
3370 an empty changeset, importing only the patch metadata.
3346
3371
3347 With -s/--similarity, hg will attempt to discover renames and
3372 With -s/--similarity, hg will attempt to discover renames and
3348 copies in the patch in the same way as :hg:`addremove`.
3373 copies in the patch in the same way as :hg:`addremove`.
3349
3374
3350 It is possible to use external patch programs to perform the patch
3375 It is possible to use external patch programs to perform the patch
3351 by setting the ``ui.patch`` configuration option. For the default
3376 by setting the ``ui.patch`` configuration option. For the default
3352 internal tool, the fuzz can also be configured via ``patch.fuzz``.
3377 internal tool, the fuzz can also be configured via ``patch.fuzz``.
3353 See :hg:`help config` for more information about configuration
3378 See :hg:`help config` for more information about configuration
3354 files and how to use these options.
3379 files and how to use these options.
3355
3380
3356 See :hg:`help dates` for a list of formats valid for -d/--date.
3381 See :hg:`help dates` for a list of formats valid for -d/--date.
3357
3382
3358 .. container:: verbose
3383 .. container:: verbose
3359
3384
3360 Examples:
3385 Examples:
3361
3386
3362 - import a traditional patch from a website and detect renames::
3387 - import a traditional patch from a website and detect renames::
3363
3388
3364 hg import -s 80 http://example.com/bugfix.patch
3389 hg import -s 80 http://example.com/bugfix.patch
3365
3390
3366 - import a changeset from an hgweb server::
3391 - import a changeset from an hgweb server::
3367
3392
3368 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
3393 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
3369
3394
3370 - import all the patches in an Unix-style mbox::
3395 - import all the patches in an Unix-style mbox::
3371
3396
3372 hg import incoming-patches.mbox
3397 hg import incoming-patches.mbox
3373
3398
3374 - import patches from stdin::
3399 - import patches from stdin::
3375
3400
3376 hg import -
3401 hg import -
3377
3402
3378 - attempt to exactly restore an exported changeset (not always
3403 - attempt to exactly restore an exported changeset (not always
3379 possible)::
3404 possible)::
3380
3405
3381 hg import --exact proposed-fix.patch
3406 hg import --exact proposed-fix.patch
3382
3407
3383 - use an external tool to apply a patch which is too fuzzy for
3408 - use an external tool to apply a patch which is too fuzzy for
3384 the default internal tool.
3409 the default internal tool.
3385
3410
3386 hg import --config ui.patch="patch --merge" fuzzy.patch
3411 hg import --config ui.patch="patch --merge" fuzzy.patch
3387
3412
3388 - change the default fuzzing from 2 to a less strict 7
3413 - change the default fuzzing from 2 to a less strict 7
3389
3414
3390 hg import --config ui.fuzz=7 fuzz.patch
3415 hg import --config ui.fuzz=7 fuzz.patch
3391
3416
3392 Returns 0 on success, 1 on partial success (see --partial).
3417 Returns 0 on success, 1 on partial success (see --partial).
3393 """
3418 """
3394
3419
3395 opts = pycompat.byteskwargs(opts)
3420 opts = pycompat.byteskwargs(opts)
3396 if not patch1:
3421 if not patch1:
3397 raise error.Abort(_('need at least one patch to import'))
3422 raise error.Abort(_('need at least one patch to import'))
3398
3423
3399 patches = (patch1,) + patches
3424 patches = (patch1,) + patches
3400
3425
3401 date = opts.get('date')
3426 date = opts.get('date')
3402 if date:
3427 if date:
3403 opts['date'] = dateutil.parsedate(date)
3428 opts['date'] = dateutil.parsedate(date)
3404
3429
3405 exact = opts.get('exact')
3430 exact = opts.get('exact')
3406 update = not opts.get('bypass')
3431 update = not opts.get('bypass')
3407 if not update and opts.get('no_commit'):
3432 if not update and opts.get('no_commit'):
3408 raise error.Abort(_('cannot use --no-commit with --bypass'))
3433 raise error.Abort(_('cannot use --no-commit with --bypass'))
3409 try:
3434 try:
3410 sim = float(opts.get('similarity') or 0)
3435 sim = float(opts.get('similarity') or 0)
3411 except ValueError:
3436 except ValueError:
3412 raise error.Abort(_('similarity must be a number'))
3437 raise error.Abort(_('similarity must be a number'))
3413 if sim < 0 or sim > 100:
3438 if sim < 0 or sim > 100:
3414 raise error.Abort(_('similarity must be between 0 and 100'))
3439 raise error.Abort(_('similarity must be between 0 and 100'))
3415 if sim and not update:
3440 if sim and not update:
3416 raise error.Abort(_('cannot use --similarity with --bypass'))
3441 raise error.Abort(_('cannot use --similarity with --bypass'))
3417 if exact:
3442 if exact:
3418 if opts.get('edit'):
3443 if opts.get('edit'):
3419 raise error.Abort(_('cannot use --exact with --edit'))
3444 raise error.Abort(_('cannot use --exact with --edit'))
3420 if opts.get('prefix'):
3445 if opts.get('prefix'):
3421 raise error.Abort(_('cannot use --exact with --prefix'))
3446 raise error.Abort(_('cannot use --exact with --prefix'))
3422
3447
3423 base = opts["base"]
3448 base = opts["base"]
3424 msgs = []
3449 msgs = []
3425 ret = 0
3450 ret = 0
3426
3451
3427 with repo.wlock():
3452 with repo.wlock():
3428 if update:
3453 if update:
3429 cmdutil.checkunfinished(repo)
3454 cmdutil.checkunfinished(repo)
3430 if (exact or not opts.get('force')):
3455 if (exact or not opts.get('force')):
3431 cmdutil.bailifchanged(repo)
3456 cmdutil.bailifchanged(repo)
3432
3457
3433 if not opts.get('no_commit'):
3458 if not opts.get('no_commit'):
3434 lock = repo.lock
3459 lock = repo.lock
3435 tr = lambda: repo.transaction('import')
3460 tr = lambda: repo.transaction('import')
3436 dsguard = util.nullcontextmanager
3461 dsguard = util.nullcontextmanager
3437 else:
3462 else:
3438 lock = util.nullcontextmanager
3463 lock = util.nullcontextmanager
3439 tr = util.nullcontextmanager
3464 tr = util.nullcontextmanager
3440 dsguard = lambda: dirstateguard.dirstateguard(repo, 'import')
3465 dsguard = lambda: dirstateguard.dirstateguard(repo, 'import')
3441 with lock(), tr(), dsguard():
3466 with lock(), tr(), dsguard():
3442 parents = repo[None].parents()
3467 parents = repo[None].parents()
3443 for patchurl in patches:
3468 for patchurl in patches:
3444 if patchurl == '-':
3469 if patchurl == '-':
3445 ui.status(_('applying patch from stdin\n'))
3470 ui.status(_('applying patch from stdin\n'))
3446 patchfile = ui.fin
3471 patchfile = ui.fin
3447 patchurl = 'stdin' # for error message
3472 patchurl = 'stdin' # for error message
3448 else:
3473 else:
3449 patchurl = os.path.join(base, patchurl)
3474 patchurl = os.path.join(base, patchurl)
3450 ui.status(_('applying %s\n') % patchurl)
3475 ui.status(_('applying %s\n') % patchurl)
3451 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
3476 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
3452
3477
3453 haspatch = False
3478 haspatch = False
3454 for hunk in patch.split(patchfile):
3479 for hunk in patch.split(patchfile):
3455 with patch.extract(ui, hunk) as patchdata:
3480 with patch.extract(ui, hunk) as patchdata:
3456 msg, node, rej = cmdutil.tryimportone(ui, repo,
3481 msg, node, rej = cmdutil.tryimportone(ui, repo,
3457 patchdata,
3482 patchdata,
3458 parents, opts,
3483 parents, opts,
3459 msgs, hg.clean)
3484 msgs, hg.clean)
3460 if msg:
3485 if msg:
3461 haspatch = True
3486 haspatch = True
3462 ui.note(msg + '\n')
3487 ui.note(msg + '\n')
3463 if update or exact:
3488 if update or exact:
3464 parents = repo[None].parents()
3489 parents = repo[None].parents()
3465 else:
3490 else:
3466 parents = [repo[node]]
3491 parents = [repo[node]]
3467 if rej:
3492 if rej:
3468 ui.write_err(_("patch applied partially\n"))
3493 ui.write_err(_("patch applied partially\n"))
3469 ui.write_err(_("(fix the .rej files and run "
3494 ui.write_err(_("(fix the .rej files and run "
3470 "`hg commit --amend`)\n"))
3495 "`hg commit --amend`)\n"))
3471 ret = 1
3496 ret = 1
3472 break
3497 break
3473
3498
3474 if not haspatch:
3499 if not haspatch:
3475 raise error.Abort(_('%s: no diffs found') % patchurl)
3500 raise error.Abort(_('%s: no diffs found') % patchurl)
3476
3501
3477 if msgs:
3502 if msgs:
3478 repo.savecommitmessage('\n* * *\n'.join(msgs))
3503 repo.savecommitmessage('\n* * *\n'.join(msgs))
3479 return ret
3504 return ret
3480
3505
3481 @command('incoming|in',
3506 @command('incoming|in',
3482 [('f', 'force', None,
3507 [('f', 'force', None,
3483 _('run even if remote repository is unrelated')),
3508 _('run even if remote repository is unrelated')),
3484 ('n', 'newest-first', None, _('show newest record first')),
3509 ('n', 'newest-first', None, _('show newest record first')),
3485 ('', 'bundle', '',
3510 ('', 'bundle', '',
3486 _('file to store the bundles into'), _('FILE')),
3511 _('file to store the bundles into'), _('FILE')),
3487 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3512 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3488 ('B', 'bookmarks', False, _("compare bookmarks")),
3513 ('B', 'bookmarks', False, _("compare bookmarks")),
3489 ('b', 'branch', [],
3514 ('b', 'branch', [],
3490 _('a specific branch you would like to pull'), _('BRANCH')),
3515 _('a specific branch you would like to pull'), _('BRANCH')),
3491 ] + logopts + remoteopts + subrepoopts,
3516 ] + logopts + remoteopts + subrepoopts,
3492 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
3517 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
3493 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
3518 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
3494 def incoming(ui, repo, source="default", **opts):
3519 def incoming(ui, repo, source="default", **opts):
3495 """show new changesets found in source
3520 """show new changesets found in source
3496
3521
3497 Show new changesets found in the specified path/URL or the default
3522 Show new changesets found in the specified path/URL or the default
3498 pull location. These are the changesets that would have been pulled
3523 pull location. These are the changesets that would have been pulled
3499 by :hg:`pull` at the time you issued this command.
3524 by :hg:`pull` at the time you issued this command.
3500
3525
3501 See pull for valid source format details.
3526 See pull for valid source format details.
3502
3527
3503 .. container:: verbose
3528 .. container:: verbose
3504
3529
3505 With -B/--bookmarks, the result of bookmark comparison between
3530 With -B/--bookmarks, the result of bookmark comparison between
3506 local and remote repositories is displayed. With -v/--verbose,
3531 local and remote repositories is displayed. With -v/--verbose,
3507 status is also displayed for each bookmark like below::
3532 status is also displayed for each bookmark like below::
3508
3533
3509 BM1 01234567890a added
3534 BM1 01234567890a added
3510 BM2 1234567890ab advanced
3535 BM2 1234567890ab advanced
3511 BM3 234567890abc diverged
3536 BM3 234567890abc diverged
3512 BM4 34567890abcd changed
3537 BM4 34567890abcd changed
3513
3538
3514 The action taken locally when pulling depends on the
3539 The action taken locally when pulling depends on the
3515 status of each bookmark:
3540 status of each bookmark:
3516
3541
3517 :``added``: pull will create it
3542 :``added``: pull will create it
3518 :``advanced``: pull will update it
3543 :``advanced``: pull will update it
3519 :``diverged``: pull will create a divergent bookmark
3544 :``diverged``: pull will create a divergent bookmark
3520 :``changed``: result depends on remote changesets
3545 :``changed``: result depends on remote changesets
3521
3546
3522 From the point of view of pulling behavior, bookmark
3547 From the point of view of pulling behavior, bookmark
3523 existing only in the remote repository are treated as ``added``,
3548 existing only in the remote repository are treated as ``added``,
3524 even if it is in fact locally deleted.
3549 even if it is in fact locally deleted.
3525
3550
3526 .. container:: verbose
3551 .. container:: verbose
3527
3552
3528 For remote repository, using --bundle avoids downloading the
3553 For remote repository, using --bundle avoids downloading the
3529 changesets twice if the incoming is followed by a pull.
3554 changesets twice if the incoming is followed by a pull.
3530
3555
3531 Examples:
3556 Examples:
3532
3557
3533 - show incoming changes with patches and full description::
3558 - show incoming changes with patches and full description::
3534
3559
3535 hg incoming -vp
3560 hg incoming -vp
3536
3561
3537 - show incoming changes excluding merges, store a bundle::
3562 - show incoming changes excluding merges, store a bundle::
3538
3563
3539 hg in -vpM --bundle incoming.hg
3564 hg in -vpM --bundle incoming.hg
3540 hg pull incoming.hg
3565 hg pull incoming.hg
3541
3566
3542 - briefly list changes inside a bundle::
3567 - briefly list changes inside a bundle::
3543
3568
3544 hg in changes.hg -T "{desc|firstline}\\n"
3569 hg in changes.hg -T "{desc|firstline}\\n"
3545
3570
3546 Returns 0 if there are incoming changes, 1 otherwise.
3571 Returns 0 if there are incoming changes, 1 otherwise.
3547 """
3572 """
3548 opts = pycompat.byteskwargs(opts)
3573 opts = pycompat.byteskwargs(opts)
3549 if opts.get('graph'):
3574 if opts.get('graph'):
3550 logcmdutil.checkunsupportedgraphflags([], opts)
3575 logcmdutil.checkunsupportedgraphflags([], opts)
3551 def display(other, chlist, displayer):
3576 def display(other, chlist, displayer):
3552 revdag = logcmdutil.graphrevs(other, chlist, opts)
3577 revdag = logcmdutil.graphrevs(other, chlist, opts)
3553 logcmdutil.displaygraph(ui, repo, revdag, displayer,
3578 logcmdutil.displaygraph(ui, repo, revdag, displayer,
3554 graphmod.asciiedges)
3579 graphmod.asciiedges)
3555
3580
3556 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3581 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3557 return 0
3582 return 0
3558
3583
3559 if opts.get('bundle') and opts.get('subrepos'):
3584 if opts.get('bundle') and opts.get('subrepos'):
3560 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3585 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3561
3586
3562 if opts.get('bookmarks'):
3587 if opts.get('bookmarks'):
3563 source, branches = hg.parseurl(ui.expandpath(source),
3588 source, branches = hg.parseurl(ui.expandpath(source),
3564 opts.get('branch'))
3589 opts.get('branch'))
3565 other = hg.peer(repo, opts, source)
3590 other = hg.peer(repo, opts, source)
3566 if 'bookmarks' not in other.listkeys('namespaces'):
3591 if 'bookmarks' not in other.listkeys('namespaces'):
3567 ui.warn(_("remote doesn't support bookmarks\n"))
3592 ui.warn(_("remote doesn't support bookmarks\n"))
3568 return 0
3593 return 0
3569 ui.pager('incoming')
3594 ui.pager('incoming')
3570 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3595 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3571 return bookmarks.incoming(ui, repo, other)
3596 return bookmarks.incoming(ui, repo, other)
3572
3597
3573 repo._subtoppath = ui.expandpath(source)
3598 repo._subtoppath = ui.expandpath(source)
3574 try:
3599 try:
3575 return hg.incoming(ui, repo, source, opts)
3600 return hg.incoming(ui, repo, source, opts)
3576 finally:
3601 finally:
3577 del repo._subtoppath
3602 del repo._subtoppath
3578
3603
3579
3604
3580 @command('init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
3605 @command('init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
3581 helpcategory=command.CATEGORY_REPO_CREATION,
3606 helpcategory=command.CATEGORY_REPO_CREATION,
3582 helpbasic=True, norepo=True)
3607 helpbasic=True, norepo=True)
3583 def init(ui, dest=".", **opts):
3608 def init(ui, dest=".", **opts):
3584 """create a new repository in the given directory
3609 """create a new repository in the given directory
3585
3610
3586 Initialize a new repository in the given directory. If the given
3611 Initialize a new repository in the given directory. If the given
3587 directory does not exist, it will be created.
3612 directory does not exist, it will be created.
3588
3613
3589 If no directory is given, the current directory is used.
3614 If no directory is given, the current directory is used.
3590
3615
3591 It is possible to specify an ``ssh://`` URL as the destination.
3616 It is possible to specify an ``ssh://`` URL as the destination.
3592 See :hg:`help urls` for more information.
3617 See :hg:`help urls` for more information.
3593
3618
3594 Returns 0 on success.
3619 Returns 0 on success.
3595 """
3620 """
3596 opts = pycompat.byteskwargs(opts)
3621 opts = pycompat.byteskwargs(opts)
3597 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3622 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3598
3623
3599 @command('locate',
3624 @command('locate',
3600 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3625 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3601 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3626 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3602 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3627 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3603 ] + walkopts,
3628 ] + walkopts,
3604 _('[OPTION]... [PATTERN]...'),
3629 _('[OPTION]... [PATTERN]...'),
3605 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
3630 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
3606 def locate(ui, repo, *pats, **opts):
3631 def locate(ui, repo, *pats, **opts):
3607 """locate files matching specific patterns (DEPRECATED)
3632 """locate files matching specific patterns (DEPRECATED)
3608
3633
3609 Print files under Mercurial control in the working directory whose
3634 Print files under Mercurial control in the working directory whose
3610 names match the given patterns.
3635 names match the given patterns.
3611
3636
3612 By default, this command searches all directories in the working
3637 By default, this command searches all directories in the working
3613 directory. To search just the current directory and its
3638 directory. To search just the current directory and its
3614 subdirectories, use "--include .".
3639 subdirectories, use "--include .".
3615
3640
3616 If no patterns are given to match, this command prints the names
3641 If no patterns are given to match, this command prints the names
3617 of all files under Mercurial control in the working directory.
3642 of all files under Mercurial control in the working directory.
3618
3643
3619 If you want to feed the output of this command into the "xargs"
3644 If you want to feed the output of this command into the "xargs"
3620 command, use the -0 option to both this command and "xargs". This
3645 command, use the -0 option to both this command and "xargs". This
3621 will avoid the problem of "xargs" treating single filenames that
3646 will avoid the problem of "xargs" treating single filenames that
3622 contain whitespace as multiple filenames.
3647 contain whitespace as multiple filenames.
3623
3648
3624 See :hg:`help files` for a more versatile command.
3649 See :hg:`help files` for a more versatile command.
3625
3650
3626 Returns 0 if a match is found, 1 otherwise.
3651 Returns 0 if a match is found, 1 otherwise.
3627 """
3652 """
3628 opts = pycompat.byteskwargs(opts)
3653 opts = pycompat.byteskwargs(opts)
3629 if opts.get('print0'):
3654 if opts.get('print0'):
3630 end = '\0'
3655 end = '\0'
3631 else:
3656 else:
3632 end = '\n'
3657 end = '\n'
3633 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3658 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3634
3659
3635 ret = 1
3660 ret = 1
3636 m = scmutil.match(ctx, pats, opts, default='relglob',
3661 m = scmutil.match(ctx, pats, opts, default='relglob',
3637 badfn=lambda x, y: False)
3662 badfn=lambda x, y: False)
3638
3663
3639 ui.pager('locate')
3664 ui.pager('locate')
3640 if ctx.rev() is None:
3665 if ctx.rev() is None:
3641 # When run on the working copy, "locate" includes removed files, so
3666 # When run on the working copy, "locate" includes removed files, so
3642 # we get the list of files from the dirstate.
3667 # we get the list of files from the dirstate.
3643 filesgen = sorted(repo.dirstate.matches(m))
3668 filesgen = sorted(repo.dirstate.matches(m))
3644 else:
3669 else:
3645 filesgen = ctx.matches(m)
3670 filesgen = ctx.matches(m)
3646 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
3671 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
3647 for abs in filesgen:
3672 for abs in filesgen:
3648 if opts.get('fullpath'):
3673 if opts.get('fullpath'):
3649 ui.write(repo.wjoin(abs), end)
3674 ui.write(repo.wjoin(abs), end)
3650 else:
3675 else:
3651 ui.write(uipathfn(abs), end)
3676 ui.write(uipathfn(abs), end)
3652 ret = 0
3677 ret = 0
3653
3678
3654 return ret
3679 return ret
3655
3680
3656 @command('log|history',
3681 @command('log|history',
3657 [('f', 'follow', None,
3682 [('f', 'follow', None,
3658 _('follow changeset history, or file history across copies and renames')),
3683 _('follow changeset history, or file history across copies and renames')),
3659 ('', 'follow-first', None,
3684 ('', 'follow-first', None,
3660 _('only follow the first parent of merge changesets (DEPRECATED)')),
3685 _('only follow the first parent of merge changesets (DEPRECATED)')),
3661 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3686 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3662 ('C', 'copies', None, _('show copied files')),
3687 ('C', 'copies', None, _('show copied files')),
3663 ('k', 'keyword', [],
3688 ('k', 'keyword', [],
3664 _('do case-insensitive search for a given text'), _('TEXT')),
3689 _('do case-insensitive search for a given text'), _('TEXT')),
3665 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3690 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3666 ('L', 'line-range', [],
3691 ('L', 'line-range', [],
3667 _('follow line range of specified file (EXPERIMENTAL)'),
3692 _('follow line range of specified file (EXPERIMENTAL)'),
3668 _('FILE,RANGE')),
3693 _('FILE,RANGE')),
3669 ('', 'removed', None, _('include revisions where files were removed')),
3694 ('', 'removed', None, _('include revisions where files were removed')),
3670 ('m', 'only-merges', None,
3695 ('m', 'only-merges', None,
3671 _('show only merges (DEPRECATED) (use -r "merge()" instead)')),
3696 _('show only merges (DEPRECATED) (use -r "merge()" instead)')),
3672 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3697 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3673 ('', 'only-branch', [],
3698 ('', 'only-branch', [],
3674 _('show only changesets within the given named branch (DEPRECATED)'),
3699 _('show only changesets within the given named branch (DEPRECATED)'),
3675 _('BRANCH')),
3700 _('BRANCH')),
3676 ('b', 'branch', [],
3701 ('b', 'branch', [],
3677 _('show changesets within the given named branch'), _('BRANCH')),
3702 _('show changesets within the given named branch'), _('BRANCH')),
3678 ('P', 'prune', [],
3703 ('P', 'prune', [],
3679 _('do not display revision or any of its ancestors'), _('REV')),
3704 _('do not display revision or any of its ancestors'), _('REV')),
3680 ] + logopts + walkopts,
3705 ] + logopts + walkopts,
3681 _('[OPTION]... [FILE]'),
3706 _('[OPTION]... [FILE]'),
3682 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3707 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3683 helpbasic=True, inferrepo=True,
3708 helpbasic=True, inferrepo=True,
3684 intents={INTENT_READONLY})
3709 intents={INTENT_READONLY})
3685 def log(ui, repo, *pats, **opts):
3710 def log(ui, repo, *pats, **opts):
3686 """show revision history of entire repository or files
3711 """show revision history of entire repository or files
3687
3712
3688 Print the revision history of the specified files or the entire
3713 Print the revision history of the specified files or the entire
3689 project.
3714 project.
3690
3715
3691 If no revision range is specified, the default is ``tip:0`` unless
3716 If no revision range is specified, the default is ``tip:0`` unless
3692 --follow is set, in which case the working directory parent is
3717 --follow is set, in which case the working directory parent is
3693 used as the starting revision.
3718 used as the starting revision.
3694
3719
3695 File history is shown without following rename or copy history of
3720 File history is shown without following rename or copy history of
3696 files. Use -f/--follow with a filename to follow history across
3721 files. Use -f/--follow with a filename to follow history across
3697 renames and copies. --follow without a filename will only show
3722 renames and copies. --follow without a filename will only show
3698 ancestors of the starting revision.
3723 ancestors of the starting revision.
3699
3724
3700 By default this command prints revision number and changeset id,
3725 By default this command prints revision number and changeset id,
3701 tags, non-trivial parents, user, date and time, and a summary for
3726 tags, non-trivial parents, user, date and time, and a summary for
3702 each commit. When the -v/--verbose switch is used, the list of
3727 each commit. When the -v/--verbose switch is used, the list of
3703 changed files and full commit message are shown.
3728 changed files and full commit message are shown.
3704
3729
3705 With --graph the revisions are shown as an ASCII art DAG with the most
3730 With --graph the revisions are shown as an ASCII art DAG with the most
3706 recent changeset at the top.
3731 recent changeset at the top.
3707 'o' is a changeset, '@' is a working directory parent, '_' closes a branch,
3732 'o' is a changeset, '@' is a working directory parent, '_' closes a branch,
3708 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
3733 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
3709 changeset from the lines below is a parent of the 'o' merge on the same
3734 changeset from the lines below is a parent of the 'o' merge on the same
3710 line.
3735 line.
3711 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
3736 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
3712 of a '|' indicates one or more revisions in a path are omitted.
3737 of a '|' indicates one or more revisions in a path are omitted.
3713
3738
3714 .. container:: verbose
3739 .. container:: verbose
3715
3740
3716 Use -L/--line-range FILE,M:N options to follow the history of lines
3741 Use -L/--line-range FILE,M:N options to follow the history of lines
3717 from M to N in FILE. With -p/--patch only diff hunks affecting
3742 from M to N in FILE. With -p/--patch only diff hunks affecting
3718 specified line range will be shown. This option requires --follow;
3743 specified line range will be shown. This option requires --follow;
3719 it can be specified multiple times. Currently, this option is not
3744 it can be specified multiple times. Currently, this option is not
3720 compatible with --graph. This option is experimental.
3745 compatible with --graph. This option is experimental.
3721
3746
3722 .. note::
3747 .. note::
3723
3748
3724 :hg:`log --patch` may generate unexpected diff output for merge
3749 :hg:`log --patch` may generate unexpected diff output for merge
3725 changesets, as it will only compare the merge changeset against
3750 changesets, as it will only compare the merge changeset against
3726 its first parent. Also, only files different from BOTH parents
3751 its first parent. Also, only files different from BOTH parents
3727 will appear in files:.
3752 will appear in files:.
3728
3753
3729 .. note::
3754 .. note::
3730
3755
3731 For performance reasons, :hg:`log FILE` may omit duplicate changes
3756 For performance reasons, :hg:`log FILE` may omit duplicate changes
3732 made on branches and will not show removals or mode changes. To
3757 made on branches and will not show removals or mode changes. To
3733 see all such changes, use the --removed switch.
3758 see all such changes, use the --removed switch.
3734
3759
3735 .. container:: verbose
3760 .. container:: verbose
3736
3761
3737 .. note::
3762 .. note::
3738
3763
3739 The history resulting from -L/--line-range options depends on diff
3764 The history resulting from -L/--line-range options depends on diff
3740 options; for instance if white-spaces are ignored, respective changes
3765 options; for instance if white-spaces are ignored, respective changes
3741 with only white-spaces in specified line range will not be listed.
3766 with only white-spaces in specified line range will not be listed.
3742
3767
3743 .. container:: verbose
3768 .. container:: verbose
3744
3769
3745 Some examples:
3770 Some examples:
3746
3771
3747 - changesets with full descriptions and file lists::
3772 - changesets with full descriptions and file lists::
3748
3773
3749 hg log -v
3774 hg log -v
3750
3775
3751 - changesets ancestral to the working directory::
3776 - changesets ancestral to the working directory::
3752
3777
3753 hg log -f
3778 hg log -f
3754
3779
3755 - last 10 commits on the current branch::
3780 - last 10 commits on the current branch::
3756
3781
3757 hg log -l 10 -b .
3782 hg log -l 10 -b .
3758
3783
3759 - changesets showing all modifications of a file, including removals::
3784 - changesets showing all modifications of a file, including removals::
3760
3785
3761 hg log --removed file.c
3786 hg log --removed file.c
3762
3787
3763 - all changesets that touch a directory, with diffs, excluding merges::
3788 - all changesets that touch a directory, with diffs, excluding merges::
3764
3789
3765 hg log -Mp lib/
3790 hg log -Mp lib/
3766
3791
3767 - all revision numbers that match a keyword::
3792 - all revision numbers that match a keyword::
3768
3793
3769 hg log -k bug --template "{rev}\\n"
3794 hg log -k bug --template "{rev}\\n"
3770
3795
3771 - the full hash identifier of the working directory parent::
3796 - the full hash identifier of the working directory parent::
3772
3797
3773 hg log -r . --template "{node}\\n"
3798 hg log -r . --template "{node}\\n"
3774
3799
3775 - list available log templates::
3800 - list available log templates::
3776
3801
3777 hg log -T list
3802 hg log -T list
3778
3803
3779 - check if a given changeset is included in a tagged release::
3804 - check if a given changeset is included in a tagged release::
3780
3805
3781 hg log -r "a21ccf and ancestor(1.9)"
3806 hg log -r "a21ccf and ancestor(1.9)"
3782
3807
3783 - find all changesets by some user in a date range::
3808 - find all changesets by some user in a date range::
3784
3809
3785 hg log -k alice -d "may 2008 to jul 2008"
3810 hg log -k alice -d "may 2008 to jul 2008"
3786
3811
3787 - summary of all changesets after the last tag::
3812 - summary of all changesets after the last tag::
3788
3813
3789 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3814 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3790
3815
3791 - changesets touching lines 13 to 23 for file.c::
3816 - changesets touching lines 13 to 23 for file.c::
3792
3817
3793 hg log -L file.c,13:23
3818 hg log -L file.c,13:23
3794
3819
3795 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
3820 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
3796 main.c with patch::
3821 main.c with patch::
3797
3822
3798 hg log -L file.c,13:23 -L main.c,2:6 -p
3823 hg log -L file.c,13:23 -L main.c,2:6 -p
3799
3824
3800 See :hg:`help dates` for a list of formats valid for -d/--date.
3825 See :hg:`help dates` for a list of formats valid for -d/--date.
3801
3826
3802 See :hg:`help revisions` for more about specifying and ordering
3827 See :hg:`help revisions` for more about specifying and ordering
3803 revisions.
3828 revisions.
3804
3829
3805 See :hg:`help templates` for more about pre-packaged styles and
3830 See :hg:`help templates` for more about pre-packaged styles and
3806 specifying custom templates. The default template used by the log
3831 specifying custom templates. The default template used by the log
3807 command can be customized via the ``ui.logtemplate`` configuration
3832 command can be customized via the ``ui.logtemplate`` configuration
3808 setting.
3833 setting.
3809
3834
3810 Returns 0 on success.
3835 Returns 0 on success.
3811
3836
3812 """
3837 """
3813 opts = pycompat.byteskwargs(opts)
3838 opts = pycompat.byteskwargs(opts)
3814 linerange = opts.get('line_range')
3839 linerange = opts.get('line_range')
3815
3840
3816 if linerange and not opts.get('follow'):
3841 if linerange and not opts.get('follow'):
3817 raise error.Abort(_('--line-range requires --follow'))
3842 raise error.Abort(_('--line-range requires --follow'))
3818
3843
3819 if linerange and pats:
3844 if linerange and pats:
3820 # TODO: take pats as patterns with no line-range filter
3845 # TODO: take pats as patterns with no line-range filter
3821 raise error.Abort(
3846 raise error.Abort(
3822 _('FILE arguments are not compatible with --line-range option')
3847 _('FILE arguments are not compatible with --line-range option')
3823 )
3848 )
3824
3849
3825 repo = scmutil.unhidehashlikerevs(repo, opts.get('rev'), 'nowarn')
3850 repo = scmutil.unhidehashlikerevs(repo, opts.get('rev'), 'nowarn')
3826 revs, differ = logcmdutil.getrevs(repo, pats, opts)
3851 revs, differ = logcmdutil.getrevs(repo, pats, opts)
3827 if linerange:
3852 if linerange:
3828 # TODO: should follow file history from logcmdutil._initialrevs(),
3853 # TODO: should follow file history from logcmdutil._initialrevs(),
3829 # then filter the result by logcmdutil._makerevset() and --limit
3854 # then filter the result by logcmdutil._makerevset() and --limit
3830 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
3855 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
3831
3856
3832 getcopies = None
3857 getcopies = None
3833 if opts.get('copies'):
3858 if opts.get('copies'):
3834 endrev = None
3859 endrev = None
3835 if revs:
3860 if revs:
3836 endrev = revs.max() + 1
3861 endrev = revs.max() + 1
3837 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
3862 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
3838
3863
3839 ui.pager('log')
3864 ui.pager('log')
3840 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, differ,
3865 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, differ,
3841 buffered=True)
3866 buffered=True)
3842 if opts.get('graph'):
3867 if opts.get('graph'):
3843 displayfn = logcmdutil.displaygraphrevs
3868 displayfn = logcmdutil.displaygraphrevs
3844 else:
3869 else:
3845 displayfn = logcmdutil.displayrevs
3870 displayfn = logcmdutil.displayrevs
3846 displayfn(ui, repo, revs, displayer, getcopies)
3871 displayfn(ui, repo, revs, displayer, getcopies)
3847
3872
3848 @command('manifest',
3873 @command('manifest',
3849 [('r', 'rev', '', _('revision to display'), _('REV')),
3874 [('r', 'rev', '', _('revision to display'), _('REV')),
3850 ('', 'all', False, _("list files from all revisions"))]
3875 ('', 'all', False, _("list files from all revisions"))]
3851 + formatteropts,
3876 + formatteropts,
3852 _('[-r REV]'),
3877 _('[-r REV]'),
3853 helpcategory=command.CATEGORY_MAINTENANCE,
3878 helpcategory=command.CATEGORY_MAINTENANCE,
3854 intents={INTENT_READONLY})
3879 intents={INTENT_READONLY})
3855 def manifest(ui, repo, node=None, rev=None, **opts):
3880 def manifest(ui, repo, node=None, rev=None, **opts):
3856 """output the current or given revision of the project manifest
3881 """output the current or given revision of the project manifest
3857
3882
3858 Print a list of version controlled files for the given revision.
3883 Print a list of version controlled files for the given revision.
3859 If no revision is given, the first parent of the working directory
3884 If no revision is given, the first parent of the working directory
3860 is used, or the null revision if no revision is checked out.
3885 is used, or the null revision if no revision is checked out.
3861
3886
3862 With -v, print file permissions, symlink and executable bits.
3887 With -v, print file permissions, symlink and executable bits.
3863 With --debug, print file revision hashes.
3888 With --debug, print file revision hashes.
3864
3889
3865 If option --all is specified, the list of all files from all revisions
3890 If option --all is specified, the list of all files from all revisions
3866 is printed. This includes deleted and renamed files.
3891 is printed. This includes deleted and renamed files.
3867
3892
3868 Returns 0 on success.
3893 Returns 0 on success.
3869 """
3894 """
3870 opts = pycompat.byteskwargs(opts)
3895 opts = pycompat.byteskwargs(opts)
3871 fm = ui.formatter('manifest', opts)
3896 fm = ui.formatter('manifest', opts)
3872
3897
3873 if opts.get('all'):
3898 if opts.get('all'):
3874 if rev or node:
3899 if rev or node:
3875 raise error.Abort(_("can't specify a revision with --all"))
3900 raise error.Abort(_("can't specify a revision with --all"))
3876
3901
3877 res = set()
3902 res = set()
3878 for rev in repo:
3903 for rev in repo:
3879 ctx = repo[rev]
3904 ctx = repo[rev]
3880 res |= set(ctx.files())
3905 res |= set(ctx.files())
3881
3906
3882 ui.pager('manifest')
3907 ui.pager('manifest')
3883 for f in sorted(res):
3908 for f in sorted(res):
3884 fm.startitem()
3909 fm.startitem()
3885 fm.write("path", '%s\n', f)
3910 fm.write("path", '%s\n', f)
3886 fm.end()
3911 fm.end()
3887 return
3912 return
3888
3913
3889 if rev and node:
3914 if rev and node:
3890 raise error.Abort(_("please specify just one revision"))
3915 raise error.Abort(_("please specify just one revision"))
3891
3916
3892 if not node:
3917 if not node:
3893 node = rev
3918 node = rev
3894
3919
3895 char = {'l': '@', 'x': '*', '': '', 't': 'd'}
3920 char = {'l': '@', 'x': '*', '': '', 't': 'd'}
3896 mode = {'l': '644', 'x': '755', '': '644', 't': '755'}
3921 mode = {'l': '644', 'x': '755', '': '644', 't': '755'}
3897 if node:
3922 if node:
3898 repo = scmutil.unhidehashlikerevs(repo, [node], 'nowarn')
3923 repo = scmutil.unhidehashlikerevs(repo, [node], 'nowarn')
3899 ctx = scmutil.revsingle(repo, node)
3924 ctx = scmutil.revsingle(repo, node)
3900 mf = ctx.manifest()
3925 mf = ctx.manifest()
3901 ui.pager('manifest')
3926 ui.pager('manifest')
3902 for f in ctx:
3927 for f in ctx:
3903 fm.startitem()
3928 fm.startitem()
3904 fm.context(ctx=ctx)
3929 fm.context(ctx=ctx)
3905 fl = ctx[f].flags()
3930 fl = ctx[f].flags()
3906 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3931 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3907 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3932 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3908 fm.write('path', '%s\n', f)
3933 fm.write('path', '%s\n', f)
3909 fm.end()
3934 fm.end()
3910
3935
3911 @command('merge',
3936 @command('merge',
3912 [('f', 'force', None,
3937 [('f', 'force', None,
3913 _('force a merge including outstanding changes (DEPRECATED)')),
3938 _('force a merge including outstanding changes (DEPRECATED)')),
3914 ('r', 'rev', '', _('revision to merge'), _('REV')),
3939 ('r', 'rev', '', _('revision to merge'), _('REV')),
3915 ('P', 'preview', None,
3940 ('P', 'preview', None,
3916 _('review revisions to merge (no merge is performed)')),
3941 _('review revisions to merge (no merge is performed)')),
3917 ('', 'abort', None, _('abort the ongoing merge')),
3942 ('', 'abort', None, _('abort the ongoing merge')),
3918 ] + mergetoolopts,
3943 ] + mergetoolopts,
3919 _('[-P] [[-r] REV]'),
3944 _('[-P] [[-r] REV]'),
3920 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, helpbasic=True)
3945 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, helpbasic=True)
3921 def merge(ui, repo, node=None, **opts):
3946 def merge(ui, repo, node=None, **opts):
3922 """merge another revision into working directory
3947 """merge another revision into working directory
3923
3948
3924 The current working directory is updated with all changes made in
3949 The current working directory is updated with all changes made in
3925 the requested revision since the last common predecessor revision.
3950 the requested revision since the last common predecessor revision.
3926
3951
3927 Files that changed between either parent are marked as changed for
3952 Files that changed between either parent are marked as changed for
3928 the next commit and a commit must be performed before any further
3953 the next commit and a commit must be performed before any further
3929 updates to the repository are allowed. The next commit will have
3954 updates to the repository are allowed. The next commit will have
3930 two parents.
3955 two parents.
3931
3956
3932 ``--tool`` can be used to specify the merge tool used for file
3957 ``--tool`` can be used to specify the merge tool used for file
3933 merges. It overrides the HGMERGE environment variable and your
3958 merges. It overrides the HGMERGE environment variable and your
3934 configuration files. See :hg:`help merge-tools` for options.
3959 configuration files. See :hg:`help merge-tools` for options.
3935
3960
3936 If no revision is specified, the working directory's parent is a
3961 If no revision is specified, the working directory's parent is a
3937 head revision, and the current branch contains exactly one other
3962 head revision, and the current branch contains exactly one other
3938 head, the other head is merged with by default. Otherwise, an
3963 head, the other head is merged with by default. Otherwise, an
3939 explicit revision with which to merge must be provided.
3964 explicit revision with which to merge must be provided.
3940
3965
3941 See :hg:`help resolve` for information on handling file conflicts.
3966 See :hg:`help resolve` for information on handling file conflicts.
3942
3967
3943 To undo an uncommitted merge, use :hg:`merge --abort` which
3968 To undo an uncommitted merge, use :hg:`merge --abort` which
3944 will check out a clean copy of the original merge parent, losing
3969 will check out a clean copy of the original merge parent, losing
3945 all changes.
3970 all changes.
3946
3971
3947 Returns 0 on success, 1 if there are unresolved files.
3972 Returns 0 on success, 1 if there are unresolved files.
3948 """
3973 """
3949
3974
3950 opts = pycompat.byteskwargs(opts)
3975 opts = pycompat.byteskwargs(opts)
3951 abort = opts.get('abort')
3976 abort = opts.get('abort')
3952 if abort and repo.dirstate.p2() == nullid:
3977 if abort and repo.dirstate.p2() == nullid:
3953 cmdutil.wrongtooltocontinue(repo, _('merge'))
3978 cmdutil.wrongtooltocontinue(repo, _('merge'))
3954 if abort:
3979 if abort:
3955 state = cmdutil.getunfinishedstate(repo)
3980 state = cmdutil.getunfinishedstate(repo)
3956 if state and state._opname != 'merge':
3981 if state and state._opname != 'merge':
3957 raise error.Abort(_('cannot abort merge with %s in progress') %
3982 raise error.Abort(_('cannot abort merge with %s in progress') %
3958 (state._opname), hint=state.hint())
3983 (state._opname), hint=state.hint())
3959 if node:
3984 if node:
3960 raise error.Abort(_("cannot specify a node with --abort"))
3985 raise error.Abort(_("cannot specify a node with --abort"))
3961 if opts.get('rev'):
3986 if opts.get('rev'):
3962 raise error.Abort(_("cannot specify both --rev and --abort"))
3987 raise error.Abort(_("cannot specify both --rev and --abort"))
3963 if opts.get('preview'):
3988 if opts.get('preview'):
3964 raise error.Abort(_("cannot specify --preview with --abort"))
3989 raise error.Abort(_("cannot specify --preview with --abort"))
3965 if opts.get('rev') and node:
3990 if opts.get('rev') and node:
3966 raise error.Abort(_("please specify just one revision"))
3991 raise error.Abort(_("please specify just one revision"))
3967 if not node:
3992 if not node:
3968 node = opts.get('rev')
3993 node = opts.get('rev')
3969
3994
3970 if node:
3995 if node:
3971 node = scmutil.revsingle(repo, node).node()
3996 node = scmutil.revsingle(repo, node).node()
3972
3997
3973 if not node and not abort:
3998 if not node and not abort:
3974 node = repo[destutil.destmerge(repo)].node()
3999 node = repo[destutil.destmerge(repo)].node()
3975
4000
3976 if opts.get('preview'):
4001 if opts.get('preview'):
3977 # find nodes that are ancestors of p2 but not of p1
4002 # find nodes that are ancestors of p2 but not of p1
3978 p1 = repo.lookup('.')
4003 p1 = repo.lookup('.')
3979 p2 = node
4004 p2 = node
3980 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4005 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
3981
4006
3982 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4007 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3983 for node in nodes:
4008 for node in nodes:
3984 displayer.show(repo[node])
4009 displayer.show(repo[node])
3985 displayer.close()
4010 displayer.close()
3986 return 0
4011 return 0
3987
4012
3988 # ui.forcemerge is an internal variable, do not document
4013 # ui.forcemerge is an internal variable, do not document
3989 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4014 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
3990 with ui.configoverride(overrides, 'merge'):
4015 with ui.configoverride(overrides, 'merge'):
3991 force = opts.get('force')
4016 force = opts.get('force')
3992 labels = ['working copy', 'merge rev']
4017 labels = ['working copy', 'merge rev']
3993 return hg.merge(repo, node, force=force, mergeforce=force,
4018 return hg.merge(repo, node, force=force, mergeforce=force,
3994 labels=labels, abort=abort)
4019 labels=labels, abort=abort)
3995
4020
3996 @command('outgoing|out',
4021 @command('outgoing|out',
3997 [('f', 'force', None, _('run even when the destination is unrelated')),
4022 [('f', 'force', None, _('run even when the destination is unrelated')),
3998 ('r', 'rev', [],
4023 ('r', 'rev', [],
3999 _('a changeset intended to be included in the destination'), _('REV')),
4024 _('a changeset intended to be included in the destination'), _('REV')),
4000 ('n', 'newest-first', None, _('show newest record first')),
4025 ('n', 'newest-first', None, _('show newest record first')),
4001 ('B', 'bookmarks', False, _('compare bookmarks')),
4026 ('B', 'bookmarks', False, _('compare bookmarks')),
4002 ('b', 'branch', [], _('a specific branch you would like to push'),
4027 ('b', 'branch', [], _('a specific branch you would like to push'),
4003 _('BRANCH')),
4028 _('BRANCH')),
4004 ] + logopts + remoteopts + subrepoopts,
4029 ] + logopts + remoteopts + subrepoopts,
4005 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4030 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4006 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
4031 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
4007 def outgoing(ui, repo, dest=None, **opts):
4032 def outgoing(ui, repo, dest=None, **opts):
4008 """show changesets not found in the destination
4033 """show changesets not found in the destination
4009
4034
4010 Show changesets not found in the specified destination repository
4035 Show changesets not found in the specified destination repository
4011 or the default push location. These are the changesets that would
4036 or the default push location. These are the changesets that would
4012 be pushed if a push was requested.
4037 be pushed if a push was requested.
4013
4038
4014 See pull for details of valid destination formats.
4039 See pull for details of valid destination formats.
4015
4040
4016 .. container:: verbose
4041 .. container:: verbose
4017
4042
4018 With -B/--bookmarks, the result of bookmark comparison between
4043 With -B/--bookmarks, the result of bookmark comparison between
4019 local and remote repositories is displayed. With -v/--verbose,
4044 local and remote repositories is displayed. With -v/--verbose,
4020 status is also displayed for each bookmark like below::
4045 status is also displayed for each bookmark like below::
4021
4046
4022 BM1 01234567890a added
4047 BM1 01234567890a added
4023 BM2 deleted
4048 BM2 deleted
4024 BM3 234567890abc advanced
4049 BM3 234567890abc advanced
4025 BM4 34567890abcd diverged
4050 BM4 34567890abcd diverged
4026 BM5 4567890abcde changed
4051 BM5 4567890abcde changed
4027
4052
4028 The action taken when pushing depends on the
4053 The action taken when pushing depends on the
4029 status of each bookmark:
4054 status of each bookmark:
4030
4055
4031 :``added``: push with ``-B`` will create it
4056 :``added``: push with ``-B`` will create it
4032 :``deleted``: push with ``-B`` will delete it
4057 :``deleted``: push with ``-B`` will delete it
4033 :``advanced``: push will update it
4058 :``advanced``: push will update it
4034 :``diverged``: push with ``-B`` will update it
4059 :``diverged``: push with ``-B`` will update it
4035 :``changed``: push with ``-B`` will update it
4060 :``changed``: push with ``-B`` will update it
4036
4061
4037 From the point of view of pushing behavior, bookmarks
4062 From the point of view of pushing behavior, bookmarks
4038 existing only in the remote repository are treated as
4063 existing only in the remote repository are treated as
4039 ``deleted``, even if it is in fact added remotely.
4064 ``deleted``, even if it is in fact added remotely.
4040
4065
4041 Returns 0 if there are outgoing changes, 1 otherwise.
4066 Returns 0 if there are outgoing changes, 1 otherwise.
4042 """
4067 """
4043 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4068 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4044 # style URLs, so don't overwrite dest.
4069 # style URLs, so don't overwrite dest.
4045 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4070 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4046 if not path:
4071 if not path:
4047 raise error.Abort(_('default repository not configured!'),
4072 raise error.Abort(_('default repository not configured!'),
4048 hint=_("see 'hg help config.paths'"))
4073 hint=_("see 'hg help config.paths'"))
4049
4074
4050 opts = pycompat.byteskwargs(opts)
4075 opts = pycompat.byteskwargs(opts)
4051 if opts.get('graph'):
4076 if opts.get('graph'):
4052 logcmdutil.checkunsupportedgraphflags([], opts)
4077 logcmdutil.checkunsupportedgraphflags([], opts)
4053 o, other = hg._outgoing(ui, repo, dest, opts)
4078 o, other = hg._outgoing(ui, repo, dest, opts)
4054 if not o:
4079 if not o:
4055 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4080 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4056 return
4081 return
4057
4082
4058 revdag = logcmdutil.graphrevs(repo, o, opts)
4083 revdag = logcmdutil.graphrevs(repo, o, opts)
4059 ui.pager('outgoing')
4084 ui.pager('outgoing')
4060 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4085 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4061 logcmdutil.displaygraph(ui, repo, revdag, displayer,
4086 logcmdutil.displaygraph(ui, repo, revdag, displayer,
4062 graphmod.asciiedges)
4087 graphmod.asciiedges)
4063 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4088 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4064 return 0
4089 return 0
4065
4090
4066 if opts.get('bookmarks'):
4091 if opts.get('bookmarks'):
4067 dest = path.pushloc or path.loc
4092 dest = path.pushloc or path.loc
4068 other = hg.peer(repo, opts, dest)
4093 other = hg.peer(repo, opts, dest)
4069 if 'bookmarks' not in other.listkeys('namespaces'):
4094 if 'bookmarks' not in other.listkeys('namespaces'):
4070 ui.warn(_("remote doesn't support bookmarks\n"))
4095 ui.warn(_("remote doesn't support bookmarks\n"))
4071 return 0
4096 return 0
4072 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4097 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4073 ui.pager('outgoing')
4098 ui.pager('outgoing')
4074 return bookmarks.outgoing(ui, repo, other)
4099 return bookmarks.outgoing(ui, repo, other)
4075
4100
4076 repo._subtoppath = path.pushloc or path.loc
4101 repo._subtoppath = path.pushloc or path.loc
4077 try:
4102 try:
4078 return hg.outgoing(ui, repo, dest, opts)
4103 return hg.outgoing(ui, repo, dest, opts)
4079 finally:
4104 finally:
4080 del repo._subtoppath
4105 del repo._subtoppath
4081
4106
4082 @command('parents',
4107 @command('parents',
4083 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4108 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4084 ] + templateopts,
4109 ] + templateopts,
4085 _('[-r REV] [FILE]'),
4110 _('[-r REV] [FILE]'),
4086 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4111 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4087 inferrepo=True)
4112 inferrepo=True)
4088 def parents(ui, repo, file_=None, **opts):
4113 def parents(ui, repo, file_=None, **opts):
4089 """show the parents of the working directory or revision (DEPRECATED)
4114 """show the parents of the working directory or revision (DEPRECATED)
4090
4115
4091 Print the working directory's parent revisions. If a revision is
4116 Print the working directory's parent revisions. If a revision is
4092 given via -r/--rev, the parent of that revision will be printed.
4117 given via -r/--rev, the parent of that revision will be printed.
4093 If a file argument is given, the revision in which the file was
4118 If a file argument is given, the revision in which the file was
4094 last changed (before the working directory revision or the
4119 last changed (before the working directory revision or the
4095 argument to --rev if given) is printed.
4120 argument to --rev if given) is printed.
4096
4121
4097 This command is equivalent to::
4122 This command is equivalent to::
4098
4123
4099 hg log -r "p1()+p2()" or
4124 hg log -r "p1()+p2()" or
4100 hg log -r "p1(REV)+p2(REV)" or
4125 hg log -r "p1(REV)+p2(REV)" or
4101 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
4126 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
4102 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
4127 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
4103
4128
4104 See :hg:`summary` and :hg:`help revsets` for related information.
4129 See :hg:`summary` and :hg:`help revsets` for related information.
4105
4130
4106 Returns 0 on success.
4131 Returns 0 on success.
4107 """
4132 """
4108
4133
4109 opts = pycompat.byteskwargs(opts)
4134 opts = pycompat.byteskwargs(opts)
4110 rev = opts.get('rev')
4135 rev = opts.get('rev')
4111 if rev:
4136 if rev:
4112 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
4137 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
4113 ctx = scmutil.revsingle(repo, rev, None)
4138 ctx = scmutil.revsingle(repo, rev, None)
4114
4139
4115 if file_:
4140 if file_:
4116 m = scmutil.match(ctx, (file_,), opts)
4141 m = scmutil.match(ctx, (file_,), opts)
4117 if m.anypats() or len(m.files()) != 1:
4142 if m.anypats() or len(m.files()) != 1:
4118 raise error.Abort(_('can only specify an explicit filename'))
4143 raise error.Abort(_('can only specify an explicit filename'))
4119 file_ = m.files()[0]
4144 file_ = m.files()[0]
4120 filenodes = []
4145 filenodes = []
4121 for cp in ctx.parents():
4146 for cp in ctx.parents():
4122 if not cp:
4147 if not cp:
4123 continue
4148 continue
4124 try:
4149 try:
4125 filenodes.append(cp.filenode(file_))
4150 filenodes.append(cp.filenode(file_))
4126 except error.LookupError:
4151 except error.LookupError:
4127 pass
4152 pass
4128 if not filenodes:
4153 if not filenodes:
4129 raise error.Abort(_("'%s' not found in manifest!") % file_)
4154 raise error.Abort(_("'%s' not found in manifest!") % file_)
4130 p = []
4155 p = []
4131 for fn in filenodes:
4156 for fn in filenodes:
4132 fctx = repo.filectx(file_, fileid=fn)
4157 fctx = repo.filectx(file_, fileid=fn)
4133 p.append(fctx.node())
4158 p.append(fctx.node())
4134 else:
4159 else:
4135 p = [cp.node() for cp in ctx.parents()]
4160 p = [cp.node() for cp in ctx.parents()]
4136
4161
4137 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4162 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4138 for n in p:
4163 for n in p:
4139 if n != nullid:
4164 if n != nullid:
4140 displayer.show(repo[n])
4165 displayer.show(repo[n])
4141 displayer.close()
4166 displayer.close()
4142
4167
4143 @command('paths', formatteropts, _('[NAME]'),
4168 @command('paths', formatteropts, _('[NAME]'),
4144 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4169 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4145 optionalrepo=True, intents={INTENT_READONLY})
4170 optionalrepo=True, intents={INTENT_READONLY})
4146 def paths(ui, repo, search=None, **opts):
4171 def paths(ui, repo, search=None, **opts):
4147 """show aliases for remote repositories
4172 """show aliases for remote repositories
4148
4173
4149 Show definition of symbolic path name NAME. If no name is given,
4174 Show definition of symbolic path name NAME. If no name is given,
4150 show definition of all available names.
4175 show definition of all available names.
4151
4176
4152 Option -q/--quiet suppresses all output when searching for NAME
4177 Option -q/--quiet suppresses all output when searching for NAME
4153 and shows only the path names when listing all definitions.
4178 and shows only the path names when listing all definitions.
4154
4179
4155 Path names are defined in the [paths] section of your
4180 Path names are defined in the [paths] section of your
4156 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4181 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4157 repository, ``.hg/hgrc`` is used, too.
4182 repository, ``.hg/hgrc`` is used, too.
4158
4183
4159 The path names ``default`` and ``default-push`` have a special
4184 The path names ``default`` and ``default-push`` have a special
4160 meaning. When performing a push or pull operation, they are used
4185 meaning. When performing a push or pull operation, they are used
4161 as fallbacks if no location is specified on the command-line.
4186 as fallbacks if no location is specified on the command-line.
4162 When ``default-push`` is set, it will be used for push and
4187 When ``default-push`` is set, it will be used for push and
4163 ``default`` will be used for pull; otherwise ``default`` is used
4188 ``default`` will be used for pull; otherwise ``default`` is used
4164 as the fallback for both. When cloning a repository, the clone
4189 as the fallback for both. When cloning a repository, the clone
4165 source is written as ``default`` in ``.hg/hgrc``.
4190 source is written as ``default`` in ``.hg/hgrc``.
4166
4191
4167 .. note::
4192 .. note::
4168
4193
4169 ``default`` and ``default-push`` apply to all inbound (e.g.
4194 ``default`` and ``default-push`` apply to all inbound (e.g.
4170 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
4195 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
4171 and :hg:`bundle`) operations.
4196 and :hg:`bundle`) operations.
4172
4197
4173 See :hg:`help urls` for more information.
4198 See :hg:`help urls` for more information.
4174
4199
4175 .. container:: verbose
4200 .. container:: verbose
4176
4201
4177 Template:
4202 Template:
4178
4203
4179 The following keywords are supported. See also :hg:`help templates`.
4204 The following keywords are supported. See also :hg:`help templates`.
4180
4205
4181 :name: String. Symbolic name of the path alias.
4206 :name: String. Symbolic name of the path alias.
4182 :pushurl: String. URL for push operations.
4207 :pushurl: String. URL for push operations.
4183 :url: String. URL or directory path for the other operations.
4208 :url: String. URL or directory path for the other operations.
4184
4209
4185 Returns 0 on success.
4210 Returns 0 on success.
4186 """
4211 """
4187
4212
4188 opts = pycompat.byteskwargs(opts)
4213 opts = pycompat.byteskwargs(opts)
4189 ui.pager('paths')
4214 ui.pager('paths')
4190 if search:
4215 if search:
4191 pathitems = [(name, path) for name, path in ui.paths.iteritems()
4216 pathitems = [(name, path) for name, path in ui.paths.iteritems()
4192 if name == search]
4217 if name == search]
4193 else:
4218 else:
4194 pathitems = sorted(ui.paths.iteritems())
4219 pathitems = sorted(ui.paths.iteritems())
4195
4220
4196 fm = ui.formatter('paths', opts)
4221 fm = ui.formatter('paths', opts)
4197 if fm.isplain():
4222 if fm.isplain():
4198 hidepassword = util.hidepassword
4223 hidepassword = util.hidepassword
4199 else:
4224 else:
4200 hidepassword = bytes
4225 hidepassword = bytes
4201 if ui.quiet:
4226 if ui.quiet:
4202 namefmt = '%s\n'
4227 namefmt = '%s\n'
4203 else:
4228 else:
4204 namefmt = '%s = '
4229 namefmt = '%s = '
4205 showsubopts = not search and not ui.quiet
4230 showsubopts = not search and not ui.quiet
4206
4231
4207 for name, path in pathitems:
4232 for name, path in pathitems:
4208 fm.startitem()
4233 fm.startitem()
4209 fm.condwrite(not search, 'name', namefmt, name)
4234 fm.condwrite(not search, 'name', namefmt, name)
4210 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
4235 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
4211 for subopt, value in sorted(path.suboptions.items()):
4236 for subopt, value in sorted(path.suboptions.items()):
4212 assert subopt not in ('name', 'url')
4237 assert subopt not in ('name', 'url')
4213 if showsubopts:
4238 if showsubopts:
4214 fm.plain('%s:%s = ' % (name, subopt))
4239 fm.plain('%s:%s = ' % (name, subopt))
4215 fm.condwrite(showsubopts, subopt, '%s\n', value)
4240 fm.condwrite(showsubopts, subopt, '%s\n', value)
4216
4241
4217 fm.end()
4242 fm.end()
4218
4243
4219 if search and not pathitems:
4244 if search and not pathitems:
4220 if not ui.quiet:
4245 if not ui.quiet:
4221 ui.warn(_("not found!\n"))
4246 ui.warn(_("not found!\n"))
4222 return 1
4247 return 1
4223 else:
4248 else:
4224 return 0
4249 return 0
4225
4250
4226 @command('phase',
4251 @command('phase',
4227 [('p', 'public', False, _('set changeset phase to public')),
4252 [('p', 'public', False, _('set changeset phase to public')),
4228 ('d', 'draft', False, _('set changeset phase to draft')),
4253 ('d', 'draft', False, _('set changeset phase to draft')),
4229 ('s', 'secret', False, _('set changeset phase to secret')),
4254 ('s', 'secret', False, _('set changeset phase to secret')),
4230 ('f', 'force', False, _('allow to move boundary backward')),
4255 ('f', 'force', False, _('allow to move boundary backward')),
4231 ('r', 'rev', [], _('target revision'), _('REV')),
4256 ('r', 'rev', [], _('target revision'), _('REV')),
4232 ],
4257 ],
4233 _('[-p|-d|-s] [-f] [-r] [REV...]'),
4258 _('[-p|-d|-s] [-f] [-r] [REV...]'),
4234 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
4259 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
4235 def phase(ui, repo, *revs, **opts):
4260 def phase(ui, repo, *revs, **opts):
4236 """set or show the current phase name
4261 """set or show the current phase name
4237
4262
4238 With no argument, show the phase name of the current revision(s).
4263 With no argument, show the phase name of the current revision(s).
4239
4264
4240 With one of -p/--public, -d/--draft or -s/--secret, change the
4265 With one of -p/--public, -d/--draft or -s/--secret, change the
4241 phase value of the specified revisions.
4266 phase value of the specified revisions.
4242
4267
4243 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
4268 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
4244 lower phase to a higher phase. Phases are ordered as follows::
4269 lower phase to a higher phase. Phases are ordered as follows::
4245
4270
4246 public < draft < secret
4271 public < draft < secret
4247
4272
4248 Returns 0 on success, 1 if some phases could not be changed.
4273 Returns 0 on success, 1 if some phases could not be changed.
4249
4274
4250 (For more information about the phases concept, see :hg:`help phases`.)
4275 (For more information about the phases concept, see :hg:`help phases`.)
4251 """
4276 """
4252 opts = pycompat.byteskwargs(opts)
4277 opts = pycompat.byteskwargs(opts)
4253 # search for a unique phase argument
4278 # search for a unique phase argument
4254 targetphase = None
4279 targetphase = None
4255 for idx, name in enumerate(phases.cmdphasenames):
4280 for idx, name in enumerate(phases.cmdphasenames):
4256 if opts[name]:
4281 if opts[name]:
4257 if targetphase is not None:
4282 if targetphase is not None:
4258 raise error.Abort(_('only one phase can be specified'))
4283 raise error.Abort(_('only one phase can be specified'))
4259 targetphase = idx
4284 targetphase = idx
4260
4285
4261 # look for specified revision
4286 # look for specified revision
4262 revs = list(revs)
4287 revs = list(revs)
4263 revs.extend(opts['rev'])
4288 revs.extend(opts['rev'])
4264 if not revs:
4289 if not revs:
4265 # display both parents as the second parent phase can influence
4290 # display both parents as the second parent phase can influence
4266 # the phase of a merge commit
4291 # the phase of a merge commit
4267 revs = [c.rev() for c in repo[None].parents()]
4292 revs = [c.rev() for c in repo[None].parents()]
4268
4293
4269 revs = scmutil.revrange(repo, revs)
4294 revs = scmutil.revrange(repo, revs)
4270
4295
4271 ret = 0
4296 ret = 0
4272 if targetphase is None:
4297 if targetphase is None:
4273 # display
4298 # display
4274 for r in revs:
4299 for r in revs:
4275 ctx = repo[r]
4300 ctx = repo[r]
4276 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4301 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4277 else:
4302 else:
4278 with repo.lock(), repo.transaction("phase") as tr:
4303 with repo.lock(), repo.transaction("phase") as tr:
4279 # set phase
4304 # set phase
4280 if not revs:
4305 if not revs:
4281 raise error.Abort(_('empty revision set'))
4306 raise error.Abort(_('empty revision set'))
4282 nodes = [repo[r].node() for r in revs]
4307 nodes = [repo[r].node() for r in revs]
4283 # moving revision from public to draft may hide them
4308 # moving revision from public to draft may hide them
4284 # We have to check result on an unfiltered repository
4309 # We have to check result on an unfiltered repository
4285 unfi = repo.unfiltered()
4310 unfi = repo.unfiltered()
4286 getphase = unfi._phasecache.phase
4311 getphase = unfi._phasecache.phase
4287 olddata = [getphase(unfi, r) for r in unfi]
4312 olddata = [getphase(unfi, r) for r in unfi]
4288 phases.advanceboundary(repo, tr, targetphase, nodes)
4313 phases.advanceboundary(repo, tr, targetphase, nodes)
4289 if opts['force']:
4314 if opts['force']:
4290 phases.retractboundary(repo, tr, targetphase, nodes)
4315 phases.retractboundary(repo, tr, targetphase, nodes)
4291 getphase = unfi._phasecache.phase
4316 getphase = unfi._phasecache.phase
4292 newdata = [getphase(unfi, r) for r in unfi]
4317 newdata = [getphase(unfi, r) for r in unfi]
4293 changes = sum(newdata[r] != olddata[r] for r in unfi)
4318 changes = sum(newdata[r] != olddata[r] for r in unfi)
4294 cl = unfi.changelog
4319 cl = unfi.changelog
4295 rejected = [n for n in nodes
4320 rejected = [n for n in nodes
4296 if newdata[cl.rev(n)] < targetphase]
4321 if newdata[cl.rev(n)] < targetphase]
4297 if rejected:
4322 if rejected:
4298 ui.warn(_('cannot move %i changesets to a higher '
4323 ui.warn(_('cannot move %i changesets to a higher '
4299 'phase, use --force\n') % len(rejected))
4324 'phase, use --force\n') % len(rejected))
4300 ret = 1
4325 ret = 1
4301 if changes:
4326 if changes:
4302 msg = _('phase changed for %i changesets\n') % changes
4327 msg = _('phase changed for %i changesets\n') % changes
4303 if ret:
4328 if ret:
4304 ui.status(msg)
4329 ui.status(msg)
4305 else:
4330 else:
4306 ui.note(msg)
4331 ui.note(msg)
4307 else:
4332 else:
4308 ui.warn(_('no phases changed\n'))
4333 ui.warn(_('no phases changed\n'))
4309 return ret
4334 return ret
4310
4335
4311 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
4336 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
4312 """Run after a changegroup has been added via pull/unbundle
4337 """Run after a changegroup has been added via pull/unbundle
4313
4338
4314 This takes arguments below:
4339 This takes arguments below:
4315
4340
4316 :modheads: change of heads by pull/unbundle
4341 :modheads: change of heads by pull/unbundle
4317 :optupdate: updating working directory is needed or not
4342 :optupdate: updating working directory is needed or not
4318 :checkout: update destination revision (or None to default destination)
4343 :checkout: update destination revision (or None to default destination)
4319 :brev: a name, which might be a bookmark to be activated after updating
4344 :brev: a name, which might be a bookmark to be activated after updating
4320 """
4345 """
4321 if modheads == 0:
4346 if modheads == 0:
4322 return
4347 return
4323 if optupdate:
4348 if optupdate:
4324 try:
4349 try:
4325 return hg.updatetotally(ui, repo, checkout, brev)
4350 return hg.updatetotally(ui, repo, checkout, brev)
4326 except error.UpdateAbort as inst:
4351 except error.UpdateAbort as inst:
4327 msg = _("not updating: %s") % stringutil.forcebytestr(inst)
4352 msg = _("not updating: %s") % stringutil.forcebytestr(inst)
4328 hint = inst.hint
4353 hint = inst.hint
4329 raise error.UpdateAbort(msg, hint=hint)
4354 raise error.UpdateAbort(msg, hint=hint)
4330 if modheads is not None and modheads > 1:
4355 if modheads is not None and modheads > 1:
4331 currentbranchheads = len(repo.branchheads())
4356 currentbranchheads = len(repo.branchheads())
4332 if currentbranchheads == modheads:
4357 if currentbranchheads == modheads:
4333 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4358 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4334 elif currentbranchheads > 1:
4359 elif currentbranchheads > 1:
4335 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4360 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4336 "merge)\n"))
4361 "merge)\n"))
4337 else:
4362 else:
4338 ui.status(_("(run 'hg heads' to see heads)\n"))
4363 ui.status(_("(run 'hg heads' to see heads)\n"))
4339 elif not ui.configbool('commands', 'update.requiredest'):
4364 elif not ui.configbool('commands', 'update.requiredest'):
4340 ui.status(_("(run 'hg update' to get a working copy)\n"))
4365 ui.status(_("(run 'hg update' to get a working copy)\n"))
4341
4366
4342 @command('pull',
4367 @command('pull',
4343 [('u', 'update', None,
4368 [('u', 'update', None,
4344 _('update to new branch head if new descendants were pulled')),
4369 _('update to new branch head if new descendants were pulled')),
4345 ('f', 'force', None, _('run even when remote repository is unrelated')),
4370 ('f', 'force', None, _('run even when remote repository is unrelated')),
4346 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4371 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4347 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4372 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4348 ('b', 'branch', [], _('a specific branch you would like to pull'),
4373 ('b', 'branch', [], _('a specific branch you would like to pull'),
4349 _('BRANCH')),
4374 _('BRANCH')),
4350 ] + remoteopts,
4375 ] + remoteopts,
4351 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
4376 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
4352 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4377 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4353 helpbasic=True)
4378 helpbasic=True)
4354 def pull(ui, repo, source="default", **opts):
4379 def pull(ui, repo, source="default", **opts):
4355 """pull changes from the specified source
4380 """pull changes from the specified source
4356
4381
4357 Pull changes from a remote repository to a local one.
4382 Pull changes from a remote repository to a local one.
4358
4383
4359 This finds all changes from the repository at the specified path
4384 This finds all changes from the repository at the specified path
4360 or URL and adds them to a local repository (the current one unless
4385 or URL and adds them to a local repository (the current one unless
4361 -R is specified). By default, this does not update the copy of the
4386 -R is specified). By default, this does not update the copy of the
4362 project in the working directory.
4387 project in the working directory.
4363
4388
4364 When cloning from servers that support it, Mercurial may fetch
4389 When cloning from servers that support it, Mercurial may fetch
4365 pre-generated data. When this is done, hooks operating on incoming
4390 pre-generated data. When this is done, hooks operating on incoming
4366 changesets and changegroups may fire more than once, once for each
4391 changesets and changegroups may fire more than once, once for each
4367 pre-generated bundle and as well as for any additional remaining
4392 pre-generated bundle and as well as for any additional remaining
4368 data. See :hg:`help -e clonebundles` for more.
4393 data. See :hg:`help -e clonebundles` for more.
4369
4394
4370 Use :hg:`incoming` if you want to see what would have been added
4395 Use :hg:`incoming` if you want to see what would have been added
4371 by a pull at the time you issued this command. If you then decide
4396 by a pull at the time you issued this command. If you then decide
4372 to add those changes to the repository, you should use :hg:`pull
4397 to add those changes to the repository, you should use :hg:`pull
4373 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4398 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4374
4399
4375 If SOURCE is omitted, the 'default' path will be used.
4400 If SOURCE is omitted, the 'default' path will be used.
4376 See :hg:`help urls` for more information.
4401 See :hg:`help urls` for more information.
4377
4402
4378 Specifying bookmark as ``.`` is equivalent to specifying the active
4403 Specifying bookmark as ``.`` is equivalent to specifying the active
4379 bookmark's name.
4404 bookmark's name.
4380
4405
4381 Returns 0 on success, 1 if an update had unresolved files.
4406 Returns 0 on success, 1 if an update had unresolved files.
4382 """
4407 """
4383
4408
4384 opts = pycompat.byteskwargs(opts)
4409 opts = pycompat.byteskwargs(opts)
4385 if ui.configbool('commands', 'update.requiredest') and opts.get('update'):
4410 if ui.configbool('commands', 'update.requiredest') and opts.get('update'):
4386 msg = _('update destination required by configuration')
4411 msg = _('update destination required by configuration')
4387 hint = _('use hg pull followed by hg update DEST')
4412 hint = _('use hg pull followed by hg update DEST')
4388 raise error.Abort(msg, hint=hint)
4413 raise error.Abort(msg, hint=hint)
4389
4414
4390 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4415 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4391 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4416 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4392 other = hg.peer(repo, opts, source)
4417 other = hg.peer(repo, opts, source)
4393 try:
4418 try:
4394 revs, checkout = hg.addbranchrevs(repo, other, branches,
4419 revs, checkout = hg.addbranchrevs(repo, other, branches,
4395 opts.get('rev'))
4420 opts.get('rev'))
4396
4421
4397 pullopargs = {}
4422 pullopargs = {}
4398
4423
4399 nodes = None
4424 nodes = None
4400 if opts.get('bookmark') or revs:
4425 if opts.get('bookmark') or revs:
4401 # The list of bookmark used here is the same used to actually update
4426 # The list of bookmark used here is the same used to actually update
4402 # the bookmark names, to avoid the race from issue 4689 and we do
4427 # the bookmark names, to avoid the race from issue 4689 and we do
4403 # all lookup and bookmark queries in one go so they see the same
4428 # all lookup and bookmark queries in one go so they see the same
4404 # version of the server state (issue 4700).
4429 # version of the server state (issue 4700).
4405 nodes = []
4430 nodes = []
4406 fnodes = []
4431 fnodes = []
4407 revs = revs or []
4432 revs = revs or []
4408 if revs and not other.capable('lookup'):
4433 if revs and not other.capable('lookup'):
4409 err = _("other repository doesn't support revision lookup, "
4434 err = _("other repository doesn't support revision lookup, "
4410 "so a rev cannot be specified.")
4435 "so a rev cannot be specified.")
4411 raise error.Abort(err)
4436 raise error.Abort(err)
4412 with other.commandexecutor() as e:
4437 with other.commandexecutor() as e:
4413 fremotebookmarks = e.callcommand('listkeys', {
4438 fremotebookmarks = e.callcommand('listkeys', {
4414 'namespace': 'bookmarks'
4439 'namespace': 'bookmarks'
4415 })
4440 })
4416 for r in revs:
4441 for r in revs:
4417 fnodes.append(e.callcommand('lookup', {'key': r}))
4442 fnodes.append(e.callcommand('lookup', {'key': r}))
4418 remotebookmarks = fremotebookmarks.result()
4443 remotebookmarks = fremotebookmarks.result()
4419 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
4444 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
4420 pullopargs['remotebookmarks'] = remotebookmarks
4445 pullopargs['remotebookmarks'] = remotebookmarks
4421 for b in opts.get('bookmark', []):
4446 for b in opts.get('bookmark', []):
4422 b = repo._bookmarks.expandname(b)
4447 b = repo._bookmarks.expandname(b)
4423 if b not in remotebookmarks:
4448 if b not in remotebookmarks:
4424 raise error.Abort(_('remote bookmark %s not found!') % b)
4449 raise error.Abort(_('remote bookmark %s not found!') % b)
4425 nodes.append(remotebookmarks[b])
4450 nodes.append(remotebookmarks[b])
4426 for i, rev in enumerate(revs):
4451 for i, rev in enumerate(revs):
4427 node = fnodes[i].result()
4452 node = fnodes[i].result()
4428 nodes.append(node)
4453 nodes.append(node)
4429 if rev == checkout:
4454 if rev == checkout:
4430 checkout = node
4455 checkout = node
4431
4456
4432 wlock = util.nullcontextmanager()
4457 wlock = util.nullcontextmanager()
4433 if opts.get('update'):
4458 if opts.get('update'):
4434 wlock = repo.wlock()
4459 wlock = repo.wlock()
4435 with wlock:
4460 with wlock:
4436 pullopargs.update(opts.get('opargs', {}))
4461 pullopargs.update(opts.get('opargs', {}))
4437 modheads = exchange.pull(repo, other, heads=nodes,
4462 modheads = exchange.pull(repo, other, heads=nodes,
4438 force=opts.get('force'),
4463 force=opts.get('force'),
4439 bookmarks=opts.get('bookmark', ()),
4464 bookmarks=opts.get('bookmark', ()),
4440 opargs=pullopargs).cgresult
4465 opargs=pullopargs).cgresult
4441
4466
4442 # brev is a name, which might be a bookmark to be activated at
4467 # brev is a name, which might be a bookmark to be activated at
4443 # the end of the update. In other words, it is an explicit
4468 # the end of the update. In other words, it is an explicit
4444 # destination of the update
4469 # destination of the update
4445 brev = None
4470 brev = None
4446
4471
4447 if checkout:
4472 if checkout:
4448 checkout = repo.unfiltered().changelog.rev(checkout)
4473 checkout = repo.unfiltered().changelog.rev(checkout)
4449
4474
4450 # order below depends on implementation of
4475 # order below depends on implementation of
4451 # hg.addbranchrevs(). opts['bookmark'] is ignored,
4476 # hg.addbranchrevs(). opts['bookmark'] is ignored,
4452 # because 'checkout' is determined without it.
4477 # because 'checkout' is determined without it.
4453 if opts.get('rev'):
4478 if opts.get('rev'):
4454 brev = opts['rev'][0]
4479 brev = opts['rev'][0]
4455 elif opts.get('branch'):
4480 elif opts.get('branch'):
4456 brev = opts['branch'][0]
4481 brev = opts['branch'][0]
4457 else:
4482 else:
4458 brev = branches[0]
4483 brev = branches[0]
4459 repo._subtoppath = source
4484 repo._subtoppath = source
4460 try:
4485 try:
4461 ret = postincoming(ui, repo, modheads, opts.get('update'),
4486 ret = postincoming(ui, repo, modheads, opts.get('update'),
4462 checkout, brev)
4487 checkout, brev)
4463 except error.FilteredRepoLookupError as exc:
4488 except error.FilteredRepoLookupError as exc:
4464 msg = _('cannot update to target: %s') % exc.args[0]
4489 msg = _('cannot update to target: %s') % exc.args[0]
4465 exc.args = (msg,) + exc.args[1:]
4490 exc.args = (msg,) + exc.args[1:]
4466 raise
4491 raise
4467 finally:
4492 finally:
4468 del repo._subtoppath
4493 del repo._subtoppath
4469
4494
4470 finally:
4495 finally:
4471 other.close()
4496 other.close()
4472 return ret
4497 return ret
4473
4498
4474 @command('push',
4499 @command('push',
4475 [('f', 'force', None, _('force push')),
4500 [('f', 'force', None, _('force push')),
4476 ('r', 'rev', [],
4501 ('r', 'rev', [],
4477 _('a changeset intended to be included in the destination'),
4502 _('a changeset intended to be included in the destination'),
4478 _('REV')),
4503 _('REV')),
4479 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4504 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4480 ('b', 'branch', [],
4505 ('b', 'branch', [],
4481 _('a specific branch you would like to push'), _('BRANCH')),
4506 _('a specific branch you would like to push'), _('BRANCH')),
4482 ('', 'new-branch', False, _('allow pushing a new branch')),
4507 ('', 'new-branch', False, _('allow pushing a new branch')),
4483 ('', 'pushvars', [], _('variables that can be sent to server (ADVANCED)')),
4508 ('', 'pushvars', [], _('variables that can be sent to server (ADVANCED)')),
4484 ('', 'publish', False, _('push the changeset as public (EXPERIMENTAL)')),
4509 ('', 'publish', False, _('push the changeset as public (EXPERIMENTAL)')),
4485 ] + remoteopts,
4510 ] + remoteopts,
4486 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
4511 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
4487 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4512 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4488 helpbasic=True)
4513 helpbasic=True)
4489 def push(ui, repo, dest=None, **opts):
4514 def push(ui, repo, dest=None, **opts):
4490 """push changes to the specified destination
4515 """push changes to the specified destination
4491
4516
4492 Push changesets from the local repository to the specified
4517 Push changesets from the local repository to the specified
4493 destination.
4518 destination.
4494
4519
4495 This operation is symmetrical to pull: it is identical to a pull
4520 This operation is symmetrical to pull: it is identical to a pull
4496 in the destination repository from the current one.
4521 in the destination repository from the current one.
4497
4522
4498 By default, push will not allow creation of new heads at the
4523 By default, push will not allow creation of new heads at the
4499 destination, since multiple heads would make it unclear which head
4524 destination, since multiple heads would make it unclear which head
4500 to use. In this situation, it is recommended to pull and merge
4525 to use. In this situation, it is recommended to pull and merge
4501 before pushing.
4526 before pushing.
4502
4527
4503 Use --new-branch if you want to allow push to create a new named
4528 Use --new-branch if you want to allow push to create a new named
4504 branch that is not present at the destination. This allows you to
4529 branch that is not present at the destination. This allows you to
4505 only create a new branch without forcing other changes.
4530 only create a new branch without forcing other changes.
4506
4531
4507 .. note::
4532 .. note::
4508
4533
4509 Extra care should be taken with the -f/--force option,
4534 Extra care should be taken with the -f/--force option,
4510 which will push all new heads on all branches, an action which will
4535 which will push all new heads on all branches, an action which will
4511 almost always cause confusion for collaborators.
4536 almost always cause confusion for collaborators.
4512
4537
4513 If -r/--rev is used, the specified revision and all its ancestors
4538 If -r/--rev is used, the specified revision and all its ancestors
4514 will be pushed to the remote repository.
4539 will be pushed to the remote repository.
4515
4540
4516 If -B/--bookmark is used, the specified bookmarked revision, its
4541 If -B/--bookmark is used, the specified bookmarked revision, its
4517 ancestors, and the bookmark will be pushed to the remote
4542 ancestors, and the bookmark will be pushed to the remote
4518 repository. Specifying ``.`` is equivalent to specifying the active
4543 repository. Specifying ``.`` is equivalent to specifying the active
4519 bookmark's name.
4544 bookmark's name.
4520
4545
4521 Please see :hg:`help urls` for important details about ``ssh://``
4546 Please see :hg:`help urls` for important details about ``ssh://``
4522 URLs. If DESTINATION is omitted, a default path will be used.
4547 URLs. If DESTINATION is omitted, a default path will be used.
4523
4548
4524 .. container:: verbose
4549 .. container:: verbose
4525
4550
4526 The --pushvars option sends strings to the server that become
4551 The --pushvars option sends strings to the server that become
4527 environment variables prepended with ``HG_USERVAR_``. For example,
4552 environment variables prepended with ``HG_USERVAR_``. For example,
4528 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
4553 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
4529 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
4554 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
4530
4555
4531 pushvars can provide for user-overridable hooks as well as set debug
4556 pushvars can provide for user-overridable hooks as well as set debug
4532 levels. One example is having a hook that blocks commits containing
4557 levels. One example is having a hook that blocks commits containing
4533 conflict markers, but enables the user to override the hook if the file
4558 conflict markers, but enables the user to override the hook if the file
4534 is using conflict markers for testing purposes or the file format has
4559 is using conflict markers for testing purposes or the file format has
4535 strings that look like conflict markers.
4560 strings that look like conflict markers.
4536
4561
4537 By default, servers will ignore `--pushvars`. To enable it add the
4562 By default, servers will ignore `--pushvars`. To enable it add the
4538 following to your configuration file::
4563 following to your configuration file::
4539
4564
4540 [push]
4565 [push]
4541 pushvars.server = true
4566 pushvars.server = true
4542
4567
4543 Returns 0 if push was successful, 1 if nothing to push.
4568 Returns 0 if push was successful, 1 if nothing to push.
4544 """
4569 """
4545
4570
4546 opts = pycompat.byteskwargs(opts)
4571 opts = pycompat.byteskwargs(opts)
4547 if opts.get('bookmark'):
4572 if opts.get('bookmark'):
4548 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4573 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4549 for b in opts['bookmark']:
4574 for b in opts['bookmark']:
4550 # translate -B options to -r so changesets get pushed
4575 # translate -B options to -r so changesets get pushed
4551 b = repo._bookmarks.expandname(b)
4576 b = repo._bookmarks.expandname(b)
4552 if b in repo._bookmarks:
4577 if b in repo._bookmarks:
4553 opts.setdefault('rev', []).append(b)
4578 opts.setdefault('rev', []).append(b)
4554 else:
4579 else:
4555 # if we try to push a deleted bookmark, translate it to null
4580 # if we try to push a deleted bookmark, translate it to null
4556 # this lets simultaneous -r, -b options continue working
4581 # this lets simultaneous -r, -b options continue working
4557 opts.setdefault('rev', []).append("null")
4582 opts.setdefault('rev', []).append("null")
4558
4583
4559 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4584 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4560 if not path:
4585 if not path:
4561 raise error.Abort(_('default repository not configured!'),
4586 raise error.Abort(_('default repository not configured!'),
4562 hint=_("see 'hg help config.paths'"))
4587 hint=_("see 'hg help config.paths'"))
4563 dest = path.pushloc or path.loc
4588 dest = path.pushloc or path.loc
4564 branches = (path.branch, opts.get('branch') or [])
4589 branches = (path.branch, opts.get('branch') or [])
4565 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4590 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4566 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4591 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4567 other = hg.peer(repo, opts, dest)
4592 other = hg.peer(repo, opts, dest)
4568
4593
4569 if revs:
4594 if revs:
4570 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
4595 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
4571 if not revs:
4596 if not revs:
4572 raise error.Abort(_("specified revisions evaluate to an empty set"),
4597 raise error.Abort(_("specified revisions evaluate to an empty set"),
4573 hint=_("use different revision arguments"))
4598 hint=_("use different revision arguments"))
4574 elif path.pushrev:
4599 elif path.pushrev:
4575 # It doesn't make any sense to specify ancestor revisions. So limit
4600 # It doesn't make any sense to specify ancestor revisions. So limit
4576 # to DAG heads to make discovery simpler.
4601 # to DAG heads to make discovery simpler.
4577 expr = revsetlang.formatspec('heads(%r)', path.pushrev)
4602 expr = revsetlang.formatspec('heads(%r)', path.pushrev)
4578 revs = scmutil.revrange(repo, [expr])
4603 revs = scmutil.revrange(repo, [expr])
4579 revs = [repo[rev].node() for rev in revs]
4604 revs = [repo[rev].node() for rev in revs]
4580 if not revs:
4605 if not revs:
4581 raise error.Abort(_('default push revset for path evaluates to an '
4606 raise error.Abort(_('default push revset for path evaluates to an '
4582 'empty set'))
4607 'empty set'))
4583
4608
4584 repo._subtoppath = dest
4609 repo._subtoppath = dest
4585 try:
4610 try:
4586 # push subrepos depth-first for coherent ordering
4611 # push subrepos depth-first for coherent ordering
4587 c = repo['.']
4612 c = repo['.']
4588 subs = c.substate # only repos that are committed
4613 subs = c.substate # only repos that are committed
4589 for s in sorted(subs):
4614 for s in sorted(subs):
4590 result = c.sub(s).push(opts)
4615 result = c.sub(s).push(opts)
4591 if result == 0:
4616 if result == 0:
4592 return not result
4617 return not result
4593 finally:
4618 finally:
4594 del repo._subtoppath
4619 del repo._subtoppath
4595
4620
4596 opargs = dict(opts.get('opargs', {})) # copy opargs since we may mutate it
4621 opargs = dict(opts.get('opargs', {})) # copy opargs since we may mutate it
4597 opargs.setdefault('pushvars', []).extend(opts.get('pushvars', []))
4622 opargs.setdefault('pushvars', []).extend(opts.get('pushvars', []))
4598
4623
4599 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
4624 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
4600 newbranch=opts.get('new_branch'),
4625 newbranch=opts.get('new_branch'),
4601 bookmarks=opts.get('bookmark', ()),
4626 bookmarks=opts.get('bookmark', ()),
4602 publish=opts.get('publish'),
4627 publish=opts.get('publish'),
4603 opargs=opargs)
4628 opargs=opargs)
4604
4629
4605 result = not pushop.cgresult
4630 result = not pushop.cgresult
4606
4631
4607 if pushop.bkresult is not None:
4632 if pushop.bkresult is not None:
4608 if pushop.bkresult == 2:
4633 if pushop.bkresult == 2:
4609 result = 2
4634 result = 2
4610 elif not result and pushop.bkresult:
4635 elif not result and pushop.bkresult:
4611 result = 2
4636 result = 2
4612
4637
4613 return result
4638 return result
4614
4639
4615 @command('recover',
4640 @command('recover',
4616 [('','verify', True, "run `hg verify` after succesful recover"),
4641 [('','verify', True, "run `hg verify` after succesful recover"),
4617 ],
4642 ],
4618 helpcategory=command.CATEGORY_MAINTENANCE)
4643 helpcategory=command.CATEGORY_MAINTENANCE)
4619 def recover(ui, repo, **opts):
4644 def recover(ui, repo, **opts):
4620 """roll back an interrupted transaction
4645 """roll back an interrupted transaction
4621
4646
4622 Recover from an interrupted commit or pull.
4647 Recover from an interrupted commit or pull.
4623
4648
4624 This command tries to fix the repository status after an
4649 This command tries to fix the repository status after an
4625 interrupted operation. It should only be necessary when Mercurial
4650 interrupted operation. It should only be necessary when Mercurial
4626 suggests it.
4651 suggests it.
4627
4652
4628 Returns 0 if successful, 1 if nothing to recover or verify fails.
4653 Returns 0 if successful, 1 if nothing to recover or verify fails.
4629 """
4654 """
4630 ret = repo.recover()
4655 ret = repo.recover()
4631 if ret:
4656 if ret:
4632 if opts[r'verify']:
4657 if opts[r'verify']:
4633 return hg.verify(repo)
4658 return hg.verify(repo)
4634 else:
4659 else:
4635 msg = _("(verify step skipped, run `hg verify` to check your "
4660 msg = _("(verify step skipped, run `hg verify` to check your "
4636 "repository content)\n")
4661 "repository content)\n")
4637 ui.warn(msg)
4662 ui.warn(msg)
4638 return 0
4663 return 0
4639 return 1
4664 return 1
4640
4665
4641 @command('remove|rm',
4666 @command('remove|rm',
4642 [('A', 'after', None, _('record delete for missing files')),
4667 [('A', 'after', None, _('record delete for missing files')),
4643 ('f', 'force', None,
4668 ('f', 'force', None,
4644 _('forget added files, delete modified files')),
4669 _('forget added files, delete modified files')),
4645 ] + subrepoopts + walkopts + dryrunopts,
4670 ] + subrepoopts + walkopts + dryrunopts,
4646 _('[OPTION]... FILE...'),
4671 _('[OPTION]... FILE...'),
4647 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4672 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4648 helpbasic=True, inferrepo=True)
4673 helpbasic=True, inferrepo=True)
4649 def remove(ui, repo, *pats, **opts):
4674 def remove(ui, repo, *pats, **opts):
4650 """remove the specified files on the next commit
4675 """remove the specified files on the next commit
4651
4676
4652 Schedule the indicated files for removal from the current branch.
4677 Schedule the indicated files for removal from the current branch.
4653
4678
4654 This command schedules the files to be removed at the next commit.
4679 This command schedules the files to be removed at the next commit.
4655 To undo a remove before that, see :hg:`revert`. To undo added
4680 To undo a remove before that, see :hg:`revert`. To undo added
4656 files, see :hg:`forget`.
4681 files, see :hg:`forget`.
4657
4682
4658 .. container:: verbose
4683 .. container:: verbose
4659
4684
4660 -A/--after can be used to remove only files that have already
4685 -A/--after can be used to remove only files that have already
4661 been deleted, -f/--force can be used to force deletion, and -Af
4686 been deleted, -f/--force can be used to force deletion, and -Af
4662 can be used to remove files from the next revision without
4687 can be used to remove files from the next revision without
4663 deleting them from the working directory.
4688 deleting them from the working directory.
4664
4689
4665 The following table details the behavior of remove for different
4690 The following table details the behavior of remove for different
4666 file states (columns) and option combinations (rows). The file
4691 file states (columns) and option combinations (rows). The file
4667 states are Added [A], Clean [C], Modified [M] and Missing [!]
4692 states are Added [A], Clean [C], Modified [M] and Missing [!]
4668 (as reported by :hg:`status`). The actions are Warn, Remove
4693 (as reported by :hg:`status`). The actions are Warn, Remove
4669 (from branch) and Delete (from disk):
4694 (from branch) and Delete (from disk):
4670
4695
4671 ========= == == == ==
4696 ========= == == == ==
4672 opt/state A C M !
4697 opt/state A C M !
4673 ========= == == == ==
4698 ========= == == == ==
4674 none W RD W R
4699 none W RD W R
4675 -f R RD RD R
4700 -f R RD RD R
4676 -A W W W R
4701 -A W W W R
4677 -Af R R R R
4702 -Af R R R R
4678 ========= == == == ==
4703 ========= == == == ==
4679
4704
4680 .. note::
4705 .. note::
4681
4706
4682 :hg:`remove` never deletes files in Added [A] state from the
4707 :hg:`remove` never deletes files in Added [A] state from the
4683 working directory, not even if ``--force`` is specified.
4708 working directory, not even if ``--force`` is specified.
4684
4709
4685 Returns 0 on success, 1 if any warnings encountered.
4710 Returns 0 on success, 1 if any warnings encountered.
4686 """
4711 """
4687
4712
4688 opts = pycompat.byteskwargs(opts)
4713 opts = pycompat.byteskwargs(opts)
4689 after, force = opts.get('after'), opts.get('force')
4714 after, force = opts.get('after'), opts.get('force')
4690 dryrun = opts.get('dry_run')
4715 dryrun = opts.get('dry_run')
4691 if not pats and not after:
4716 if not pats and not after:
4692 raise error.Abort(_('no files specified'))
4717 raise error.Abort(_('no files specified'))
4693
4718
4694 m = scmutil.match(repo[None], pats, opts)
4719 m = scmutil.match(repo[None], pats, opts)
4695 subrepos = opts.get('subrepos')
4720 subrepos = opts.get('subrepos')
4696 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
4721 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
4697 return cmdutil.remove(ui, repo, m, "", uipathfn, after, force, subrepos,
4722 return cmdutil.remove(ui, repo, m, "", uipathfn, after, force, subrepos,
4698 dryrun=dryrun)
4723 dryrun=dryrun)
4699
4724
4700 @command('rename|move|mv',
4725 @command('rename|move|mv',
4701 [('A', 'after', None, _('record a rename that has already occurred')),
4726 [('A', 'after', None, _('record a rename that has already occurred')),
4702 ('f', 'force', None, _('forcibly move over an existing managed file')),
4727 ('f', 'force', None, _('forcibly move over an existing managed file')),
4703 ] + walkopts + dryrunopts,
4728 ] + walkopts + dryrunopts,
4704 _('[OPTION]... SOURCE... DEST'),
4729 _('[OPTION]... SOURCE... DEST'),
4705 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
4730 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
4706 def rename(ui, repo, *pats, **opts):
4731 def rename(ui, repo, *pats, **opts):
4707 """rename files; equivalent of copy + remove
4732 """rename files; equivalent of copy + remove
4708
4733
4709 Mark dest as copies of sources; mark sources for deletion. If dest
4734 Mark dest as copies of sources; mark sources for deletion. If dest
4710 is a directory, copies are put in that directory. If dest is a
4735 is a directory, copies are put in that directory. If dest is a
4711 file, there can only be one source.
4736 file, there can only be one source.
4712
4737
4713 By default, this command copies the contents of files as they
4738 By default, this command copies the contents of files as they
4714 exist in the working directory. If invoked with -A/--after, the
4739 exist in the working directory. If invoked with -A/--after, the
4715 operation is recorded, but no copying is performed.
4740 operation is recorded, but no copying is performed.
4716
4741
4717 This command takes effect at the next commit. To undo a rename
4742 This command takes effect at the next commit. To undo a rename
4718 before that, see :hg:`revert`.
4743 before that, see :hg:`revert`.
4719
4744
4720 Returns 0 on success, 1 if errors are encountered.
4745 Returns 0 on success, 1 if errors are encountered.
4721 """
4746 """
4722 opts = pycompat.byteskwargs(opts)
4747 opts = pycompat.byteskwargs(opts)
4723 with repo.wlock(False):
4748 with repo.wlock(False):
4724 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4749 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4725
4750
4726 @command('resolve',
4751 @command('resolve',
4727 [('a', 'all', None, _('select all unresolved files')),
4752 [('a', 'all', None, _('select all unresolved files')),
4728 ('l', 'list', None, _('list state of files needing merge')),
4753 ('l', 'list', None, _('list state of files needing merge')),
4729 ('m', 'mark', None, _('mark files as resolved')),
4754 ('m', 'mark', None, _('mark files as resolved')),
4730 ('u', 'unmark', None, _('mark files as unresolved')),
4755 ('u', 'unmark', None, _('mark files as unresolved')),
4731 ('n', 'no-status', None, _('hide status prefix')),
4756 ('n', 'no-status', None, _('hide status prefix')),
4732 ('', 're-merge', None, _('re-merge files'))]
4757 ('', 're-merge', None, _('re-merge files'))]
4733 + mergetoolopts + walkopts + formatteropts,
4758 + mergetoolopts + walkopts + formatteropts,
4734 _('[OPTION]... [FILE]...'),
4759 _('[OPTION]... [FILE]...'),
4735 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4760 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4736 inferrepo=True)
4761 inferrepo=True)
4737 def resolve(ui, repo, *pats, **opts):
4762 def resolve(ui, repo, *pats, **opts):
4738 """redo merges or set/view the merge status of files
4763 """redo merges or set/view the merge status of files
4739
4764
4740 Merges with unresolved conflicts are often the result of
4765 Merges with unresolved conflicts are often the result of
4741 non-interactive merging using the ``internal:merge`` configuration
4766 non-interactive merging using the ``internal:merge`` configuration
4742 setting, or a command-line merge tool like ``diff3``. The resolve
4767 setting, or a command-line merge tool like ``diff3``. The resolve
4743 command is used to manage the files involved in a merge, after
4768 command is used to manage the files involved in a merge, after
4744 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4769 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4745 working directory must have two parents). See :hg:`help
4770 working directory must have two parents). See :hg:`help
4746 merge-tools` for information on configuring merge tools.
4771 merge-tools` for information on configuring merge tools.
4747
4772
4748 The resolve command can be used in the following ways:
4773 The resolve command can be used in the following ways:
4749
4774
4750 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
4775 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
4751 the specified files, discarding any previous merge attempts. Re-merging
4776 the specified files, discarding any previous merge attempts. Re-merging
4752 is not performed for files already marked as resolved. Use ``--all/-a``
4777 is not performed for files already marked as resolved. Use ``--all/-a``
4753 to select all unresolved files. ``--tool`` can be used to specify
4778 to select all unresolved files. ``--tool`` can be used to specify
4754 the merge tool used for the given files. It overrides the HGMERGE
4779 the merge tool used for the given files. It overrides the HGMERGE
4755 environment variable and your configuration files. Previous file
4780 environment variable and your configuration files. Previous file
4756 contents are saved with a ``.orig`` suffix.
4781 contents are saved with a ``.orig`` suffix.
4757
4782
4758 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4783 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4759 (e.g. after having manually fixed-up the files). The default is
4784 (e.g. after having manually fixed-up the files). The default is
4760 to mark all unresolved files.
4785 to mark all unresolved files.
4761
4786
4762 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4787 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4763 default is to mark all resolved files.
4788 default is to mark all resolved files.
4764
4789
4765 - :hg:`resolve -l`: list files which had or still have conflicts.
4790 - :hg:`resolve -l`: list files which had or still have conflicts.
4766 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4791 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4767 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
4792 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
4768 the list. See :hg:`help filesets` for details.
4793 the list. See :hg:`help filesets` for details.
4769
4794
4770 .. note::
4795 .. note::
4771
4796
4772 Mercurial will not let you commit files with unresolved merge
4797 Mercurial will not let you commit files with unresolved merge
4773 conflicts. You must use :hg:`resolve -m ...` before you can
4798 conflicts. You must use :hg:`resolve -m ...` before you can
4774 commit after a conflicting merge.
4799 commit after a conflicting merge.
4775
4800
4776 .. container:: verbose
4801 .. container:: verbose
4777
4802
4778 Template:
4803 Template:
4779
4804
4780 The following keywords are supported in addition to the common template
4805 The following keywords are supported in addition to the common template
4781 keywords and functions. See also :hg:`help templates`.
4806 keywords and functions. See also :hg:`help templates`.
4782
4807
4783 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
4808 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
4784 :path: String. Repository-absolute path of the file.
4809 :path: String. Repository-absolute path of the file.
4785
4810
4786 Returns 0 on success, 1 if any files fail a resolve attempt.
4811 Returns 0 on success, 1 if any files fail a resolve attempt.
4787 """
4812 """
4788
4813
4789 opts = pycompat.byteskwargs(opts)
4814 opts = pycompat.byteskwargs(opts)
4790 confirm = ui.configbool('commands', 'resolve.confirm')
4815 confirm = ui.configbool('commands', 'resolve.confirm')
4791 flaglist = 'all mark unmark list no_status re_merge'.split()
4816 flaglist = 'all mark unmark list no_status re_merge'.split()
4792 all, mark, unmark, show, nostatus, remerge = [
4817 all, mark, unmark, show, nostatus, remerge = [
4793 opts.get(o) for o in flaglist]
4818 opts.get(o) for o in flaglist]
4794
4819
4795 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
4820 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
4796 if actioncount > 1:
4821 if actioncount > 1:
4797 raise error.Abort(_("too many actions specified"))
4822 raise error.Abort(_("too many actions specified"))
4798 elif (actioncount == 0
4823 elif (actioncount == 0
4799 and ui.configbool('commands', 'resolve.explicit-re-merge')):
4824 and ui.configbool('commands', 'resolve.explicit-re-merge')):
4800 hint = _('use --mark, --unmark, --list or --re-merge')
4825 hint = _('use --mark, --unmark, --list or --re-merge')
4801 raise error.Abort(_('no action specified'), hint=hint)
4826 raise error.Abort(_('no action specified'), hint=hint)
4802 if pats and all:
4827 if pats and all:
4803 raise error.Abort(_("can't specify --all and patterns"))
4828 raise error.Abort(_("can't specify --all and patterns"))
4804 if not (all or pats or show or mark or unmark):
4829 if not (all or pats or show or mark or unmark):
4805 raise error.Abort(_('no files or directories specified'),
4830 raise error.Abort(_('no files or directories specified'),
4806 hint=('use --all to re-merge all unresolved files'))
4831 hint=('use --all to re-merge all unresolved files'))
4807
4832
4808 if confirm:
4833 if confirm:
4809 if all:
4834 if all:
4810 if ui.promptchoice(_(b're-merge all unresolved files (yn)?'
4835 if ui.promptchoice(_(b're-merge all unresolved files (yn)?'
4811 b'$$ &Yes $$ &No')):
4836 b'$$ &Yes $$ &No')):
4812 raise error.Abort(_('user quit'))
4837 raise error.Abort(_('user quit'))
4813 if mark and not pats:
4838 if mark and not pats:
4814 if ui.promptchoice(_(b'mark all unresolved files as resolved (yn)?'
4839 if ui.promptchoice(_(b'mark all unresolved files as resolved (yn)?'
4815 b'$$ &Yes $$ &No')):
4840 b'$$ &Yes $$ &No')):
4816 raise error.Abort(_('user quit'))
4841 raise error.Abort(_('user quit'))
4817 if unmark and not pats:
4842 if unmark and not pats:
4818 if ui.promptchoice(_(b'mark all resolved files as unresolved (yn)?'
4843 if ui.promptchoice(_(b'mark all resolved files as unresolved (yn)?'
4819 b'$$ &Yes $$ &No')):
4844 b'$$ &Yes $$ &No')):
4820 raise error.Abort(_('user quit'))
4845 raise error.Abort(_('user quit'))
4821
4846
4822 uipathfn = scmutil.getuipathfn(repo)
4847 uipathfn = scmutil.getuipathfn(repo)
4823
4848
4824 if show:
4849 if show:
4825 ui.pager('resolve')
4850 ui.pager('resolve')
4826 fm = ui.formatter('resolve', opts)
4851 fm = ui.formatter('resolve', opts)
4827 ms = mergemod.mergestate.read(repo)
4852 ms = mergemod.mergestate.read(repo)
4828 wctx = repo[None]
4853 wctx = repo[None]
4829 m = scmutil.match(wctx, pats, opts)
4854 m = scmutil.match(wctx, pats, opts)
4830
4855
4831 # Labels and keys based on merge state. Unresolved path conflicts show
4856 # Labels and keys based on merge state. Unresolved path conflicts show
4832 # as 'P'. Resolved path conflicts show as 'R', the same as normal
4857 # as 'P'. Resolved path conflicts show as 'R', the same as normal
4833 # resolved conflicts.
4858 # resolved conflicts.
4834 mergestateinfo = {
4859 mergestateinfo = {
4835 mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'),
4860 mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'),
4836 mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'),
4861 mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'),
4837 mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'),
4862 mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'),
4838 mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'),
4863 mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'),
4839 mergemod.MERGE_RECORD_DRIVER_RESOLVED: ('resolve.driverresolved',
4864 mergemod.MERGE_RECORD_DRIVER_RESOLVED: ('resolve.driverresolved',
4840 'D'),
4865 'D'),
4841 }
4866 }
4842
4867
4843 for f in ms:
4868 for f in ms:
4844 if not m(f):
4869 if not m(f):
4845 continue
4870 continue
4846
4871
4847 label, key = mergestateinfo[ms[f]]
4872 label, key = mergestateinfo[ms[f]]
4848 fm.startitem()
4873 fm.startitem()
4849 fm.context(ctx=wctx)
4874 fm.context(ctx=wctx)
4850 fm.condwrite(not nostatus, 'mergestatus', '%s ', key, label=label)
4875 fm.condwrite(not nostatus, 'mergestatus', '%s ', key, label=label)
4851 fm.data(path=f)
4876 fm.data(path=f)
4852 fm.plain('%s\n' % uipathfn(f), label=label)
4877 fm.plain('%s\n' % uipathfn(f), label=label)
4853 fm.end()
4878 fm.end()
4854 return 0
4879 return 0
4855
4880
4856 with repo.wlock():
4881 with repo.wlock():
4857 ms = mergemod.mergestate.read(repo)
4882 ms = mergemod.mergestate.read(repo)
4858
4883
4859 if not (ms.active() or repo.dirstate.p2() != nullid):
4884 if not (ms.active() or repo.dirstate.p2() != nullid):
4860 raise error.Abort(
4885 raise error.Abort(
4861 _('resolve command not applicable when not merging'))
4886 _('resolve command not applicable when not merging'))
4862
4887
4863 wctx = repo[None]
4888 wctx = repo[None]
4864
4889
4865 if (ms.mergedriver
4890 if (ms.mergedriver
4866 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED):
4891 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED):
4867 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4892 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4868 ms.commit()
4893 ms.commit()
4869 # allow mark and unmark to go through
4894 # allow mark and unmark to go through
4870 if not mark and not unmark and not proceed:
4895 if not mark and not unmark and not proceed:
4871 return 1
4896 return 1
4872
4897
4873 m = scmutil.match(wctx, pats, opts)
4898 m = scmutil.match(wctx, pats, opts)
4874 ret = 0
4899 ret = 0
4875 didwork = False
4900 didwork = False
4876 runconclude = False
4901 runconclude = False
4877
4902
4878 tocomplete = []
4903 tocomplete = []
4879 hasconflictmarkers = []
4904 hasconflictmarkers = []
4880 if mark:
4905 if mark:
4881 markcheck = ui.config('commands', 'resolve.mark-check')
4906 markcheck = ui.config('commands', 'resolve.mark-check')
4882 if markcheck not in ['warn', 'abort']:
4907 if markcheck not in ['warn', 'abort']:
4883 # Treat all invalid / unrecognized values as 'none'.
4908 # Treat all invalid / unrecognized values as 'none'.
4884 markcheck = False
4909 markcheck = False
4885 for f in ms:
4910 for f in ms:
4886 if not m(f):
4911 if not m(f):
4887 continue
4912 continue
4888
4913
4889 didwork = True
4914 didwork = True
4890
4915
4891 # don't let driver-resolved files be marked, and run the conclude
4916 # don't let driver-resolved files be marked, and run the conclude
4892 # step if asked to resolve
4917 # step if asked to resolve
4893 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
4918 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
4894 exact = m.exact(f)
4919 exact = m.exact(f)
4895 if mark:
4920 if mark:
4896 if exact:
4921 if exact:
4897 ui.warn(_('not marking %s as it is driver-resolved\n')
4922 ui.warn(_('not marking %s as it is driver-resolved\n')
4898 % uipathfn(f))
4923 % uipathfn(f))
4899 elif unmark:
4924 elif unmark:
4900 if exact:
4925 if exact:
4901 ui.warn(_('not unmarking %s as it is driver-resolved\n')
4926 ui.warn(_('not unmarking %s as it is driver-resolved\n')
4902 % uipathfn(f))
4927 % uipathfn(f))
4903 else:
4928 else:
4904 runconclude = True
4929 runconclude = True
4905 continue
4930 continue
4906
4931
4907 # path conflicts must be resolved manually
4932 # path conflicts must be resolved manually
4908 if ms[f] in (mergemod.MERGE_RECORD_UNRESOLVED_PATH,
4933 if ms[f] in (mergemod.MERGE_RECORD_UNRESOLVED_PATH,
4909 mergemod.MERGE_RECORD_RESOLVED_PATH):
4934 mergemod.MERGE_RECORD_RESOLVED_PATH):
4910 if mark:
4935 if mark:
4911 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
4936 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
4912 elif unmark:
4937 elif unmark:
4913 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
4938 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
4914 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
4939 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
4915 ui.warn(_('%s: path conflict must be resolved manually\n')
4940 ui.warn(_('%s: path conflict must be resolved manually\n')
4916 % uipathfn(f))
4941 % uipathfn(f))
4917 continue
4942 continue
4918
4943
4919 if mark:
4944 if mark:
4920 if markcheck:
4945 if markcheck:
4921 fdata = repo.wvfs.tryread(f)
4946 fdata = repo.wvfs.tryread(f)
4922 if (filemerge.hasconflictmarkers(fdata) and
4947 if (filemerge.hasconflictmarkers(fdata) and
4923 ms[f] != mergemod.MERGE_RECORD_RESOLVED):
4948 ms[f] != mergemod.MERGE_RECORD_RESOLVED):
4924 hasconflictmarkers.append(f)
4949 hasconflictmarkers.append(f)
4925 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
4950 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
4926 elif unmark:
4951 elif unmark:
4927 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
4952 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
4928 else:
4953 else:
4929 # backup pre-resolve (merge uses .orig for its own purposes)
4954 # backup pre-resolve (merge uses .orig for its own purposes)
4930 a = repo.wjoin(f)
4955 a = repo.wjoin(f)
4931 try:
4956 try:
4932 util.copyfile(a, a + ".resolve")
4957 util.copyfile(a, a + ".resolve")
4933 except (IOError, OSError) as inst:
4958 except (IOError, OSError) as inst:
4934 if inst.errno != errno.ENOENT:
4959 if inst.errno != errno.ENOENT:
4935 raise
4960 raise
4936
4961
4937 try:
4962 try:
4938 # preresolve file
4963 # preresolve file
4939 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4964 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4940 with ui.configoverride(overrides, 'resolve'):
4965 with ui.configoverride(overrides, 'resolve'):
4941 complete, r = ms.preresolve(f, wctx)
4966 complete, r = ms.preresolve(f, wctx)
4942 if not complete:
4967 if not complete:
4943 tocomplete.append(f)
4968 tocomplete.append(f)
4944 elif r:
4969 elif r:
4945 ret = 1
4970 ret = 1
4946 finally:
4971 finally:
4947 ms.commit()
4972 ms.commit()
4948
4973
4949 # replace filemerge's .orig file with our resolve file, but only
4974 # replace filemerge's .orig file with our resolve file, but only
4950 # for merges that are complete
4975 # for merges that are complete
4951 if complete:
4976 if complete:
4952 try:
4977 try:
4953 util.rename(a + ".resolve",
4978 util.rename(a + ".resolve",
4954 scmutil.backuppath(ui, repo, f))
4979 scmutil.backuppath(ui, repo, f))
4955 except OSError as inst:
4980 except OSError as inst:
4956 if inst.errno != errno.ENOENT:
4981 if inst.errno != errno.ENOENT:
4957 raise
4982 raise
4958
4983
4959 if hasconflictmarkers:
4984 if hasconflictmarkers:
4960 ui.warn(_('warning: the following files still have conflict '
4985 ui.warn(_('warning: the following files still have conflict '
4961 'markers:\n') + ''.join(' ' + uipathfn(f) + '\n'
4986 'markers:\n') + ''.join(' ' + uipathfn(f) + '\n'
4962 for f in hasconflictmarkers))
4987 for f in hasconflictmarkers))
4963 if markcheck == 'abort' and not all and not pats:
4988 if markcheck == 'abort' and not all and not pats:
4964 raise error.Abort(_('conflict markers detected'),
4989 raise error.Abort(_('conflict markers detected'),
4965 hint=_('use --all to mark anyway'))
4990 hint=_('use --all to mark anyway'))
4966
4991
4967 for f in tocomplete:
4992 for f in tocomplete:
4968 try:
4993 try:
4969 # resolve file
4994 # resolve file
4970 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4995 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4971 with ui.configoverride(overrides, 'resolve'):
4996 with ui.configoverride(overrides, 'resolve'):
4972 r = ms.resolve(f, wctx)
4997 r = ms.resolve(f, wctx)
4973 if r:
4998 if r:
4974 ret = 1
4999 ret = 1
4975 finally:
5000 finally:
4976 ms.commit()
5001 ms.commit()
4977
5002
4978 # replace filemerge's .orig file with our resolve file
5003 # replace filemerge's .orig file with our resolve file
4979 a = repo.wjoin(f)
5004 a = repo.wjoin(f)
4980 try:
5005 try:
4981 util.rename(a + ".resolve", scmutil.backuppath(ui, repo, f))
5006 util.rename(a + ".resolve", scmutil.backuppath(ui, repo, f))
4982 except OSError as inst:
5007 except OSError as inst:
4983 if inst.errno != errno.ENOENT:
5008 if inst.errno != errno.ENOENT:
4984 raise
5009 raise
4985
5010
4986 ms.commit()
5011 ms.commit()
4987 ms.recordactions()
5012 ms.recordactions()
4988
5013
4989 if not didwork and pats:
5014 if not didwork and pats:
4990 hint = None
5015 hint = None
4991 if not any([p for p in pats if p.find(':') >= 0]):
5016 if not any([p for p in pats if p.find(':') >= 0]):
4992 pats = ['path:%s' % p for p in pats]
5017 pats = ['path:%s' % p for p in pats]
4993 m = scmutil.match(wctx, pats, opts)
5018 m = scmutil.match(wctx, pats, opts)
4994 for f in ms:
5019 for f in ms:
4995 if not m(f):
5020 if not m(f):
4996 continue
5021 continue
4997 def flag(o):
5022 def flag(o):
4998 if o == 're_merge':
5023 if o == 're_merge':
4999 return '--re-merge '
5024 return '--re-merge '
5000 return '-%s ' % o[0:1]
5025 return '-%s ' % o[0:1]
5001 flags = ''.join([flag(o) for o in flaglist if opts.get(o)])
5026 flags = ''.join([flag(o) for o in flaglist if opts.get(o)])
5002 hint = _("(try: hg resolve %s%s)\n") % (
5027 hint = _("(try: hg resolve %s%s)\n") % (
5003 flags,
5028 flags,
5004 ' '.join(pats))
5029 ' '.join(pats))
5005 break
5030 break
5006 ui.warn(_("arguments do not match paths that need resolving\n"))
5031 ui.warn(_("arguments do not match paths that need resolving\n"))
5007 if hint:
5032 if hint:
5008 ui.warn(hint)
5033 ui.warn(hint)
5009 elif ms.mergedriver and ms.mdstate() != 's':
5034 elif ms.mergedriver and ms.mdstate() != 's':
5010 # run conclude step when either a driver-resolved file is requested
5035 # run conclude step when either a driver-resolved file is requested
5011 # or there are no driver-resolved files
5036 # or there are no driver-resolved files
5012 # we can't use 'ret' to determine whether any files are unresolved
5037 # we can't use 'ret' to determine whether any files are unresolved
5013 # because we might not have tried to resolve some
5038 # because we might not have tried to resolve some
5014 if ((runconclude or not list(ms.driverresolved()))
5039 if ((runconclude or not list(ms.driverresolved()))
5015 and not list(ms.unresolved())):
5040 and not list(ms.unresolved())):
5016 proceed = mergemod.driverconclude(repo, ms, wctx)
5041 proceed = mergemod.driverconclude(repo, ms, wctx)
5017 ms.commit()
5042 ms.commit()
5018 if not proceed:
5043 if not proceed:
5019 return 1
5044 return 1
5020
5045
5021 # Nudge users into finishing an unfinished operation
5046 # Nudge users into finishing an unfinished operation
5022 unresolvedf = list(ms.unresolved())
5047 unresolvedf = list(ms.unresolved())
5023 driverresolvedf = list(ms.driverresolved())
5048 driverresolvedf = list(ms.driverresolved())
5024 if not unresolvedf and not driverresolvedf:
5049 if not unresolvedf and not driverresolvedf:
5025 ui.status(_('(no more unresolved files)\n'))
5050 ui.status(_('(no more unresolved files)\n'))
5026 cmdutil.checkafterresolved(repo)
5051 cmdutil.checkafterresolved(repo)
5027 elif not unresolvedf:
5052 elif not unresolvedf:
5028 ui.status(_('(no more unresolved files -- '
5053 ui.status(_('(no more unresolved files -- '
5029 'run "hg resolve --all" to conclude)\n'))
5054 'run "hg resolve --all" to conclude)\n'))
5030
5055
5031 return ret
5056 return ret
5032
5057
5033 @command('revert',
5058 @command('revert',
5034 [('a', 'all', None, _('revert all changes when no arguments given')),
5059 [('a', 'all', None, _('revert all changes when no arguments given')),
5035 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5060 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5036 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5061 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5037 ('C', 'no-backup', None, _('do not save backup copies of files')),
5062 ('C', 'no-backup', None, _('do not save backup copies of files')),
5038 ('i', 'interactive', None, _('interactively select the changes')),
5063 ('i', 'interactive', None, _('interactively select the changes')),
5039 ] + walkopts + dryrunopts,
5064 ] + walkopts + dryrunopts,
5040 _('[OPTION]... [-r REV] [NAME]...'),
5065 _('[OPTION]... [-r REV] [NAME]...'),
5041 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5066 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5042 def revert(ui, repo, *pats, **opts):
5067 def revert(ui, repo, *pats, **opts):
5043 """restore files to their checkout state
5068 """restore files to their checkout state
5044
5069
5045 .. note::
5070 .. note::
5046
5071
5047 To check out earlier revisions, you should use :hg:`update REV`.
5072 To check out earlier revisions, you should use :hg:`update REV`.
5048 To cancel an uncommitted merge (and lose your changes),
5073 To cancel an uncommitted merge (and lose your changes),
5049 use :hg:`merge --abort`.
5074 use :hg:`merge --abort`.
5050
5075
5051 With no revision specified, revert the specified files or directories
5076 With no revision specified, revert the specified files or directories
5052 to the contents they had in the parent of the working directory.
5077 to the contents they had in the parent of the working directory.
5053 This restores the contents of files to an unmodified
5078 This restores the contents of files to an unmodified
5054 state and unschedules adds, removes, copies, and renames. If the
5079 state and unschedules adds, removes, copies, and renames. If the
5055 working directory has two parents, you must explicitly specify a
5080 working directory has two parents, you must explicitly specify a
5056 revision.
5081 revision.
5057
5082
5058 Using the -r/--rev or -d/--date options, revert the given files or
5083 Using the -r/--rev or -d/--date options, revert the given files or
5059 directories to their states as of a specific revision. Because
5084 directories to their states as of a specific revision. Because
5060 revert does not change the working directory parents, this will
5085 revert does not change the working directory parents, this will
5061 cause these files to appear modified. This can be helpful to "back
5086 cause these files to appear modified. This can be helpful to "back
5062 out" some or all of an earlier change. See :hg:`backout` for a
5087 out" some or all of an earlier change. See :hg:`backout` for a
5063 related method.
5088 related method.
5064
5089
5065 Modified files are saved with a .orig suffix before reverting.
5090 Modified files are saved with a .orig suffix before reverting.
5066 To disable these backups, use --no-backup. It is possible to store
5091 To disable these backups, use --no-backup. It is possible to store
5067 the backup files in a custom directory relative to the root of the
5092 the backup files in a custom directory relative to the root of the
5068 repository by setting the ``ui.origbackuppath`` configuration
5093 repository by setting the ``ui.origbackuppath`` configuration
5069 option.
5094 option.
5070
5095
5071 See :hg:`help dates` for a list of formats valid for -d/--date.
5096 See :hg:`help dates` for a list of formats valid for -d/--date.
5072
5097
5073 See :hg:`help backout` for a way to reverse the effect of an
5098 See :hg:`help backout` for a way to reverse the effect of an
5074 earlier changeset.
5099 earlier changeset.
5075
5100
5076 Returns 0 on success.
5101 Returns 0 on success.
5077 """
5102 """
5078
5103
5079 opts = pycompat.byteskwargs(opts)
5104 opts = pycompat.byteskwargs(opts)
5080 if opts.get("date"):
5105 if opts.get("date"):
5081 if opts.get("rev"):
5106 if opts.get("rev"):
5082 raise error.Abort(_("you can't specify a revision and a date"))
5107 raise error.Abort(_("you can't specify a revision and a date"))
5083 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5108 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5084
5109
5085 parent, p2 = repo.dirstate.parents()
5110 parent, p2 = repo.dirstate.parents()
5086 if not opts.get('rev') and p2 != nullid:
5111 if not opts.get('rev') and p2 != nullid:
5087 # revert after merge is a trap for new users (issue2915)
5112 # revert after merge is a trap for new users (issue2915)
5088 raise error.Abort(_('uncommitted merge with no revision specified'),
5113 raise error.Abort(_('uncommitted merge with no revision specified'),
5089 hint=_("use 'hg update' or see 'hg help revert'"))
5114 hint=_("use 'hg update' or see 'hg help revert'"))
5090
5115
5091 rev = opts.get('rev')
5116 rev = opts.get('rev')
5092 if rev:
5117 if rev:
5093 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
5118 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
5094 ctx = scmutil.revsingle(repo, rev)
5119 ctx = scmutil.revsingle(repo, rev)
5095
5120
5096 if (not (pats or opts.get('include') or opts.get('exclude') or
5121 if (not (pats or opts.get('include') or opts.get('exclude') or
5097 opts.get('all') or opts.get('interactive'))):
5122 opts.get('all') or opts.get('interactive'))):
5098 msg = _("no files or directories specified")
5123 msg = _("no files or directories specified")
5099 if p2 != nullid:
5124 if p2 != nullid:
5100 hint = _("uncommitted merge, use --all to discard all changes,"
5125 hint = _("uncommitted merge, use --all to discard all changes,"
5101 " or 'hg update -C .' to abort the merge")
5126 " or 'hg update -C .' to abort the merge")
5102 raise error.Abort(msg, hint=hint)
5127 raise error.Abort(msg, hint=hint)
5103 dirty = any(repo.status())
5128 dirty = any(repo.status())
5104 node = ctx.node()
5129 node = ctx.node()
5105 if node != parent:
5130 if node != parent:
5106 if dirty:
5131 if dirty:
5107 hint = _("uncommitted changes, use --all to discard all"
5132 hint = _("uncommitted changes, use --all to discard all"
5108 " changes, or 'hg update %d' to update") % ctx.rev()
5133 " changes, or 'hg update %d' to update") % ctx.rev()
5109 else:
5134 else:
5110 hint = _("use --all to revert all files,"
5135 hint = _("use --all to revert all files,"
5111 " or 'hg update %d' to update") % ctx.rev()
5136 " or 'hg update %d' to update") % ctx.rev()
5112 elif dirty:
5137 elif dirty:
5113 hint = _("uncommitted changes, use --all to discard all changes")
5138 hint = _("uncommitted changes, use --all to discard all changes")
5114 else:
5139 else:
5115 hint = _("use --all to revert all files")
5140 hint = _("use --all to revert all files")
5116 raise error.Abort(msg, hint=hint)
5141 raise error.Abort(msg, hint=hint)
5117
5142
5118 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats,
5143 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats,
5119 **pycompat.strkwargs(opts))
5144 **pycompat.strkwargs(opts))
5120
5145
5121 @command(
5146 @command(
5122 'rollback',
5147 'rollback',
5123 dryrunopts + [('f', 'force', False, _('ignore safety measures'))],
5148 dryrunopts + [('f', 'force', False, _('ignore safety measures'))],
5124 helpcategory=command.CATEGORY_MAINTENANCE)
5149 helpcategory=command.CATEGORY_MAINTENANCE)
5125 def rollback(ui, repo, **opts):
5150 def rollback(ui, repo, **opts):
5126 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5151 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5127
5152
5128 Please use :hg:`commit --amend` instead of rollback to correct
5153 Please use :hg:`commit --amend` instead of rollback to correct
5129 mistakes in the last commit.
5154 mistakes in the last commit.
5130
5155
5131 This command should be used with care. There is only one level of
5156 This command should be used with care. There is only one level of
5132 rollback, and there is no way to undo a rollback. It will also
5157 rollback, and there is no way to undo a rollback. It will also
5133 restore the dirstate at the time of the last transaction, losing
5158 restore the dirstate at the time of the last transaction, losing
5134 any dirstate changes since that time. This command does not alter
5159 any dirstate changes since that time. This command does not alter
5135 the working directory.
5160 the working directory.
5136
5161
5137 Transactions are used to encapsulate the effects of all commands
5162 Transactions are used to encapsulate the effects of all commands
5138 that create new changesets or propagate existing changesets into a
5163 that create new changesets or propagate existing changesets into a
5139 repository.
5164 repository.
5140
5165
5141 .. container:: verbose
5166 .. container:: verbose
5142
5167
5143 For example, the following commands are transactional, and their
5168 For example, the following commands are transactional, and their
5144 effects can be rolled back:
5169 effects can be rolled back:
5145
5170
5146 - commit
5171 - commit
5147 - import
5172 - import
5148 - pull
5173 - pull
5149 - push (with this repository as the destination)
5174 - push (with this repository as the destination)
5150 - unbundle
5175 - unbundle
5151
5176
5152 To avoid permanent data loss, rollback will refuse to rollback a
5177 To avoid permanent data loss, rollback will refuse to rollback a
5153 commit transaction if it isn't checked out. Use --force to
5178 commit transaction if it isn't checked out. Use --force to
5154 override this protection.
5179 override this protection.
5155
5180
5156 The rollback command can be entirely disabled by setting the
5181 The rollback command can be entirely disabled by setting the
5157 ``ui.rollback`` configuration setting to false. If you're here
5182 ``ui.rollback`` configuration setting to false. If you're here
5158 because you want to use rollback and it's disabled, you can
5183 because you want to use rollback and it's disabled, you can
5159 re-enable the command by setting ``ui.rollback`` to true.
5184 re-enable the command by setting ``ui.rollback`` to true.
5160
5185
5161 This command is not intended for use on public repositories. Once
5186 This command is not intended for use on public repositories. Once
5162 changes are visible for pull by other users, rolling a transaction
5187 changes are visible for pull by other users, rolling a transaction
5163 back locally is ineffective (someone else may already have pulled
5188 back locally is ineffective (someone else may already have pulled
5164 the changes). Furthermore, a race is possible with readers of the
5189 the changes). Furthermore, a race is possible with readers of the
5165 repository; for example an in-progress pull from the repository
5190 repository; for example an in-progress pull from the repository
5166 may fail if a rollback is performed.
5191 may fail if a rollback is performed.
5167
5192
5168 Returns 0 on success, 1 if no rollback data is available.
5193 Returns 0 on success, 1 if no rollback data is available.
5169 """
5194 """
5170 if not ui.configbool('ui', 'rollback'):
5195 if not ui.configbool('ui', 'rollback'):
5171 raise error.Abort(_('rollback is disabled because it is unsafe'),
5196 raise error.Abort(_('rollback is disabled because it is unsafe'),
5172 hint=('see `hg help -v rollback` for information'))
5197 hint=('see `hg help -v rollback` for information'))
5173 return repo.rollback(dryrun=opts.get(r'dry_run'),
5198 return repo.rollback(dryrun=opts.get(r'dry_run'),
5174 force=opts.get(r'force'))
5199 force=opts.get(r'force'))
5175
5200
5176 @command(
5201 @command(
5177 'root', [] + formatteropts, intents={INTENT_READONLY},
5202 'root', [] + formatteropts, intents={INTENT_READONLY},
5178 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5203 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5179 def root(ui, repo, **opts):
5204 def root(ui, repo, **opts):
5180 """print the root (top) of the current working directory
5205 """print the root (top) of the current working directory
5181
5206
5182 Print the root directory of the current repository.
5207 Print the root directory of the current repository.
5183
5208
5184 .. container:: verbose
5209 .. container:: verbose
5185
5210
5186 Template:
5211 Template:
5187
5212
5188 The following keywords are supported in addition to the common template
5213 The following keywords are supported in addition to the common template
5189 keywords and functions. See also :hg:`help templates`.
5214 keywords and functions. See also :hg:`help templates`.
5190
5215
5191 :hgpath: String. Path to the .hg directory.
5216 :hgpath: String. Path to the .hg directory.
5192 :storepath: String. Path to the directory holding versioned data.
5217 :storepath: String. Path to the directory holding versioned data.
5193
5218
5194 Returns 0 on success.
5219 Returns 0 on success.
5195 """
5220 """
5196 opts = pycompat.byteskwargs(opts)
5221 opts = pycompat.byteskwargs(opts)
5197 with ui.formatter('root', opts) as fm:
5222 with ui.formatter('root', opts) as fm:
5198 fm.startitem()
5223 fm.startitem()
5199 fm.write('reporoot', '%s\n', repo.root)
5224 fm.write('reporoot', '%s\n', repo.root)
5200 fm.data(hgpath=repo.path, storepath=repo.spath)
5225 fm.data(hgpath=repo.path, storepath=repo.spath)
5201
5226
5202 @command('serve',
5227 @command('serve',
5203 [('A', 'accesslog', '', _('name of access log file to write to'),
5228 [('A', 'accesslog', '', _('name of access log file to write to'),
5204 _('FILE')),
5229 _('FILE')),
5205 ('d', 'daemon', None, _('run server in background')),
5230 ('d', 'daemon', None, _('run server in background')),
5206 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
5231 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
5207 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5232 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5208 # use string type, then we can check if something was passed
5233 # use string type, then we can check if something was passed
5209 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5234 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5210 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5235 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5211 _('ADDR')),
5236 _('ADDR')),
5212 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5237 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5213 _('PREFIX')),
5238 _('PREFIX')),
5214 ('n', 'name', '',
5239 ('n', 'name', '',
5215 _('name to show in web pages (default: working directory)'), _('NAME')),
5240 _('name to show in web pages (default: working directory)'), _('NAME')),
5216 ('', 'web-conf', '',
5241 ('', 'web-conf', '',
5217 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
5242 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
5218 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5243 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5219 _('FILE')),
5244 _('FILE')),
5220 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5245 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5221 ('', 'stdio', None, _('for remote clients (ADVANCED)')),
5246 ('', 'stdio', None, _('for remote clients (ADVANCED)')),
5222 ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')),
5247 ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')),
5223 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5248 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5224 ('', 'style', '', _('template style to use'), _('STYLE')),
5249 ('', 'style', '', _('template style to use'), _('STYLE')),
5225 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5250 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5226 ('', 'certificate', '', _('SSL certificate file'), _('FILE')),
5251 ('', 'certificate', '', _('SSL certificate file'), _('FILE')),
5227 ('', 'print-url', None, _('start and print only the URL'))]
5252 ('', 'print-url', None, _('start and print only the URL'))]
5228 + subrepoopts,
5253 + subrepoopts,
5229 _('[OPTION]...'),
5254 _('[OPTION]...'),
5230 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5255 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5231 helpbasic=True, optionalrepo=True)
5256 helpbasic=True, optionalrepo=True)
5232 def serve(ui, repo, **opts):
5257 def serve(ui, repo, **opts):
5233 """start stand-alone webserver
5258 """start stand-alone webserver
5234
5259
5235 Start a local HTTP repository browser and pull server. You can use
5260 Start a local HTTP repository browser and pull server. You can use
5236 this for ad-hoc sharing and browsing of repositories. It is
5261 this for ad-hoc sharing and browsing of repositories. It is
5237 recommended to use a real web server to serve a repository for
5262 recommended to use a real web server to serve a repository for
5238 longer periods of time.
5263 longer periods of time.
5239
5264
5240 Please note that the server does not implement access control.
5265 Please note that the server does not implement access control.
5241 This means that, by default, anybody can read from the server and
5266 This means that, by default, anybody can read from the server and
5242 nobody can write to it by default. Set the ``web.allow-push``
5267 nobody can write to it by default. Set the ``web.allow-push``
5243 option to ``*`` to allow everybody to push to the server. You
5268 option to ``*`` to allow everybody to push to the server. You
5244 should use a real web server if you need to authenticate users.
5269 should use a real web server if you need to authenticate users.
5245
5270
5246 By default, the server logs accesses to stdout and errors to
5271 By default, the server logs accesses to stdout and errors to
5247 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5272 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5248 files.
5273 files.
5249
5274
5250 To have the server choose a free port number to listen on, specify
5275 To have the server choose a free port number to listen on, specify
5251 a port number of 0; in this case, the server will print the port
5276 a port number of 0; in this case, the server will print the port
5252 number it uses.
5277 number it uses.
5253
5278
5254 Returns 0 on success.
5279 Returns 0 on success.
5255 """
5280 """
5256
5281
5257 opts = pycompat.byteskwargs(opts)
5282 opts = pycompat.byteskwargs(opts)
5258 if opts["stdio"] and opts["cmdserver"]:
5283 if opts["stdio"] and opts["cmdserver"]:
5259 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5284 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5260 if opts["print_url"] and ui.verbose:
5285 if opts["print_url"] and ui.verbose:
5261 raise error.Abort(_("cannot use --print-url with --verbose"))
5286 raise error.Abort(_("cannot use --print-url with --verbose"))
5262
5287
5263 if opts["stdio"]:
5288 if opts["stdio"]:
5264 if repo is None:
5289 if repo is None:
5265 raise error.RepoError(_("there is no Mercurial repository here"
5290 raise error.RepoError(_("there is no Mercurial repository here"
5266 " (.hg not found)"))
5291 " (.hg not found)"))
5267 s = wireprotoserver.sshserver(ui, repo)
5292 s = wireprotoserver.sshserver(ui, repo)
5268 s.serve_forever()
5293 s.serve_forever()
5269
5294
5270 service = server.createservice(ui, repo, opts)
5295 service = server.createservice(ui, repo, opts)
5271 return server.runservice(opts, initfn=service.init, runfn=service.run)
5296 return server.runservice(opts, initfn=service.init, runfn=service.run)
5272
5297
5273 @command('shelve',
5298 @command('shelve',
5274 [('A', 'addremove', None,
5299 [('A', 'addremove', None,
5275 _('mark new/missing files as added/removed before shelving')),
5300 _('mark new/missing files as added/removed before shelving')),
5276 ('u', 'unknown', None,
5301 ('u', 'unknown', None,
5277 _('store unknown files in the shelve')),
5302 _('store unknown files in the shelve')),
5278 ('', 'cleanup', None,
5303 ('', 'cleanup', None,
5279 _('delete all shelved changes')),
5304 _('delete all shelved changes')),
5280 ('', 'date', '',
5305 ('', 'date', '',
5281 _('shelve with the specified commit date'), _('DATE')),
5306 _('shelve with the specified commit date'), _('DATE')),
5282 ('d', 'delete', None,
5307 ('d', 'delete', None,
5283 _('delete the named shelved change(s)')),
5308 _('delete the named shelved change(s)')),
5284 ('e', 'edit', False,
5309 ('e', 'edit', False,
5285 _('invoke editor on commit messages')),
5310 _('invoke editor on commit messages')),
5286 ('k', 'keep', False,
5311 ('k', 'keep', False,
5287 _('shelve, but keep changes in the working directory')),
5312 _('shelve, but keep changes in the working directory')),
5288 ('l', 'list', None,
5313 ('l', 'list', None,
5289 _('list current shelves')),
5314 _('list current shelves')),
5290 ('m', 'message', '',
5315 ('m', 'message', '',
5291 _('use text as shelve message'), _('TEXT')),
5316 _('use text as shelve message'), _('TEXT')),
5292 ('n', 'name', '',
5317 ('n', 'name', '',
5293 _('use the given name for the shelved commit'), _('NAME')),
5318 _('use the given name for the shelved commit'), _('NAME')),
5294 ('p', 'patch', None,
5319 ('p', 'patch', None,
5295 _('output patches for changes (provide the names of the shelved '
5320 _('output patches for changes (provide the names of the shelved '
5296 'changes as positional arguments)')),
5321 'changes as positional arguments)')),
5297 ('i', 'interactive', None,
5322 ('i', 'interactive', None,
5298 _('interactive mode, only works while creating a shelve')),
5323 _('interactive mode, only works while creating a shelve')),
5299 ('', 'stat', None,
5324 ('', 'stat', None,
5300 _('output diffstat-style summary of changes (provide the names of '
5325 _('output diffstat-style summary of changes (provide the names of '
5301 'the shelved changes as positional arguments)')
5326 'the shelved changes as positional arguments)')
5302 )] + cmdutil.walkopts,
5327 )] + cmdutil.walkopts,
5303 _('hg shelve [OPTION]... [FILE]...'),
5328 _('hg shelve [OPTION]... [FILE]...'),
5304 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5329 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5305 def shelve(ui, repo, *pats, **opts):
5330 def shelve(ui, repo, *pats, **opts):
5306 '''save and set aside changes from the working directory
5331 '''save and set aside changes from the working directory
5307
5332
5308 Shelving takes files that "hg status" reports as not clean, saves
5333 Shelving takes files that "hg status" reports as not clean, saves
5309 the modifications to a bundle (a shelved change), and reverts the
5334 the modifications to a bundle (a shelved change), and reverts the
5310 files so that their state in the working directory becomes clean.
5335 files so that their state in the working directory becomes clean.
5311
5336
5312 To restore these changes to the working directory, using "hg
5337 To restore these changes to the working directory, using "hg
5313 unshelve"; this will work even if you switch to a different
5338 unshelve"; this will work even if you switch to a different
5314 commit.
5339 commit.
5315
5340
5316 When no files are specified, "hg shelve" saves all not-clean
5341 When no files are specified, "hg shelve" saves all not-clean
5317 files. If specific files or directories are named, only changes to
5342 files. If specific files or directories are named, only changes to
5318 those files are shelved.
5343 those files are shelved.
5319
5344
5320 In bare shelve (when no files are specified, without interactive,
5345 In bare shelve (when no files are specified, without interactive,
5321 include and exclude option), shelving remembers information if the
5346 include and exclude option), shelving remembers information if the
5322 working directory was on newly created branch, in other words working
5347 working directory was on newly created branch, in other words working
5323 directory was on different branch than its first parent. In this
5348 directory was on different branch than its first parent. In this
5324 situation unshelving restores branch information to the working directory.
5349 situation unshelving restores branch information to the working directory.
5325
5350
5326 Each shelved change has a name that makes it easier to find later.
5351 Each shelved change has a name that makes it easier to find later.
5327 The name of a shelved change defaults to being based on the active
5352 The name of a shelved change defaults to being based on the active
5328 bookmark, or if there is no active bookmark, the current named
5353 bookmark, or if there is no active bookmark, the current named
5329 branch. To specify a different name, use ``--name``.
5354 branch. To specify a different name, use ``--name``.
5330
5355
5331 To see a list of existing shelved changes, use the ``--list``
5356 To see a list of existing shelved changes, use the ``--list``
5332 option. For each shelved change, this will print its name, age,
5357 option. For each shelved change, this will print its name, age,
5333 and description; use ``--patch`` or ``--stat`` for more details.
5358 and description; use ``--patch`` or ``--stat`` for more details.
5334
5359
5335 To delete specific shelved changes, use ``--delete``. To delete
5360 To delete specific shelved changes, use ``--delete``. To delete
5336 all shelved changes, use ``--cleanup``.
5361 all shelved changes, use ``--cleanup``.
5337 '''
5362 '''
5338 opts = pycompat.byteskwargs(opts)
5363 opts = pycompat.byteskwargs(opts)
5339 allowables = [
5364 allowables = [
5340 ('addremove', {'create'}), # 'create' is pseudo action
5365 ('addremove', {'create'}), # 'create' is pseudo action
5341 ('unknown', {'create'}),
5366 ('unknown', {'create'}),
5342 ('cleanup', {'cleanup'}),
5367 ('cleanup', {'cleanup'}),
5343 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
5368 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
5344 ('delete', {'delete'}),
5369 ('delete', {'delete'}),
5345 ('edit', {'create'}),
5370 ('edit', {'create'}),
5346 ('keep', {'create'}),
5371 ('keep', {'create'}),
5347 ('list', {'list'}),
5372 ('list', {'list'}),
5348 ('message', {'create'}),
5373 ('message', {'create'}),
5349 ('name', {'create'}),
5374 ('name', {'create'}),
5350 ('patch', {'patch', 'list'}),
5375 ('patch', {'patch', 'list'}),
5351 ('stat', {'stat', 'list'}),
5376 ('stat', {'stat', 'list'}),
5352 ]
5377 ]
5353 def checkopt(opt):
5378 def checkopt(opt):
5354 if opts.get(opt):
5379 if opts.get(opt):
5355 for i, allowable in allowables:
5380 for i, allowable in allowables:
5356 if opts[i] and opt not in allowable:
5381 if opts[i] and opt not in allowable:
5357 raise error.Abort(_("options '--%s' and '--%s' may not be "
5382 raise error.Abort(_("options '--%s' and '--%s' may not be "
5358 "used together") % (opt, i))
5383 "used together") % (opt, i))
5359 return True
5384 return True
5360 if checkopt('cleanup'):
5385 if checkopt('cleanup'):
5361 if pats:
5386 if pats:
5362 raise error.Abort(_("cannot specify names when using '--cleanup'"))
5387 raise error.Abort(_("cannot specify names when using '--cleanup'"))
5363 return shelvemod.cleanupcmd(ui, repo)
5388 return shelvemod.cleanupcmd(ui, repo)
5364 elif checkopt('delete'):
5389 elif checkopt('delete'):
5365 return shelvemod.deletecmd(ui, repo, pats)
5390 return shelvemod.deletecmd(ui, repo, pats)
5366 elif checkopt('list'):
5391 elif checkopt('list'):
5367 return shelvemod.listcmd(ui, repo, pats, opts)
5392 return shelvemod.listcmd(ui, repo, pats, opts)
5368 elif checkopt('patch') or checkopt('stat'):
5393 elif checkopt('patch') or checkopt('stat'):
5369 return shelvemod.patchcmds(ui, repo, pats, opts)
5394 return shelvemod.patchcmds(ui, repo, pats, opts)
5370 else:
5395 else:
5371 return shelvemod.createcmd(ui, repo, pats, opts)
5396 return shelvemod.createcmd(ui, repo, pats, opts)
5372
5397
5373 _NOTTERSE = 'nothing'
5398 _NOTTERSE = 'nothing'
5374
5399
5375 @command('status|st',
5400 @command('status|st',
5376 [('A', 'all', None, _('show status of all files')),
5401 [('A', 'all', None, _('show status of all files')),
5377 ('m', 'modified', None, _('show only modified files')),
5402 ('m', 'modified', None, _('show only modified files')),
5378 ('a', 'added', None, _('show only added files')),
5403 ('a', 'added', None, _('show only added files')),
5379 ('r', 'removed', None, _('show only removed files')),
5404 ('r', 'removed', None, _('show only removed files')),
5380 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5405 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5381 ('c', 'clean', None, _('show only files without changes')),
5406 ('c', 'clean', None, _('show only files without changes')),
5382 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5407 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5383 ('i', 'ignored', None, _('show only ignored files')),
5408 ('i', 'ignored', None, _('show only ignored files')),
5384 ('n', 'no-status', None, _('hide status prefix')),
5409 ('n', 'no-status', None, _('hide status prefix')),
5385 ('t', 'terse', _NOTTERSE, _('show the terse output (EXPERIMENTAL)')),
5410 ('t', 'terse', _NOTTERSE, _('show the terse output (EXPERIMENTAL)')),
5386 ('C', 'copies', None, _('show source of copied files')),
5411 ('C', 'copies', None, _('show source of copied files')),
5387 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5412 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5388 ('', 'rev', [], _('show difference from revision'), _('REV')),
5413 ('', 'rev', [], _('show difference from revision'), _('REV')),
5389 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5414 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5390 ] + walkopts + subrepoopts + formatteropts,
5415 ] + walkopts + subrepoopts + formatteropts,
5391 _('[OPTION]... [FILE]...'),
5416 _('[OPTION]... [FILE]...'),
5392 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5417 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5393 helpbasic=True, inferrepo=True,
5418 helpbasic=True, inferrepo=True,
5394 intents={INTENT_READONLY})
5419 intents={INTENT_READONLY})
5395 def status(ui, repo, *pats, **opts):
5420 def status(ui, repo, *pats, **opts):
5396 """show changed files in the working directory
5421 """show changed files in the working directory
5397
5422
5398 Show status of files in the repository. If names are given, only
5423 Show status of files in the repository. If names are given, only
5399 files that match are shown. Files that are clean or ignored or
5424 files that match are shown. Files that are clean or ignored or
5400 the source of a copy/move operation, are not listed unless
5425 the source of a copy/move operation, are not listed unless
5401 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5426 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5402 Unless options described with "show only ..." are given, the
5427 Unless options described with "show only ..." are given, the
5403 options -mardu are used.
5428 options -mardu are used.
5404
5429
5405 Option -q/--quiet hides untracked (unknown and ignored) files
5430 Option -q/--quiet hides untracked (unknown and ignored) files
5406 unless explicitly requested with -u/--unknown or -i/--ignored.
5431 unless explicitly requested with -u/--unknown or -i/--ignored.
5407
5432
5408 .. note::
5433 .. note::
5409
5434
5410 :hg:`status` may appear to disagree with diff if permissions have
5435 :hg:`status` may appear to disagree with diff if permissions have
5411 changed or a merge has occurred. The standard diff format does
5436 changed or a merge has occurred. The standard diff format does
5412 not report permission changes and diff only reports changes
5437 not report permission changes and diff only reports changes
5413 relative to one merge parent.
5438 relative to one merge parent.
5414
5439
5415 If one revision is given, it is used as the base revision.
5440 If one revision is given, it is used as the base revision.
5416 If two revisions are given, the differences between them are
5441 If two revisions are given, the differences between them are
5417 shown. The --change option can also be used as a shortcut to list
5442 shown. The --change option can also be used as a shortcut to list
5418 the changed files of a revision from its first parent.
5443 the changed files of a revision from its first parent.
5419
5444
5420 The codes used to show the status of files are::
5445 The codes used to show the status of files are::
5421
5446
5422 M = modified
5447 M = modified
5423 A = added
5448 A = added
5424 R = removed
5449 R = removed
5425 C = clean
5450 C = clean
5426 ! = missing (deleted by non-hg command, but still tracked)
5451 ! = missing (deleted by non-hg command, but still tracked)
5427 ? = not tracked
5452 ? = not tracked
5428 I = ignored
5453 I = ignored
5429 = origin of the previous file (with --copies)
5454 = origin of the previous file (with --copies)
5430
5455
5431 .. container:: verbose
5456 .. container:: verbose
5432
5457
5433 The -t/--terse option abbreviates the output by showing only the directory
5458 The -t/--terse option abbreviates the output by showing only the directory
5434 name if all the files in it share the same status. The option takes an
5459 name if all the files in it share the same status. The option takes an
5435 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
5460 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
5436 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
5461 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
5437 for 'ignored' and 'c' for clean.
5462 for 'ignored' and 'c' for clean.
5438
5463
5439 It abbreviates only those statuses which are passed. Note that clean and
5464 It abbreviates only those statuses which are passed. Note that clean and
5440 ignored files are not displayed with '--terse ic' unless the -c/--clean
5465 ignored files are not displayed with '--terse ic' unless the -c/--clean
5441 and -i/--ignored options are also used.
5466 and -i/--ignored options are also used.
5442
5467
5443 The -v/--verbose option shows information when the repository is in an
5468 The -v/--verbose option shows information when the repository is in an
5444 unfinished merge, shelve, rebase state etc. You can have this behavior
5469 unfinished merge, shelve, rebase state etc. You can have this behavior
5445 turned on by default by enabling the ``commands.status.verbose`` option.
5470 turned on by default by enabling the ``commands.status.verbose`` option.
5446
5471
5447 You can skip displaying some of these states by setting
5472 You can skip displaying some of these states by setting
5448 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
5473 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
5449 'histedit', 'merge', 'rebase', or 'unshelve'.
5474 'histedit', 'merge', 'rebase', or 'unshelve'.
5450
5475
5451 Template:
5476 Template:
5452
5477
5453 The following keywords are supported in addition to the common template
5478 The following keywords are supported in addition to the common template
5454 keywords and functions. See also :hg:`help templates`.
5479 keywords and functions. See also :hg:`help templates`.
5455
5480
5456 :path: String. Repository-absolute path of the file.
5481 :path: String. Repository-absolute path of the file.
5457 :source: String. Repository-absolute path of the file originated from.
5482 :source: String. Repository-absolute path of the file originated from.
5458 Available if ``--copies`` is specified.
5483 Available if ``--copies`` is specified.
5459 :status: String. Character denoting file's status.
5484 :status: String. Character denoting file's status.
5460
5485
5461 Examples:
5486 Examples:
5462
5487
5463 - show changes in the working directory relative to a
5488 - show changes in the working directory relative to a
5464 changeset::
5489 changeset::
5465
5490
5466 hg status --rev 9353
5491 hg status --rev 9353
5467
5492
5468 - show changes in the working directory relative to the
5493 - show changes in the working directory relative to the
5469 current directory (see :hg:`help patterns` for more information)::
5494 current directory (see :hg:`help patterns` for more information)::
5470
5495
5471 hg status re:
5496 hg status re:
5472
5497
5473 - show all changes including copies in an existing changeset::
5498 - show all changes including copies in an existing changeset::
5474
5499
5475 hg status --copies --change 9353
5500 hg status --copies --change 9353
5476
5501
5477 - get a NUL separated list of added files, suitable for xargs::
5502 - get a NUL separated list of added files, suitable for xargs::
5478
5503
5479 hg status -an0
5504 hg status -an0
5480
5505
5481 - show more information about the repository status, abbreviating
5506 - show more information about the repository status, abbreviating
5482 added, removed, modified, deleted, and untracked paths::
5507 added, removed, modified, deleted, and untracked paths::
5483
5508
5484 hg status -v -t mardu
5509 hg status -v -t mardu
5485
5510
5486 Returns 0 on success.
5511 Returns 0 on success.
5487
5512
5488 """
5513 """
5489
5514
5490 opts = pycompat.byteskwargs(opts)
5515 opts = pycompat.byteskwargs(opts)
5491 revs = opts.get('rev')
5516 revs = opts.get('rev')
5492 change = opts.get('change')
5517 change = opts.get('change')
5493 terse = opts.get('terse')
5518 terse = opts.get('terse')
5494 if terse is _NOTTERSE:
5519 if terse is _NOTTERSE:
5495 if revs:
5520 if revs:
5496 terse = ''
5521 terse = ''
5497 else:
5522 else:
5498 terse = ui.config('commands', 'status.terse')
5523 terse = ui.config('commands', 'status.terse')
5499
5524
5500 if revs and change:
5525 if revs and change:
5501 msg = _('cannot specify --rev and --change at the same time')
5526 msg = _('cannot specify --rev and --change at the same time')
5502 raise error.Abort(msg)
5527 raise error.Abort(msg)
5503 elif revs and terse:
5528 elif revs and terse:
5504 msg = _('cannot use --terse with --rev')
5529 msg = _('cannot use --terse with --rev')
5505 raise error.Abort(msg)
5530 raise error.Abort(msg)
5506 elif change:
5531 elif change:
5507 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
5532 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
5508 ctx2 = scmutil.revsingle(repo, change, None)
5533 ctx2 = scmutil.revsingle(repo, change, None)
5509 ctx1 = ctx2.p1()
5534 ctx1 = ctx2.p1()
5510 else:
5535 else:
5511 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
5536 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
5512 ctx1, ctx2 = scmutil.revpair(repo, revs)
5537 ctx1, ctx2 = scmutil.revpair(repo, revs)
5513
5538
5514 forcerelativevalue = None
5539 forcerelativevalue = None
5515 if ui.hasconfig('commands', 'status.relative'):
5540 if ui.hasconfig('commands', 'status.relative'):
5516 forcerelativevalue = ui.configbool('commands', 'status.relative')
5541 forcerelativevalue = ui.configbool('commands', 'status.relative')
5517 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats),
5542 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats),
5518 forcerelativevalue=forcerelativevalue)
5543 forcerelativevalue=forcerelativevalue)
5519
5544
5520 if opts.get('print0'):
5545 if opts.get('print0'):
5521 end = '\0'
5546 end = '\0'
5522 else:
5547 else:
5523 end = '\n'
5548 end = '\n'
5524 copy = {}
5549 copy = {}
5525 states = 'modified added removed deleted unknown ignored clean'.split()
5550 states = 'modified added removed deleted unknown ignored clean'.split()
5526 show = [k for k in states if opts.get(k)]
5551 show = [k for k in states if opts.get(k)]
5527 if opts.get('all'):
5552 if opts.get('all'):
5528 show += ui.quiet and (states[:4] + ['clean']) or states
5553 show += ui.quiet and (states[:4] + ['clean']) or states
5529
5554
5530 if not show:
5555 if not show:
5531 if ui.quiet:
5556 if ui.quiet:
5532 show = states[:4]
5557 show = states[:4]
5533 else:
5558 else:
5534 show = states[:5]
5559 show = states[:5]
5535
5560
5536 m = scmutil.match(ctx2, pats, opts)
5561 m = scmutil.match(ctx2, pats, opts)
5537 if terse:
5562 if terse:
5538 # we need to compute clean and unknown to terse
5563 # we need to compute clean and unknown to terse
5539 stat = repo.status(ctx1.node(), ctx2.node(), m,
5564 stat = repo.status(ctx1.node(), ctx2.node(), m,
5540 'ignored' in show or 'i' in terse,
5565 'ignored' in show or 'i' in terse,
5541 clean=True, unknown=True,
5566 clean=True, unknown=True,
5542 listsubrepos=opts.get('subrepos'))
5567 listsubrepos=opts.get('subrepos'))
5543
5568
5544 stat = cmdutil.tersedir(stat, terse)
5569 stat = cmdutil.tersedir(stat, terse)
5545 else:
5570 else:
5546 stat = repo.status(ctx1.node(), ctx2.node(), m,
5571 stat = repo.status(ctx1.node(), ctx2.node(), m,
5547 'ignored' in show, 'clean' in show,
5572 'ignored' in show, 'clean' in show,
5548 'unknown' in show, opts.get('subrepos'))
5573 'unknown' in show, opts.get('subrepos'))
5549
5574
5550 changestates = zip(states, pycompat.iterbytestr('MAR!?IC'), stat)
5575 changestates = zip(states, pycompat.iterbytestr('MAR!?IC'), stat)
5551
5576
5552 if (opts.get('all') or opts.get('copies')
5577 if (opts.get('all') or opts.get('copies')
5553 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5578 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5554 copy = copies.pathcopies(ctx1, ctx2, m)
5579 copy = copies.pathcopies(ctx1, ctx2, m)
5555
5580
5556 ui.pager('status')
5581 ui.pager('status')
5557 fm = ui.formatter('status', opts)
5582 fm = ui.formatter('status', opts)
5558 fmt = '%s' + end
5583 fmt = '%s' + end
5559 showchar = not opts.get('no_status')
5584 showchar = not opts.get('no_status')
5560
5585
5561 for state, char, files in changestates:
5586 for state, char, files in changestates:
5562 if state in show:
5587 if state in show:
5563 label = 'status.' + state
5588 label = 'status.' + state
5564 for f in files:
5589 for f in files:
5565 fm.startitem()
5590 fm.startitem()
5566 fm.context(ctx=ctx2)
5591 fm.context(ctx=ctx2)
5567 fm.data(path=f)
5592 fm.data(path=f)
5568 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5593 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5569 fm.plain(fmt % uipathfn(f), label=label)
5594 fm.plain(fmt % uipathfn(f), label=label)
5570 if f in copy:
5595 if f in copy:
5571 fm.data(source=copy[f])
5596 fm.data(source=copy[f])
5572 fm.plain((' %s' + end) % uipathfn(copy[f]),
5597 fm.plain((' %s' + end) % uipathfn(copy[f]),
5573 label='status.copied')
5598 label='status.copied')
5574
5599
5575 if ((ui.verbose or ui.configbool('commands', 'status.verbose'))
5600 if ((ui.verbose or ui.configbool('commands', 'status.verbose'))
5576 and not ui.plain()):
5601 and not ui.plain()):
5577 cmdutil.morestatus(repo, fm)
5602 cmdutil.morestatus(repo, fm)
5578 fm.end()
5603 fm.end()
5579
5604
5580 @command('summary|sum',
5605 @command('summary|sum',
5581 [('', 'remote', None, _('check for push and pull'))],
5606 [('', 'remote', None, _('check for push and pull'))],
5582 '[--remote]',
5607 '[--remote]',
5583 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5608 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5584 helpbasic=True,
5609 helpbasic=True,
5585 intents={INTENT_READONLY})
5610 intents={INTENT_READONLY})
5586 def summary(ui, repo, **opts):
5611 def summary(ui, repo, **opts):
5587 """summarize working directory state
5612 """summarize working directory state
5588
5613
5589 This generates a brief summary of the working directory state,
5614 This generates a brief summary of the working directory state,
5590 including parents, branch, commit status, phase and available updates.
5615 including parents, branch, commit status, phase and available updates.
5591
5616
5592 With the --remote option, this will check the default paths for
5617 With the --remote option, this will check the default paths for
5593 incoming and outgoing changes. This can be time-consuming.
5618 incoming and outgoing changes. This can be time-consuming.
5594
5619
5595 Returns 0 on success.
5620 Returns 0 on success.
5596 """
5621 """
5597
5622
5598 opts = pycompat.byteskwargs(opts)
5623 opts = pycompat.byteskwargs(opts)
5599 ui.pager('summary')
5624 ui.pager('summary')
5600 ctx = repo[None]
5625 ctx = repo[None]
5601 parents = ctx.parents()
5626 parents = ctx.parents()
5602 pnode = parents[0].node()
5627 pnode = parents[0].node()
5603 marks = []
5628 marks = []
5604
5629
5605 try:
5630 try:
5606 ms = mergemod.mergestate.read(repo)
5631 ms = mergemod.mergestate.read(repo)
5607 except error.UnsupportedMergeRecords as e:
5632 except error.UnsupportedMergeRecords as e:
5608 s = ' '.join(e.recordtypes)
5633 s = ' '.join(e.recordtypes)
5609 ui.warn(
5634 ui.warn(
5610 _('warning: merge state has unsupported record types: %s\n') % s)
5635 _('warning: merge state has unsupported record types: %s\n') % s)
5611 unresolved = []
5636 unresolved = []
5612 else:
5637 else:
5613 unresolved = list(ms.unresolved())
5638 unresolved = list(ms.unresolved())
5614
5639
5615 for p in parents:
5640 for p in parents:
5616 # label with log.changeset (instead of log.parent) since this
5641 # label with log.changeset (instead of log.parent) since this
5617 # shows a working directory parent *changeset*:
5642 # shows a working directory parent *changeset*:
5618 # i18n: column positioning for "hg summary"
5643 # i18n: column positioning for "hg summary"
5619 ui.write(_('parent: %d:%s ') % (p.rev(), p),
5644 ui.write(_('parent: %d:%s ') % (p.rev(), p),
5620 label=logcmdutil.changesetlabels(p))
5645 label=logcmdutil.changesetlabels(p))
5621 ui.write(' '.join(p.tags()), label='log.tag')
5646 ui.write(' '.join(p.tags()), label='log.tag')
5622 if p.bookmarks():
5647 if p.bookmarks():
5623 marks.extend(p.bookmarks())
5648 marks.extend(p.bookmarks())
5624 if p.rev() == -1:
5649 if p.rev() == -1:
5625 if not len(repo):
5650 if not len(repo):
5626 ui.write(_(' (empty repository)'))
5651 ui.write(_(' (empty repository)'))
5627 else:
5652 else:
5628 ui.write(_(' (no revision checked out)'))
5653 ui.write(_(' (no revision checked out)'))
5629 if p.obsolete():
5654 if p.obsolete():
5630 ui.write(_(' (obsolete)'))
5655 ui.write(_(' (obsolete)'))
5631 if p.isunstable():
5656 if p.isunstable():
5632 instabilities = (ui.label(instability, 'trouble.%s' % instability)
5657 instabilities = (ui.label(instability, 'trouble.%s' % instability)
5633 for instability in p.instabilities())
5658 for instability in p.instabilities())
5634 ui.write(' ('
5659 ui.write(' ('
5635 + ', '.join(instabilities)
5660 + ', '.join(instabilities)
5636 + ')')
5661 + ')')
5637 ui.write('\n')
5662 ui.write('\n')
5638 if p.description():
5663 if p.description():
5639 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5664 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5640 label='log.summary')
5665 label='log.summary')
5641
5666
5642 branch = ctx.branch()
5667 branch = ctx.branch()
5643 bheads = repo.branchheads(branch)
5668 bheads = repo.branchheads(branch)
5644 # i18n: column positioning for "hg summary"
5669 # i18n: column positioning for "hg summary"
5645 m = _('branch: %s\n') % branch
5670 m = _('branch: %s\n') % branch
5646 if branch != 'default':
5671 if branch != 'default':
5647 ui.write(m, label='log.branch')
5672 ui.write(m, label='log.branch')
5648 else:
5673 else:
5649 ui.status(m, label='log.branch')
5674 ui.status(m, label='log.branch')
5650
5675
5651 if marks:
5676 if marks:
5652 active = repo._activebookmark
5677 active = repo._activebookmark
5653 # i18n: column positioning for "hg summary"
5678 # i18n: column positioning for "hg summary"
5654 ui.write(_('bookmarks:'), label='log.bookmark')
5679 ui.write(_('bookmarks:'), label='log.bookmark')
5655 if active is not None:
5680 if active is not None:
5656 if active in marks:
5681 if active in marks:
5657 ui.write(' *' + active, label=bookmarks.activebookmarklabel)
5682 ui.write(' *' + active, label=bookmarks.activebookmarklabel)
5658 marks.remove(active)
5683 marks.remove(active)
5659 else:
5684 else:
5660 ui.write(' [%s]' % active, label=bookmarks.activebookmarklabel)
5685 ui.write(' [%s]' % active, label=bookmarks.activebookmarklabel)
5661 for m in marks:
5686 for m in marks:
5662 ui.write(' ' + m, label='log.bookmark')
5687 ui.write(' ' + m, label='log.bookmark')
5663 ui.write('\n', label='log.bookmark')
5688 ui.write('\n', label='log.bookmark')
5664
5689
5665 status = repo.status(unknown=True)
5690 status = repo.status(unknown=True)
5666
5691
5667 c = repo.dirstate.copies()
5692 c = repo.dirstate.copies()
5668 copied, renamed = [], []
5693 copied, renamed = [], []
5669 for d, s in c.iteritems():
5694 for d, s in c.iteritems():
5670 if s in status.removed:
5695 if s in status.removed:
5671 status.removed.remove(s)
5696 status.removed.remove(s)
5672 renamed.append(d)
5697 renamed.append(d)
5673 else:
5698 else:
5674 copied.append(d)
5699 copied.append(d)
5675 if d in status.added:
5700 if d in status.added:
5676 status.added.remove(d)
5701 status.added.remove(d)
5677
5702
5678 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5703 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5679
5704
5680 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
5705 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
5681 (ui.label(_('%d added'), 'status.added'), status.added),
5706 (ui.label(_('%d added'), 'status.added'), status.added),
5682 (ui.label(_('%d removed'), 'status.removed'), status.removed),
5707 (ui.label(_('%d removed'), 'status.removed'), status.removed),
5683 (ui.label(_('%d renamed'), 'status.copied'), renamed),
5708 (ui.label(_('%d renamed'), 'status.copied'), renamed),
5684 (ui.label(_('%d copied'), 'status.copied'), copied),
5709 (ui.label(_('%d copied'), 'status.copied'), copied),
5685 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
5710 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
5686 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
5711 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
5687 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
5712 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
5688 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
5713 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
5689 t = []
5714 t = []
5690 for l, s in labels:
5715 for l, s in labels:
5691 if s:
5716 if s:
5692 t.append(l % len(s))
5717 t.append(l % len(s))
5693
5718
5694 t = ', '.join(t)
5719 t = ', '.join(t)
5695 cleanworkdir = False
5720 cleanworkdir = False
5696
5721
5697 if repo.vfs.exists('graftstate'):
5722 if repo.vfs.exists('graftstate'):
5698 t += _(' (graft in progress)')
5723 t += _(' (graft in progress)')
5699 if repo.vfs.exists('updatestate'):
5724 if repo.vfs.exists('updatestate'):
5700 t += _(' (interrupted update)')
5725 t += _(' (interrupted update)')
5701 elif len(parents) > 1:
5726 elif len(parents) > 1:
5702 t += _(' (merge)')
5727 t += _(' (merge)')
5703 elif branch != parents[0].branch():
5728 elif branch != parents[0].branch():
5704 t += _(' (new branch)')
5729 t += _(' (new branch)')
5705 elif (parents[0].closesbranch() and
5730 elif (parents[0].closesbranch() and
5706 pnode in repo.branchheads(branch, closed=True)):
5731 pnode in repo.branchheads(branch, closed=True)):
5707 t += _(' (head closed)')
5732 t += _(' (head closed)')
5708 elif not (status.modified or status.added or status.removed or renamed or
5733 elif not (status.modified or status.added or status.removed or renamed or
5709 copied or subs):
5734 copied or subs):
5710 t += _(' (clean)')
5735 t += _(' (clean)')
5711 cleanworkdir = True
5736 cleanworkdir = True
5712 elif pnode not in bheads:
5737 elif pnode not in bheads:
5713 t += _(' (new branch head)')
5738 t += _(' (new branch head)')
5714
5739
5715 if parents:
5740 if parents:
5716 pendingphase = max(p.phase() for p in parents)
5741 pendingphase = max(p.phase() for p in parents)
5717 else:
5742 else:
5718 pendingphase = phases.public
5743 pendingphase = phases.public
5719
5744
5720 if pendingphase > phases.newcommitphase(ui):
5745 if pendingphase > phases.newcommitphase(ui):
5721 t += ' (%s)' % phases.phasenames[pendingphase]
5746 t += ' (%s)' % phases.phasenames[pendingphase]
5722
5747
5723 if cleanworkdir:
5748 if cleanworkdir:
5724 # i18n: column positioning for "hg summary"
5749 # i18n: column positioning for "hg summary"
5725 ui.status(_('commit: %s\n') % t.strip())
5750 ui.status(_('commit: %s\n') % t.strip())
5726 else:
5751 else:
5727 # i18n: column positioning for "hg summary"
5752 # i18n: column positioning for "hg summary"
5728 ui.write(_('commit: %s\n') % t.strip())
5753 ui.write(_('commit: %s\n') % t.strip())
5729
5754
5730 # all ancestors of branch heads - all ancestors of parent = new csets
5755 # all ancestors of branch heads - all ancestors of parent = new csets
5731 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
5756 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
5732 bheads))
5757 bheads))
5733
5758
5734 if new == 0:
5759 if new == 0:
5735 # i18n: column positioning for "hg summary"
5760 # i18n: column positioning for "hg summary"
5736 ui.status(_('update: (current)\n'))
5761 ui.status(_('update: (current)\n'))
5737 elif pnode not in bheads:
5762 elif pnode not in bheads:
5738 # i18n: column positioning for "hg summary"
5763 # i18n: column positioning for "hg summary"
5739 ui.write(_('update: %d new changesets (update)\n') % new)
5764 ui.write(_('update: %d new changesets (update)\n') % new)
5740 else:
5765 else:
5741 # i18n: column positioning for "hg summary"
5766 # i18n: column positioning for "hg summary"
5742 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5767 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5743 (new, len(bheads)))
5768 (new, len(bheads)))
5744
5769
5745 t = []
5770 t = []
5746 draft = len(repo.revs('draft()'))
5771 draft = len(repo.revs('draft()'))
5747 if draft:
5772 if draft:
5748 t.append(_('%d draft') % draft)
5773 t.append(_('%d draft') % draft)
5749 secret = len(repo.revs('secret()'))
5774 secret = len(repo.revs('secret()'))
5750 if secret:
5775 if secret:
5751 t.append(_('%d secret') % secret)
5776 t.append(_('%d secret') % secret)
5752
5777
5753 if draft or secret:
5778 if draft or secret:
5754 ui.status(_('phases: %s\n') % ', '.join(t))
5779 ui.status(_('phases: %s\n') % ', '.join(t))
5755
5780
5756 if obsolete.isenabled(repo, obsolete.createmarkersopt):
5781 if obsolete.isenabled(repo, obsolete.createmarkersopt):
5757 for trouble in ("orphan", "contentdivergent", "phasedivergent"):
5782 for trouble in ("orphan", "contentdivergent", "phasedivergent"):
5758 numtrouble = len(repo.revs(trouble + "()"))
5783 numtrouble = len(repo.revs(trouble + "()"))
5759 # We write all the possibilities to ease translation
5784 # We write all the possibilities to ease translation
5760 troublemsg = {
5785 troublemsg = {
5761 "orphan": _("orphan: %d changesets"),
5786 "orphan": _("orphan: %d changesets"),
5762 "contentdivergent": _("content-divergent: %d changesets"),
5787 "contentdivergent": _("content-divergent: %d changesets"),
5763 "phasedivergent": _("phase-divergent: %d changesets"),
5788 "phasedivergent": _("phase-divergent: %d changesets"),
5764 }
5789 }
5765 if numtrouble > 0:
5790 if numtrouble > 0:
5766 ui.status(troublemsg[trouble] % numtrouble + "\n")
5791 ui.status(troublemsg[trouble] % numtrouble + "\n")
5767
5792
5768 cmdutil.summaryhooks(ui, repo)
5793 cmdutil.summaryhooks(ui, repo)
5769
5794
5770 if opts.get('remote'):
5795 if opts.get('remote'):
5771 needsincoming, needsoutgoing = True, True
5796 needsincoming, needsoutgoing = True, True
5772 else:
5797 else:
5773 needsincoming, needsoutgoing = False, False
5798 needsincoming, needsoutgoing = False, False
5774 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5799 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5775 if i:
5800 if i:
5776 needsincoming = True
5801 needsincoming = True
5777 if o:
5802 if o:
5778 needsoutgoing = True
5803 needsoutgoing = True
5779 if not needsincoming and not needsoutgoing:
5804 if not needsincoming and not needsoutgoing:
5780 return
5805 return
5781
5806
5782 def getincoming():
5807 def getincoming():
5783 source, branches = hg.parseurl(ui.expandpath('default'))
5808 source, branches = hg.parseurl(ui.expandpath('default'))
5784 sbranch = branches[0]
5809 sbranch = branches[0]
5785 try:
5810 try:
5786 other = hg.peer(repo, {}, source)
5811 other = hg.peer(repo, {}, source)
5787 except error.RepoError:
5812 except error.RepoError:
5788 if opts.get('remote'):
5813 if opts.get('remote'):
5789 raise
5814 raise
5790 return source, sbranch, None, None, None
5815 return source, sbranch, None, None, None
5791 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5816 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5792 if revs:
5817 if revs:
5793 revs = [other.lookup(rev) for rev in revs]
5818 revs = [other.lookup(rev) for rev in revs]
5794 ui.debug('comparing with %s\n' % util.hidepassword(source))
5819 ui.debug('comparing with %s\n' % util.hidepassword(source))
5795 repo.ui.pushbuffer()
5820 repo.ui.pushbuffer()
5796 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5821 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5797 repo.ui.popbuffer()
5822 repo.ui.popbuffer()
5798 return source, sbranch, other, commoninc, commoninc[1]
5823 return source, sbranch, other, commoninc, commoninc[1]
5799
5824
5800 if needsincoming:
5825 if needsincoming:
5801 source, sbranch, sother, commoninc, incoming = getincoming()
5826 source, sbranch, sother, commoninc, incoming = getincoming()
5802 else:
5827 else:
5803 source = sbranch = sother = commoninc = incoming = None
5828 source = sbranch = sother = commoninc = incoming = None
5804
5829
5805 def getoutgoing():
5830 def getoutgoing():
5806 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5831 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5807 dbranch = branches[0]
5832 dbranch = branches[0]
5808 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5833 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5809 if source != dest:
5834 if source != dest:
5810 try:
5835 try:
5811 dother = hg.peer(repo, {}, dest)
5836 dother = hg.peer(repo, {}, dest)
5812 except error.RepoError:
5837 except error.RepoError:
5813 if opts.get('remote'):
5838 if opts.get('remote'):
5814 raise
5839 raise
5815 return dest, dbranch, None, None
5840 return dest, dbranch, None, None
5816 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5841 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5817 elif sother is None:
5842 elif sother is None:
5818 # there is no explicit destination peer, but source one is invalid
5843 # there is no explicit destination peer, but source one is invalid
5819 return dest, dbranch, None, None
5844 return dest, dbranch, None, None
5820 else:
5845 else:
5821 dother = sother
5846 dother = sother
5822 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5847 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5823 common = None
5848 common = None
5824 else:
5849 else:
5825 common = commoninc
5850 common = commoninc
5826 if revs:
5851 if revs:
5827 revs = [repo.lookup(rev) for rev in revs]
5852 revs = [repo.lookup(rev) for rev in revs]
5828 repo.ui.pushbuffer()
5853 repo.ui.pushbuffer()
5829 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5854 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5830 commoninc=common)
5855 commoninc=common)
5831 repo.ui.popbuffer()
5856 repo.ui.popbuffer()
5832 return dest, dbranch, dother, outgoing
5857 return dest, dbranch, dother, outgoing
5833
5858
5834 if needsoutgoing:
5859 if needsoutgoing:
5835 dest, dbranch, dother, outgoing = getoutgoing()
5860 dest, dbranch, dother, outgoing = getoutgoing()
5836 else:
5861 else:
5837 dest = dbranch = dother = outgoing = None
5862 dest = dbranch = dother = outgoing = None
5838
5863
5839 if opts.get('remote'):
5864 if opts.get('remote'):
5840 t = []
5865 t = []
5841 if incoming:
5866 if incoming:
5842 t.append(_('1 or more incoming'))
5867 t.append(_('1 or more incoming'))
5843 o = outgoing.missing
5868 o = outgoing.missing
5844 if o:
5869 if o:
5845 t.append(_('%d outgoing') % len(o))
5870 t.append(_('%d outgoing') % len(o))
5846 other = dother or sother
5871 other = dother or sother
5847 if 'bookmarks' in other.listkeys('namespaces'):
5872 if 'bookmarks' in other.listkeys('namespaces'):
5848 counts = bookmarks.summary(repo, other)
5873 counts = bookmarks.summary(repo, other)
5849 if counts[0] > 0:
5874 if counts[0] > 0:
5850 t.append(_('%d incoming bookmarks') % counts[0])
5875 t.append(_('%d incoming bookmarks') % counts[0])
5851 if counts[1] > 0:
5876 if counts[1] > 0:
5852 t.append(_('%d outgoing bookmarks') % counts[1])
5877 t.append(_('%d outgoing bookmarks') % counts[1])
5853
5878
5854 if t:
5879 if t:
5855 # i18n: column positioning for "hg summary"
5880 # i18n: column positioning for "hg summary"
5856 ui.write(_('remote: %s\n') % (', '.join(t)))
5881 ui.write(_('remote: %s\n') % (', '.join(t)))
5857 else:
5882 else:
5858 # i18n: column positioning for "hg summary"
5883 # i18n: column positioning for "hg summary"
5859 ui.status(_('remote: (synced)\n'))
5884 ui.status(_('remote: (synced)\n'))
5860
5885
5861 cmdutil.summaryremotehooks(ui, repo, opts,
5886 cmdutil.summaryremotehooks(ui, repo, opts,
5862 ((source, sbranch, sother, commoninc),
5887 ((source, sbranch, sother, commoninc),
5863 (dest, dbranch, dother, outgoing)))
5888 (dest, dbranch, dother, outgoing)))
5864
5889
5865 @command('tag',
5890 @command('tag',
5866 [('f', 'force', None, _('force tag')),
5891 [('f', 'force', None, _('force tag')),
5867 ('l', 'local', None, _('make the tag local')),
5892 ('l', 'local', None, _('make the tag local')),
5868 ('r', 'rev', '', _('revision to tag'), _('REV')),
5893 ('r', 'rev', '', _('revision to tag'), _('REV')),
5869 ('', 'remove', None, _('remove a tag')),
5894 ('', 'remove', None, _('remove a tag')),
5870 # -l/--local is already there, commitopts cannot be used
5895 # -l/--local is already there, commitopts cannot be used
5871 ('e', 'edit', None, _('invoke editor on commit messages')),
5896 ('e', 'edit', None, _('invoke editor on commit messages')),
5872 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
5897 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
5873 ] + commitopts2,
5898 ] + commitopts2,
5874 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
5899 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
5875 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
5900 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
5876 def tag(ui, repo, name1, *names, **opts):
5901 def tag(ui, repo, name1, *names, **opts):
5877 """add one or more tags for the current or given revision
5902 """add one or more tags for the current or given revision
5878
5903
5879 Name a particular revision using <name>.
5904 Name a particular revision using <name>.
5880
5905
5881 Tags are used to name particular revisions of the repository and are
5906 Tags are used to name particular revisions of the repository and are
5882 very useful to compare different revisions, to go back to significant
5907 very useful to compare different revisions, to go back to significant
5883 earlier versions or to mark branch points as releases, etc. Changing
5908 earlier versions or to mark branch points as releases, etc. Changing
5884 an existing tag is normally disallowed; use -f/--force to override.
5909 an existing tag is normally disallowed; use -f/--force to override.
5885
5910
5886 If no revision is given, the parent of the working directory is
5911 If no revision is given, the parent of the working directory is
5887 used.
5912 used.
5888
5913
5889 To facilitate version control, distribution, and merging of tags,
5914 To facilitate version control, distribution, and merging of tags,
5890 they are stored as a file named ".hgtags" which is managed similarly
5915 they are stored as a file named ".hgtags" which is managed similarly
5891 to other project files and can be hand-edited if necessary. This
5916 to other project files and can be hand-edited if necessary. This
5892 also means that tagging creates a new commit. The file
5917 also means that tagging creates a new commit. The file
5893 ".hg/localtags" is used for local tags (not shared among
5918 ".hg/localtags" is used for local tags (not shared among
5894 repositories).
5919 repositories).
5895
5920
5896 Tag commits are usually made at the head of a branch. If the parent
5921 Tag commits are usually made at the head of a branch. If the parent
5897 of the working directory is not a branch head, :hg:`tag` aborts; use
5922 of the working directory is not a branch head, :hg:`tag` aborts; use
5898 -f/--force to force the tag commit to be based on a non-head
5923 -f/--force to force the tag commit to be based on a non-head
5899 changeset.
5924 changeset.
5900
5925
5901 See :hg:`help dates` for a list of formats valid for -d/--date.
5926 See :hg:`help dates` for a list of formats valid for -d/--date.
5902
5927
5903 Since tag names have priority over branch names during revision
5928 Since tag names have priority over branch names during revision
5904 lookup, using an existing branch name as a tag name is discouraged.
5929 lookup, using an existing branch name as a tag name is discouraged.
5905
5930
5906 Returns 0 on success.
5931 Returns 0 on success.
5907 """
5932 """
5908 opts = pycompat.byteskwargs(opts)
5933 opts = pycompat.byteskwargs(opts)
5909 with repo.wlock(), repo.lock():
5934 with repo.wlock(), repo.lock():
5910 rev_ = "."
5935 rev_ = "."
5911 names = [t.strip() for t in (name1,) + names]
5936 names = [t.strip() for t in (name1,) + names]
5912 if len(names) != len(set(names)):
5937 if len(names) != len(set(names)):
5913 raise error.Abort(_('tag names must be unique'))
5938 raise error.Abort(_('tag names must be unique'))
5914 for n in names:
5939 for n in names:
5915 scmutil.checknewlabel(repo, n, 'tag')
5940 scmutil.checknewlabel(repo, n, 'tag')
5916 if not n:
5941 if not n:
5917 raise error.Abort(_('tag names cannot consist entirely of '
5942 raise error.Abort(_('tag names cannot consist entirely of '
5918 'whitespace'))
5943 'whitespace'))
5919 if opts.get('rev') and opts.get('remove'):
5944 if opts.get('rev') and opts.get('remove'):
5920 raise error.Abort(_("--rev and --remove are incompatible"))
5945 raise error.Abort(_("--rev and --remove are incompatible"))
5921 if opts.get('rev'):
5946 if opts.get('rev'):
5922 rev_ = opts['rev']
5947 rev_ = opts['rev']
5923 message = opts.get('message')
5948 message = opts.get('message')
5924 if opts.get('remove'):
5949 if opts.get('remove'):
5925 if opts.get('local'):
5950 if opts.get('local'):
5926 expectedtype = 'local'
5951 expectedtype = 'local'
5927 else:
5952 else:
5928 expectedtype = 'global'
5953 expectedtype = 'global'
5929
5954
5930 for n in names:
5955 for n in names:
5931 if repo.tagtype(n) == 'global':
5956 if repo.tagtype(n) == 'global':
5932 alltags = tagsmod.findglobaltags(ui, repo)
5957 alltags = tagsmod.findglobaltags(ui, repo)
5933 if alltags[n][0] == nullid:
5958 if alltags[n][0] == nullid:
5934 raise error.Abort(_("tag '%s' is already removed") % n)
5959 raise error.Abort(_("tag '%s' is already removed") % n)
5935 if not repo.tagtype(n):
5960 if not repo.tagtype(n):
5936 raise error.Abort(_("tag '%s' does not exist") % n)
5961 raise error.Abort(_("tag '%s' does not exist") % n)
5937 if repo.tagtype(n) != expectedtype:
5962 if repo.tagtype(n) != expectedtype:
5938 if expectedtype == 'global':
5963 if expectedtype == 'global':
5939 raise error.Abort(_("tag '%s' is not a global tag") % n)
5964 raise error.Abort(_("tag '%s' is not a global tag") % n)
5940 else:
5965 else:
5941 raise error.Abort(_("tag '%s' is not a local tag") % n)
5966 raise error.Abort(_("tag '%s' is not a local tag") % n)
5942 rev_ = 'null'
5967 rev_ = 'null'
5943 if not message:
5968 if not message:
5944 # we don't translate commit messages
5969 # we don't translate commit messages
5945 message = 'Removed tag %s' % ', '.join(names)
5970 message = 'Removed tag %s' % ', '.join(names)
5946 elif not opts.get('force'):
5971 elif not opts.get('force'):
5947 for n in names:
5972 for n in names:
5948 if n in repo.tags():
5973 if n in repo.tags():
5949 raise error.Abort(_("tag '%s' already exists "
5974 raise error.Abort(_("tag '%s' already exists "
5950 "(use -f to force)") % n)
5975 "(use -f to force)") % n)
5951 if not opts.get('local'):
5976 if not opts.get('local'):
5952 p1, p2 = repo.dirstate.parents()
5977 p1, p2 = repo.dirstate.parents()
5953 if p2 != nullid:
5978 if p2 != nullid:
5954 raise error.Abort(_('uncommitted merge'))
5979 raise error.Abort(_('uncommitted merge'))
5955 bheads = repo.branchheads()
5980 bheads = repo.branchheads()
5956 if not opts.get('force') and bheads and p1 not in bheads:
5981 if not opts.get('force') and bheads and p1 not in bheads:
5957 raise error.Abort(_('working directory is not at a branch head '
5982 raise error.Abort(_('working directory is not at a branch head '
5958 '(use -f to force)'))
5983 '(use -f to force)'))
5959 node = scmutil.revsingle(repo, rev_).node()
5984 node = scmutil.revsingle(repo, rev_).node()
5960
5985
5961 if not message:
5986 if not message:
5962 # we don't translate commit messages
5987 # we don't translate commit messages
5963 message = ('Added tag %s for changeset %s' %
5988 message = ('Added tag %s for changeset %s' %
5964 (', '.join(names), short(node)))
5989 (', '.join(names), short(node)))
5965
5990
5966 date = opts.get('date')
5991 date = opts.get('date')
5967 if date:
5992 if date:
5968 date = dateutil.parsedate(date)
5993 date = dateutil.parsedate(date)
5969
5994
5970 if opts.get('remove'):
5995 if opts.get('remove'):
5971 editform = 'tag.remove'
5996 editform = 'tag.remove'
5972 else:
5997 else:
5973 editform = 'tag.add'
5998 editform = 'tag.add'
5974 editor = cmdutil.getcommiteditor(editform=editform,
5999 editor = cmdutil.getcommiteditor(editform=editform,
5975 **pycompat.strkwargs(opts))
6000 **pycompat.strkwargs(opts))
5976
6001
5977 # don't allow tagging the null rev
6002 # don't allow tagging the null rev
5978 if (not opts.get('remove') and
6003 if (not opts.get('remove') and
5979 scmutil.revsingle(repo, rev_).rev() == nullrev):
6004 scmutil.revsingle(repo, rev_).rev() == nullrev):
5980 raise error.Abort(_("cannot tag null revision"))
6005 raise error.Abort(_("cannot tag null revision"))
5981
6006
5982 tagsmod.tag(repo, names, node, message, opts.get('local'),
6007 tagsmod.tag(repo, names, node, message, opts.get('local'),
5983 opts.get('user'), date, editor=editor)
6008 opts.get('user'), date, editor=editor)
5984
6009
5985 @command(
6010 @command(
5986 'tags', formatteropts, '',
6011 'tags', formatteropts, '',
5987 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
6012 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5988 intents={INTENT_READONLY})
6013 intents={INTENT_READONLY})
5989 def tags(ui, repo, **opts):
6014 def tags(ui, repo, **opts):
5990 """list repository tags
6015 """list repository tags
5991
6016
5992 This lists both regular and local tags. When the -v/--verbose
6017 This lists both regular and local tags. When the -v/--verbose
5993 switch is used, a third column "local" is printed for local tags.
6018 switch is used, a third column "local" is printed for local tags.
5994 When the -q/--quiet switch is used, only the tag name is printed.
6019 When the -q/--quiet switch is used, only the tag name is printed.
5995
6020
5996 .. container:: verbose
6021 .. container:: verbose
5997
6022
5998 Template:
6023 Template:
5999
6024
6000 The following keywords are supported in addition to the common template
6025 The following keywords are supported in addition to the common template
6001 keywords and functions such as ``{tag}``. See also
6026 keywords and functions such as ``{tag}``. See also
6002 :hg:`help templates`.
6027 :hg:`help templates`.
6003
6028
6004 :type: String. ``local`` for local tags.
6029 :type: String. ``local`` for local tags.
6005
6030
6006 Returns 0 on success.
6031 Returns 0 on success.
6007 """
6032 """
6008
6033
6009 opts = pycompat.byteskwargs(opts)
6034 opts = pycompat.byteskwargs(opts)
6010 ui.pager('tags')
6035 ui.pager('tags')
6011 fm = ui.formatter('tags', opts)
6036 fm = ui.formatter('tags', opts)
6012 hexfunc = fm.hexfunc
6037 hexfunc = fm.hexfunc
6013
6038
6014 for t, n in reversed(repo.tagslist()):
6039 for t, n in reversed(repo.tagslist()):
6015 hn = hexfunc(n)
6040 hn = hexfunc(n)
6016 label = 'tags.normal'
6041 label = 'tags.normal'
6017 tagtype = ''
6042 tagtype = ''
6018 if repo.tagtype(t) == 'local':
6043 if repo.tagtype(t) == 'local':
6019 label = 'tags.local'
6044 label = 'tags.local'
6020 tagtype = 'local'
6045 tagtype = 'local'
6021
6046
6022 fm.startitem()
6047 fm.startitem()
6023 fm.context(repo=repo)
6048 fm.context(repo=repo)
6024 fm.write('tag', '%s', t, label=label)
6049 fm.write('tag', '%s', t, label=label)
6025 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6050 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6026 fm.condwrite(not ui.quiet, 'rev node', fmt,
6051 fm.condwrite(not ui.quiet, 'rev node', fmt,
6027 repo.changelog.rev(n), hn, label=label)
6052 repo.changelog.rev(n), hn, label=label)
6028 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6053 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6029 tagtype, label=label)
6054 tagtype, label=label)
6030 fm.plain('\n')
6055 fm.plain('\n')
6031 fm.end()
6056 fm.end()
6032
6057
6033 @command('tip',
6058 @command('tip',
6034 [('p', 'patch', None, _('show patch')),
6059 [('p', 'patch', None, _('show patch')),
6035 ('g', 'git', None, _('use git extended diff format')),
6060 ('g', 'git', None, _('use git extended diff format')),
6036 ] + templateopts,
6061 ] + templateopts,
6037 _('[-p] [-g]'),
6062 _('[-p] [-g]'),
6038 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
6063 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
6039 def tip(ui, repo, **opts):
6064 def tip(ui, repo, **opts):
6040 """show the tip revision (DEPRECATED)
6065 """show the tip revision (DEPRECATED)
6041
6066
6042 The tip revision (usually just called the tip) is the changeset
6067 The tip revision (usually just called the tip) is the changeset
6043 most recently added to the repository (and therefore the most
6068 most recently added to the repository (and therefore the most
6044 recently changed head).
6069 recently changed head).
6045
6070
6046 If you have just made a commit, that commit will be the tip. If
6071 If you have just made a commit, that commit will be the tip. If
6047 you have just pulled changes from another repository, the tip of
6072 you have just pulled changes from another repository, the tip of
6048 that repository becomes the current tip. The "tip" tag is special
6073 that repository becomes the current tip. The "tip" tag is special
6049 and cannot be renamed or assigned to a different changeset.
6074 and cannot be renamed or assigned to a different changeset.
6050
6075
6051 This command is deprecated, please use :hg:`heads` instead.
6076 This command is deprecated, please use :hg:`heads` instead.
6052
6077
6053 Returns 0 on success.
6078 Returns 0 on success.
6054 """
6079 """
6055 opts = pycompat.byteskwargs(opts)
6080 opts = pycompat.byteskwargs(opts)
6056 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
6081 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
6057 displayer.show(repo['tip'])
6082 displayer.show(repo['tip'])
6058 displayer.close()
6083 displayer.close()
6059
6084
6060 @command('unbundle',
6085 @command('unbundle',
6061 [('u', 'update', None,
6086 [('u', 'update', None,
6062 _('update to new branch head if changesets were unbundled'))],
6087 _('update to new branch head if changesets were unbundled'))],
6063 _('[-u] FILE...'),
6088 _('[-u] FILE...'),
6064 helpcategory=command.CATEGORY_IMPORT_EXPORT)
6089 helpcategory=command.CATEGORY_IMPORT_EXPORT)
6065 def unbundle(ui, repo, fname1, *fnames, **opts):
6090 def unbundle(ui, repo, fname1, *fnames, **opts):
6066 """apply one or more bundle files
6091 """apply one or more bundle files
6067
6092
6068 Apply one or more bundle files generated by :hg:`bundle`.
6093 Apply one or more bundle files generated by :hg:`bundle`.
6069
6094
6070 Returns 0 on success, 1 if an update has unresolved files.
6095 Returns 0 on success, 1 if an update has unresolved files.
6071 """
6096 """
6072 fnames = (fname1,) + fnames
6097 fnames = (fname1,) + fnames
6073
6098
6074 with repo.lock():
6099 with repo.lock():
6075 for fname in fnames:
6100 for fname in fnames:
6076 f = hg.openpath(ui, fname)
6101 f = hg.openpath(ui, fname)
6077 gen = exchange.readbundle(ui, f, fname)
6102 gen = exchange.readbundle(ui, f, fname)
6078 if isinstance(gen, streamclone.streamcloneapplier):
6103 if isinstance(gen, streamclone.streamcloneapplier):
6079 raise error.Abort(
6104 raise error.Abort(
6080 _('packed bundles cannot be applied with '
6105 _('packed bundles cannot be applied with '
6081 '"hg unbundle"'),
6106 '"hg unbundle"'),
6082 hint=_('use "hg debugapplystreamclonebundle"'))
6107 hint=_('use "hg debugapplystreamclonebundle"'))
6083 url = 'bundle:' + fname
6108 url = 'bundle:' + fname
6084 try:
6109 try:
6085 txnname = 'unbundle'
6110 txnname = 'unbundle'
6086 if not isinstance(gen, bundle2.unbundle20):
6111 if not isinstance(gen, bundle2.unbundle20):
6087 txnname = 'unbundle\n%s' % util.hidepassword(url)
6112 txnname = 'unbundle\n%s' % util.hidepassword(url)
6088 with repo.transaction(txnname) as tr:
6113 with repo.transaction(txnname) as tr:
6089 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6114 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6090 url=url)
6115 url=url)
6091 except error.BundleUnknownFeatureError as exc:
6116 except error.BundleUnknownFeatureError as exc:
6092 raise error.Abort(
6117 raise error.Abort(
6093 _('%s: unknown bundle feature, %s') % (fname, exc),
6118 _('%s: unknown bundle feature, %s') % (fname, exc),
6094 hint=_("see https://mercurial-scm.org/"
6119 hint=_("see https://mercurial-scm.org/"
6095 "wiki/BundleFeature for more "
6120 "wiki/BundleFeature for more "
6096 "information"))
6121 "information"))
6097 modheads = bundle2.combinechangegroupresults(op)
6122 modheads = bundle2.combinechangegroupresults(op)
6098
6123
6099 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
6124 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
6100
6125
6101 @command('unshelve',
6126 @command('unshelve',
6102 [('a', 'abort', None,
6127 [('a', 'abort', None,
6103 _('abort an incomplete unshelve operation')),
6128 _('abort an incomplete unshelve operation')),
6104 ('c', 'continue', None,
6129 ('c', 'continue', None,
6105 _('continue an incomplete unshelve operation')),
6130 _('continue an incomplete unshelve operation')),
6106 ('k', 'keep', None,
6131 ('k', 'keep', None,
6107 _('keep shelve after unshelving')),
6132 _('keep shelve after unshelving')),
6108 ('n', 'name', '',
6133 ('n', 'name', '',
6109 _('restore shelved change with given name'), _('NAME')),
6134 _('restore shelved change with given name'), _('NAME')),
6110 ('t', 'tool', '', _('specify merge tool')),
6135 ('t', 'tool', '', _('specify merge tool')),
6111 ('', 'date', '',
6136 ('', 'date', '',
6112 _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
6137 _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
6113 _('hg unshelve [[-n] SHELVED]'),
6138 _('hg unshelve [[-n] SHELVED]'),
6114 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
6139 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
6115 def unshelve(ui, repo, *shelved, **opts):
6140 def unshelve(ui, repo, *shelved, **opts):
6116 """restore a shelved change to the working directory
6141 """restore a shelved change to the working directory
6117
6142
6118 This command accepts an optional name of a shelved change to
6143 This command accepts an optional name of a shelved change to
6119 restore. If none is given, the most recent shelved change is used.
6144 restore. If none is given, the most recent shelved change is used.
6120
6145
6121 If a shelved change is applied successfully, the bundle that
6146 If a shelved change is applied successfully, the bundle that
6122 contains the shelved changes is moved to a backup location
6147 contains the shelved changes is moved to a backup location
6123 (.hg/shelve-backup).
6148 (.hg/shelve-backup).
6124
6149
6125 Since you can restore a shelved change on top of an arbitrary
6150 Since you can restore a shelved change on top of an arbitrary
6126 commit, it is possible that unshelving will result in a conflict
6151 commit, it is possible that unshelving will result in a conflict
6127 between your changes and the commits you are unshelving onto. If
6152 between your changes and the commits you are unshelving onto. If
6128 this occurs, you must resolve the conflict, then use
6153 this occurs, you must resolve the conflict, then use
6129 ``--continue`` to complete the unshelve operation. (The bundle
6154 ``--continue`` to complete the unshelve operation. (The bundle
6130 will not be moved until you successfully complete the unshelve.)
6155 will not be moved until you successfully complete the unshelve.)
6131
6156
6132 (Alternatively, you can use ``--abort`` to abandon an unshelve
6157 (Alternatively, you can use ``--abort`` to abandon an unshelve
6133 that causes a conflict. This reverts the unshelved changes, and
6158 that causes a conflict. This reverts the unshelved changes, and
6134 leaves the bundle in place.)
6159 leaves the bundle in place.)
6135
6160
6136 If bare shelved change (when no files are specified, without interactive,
6161 If bare shelved change (when no files are specified, without interactive,
6137 include and exclude option) was done on newly created branch it would
6162 include and exclude option) was done on newly created branch it would
6138 restore branch information to the working directory.
6163 restore branch information to the working directory.
6139
6164
6140 After a successful unshelve, the shelved changes are stored in a
6165 After a successful unshelve, the shelved changes are stored in a
6141 backup directory. Only the N most recent backups are kept. N
6166 backup directory. Only the N most recent backups are kept. N
6142 defaults to 10 but can be overridden using the ``shelve.maxbackups``
6167 defaults to 10 but can be overridden using the ``shelve.maxbackups``
6143 configuration option.
6168 configuration option.
6144
6169
6145 .. container:: verbose
6170 .. container:: verbose
6146
6171
6147 Timestamp in seconds is used to decide order of backups. More
6172 Timestamp in seconds is used to decide order of backups. More
6148 than ``maxbackups`` backups are kept, if same timestamp
6173 than ``maxbackups`` backups are kept, if same timestamp
6149 prevents from deciding exact order of them, for safety.
6174 prevents from deciding exact order of them, for safety.
6150 """
6175 """
6151 with repo.wlock():
6176 with repo.wlock():
6152 return shelvemod.dounshelve(ui, repo, *shelved, **opts)
6177 return shelvemod.dounshelve(ui, repo, *shelved, **opts)
6153
6178
6154 @command('update|up|checkout|co',
6179 @command('update|up|checkout|co',
6155 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6180 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6156 ('c', 'check', None, _('require clean working directory')),
6181 ('c', 'check', None, _('require clean working directory')),
6157 ('m', 'merge', None, _('merge uncommitted changes')),
6182 ('m', 'merge', None, _('merge uncommitted changes')),
6158 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6183 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6159 ('r', 'rev', '', _('revision'), _('REV'))
6184 ('r', 'rev', '', _('revision'), _('REV'))
6160 ] + mergetoolopts,
6185 ] + mergetoolopts,
6161 _('[-C|-c|-m] [-d DATE] [[-r] REV]'),
6186 _('[-C|-c|-m] [-d DATE] [[-r] REV]'),
6162 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6187 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6163 helpbasic=True)
6188 helpbasic=True)
6164 def update(ui, repo, node=None, **opts):
6189 def update(ui, repo, node=None, **opts):
6165 """update working directory (or switch revisions)
6190 """update working directory (or switch revisions)
6166
6191
6167 Update the repository's working directory to the specified
6192 Update the repository's working directory to the specified
6168 changeset. If no changeset is specified, update to the tip of the
6193 changeset. If no changeset is specified, update to the tip of the
6169 current named branch and move the active bookmark (see :hg:`help
6194 current named branch and move the active bookmark (see :hg:`help
6170 bookmarks`).
6195 bookmarks`).
6171
6196
6172 Update sets the working directory's parent revision to the specified
6197 Update sets the working directory's parent revision to the specified
6173 changeset (see :hg:`help parents`).
6198 changeset (see :hg:`help parents`).
6174
6199
6175 If the changeset is not a descendant or ancestor of the working
6200 If the changeset is not a descendant or ancestor of the working
6176 directory's parent and there are uncommitted changes, the update is
6201 directory's parent and there are uncommitted changes, the update is
6177 aborted. With the -c/--check option, the working directory is checked
6202 aborted. With the -c/--check option, the working directory is checked
6178 for uncommitted changes; if none are found, the working directory is
6203 for uncommitted changes; if none are found, the working directory is
6179 updated to the specified changeset.
6204 updated to the specified changeset.
6180
6205
6181 .. container:: verbose
6206 .. container:: verbose
6182
6207
6183 The -C/--clean, -c/--check, and -m/--merge options control what
6208 The -C/--clean, -c/--check, and -m/--merge options control what
6184 happens if the working directory contains uncommitted changes.
6209 happens if the working directory contains uncommitted changes.
6185 At most of one of them can be specified.
6210 At most of one of them can be specified.
6186
6211
6187 1. If no option is specified, and if
6212 1. If no option is specified, and if
6188 the requested changeset is an ancestor or descendant of
6213 the requested changeset is an ancestor or descendant of
6189 the working directory's parent, the uncommitted changes
6214 the working directory's parent, the uncommitted changes
6190 are merged into the requested changeset and the merged
6215 are merged into the requested changeset and the merged
6191 result is left uncommitted. If the requested changeset is
6216 result is left uncommitted. If the requested changeset is
6192 not an ancestor or descendant (that is, it is on another
6217 not an ancestor or descendant (that is, it is on another
6193 branch), the update is aborted and the uncommitted changes
6218 branch), the update is aborted and the uncommitted changes
6194 are preserved.
6219 are preserved.
6195
6220
6196 2. With the -m/--merge option, the update is allowed even if the
6221 2. With the -m/--merge option, the update is allowed even if the
6197 requested changeset is not an ancestor or descendant of
6222 requested changeset is not an ancestor or descendant of
6198 the working directory's parent.
6223 the working directory's parent.
6199
6224
6200 3. With the -c/--check option, the update is aborted and the
6225 3. With the -c/--check option, the update is aborted and the
6201 uncommitted changes are preserved.
6226 uncommitted changes are preserved.
6202
6227
6203 4. With the -C/--clean option, uncommitted changes are discarded and
6228 4. With the -C/--clean option, uncommitted changes are discarded and
6204 the working directory is updated to the requested changeset.
6229 the working directory is updated to the requested changeset.
6205
6230
6206 To cancel an uncommitted merge (and lose your changes), use
6231 To cancel an uncommitted merge (and lose your changes), use
6207 :hg:`merge --abort`.
6232 :hg:`merge --abort`.
6208
6233
6209 Use null as the changeset to remove the working directory (like
6234 Use null as the changeset to remove the working directory (like
6210 :hg:`clone -U`).
6235 :hg:`clone -U`).
6211
6236
6212 If you want to revert just one file to an older revision, use
6237 If you want to revert just one file to an older revision, use
6213 :hg:`revert [-r REV] NAME`.
6238 :hg:`revert [-r REV] NAME`.
6214
6239
6215 See :hg:`help dates` for a list of formats valid for -d/--date.
6240 See :hg:`help dates` for a list of formats valid for -d/--date.
6216
6241
6217 Returns 0 on success, 1 if there are unresolved files.
6242 Returns 0 on success, 1 if there are unresolved files.
6218 """
6243 """
6219 rev = opts.get(r'rev')
6244 rev = opts.get(r'rev')
6220 date = opts.get(r'date')
6245 date = opts.get(r'date')
6221 clean = opts.get(r'clean')
6246 clean = opts.get(r'clean')
6222 check = opts.get(r'check')
6247 check = opts.get(r'check')
6223 merge = opts.get(r'merge')
6248 merge = opts.get(r'merge')
6224 if rev and node:
6249 if rev and node:
6225 raise error.Abort(_("please specify just one revision"))
6250 raise error.Abort(_("please specify just one revision"))
6226
6251
6227 if ui.configbool('commands', 'update.requiredest'):
6252 if ui.configbool('commands', 'update.requiredest'):
6228 if not node and not rev and not date:
6253 if not node and not rev and not date:
6229 raise error.Abort(_('you must specify a destination'),
6254 raise error.Abort(_('you must specify a destination'),
6230 hint=_('for example: hg update ".::"'))
6255 hint=_('for example: hg update ".::"'))
6231
6256
6232 if rev is None or rev == '':
6257 if rev is None or rev == '':
6233 rev = node
6258 rev = node
6234
6259
6235 if date and rev is not None:
6260 if date and rev is not None:
6236 raise error.Abort(_("you can't specify a revision and a date"))
6261 raise error.Abort(_("you can't specify a revision and a date"))
6237
6262
6238 if len([x for x in (clean, check, merge) if x]) > 1:
6263 if len([x for x in (clean, check, merge) if x]) > 1:
6239 raise error.Abort(_("can only specify one of -C/--clean, -c/--check, "
6264 raise error.Abort(_("can only specify one of -C/--clean, -c/--check, "
6240 "or -m/--merge"))
6265 "or -m/--merge"))
6241
6266
6242 updatecheck = None
6267 updatecheck = None
6243 if check:
6268 if check:
6244 updatecheck = 'abort'
6269 updatecheck = 'abort'
6245 elif merge:
6270 elif merge:
6246 updatecheck = 'none'
6271 updatecheck = 'none'
6247
6272
6248 with repo.wlock():
6273 with repo.wlock():
6249 cmdutil.clearunfinished(repo)
6274 cmdutil.clearunfinished(repo)
6250 if date:
6275 if date:
6251 rev = cmdutil.finddate(ui, repo, date)
6276 rev = cmdutil.finddate(ui, repo, date)
6252
6277
6253 # if we defined a bookmark, we have to remember the original name
6278 # if we defined a bookmark, we have to remember the original name
6254 brev = rev
6279 brev = rev
6255 if rev:
6280 if rev:
6256 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
6281 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
6257 ctx = scmutil.revsingle(repo, rev, default=None)
6282 ctx = scmutil.revsingle(repo, rev, default=None)
6258 rev = ctx.rev()
6283 rev = ctx.rev()
6259 hidden = ctx.hidden()
6284 hidden = ctx.hidden()
6260 overrides = {('ui', 'forcemerge'): opts.get(r'tool', '')}
6285 overrides = {('ui', 'forcemerge'): opts.get(r'tool', '')}
6261 with ui.configoverride(overrides, 'update'):
6286 with ui.configoverride(overrides, 'update'):
6262 ret = hg.updatetotally(ui, repo, rev, brev, clean=clean,
6287 ret = hg.updatetotally(ui, repo, rev, brev, clean=clean,
6263 updatecheck=updatecheck)
6288 updatecheck=updatecheck)
6264 if hidden:
6289 if hidden:
6265 ctxstr = ctx.hex()[:12]
6290 ctxstr = ctx.hex()[:12]
6266 ui.warn(_("updated to hidden changeset %s\n") % ctxstr)
6291 ui.warn(_("updated to hidden changeset %s\n") % ctxstr)
6267
6292
6268 if ctx.obsolete():
6293 if ctx.obsolete():
6269 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
6294 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
6270 ui.warn("(%s)\n" % obsfatemsg)
6295 ui.warn("(%s)\n" % obsfatemsg)
6271 return ret
6296 return ret
6272
6297
6273 @command('verify',
6298 @command('verify',
6274 [('', 'full', False, 'perform more checks (EXPERIMENTAL)')],
6299 [('', 'full', False, 'perform more checks (EXPERIMENTAL)')],
6275 helpcategory=command.CATEGORY_MAINTENANCE)
6300 helpcategory=command.CATEGORY_MAINTENANCE)
6276 def verify(ui, repo, **opts):
6301 def verify(ui, repo, **opts):
6277 """verify the integrity of the repository
6302 """verify the integrity of the repository
6278
6303
6279 Verify the integrity of the current repository.
6304 Verify the integrity of the current repository.
6280
6305
6281 This will perform an extensive check of the repository's
6306 This will perform an extensive check of the repository's
6282 integrity, validating the hashes and checksums of each entry in
6307 integrity, validating the hashes and checksums of each entry in
6283 the changelog, manifest, and tracked files, as well as the
6308 the changelog, manifest, and tracked files, as well as the
6284 integrity of their crosslinks and indices.
6309 integrity of their crosslinks and indices.
6285
6310
6286 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6311 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6287 for more information about recovery from corruption of the
6312 for more information about recovery from corruption of the
6288 repository.
6313 repository.
6289
6314
6290 Returns 0 on success, 1 if errors are encountered.
6315 Returns 0 on success, 1 if errors are encountered.
6291 """
6316 """
6292 opts = pycompat.byteskwargs(opts)
6317 opts = pycompat.byteskwargs(opts)
6293
6318
6294 level = None
6319 level = None
6295 if opts['full']:
6320 if opts['full']:
6296 level = verifymod.VERIFY_FULL
6321 level = verifymod.VERIFY_FULL
6297 return hg.verify(repo, level)
6322 return hg.verify(repo, level)
6298
6323
6299 @command(
6324 @command(
6300 'version', [] + formatteropts, helpcategory=command.CATEGORY_HELP,
6325 'version', [] + formatteropts, helpcategory=command.CATEGORY_HELP,
6301 norepo=True, intents={INTENT_READONLY})
6326 norepo=True, intents={INTENT_READONLY})
6302 def version_(ui, **opts):
6327 def version_(ui, **opts):
6303 """output version and copyright information
6328 """output version and copyright information
6304
6329
6305 .. container:: verbose
6330 .. container:: verbose
6306
6331
6307 Template:
6332 Template:
6308
6333
6309 The following keywords are supported. See also :hg:`help templates`.
6334 The following keywords are supported. See also :hg:`help templates`.
6310
6335
6311 :extensions: List of extensions.
6336 :extensions: List of extensions.
6312 :ver: String. Version number.
6337 :ver: String. Version number.
6313
6338
6314 And each entry of ``{extensions}`` provides the following sub-keywords
6339 And each entry of ``{extensions}`` provides the following sub-keywords
6315 in addition to ``{ver}``.
6340 in addition to ``{ver}``.
6316
6341
6317 :bundled: Boolean. True if included in the release.
6342 :bundled: Boolean. True if included in the release.
6318 :name: String. Extension name.
6343 :name: String. Extension name.
6319 """
6344 """
6320 opts = pycompat.byteskwargs(opts)
6345 opts = pycompat.byteskwargs(opts)
6321 if ui.verbose:
6346 if ui.verbose:
6322 ui.pager('version')
6347 ui.pager('version')
6323 fm = ui.formatter("version", opts)
6348 fm = ui.formatter("version", opts)
6324 fm.startitem()
6349 fm.startitem()
6325 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
6350 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
6326 util.version())
6351 util.version())
6327 license = _(
6352 license = _(
6328 "(see https://mercurial-scm.org for more information)\n"
6353 "(see https://mercurial-scm.org for more information)\n"
6329 "\nCopyright (C) 2005-2019 Matt Mackall and others\n"
6354 "\nCopyright (C) 2005-2019 Matt Mackall and others\n"
6330 "This is free software; see the source for copying conditions. "
6355 "This is free software; see the source for copying conditions. "
6331 "There is NO\nwarranty; "
6356 "There is NO\nwarranty; "
6332 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6357 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6333 )
6358 )
6334 if not ui.quiet:
6359 if not ui.quiet:
6335 fm.plain(license)
6360 fm.plain(license)
6336
6361
6337 if ui.verbose:
6362 if ui.verbose:
6338 fm.plain(_("\nEnabled extensions:\n\n"))
6363 fm.plain(_("\nEnabled extensions:\n\n"))
6339 # format names and versions into columns
6364 # format names and versions into columns
6340 names = []
6365 names = []
6341 vers = []
6366 vers = []
6342 isinternals = []
6367 isinternals = []
6343 for name, module in extensions.extensions():
6368 for name, module in extensions.extensions():
6344 names.append(name)
6369 names.append(name)
6345 vers.append(extensions.moduleversion(module) or None)
6370 vers.append(extensions.moduleversion(module) or None)
6346 isinternals.append(extensions.ismoduleinternal(module))
6371 isinternals.append(extensions.ismoduleinternal(module))
6347 fn = fm.nested("extensions", tmpl='{name}\n')
6372 fn = fm.nested("extensions", tmpl='{name}\n')
6348 if names:
6373 if names:
6349 namefmt = " %%-%ds " % max(len(n) for n in names)
6374 namefmt = " %%-%ds " % max(len(n) for n in names)
6350 places = [_("external"), _("internal")]
6375 places = [_("external"), _("internal")]
6351 for n, v, p in zip(names, vers, isinternals):
6376 for n, v, p in zip(names, vers, isinternals):
6352 fn.startitem()
6377 fn.startitem()
6353 fn.condwrite(ui.verbose, "name", namefmt, n)
6378 fn.condwrite(ui.verbose, "name", namefmt, n)
6354 if ui.verbose:
6379 if ui.verbose:
6355 fn.plain("%s " % places[p])
6380 fn.plain("%s " % places[p])
6356 fn.data(bundled=p)
6381 fn.data(bundled=p)
6357 fn.condwrite(ui.verbose and v, "ver", "%s", v)
6382 fn.condwrite(ui.verbose and v, "ver", "%s", v)
6358 if ui.verbose:
6383 if ui.verbose:
6359 fn.plain("\n")
6384 fn.plain("\n")
6360 fn.end()
6385 fn.end()
6361 fm.end()
6386 fm.end()
6362
6387
6363 def loadcmdtable(ui, name, cmdtable):
6388 def loadcmdtable(ui, name, cmdtable):
6364 """Load command functions from specified cmdtable
6389 """Load command functions from specified cmdtable
6365 """
6390 """
6366 overrides = [cmd for cmd in cmdtable if cmd in table]
6391 overrides = [cmd for cmd in cmdtable if cmd in table]
6367 if overrides:
6392 if overrides:
6368 ui.warn(_("extension '%s' overrides commands: %s\n")
6393 ui.warn(_("extension '%s' overrides commands: %s\n")
6369 % (name, " ".join(overrides)))
6394 % (name, " ".join(overrides)))
6370 table.update(cmdtable)
6395 table.update(cmdtable)
@@ -1,229 +1,232 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 self._opname = opname
103 self._opname = opname
103 self._fname = fname
104 self._fname = fname
104 self._clearable = clearable
105 self._clearable = clearable
105 self._allowcommit = allowcommit
106 self._allowcommit = allowcommit
106 self._reportonly = reportonly
107 self._reportonly = reportonly
107 self._continueflag = continueflag
108 self._continueflag = continueflag
108 self._stopflag = stopflag
109 self._stopflag = stopflag
109 self._cmdmsg = cmdmsg
110 self._cmdmsg = cmdmsg
110 self._cmdhint = cmdhint
111 self._cmdhint = cmdhint
111 self._statushint = statushint
112 self._statushint = statushint
113 self.abortfunc = abortfunc
112
114
113 def statusmsg(self):
115 def statusmsg(self):
114 """returns the hint message corresponding to the command for
116 """returns the hint message corresponding to the command for
115 hg status --verbose
117 hg status --verbose
116 """
118 """
117 if not self._statushint:
119 if not self._statushint:
118 hint = (_('To continue: hg %s --continue\n'
120 hint = (_('To continue: hg %s --continue\n'
119 'To abort: hg %s --abort') % (self._opname,
121 'To abort: hg %s --abort') % (self._opname,
120 self._opname))
122 self._opname))
121 if self._stopflag:
123 if self._stopflag:
122 hint = hint + (_('\nTo stop: hg %s --stop') %
124 hint = hint + (_('\nTo stop: hg %s --stop') %
123 (self._opname))
125 (self._opname))
124 return hint
126 return hint
125 return self._statushint
127 return self._statushint
126
128
127 def hint(self):
129 def hint(self):
128 """returns the hint message corresponding to an interrupted
130 """returns the hint message corresponding to an interrupted
129 operation
131 operation
130 """
132 """
131 if not self._cmdhint:
133 if not self._cmdhint:
132 return (_("use 'hg %s --continue' or 'hg %s --abort'") %
134 return (_("use 'hg %s --continue' or 'hg %s --abort'") %
133 (self._opname, self._opname))
135 (self._opname, self._opname))
134 return self._cmdhint
136 return self._cmdhint
135
137
136 def msg(self):
138 def msg(self):
137 """returns the status message corresponding to the command"""
139 """returns the status message corresponding to the command"""
138 if not self._cmdmsg:
140 if not self._cmdmsg:
139 return _('%s in progress') % (self._opname)
141 return _('%s in progress') % (self._opname)
140 return self._cmdmsg
142 return self._cmdmsg
141
143
142 def continuemsg(self):
144 def continuemsg(self):
143 """ returns appropriate continue message corresponding to command"""
145 """ returns appropriate continue message corresponding to command"""
144 return _('hg %s --continue') % (self._opname)
146 return _('hg %s --continue') % (self._opname)
145
147
146 def isunfinished(self, repo):
148 def isunfinished(self, repo):
147 """determines whether a multi-step operation is in progress
149 """determines whether a multi-step operation is in progress
148 or not
150 or not
149 """
151 """
150 if self._opname == 'merge':
152 if self._opname == 'merge':
151 return len(repo[None].parents()) > 1
153 return len(repo[None].parents()) > 1
152 else:
154 else:
153 return repo.vfs.exists(self._fname)
155 return repo.vfs.exists(self._fname)
154
156
155 # A list of statecheck objects for multistep operations like graft.
157 # A list of statecheck objects for multistep operations like graft.
156 _unfinishedstates = []
158 _unfinishedstates = []
157
159
158 def addunfinished(opname, fname, clearable=False, allowcommit=False,
160 def addunfinished(opname, fname, clearable=False, allowcommit=False,
159 reportonly=False, continueflag=False, stopflag=False,
161 reportonly=False, continueflag=False, stopflag=False,
160 cmdmsg="", cmdhint="", statushint=""):
162 cmdmsg="", cmdhint="", statushint="", abortfunc=None):
161 """this registers a new command or operation to unfinishedstates
163 """this registers a new command or operation to unfinishedstates
162 opname is the name the command or operation
164 opname is the name the command or operation
163 fname is the file name in which data should be stored in .hg directory.
165 fname is the file name in which data should be stored in .hg directory.
164 It is None for merge command.
166 It is None for merge command.
165 clearable boolean determines whether or not interrupted states can be
167 clearable boolean determines whether or not interrupted states can be
166 cleared by running `hg update -C .` which in turn deletes the
168 cleared by running `hg update -C .` which in turn deletes the
167 state file.
169 state file.
168 allowcommit boolean decides whether commit is allowed during interrupted
170 allowcommit boolean decides whether commit is allowed during interrupted
169 state or not.
171 state or not.
170 reportonly flag is used for operations like bisect where we just
172 reportonly flag is used for operations like bisect where we just
171 need to detect the operation using 'hg status --verbose'
173 need to detect the operation using 'hg status --verbose'
172 continueflag is a boolean determines whether or not a command supports
174 continueflag is a boolean determines whether or not a command supports
173 `--continue` option or not.
175 `--continue` option or not.
174 stopflag is a boolean that determines whether or not a command supports
176 stopflag is a boolean that determines whether or not a command supports
175 --stop flag
177 --stop flag
176 cmdmsg is used to pass a different status message in case standard
178 cmdmsg is used to pass a different status message in case standard
177 message of the format "abort: cmdname in progress" is not desired.
179 message of the format "abort: cmdname in progress" is not desired.
178 cmdhint is used to pass a different hint message in case standard
180 cmdhint is used to pass a different hint message in case standard
179 message of the format "To continue: hg cmdname --continue
181 message of the format "To continue: hg cmdname --continue
180 To abort: hg cmdname --abort" is not desired.
182 To abort: hg cmdname --abort" is not desired.
181 statushint is used to pass a different status message in case standard
183 statushint is used to pass a different status message in case standard
182 message of the format ('To continue: hg cmdname --continue'
184 message of the format ('To continue: hg cmdname --continue'
183 'To abort: hg cmdname --abort') is not desired
185 'To abort: hg cmdname --abort') is not desired
186 abortfunc stores the function required to abort an unfinished state.
184 """
187 """
185 statecheckobj = _statecheck(opname, fname, clearable, allowcommit,
188 statecheckobj = _statecheck(opname, fname, clearable, allowcommit,
186 reportonly, continueflag, stopflag, cmdmsg,
189 reportonly, continueflag, stopflag, cmdmsg,
187 cmdhint, statushint)
190 cmdhint, statushint, abortfunc)
188 if opname == 'merge':
191 if opname == 'merge':
189 _unfinishedstates.append(statecheckobj)
192 _unfinishedstates.append(statecheckobj)
190 else:
193 else:
191 _unfinishedstates.insert(0, statecheckobj)
194 _unfinishedstates.insert(0, statecheckobj)
192
195
193 addunfinished(
196 addunfinished(
194 'graft', fname='graftstate', clearable=True, stopflag=True,
197 'graft', fname='graftstate', clearable=True, stopflag=True,
195 continueflag=True,
198 continueflag=True,
196 cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop")
199 cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop")
197 )
200 )
198 addunfinished(
201 addunfinished(
199 'unshelve', fname='shelvedstate', continueflag=True,
202 'unshelve', fname='shelvedstate', continueflag=True,
200 cmdmsg=_('unshelve already in progress')
203 cmdmsg=_('unshelve already in progress')
201 )
204 )
202 addunfinished(
205 addunfinished(
203 'update', fname='updatestate', clearable=True,
206 'update', fname='updatestate', clearable=True,
204 cmdmsg=_('last update was interrupted'),
207 cmdmsg=_('last update was interrupted'),
205 cmdhint=_("use 'hg update' to get a consistent checkout"),
208 cmdhint=_("use 'hg update' to get a consistent checkout"),
206 statushint=_("To continue: hg update")
209 statushint=_("To continue: hg update")
207 )
210 )
208 addunfinished(
211 addunfinished(
209 'bisect', fname='bisect.state', allowcommit=True, reportonly=True,
212 'bisect', fname='bisect.state', allowcommit=True, reportonly=True,
210 statushint=_('To mark the changeset good: hg bisect --good\n'
213 statushint=_('To mark the changeset good: hg bisect --good\n'
211 'To mark the changeset bad: hg bisect --bad\n'
214 'To mark the changeset bad: hg bisect --bad\n'
212 'To abort: hg bisect --reset\n')
215 'To abort: hg bisect --reset\n')
213 )
216 )
214 addunfinished(
217 addunfinished(
215 'merge', fname=None, clearable=True, allowcommit=True,
218 'merge', fname=None, clearable=True, allowcommit=True,
216 cmdmsg=_('outstanding uncommitted merge'),
219 cmdmsg=_('outstanding uncommitted merge'),
217 statushint=_('To continue: hg commit\n'
220 statushint=_('To continue: hg commit\n'
218 'To abort: hg merge --abort'),
221 'To abort: hg merge --abort'),
219 cmdhint=_("use 'hg commit' or 'hg merge --abort'")
222 cmdhint=_("use 'hg commit' or 'hg merge --abort'")
220 )
223 )
221
224
222 def getrepostate(repo):
225 def getrepostate(repo):
223 # experimental config: commands.status.skipstates
226 # experimental config: commands.status.skipstates
224 skip = set(repo.ui.configlist('commands', 'status.skipstates'))
227 skip = set(repo.ui.configlist('commands', 'status.skipstates'))
225 for state in _unfinishedstates:
228 for state in _unfinishedstates:
226 if state._opname in skip:
229 if state._opname in skip:
227 continue
230 continue
228 if state.isunfinished(repo):
231 if state.isunfinished(repo):
229 return (state._opname, state.statusmsg())
232 return (state._opname, state.statusmsg())
@@ -1,484 +1,484 b''
1 setup
1 setup
2
2
3 $ cat > myextension.py <<EOF
3 $ cat > myextension.py <<EOF
4 > from mercurial import error, registrar
4 > from mercurial import error, registrar
5 > cmdtable = {}
5 > cmdtable = {}
6 > command = registrar.command(cmdtable)
6 > command = registrar.command(cmdtable)
7 > @command(b'crash', [], b'hg crash')
7 > @command(b'crash', [], b'hg crash')
8 > def crash(ui, *args, **kwargs):
8 > def crash(ui, *args, **kwargs):
9 > raise Exception("oops")
9 > raise Exception("oops")
10 > @command(b'abort', [], b'hg abort')
10 > @command(b'abortcmd', [], b'hg abortcmd')
11 > def abort(ui, *args, **kwargs):
11 > def abort(ui, *args, **kwargs):
12 > raise error.Abort(b"oops")
12 > raise error.Abort(b"oops")
13 > EOF
13 > EOF
14 $ abspath=`pwd`/myextension.py
14 $ abspath=`pwd`/myextension.py
15
15
16 $ cat >> $HGRCPATH <<EOF
16 $ cat >> $HGRCPATH <<EOF
17 > [extensions]
17 > [extensions]
18 > blackbox=
18 > blackbox=
19 > mock=$TESTDIR/mockblackbox.py
19 > mock=$TESTDIR/mockblackbox.py
20 > mq=
20 > mq=
21 > myextension=$TESTTMP/myextension.py
21 > myextension=$TESTTMP/myextension.py
22 > [alias]
22 > [alias]
23 > confuse = log --limit 3
23 > confuse = log --limit 3
24 > so-confusing = confuse --style compact
24 > so-confusing = confuse --style compact
25 > [blackbox]
25 > [blackbox]
26 > track = backupbundle, branchcache, command, commandalias, commandexception,
26 > track = backupbundle, branchcache, command, commandalias, commandexception,
27 > commandfinish, debug, exthook, incoming, pythonhook, tagscache
27 > commandfinish, debug, exthook, incoming, pythonhook, tagscache
28 > EOF
28 > EOF
29
29
30 $ hg init blackboxtest
30 $ hg init blackboxtest
31 $ cd blackboxtest
31 $ cd blackboxtest
32
32
33 command, exit codes, and duration
33 command, exit codes, and duration
34
34
35 $ echo a > a
35 $ echo a > a
36 $ hg add a
36 $ hg add a
37 $ hg blackbox --config blackbox.dirty=True
37 $ hg blackbox --config blackbox.dirty=True
38 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest exited 0 after * seconds (glob)
38 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest exited 0 after * seconds (glob)
39 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a
39 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a
40 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a exited 0 after * seconds (glob)
40 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a exited 0 after * seconds (glob)
41 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000+ (5000)> blackbox --config *blackbox.dirty=True* (glob)
41 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000+ (5000)> blackbox --config *blackbox.dirty=True* (glob)
42
42
43 failure exit code
43 failure exit code
44 $ rm ./.hg/blackbox.log
44 $ rm ./.hg/blackbox.log
45 $ hg add non-existent
45 $ hg add non-existent
46 non-existent: $ENOENT$
46 non-existent: $ENOENT$
47 [1]
47 [1]
48 $ hg blackbox
48 $ hg blackbox
49 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add non-existent
49 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add non-existent
50 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add non-existent exited 1 after * seconds (glob)
50 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add non-existent exited 1 after * seconds (glob)
51 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
51 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
52
52
53 abort exit code
53 abort exit code
54 $ rm ./.hg/blackbox.log
54 $ rm ./.hg/blackbox.log
55 $ hg abort 2> /dev/null
55 $ hg abortcmd 2> /dev/null
56 [255]
56 [255]
57 $ hg blackbox -l 2
57 $ hg blackbox -l 2
58 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> abort exited 255 after * seconds (glob)
58 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> abortcmd exited 255 after * seconds (glob)
59 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox -l 2
59 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox -l 2
60
60
61 unhandled exception
61 unhandled exception
62 $ rm ./.hg/blackbox.log
62 $ rm ./.hg/blackbox.log
63 $ hg crash 2> /dev/null
63 $ hg crash 2> /dev/null
64 [1]
64 [1]
65 $ hg blackbox -l 2
65 $ hg blackbox -l 2
66 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> crash exited 1 after * seconds (glob)
66 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> crash exited 1 after * seconds (glob)
67 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox -l 2
67 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox -l 2
68
68
69 alias expansion is logged
69 alias expansion is logged
70 $ rm ./.hg/blackbox.log
70 $ rm ./.hg/blackbox.log
71 $ hg confuse
71 $ hg confuse
72 $ hg blackbox
72 $ hg blackbox
73 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> confuse
73 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> confuse
74 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'confuse' expands to 'log --limit 3'
74 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'confuse' expands to 'log --limit 3'
75 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> confuse exited 0 after * seconds (glob)
75 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> confuse exited 0 after * seconds (glob)
76 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
76 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
77
77
78 recursive aliases work correctly
78 recursive aliases work correctly
79 $ rm ./.hg/blackbox.log
79 $ rm ./.hg/blackbox.log
80 $ hg so-confusing
80 $ hg so-confusing
81 $ hg blackbox
81 $ hg blackbox
82 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> so-confusing
82 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> so-confusing
83 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'so-confusing' expands to 'confuse --style compact'
83 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'so-confusing' expands to 'confuse --style compact'
84 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'confuse' expands to 'log --limit 3'
84 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'confuse' expands to 'log --limit 3'
85 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> so-confusing exited 0 after * seconds (glob)
85 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> so-confusing exited 0 after * seconds (glob)
86 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
86 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
87
87
88 custom date format
88 custom date format
89 $ rm ./.hg/blackbox.log
89 $ rm ./.hg/blackbox.log
90 $ hg --config blackbox.date-format='%Y-%m-%d @ %H:%M:%S' \
90 $ hg --config blackbox.date-format='%Y-%m-%d @ %H:%M:%S' \
91 > --config devel.default-date='1334347993 0' --traceback status
91 > --config devel.default-date='1334347993 0' --traceback status
92 A a
92 A a
93 $ hg blackbox
93 $ hg blackbox
94 2012-04-13 @ 20:13:13 bob @0000000000000000000000000000000000000000 (5000)> --config *blackbox.date-format=%Y-%m-%d @ %H:%M:%S* --config *devel.default-date=1334347993 0* --traceback status (glob)
94 2012-04-13 @ 20:13:13 bob @0000000000000000000000000000000000000000 (5000)> --config *blackbox.date-format=%Y-%m-%d @ %H:%M:%S* --config *devel.default-date=1334347993 0* --traceback status (glob)
95 2012-04-13 @ 20:13:13 bob @0000000000000000000000000000000000000000 (5000)> --config *blackbox.date-format=%Y-%m-%d @ %H:%M:%S* --config *devel.default-date=1334347993 0* --traceback status exited 0 after * seconds (glob)
95 2012-04-13 @ 20:13:13 bob @0000000000000000000000000000000000000000 (5000)> --config *blackbox.date-format=%Y-%m-%d @ %H:%M:%S* --config *devel.default-date=1334347993 0* --traceback status exited 0 after * seconds (glob)
96 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
96 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
97
97
98 incoming change tracking
98 incoming change tracking
99
99
100 create two heads to verify that we only see one change in the log later
100 create two heads to verify that we only see one change in the log later
101 $ hg commit -ma
101 $ hg commit -ma
102 $ hg up null
102 $ hg up null
103 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
103 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
104 $ echo b > b
104 $ echo b > b
105 $ hg commit -Amb
105 $ hg commit -Amb
106 adding b
106 adding b
107 created new head
107 created new head
108
108
109 clone, commit, pull
109 clone, commit, pull
110 $ hg clone . ../blackboxtest2
110 $ hg clone . ../blackboxtest2
111 updating to branch default
111 updating to branch default
112 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
112 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 $ echo c > c
113 $ echo c > c
114 $ hg commit -Amc
114 $ hg commit -Amc
115 adding c
115 adding c
116 $ cd ../blackboxtest2
116 $ cd ../blackboxtest2
117 $ hg pull
117 $ hg pull
118 pulling from $TESTTMP/blackboxtest
118 pulling from $TESTTMP/blackboxtest
119 searching for changes
119 searching for changes
120 adding changesets
120 adding changesets
121 adding manifests
121 adding manifests
122 adding file changes
122 adding file changes
123 added 1 changesets with 1 changes to 1 files
123 added 1 changesets with 1 changes to 1 files
124 new changesets d02f48003e62
124 new changesets d02f48003e62
125 (run 'hg update' to get a working copy)
125 (run 'hg update' to get a working copy)
126 $ hg blackbox -l 6
126 $ hg blackbox -l 6
127 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pull
127 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pull
128 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> updated served branch cache in * seconds (glob)
128 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> updated served branch cache in * seconds (glob)
129 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> wrote served branch cache with 1 labels and 2 nodes
129 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> wrote served branch cache with 1 labels and 2 nodes
130 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> 1 incoming changes - new heads: d02f48003e62
130 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> 1 incoming changes - new heads: d02f48003e62
131 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pull exited 0 after * seconds (glob)
131 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pull exited 0 after * seconds (glob)
132 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> blackbox -l 6
132 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> blackbox -l 6
133
133
134 we must not cause a failure if we cannot write to the log
134 we must not cause a failure if we cannot write to the log
135
135
136 $ hg rollback
136 $ hg rollback
137 repository tip rolled back to revision 1 (undo pull)
137 repository tip rolled back to revision 1 (undo pull)
138
138
139 $ mv .hg/blackbox.log .hg/blackbox.log-
139 $ mv .hg/blackbox.log .hg/blackbox.log-
140 $ mkdir .hg/blackbox.log
140 $ mkdir .hg/blackbox.log
141 $ hg --debug incoming
141 $ hg --debug incoming
142 warning: cannot write to blackbox.log: * (glob)
142 warning: cannot write to blackbox.log: * (glob)
143 comparing with $TESTTMP/blackboxtest
143 comparing with $TESTTMP/blackboxtest
144 query 1; heads
144 query 1; heads
145 searching for changes
145 searching for changes
146 all local heads known remotely
146 all local heads known remotely
147 changeset: 2:d02f48003e62c24e2659d97d30f2a83abe5d5d51
147 changeset: 2:d02f48003e62c24e2659d97d30f2a83abe5d5d51
148 tag: tip
148 tag: tip
149 phase: draft
149 phase: draft
150 parent: 1:6563da9dcf87b1949716e38ff3e3dfaa3198eb06
150 parent: 1:6563da9dcf87b1949716e38ff3e3dfaa3198eb06
151 parent: -1:0000000000000000000000000000000000000000
151 parent: -1:0000000000000000000000000000000000000000
152 manifest: 2:ab9d46b053ebf45b7996f2922b9893ff4b63d892
152 manifest: 2:ab9d46b053ebf45b7996f2922b9893ff4b63d892
153 user: test
153 user: test
154 date: Thu Jan 01 00:00:00 1970 +0000
154 date: Thu Jan 01 00:00:00 1970 +0000
155 files+: c
155 files+: c
156 extra: branch=default
156 extra: branch=default
157 description:
157 description:
158 c
158 c
159
159
160
160
161 $ hg pull
161 $ hg pull
162 pulling from $TESTTMP/blackboxtest
162 pulling from $TESTTMP/blackboxtest
163 searching for changes
163 searching for changes
164 adding changesets
164 adding changesets
165 adding manifests
165 adding manifests
166 adding file changes
166 adding file changes
167 added 1 changesets with 1 changes to 1 files
167 added 1 changesets with 1 changes to 1 files
168 new changesets d02f48003e62
168 new changesets d02f48003e62
169 (run 'hg update' to get a working copy)
169 (run 'hg update' to get a working copy)
170
170
171 a failure reading from the log is fatal
171 a failure reading from the log is fatal
172
172
173 $ hg blackbox -l 3
173 $ hg blackbox -l 3
174 abort: *$TESTTMP/blackboxtest2/.hg/blackbox.log* (glob)
174 abort: *$TESTTMP/blackboxtest2/.hg/blackbox.log* (glob)
175 [255]
175 [255]
176
176
177 $ rmdir .hg/blackbox.log
177 $ rmdir .hg/blackbox.log
178 $ mv .hg/blackbox.log- .hg/blackbox.log
178 $ mv .hg/blackbox.log- .hg/blackbox.log
179
179
180 backup bundles get logged
180 backup bundles get logged
181
181
182 $ touch d
182 $ touch d
183 $ hg commit -Amd
183 $ hg commit -Amd
184 adding d
184 adding d
185 created new head
185 created new head
186 $ hg strip tip
186 $ hg strip tip
187 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
187 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
188 saved backup bundle to $TESTTMP/blackboxtest2/.hg/strip-backup/*-backup.hg (glob)
188 saved backup bundle to $TESTTMP/blackboxtest2/.hg/strip-backup/*-backup.hg (glob)
189 $ hg blackbox -l 6
189 $ hg blackbox -l 6
190 1970/01/01 00:00:00 bob @73f6ee326b27d820b0472f1a825e3a50f3dc489b (5000)> strip tip
190 1970/01/01 00:00:00 bob @73f6ee326b27d820b0472f1a825e3a50f3dc489b (5000)> strip tip
191 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> saved backup bundle to $TESTTMP/blackboxtest2/.hg/strip-backup/73f6ee326b27-7612e004-backup.hg
191 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> saved backup bundle to $TESTTMP/blackboxtest2/.hg/strip-backup/73f6ee326b27-7612e004-backup.hg
192 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> updated base branch cache in * seconds (glob)
192 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> updated base branch cache in * seconds (glob)
193 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> wrote base branch cache with 1 labels and 2 nodes
193 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> wrote base branch cache with 1 labels and 2 nodes
194 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> strip tip exited 0 after * seconds (glob)
194 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> strip tip exited 0 after * seconds (glob)
195 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> blackbox -l 6
195 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> blackbox -l 6
196
196
197 extension and python hooks - use the eol extension for a pythonhook
197 extension and python hooks - use the eol extension for a pythonhook
198
198
199 $ echo '[extensions]' >> .hg/hgrc
199 $ echo '[extensions]' >> .hg/hgrc
200 $ echo 'eol=' >> .hg/hgrc
200 $ echo 'eol=' >> .hg/hgrc
201 $ echo '[hooks]' >> .hg/hgrc
201 $ echo '[hooks]' >> .hg/hgrc
202 $ echo 'update = echo hooked' >> .hg/hgrc
202 $ echo 'update = echo hooked' >> .hg/hgrc
203 $ hg update
203 $ hg update
204 The fsmonitor extension is incompatible with the eol extension and has been disabled. (fsmonitor !)
204 The fsmonitor extension is incompatible with the eol extension and has been disabled. (fsmonitor !)
205 hooked
205 hooked
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
207 updated to "d02f48003e62: c"
207 updated to "d02f48003e62: c"
208 1 other heads for branch "default"
208 1 other heads for branch "default"
209 $ cat >> .hg/hgrc <<EOF
209 $ cat >> .hg/hgrc <<EOF
210 > [extensions]
210 > [extensions]
211 > # disable eol, because it is not needed for subsequent tests
211 > # disable eol, because it is not needed for subsequent tests
212 > # (in addition, keeping it requires extra care for fsmonitor)
212 > # (in addition, keeping it requires extra care for fsmonitor)
213 > eol=!
213 > eol=!
214 > EOF
214 > EOF
215 $ hg blackbox -l 5
215 $ hg blackbox -l 5
216 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> update (no-chg !)
216 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> update (no-chg !)
217 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pythonhook-preupdate: hgext.eol.preupdate finished in * seconds (glob)
217 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pythonhook-preupdate: hgext.eol.preupdate finished in * seconds (glob)
218 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> exthook-update: echo hooked finished in * seconds (glob)
218 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> exthook-update: echo hooked finished in * seconds (glob)
219 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> update exited 0 after * seconds (glob)
219 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> update exited 0 after * seconds (glob)
220 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> serve --cmdserver chgunix --address $TESTTMP.chgsock/server.* --daemon-postexec 'chdir:/' (glob) (chg !)
220 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> serve --cmdserver chgunix --address $TESTTMP.chgsock/server.* --daemon-postexec 'chdir:/' (glob) (chg !)
221 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> blackbox -l 5
221 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> blackbox -l 5
222
222
223 log rotation
223 log rotation
224
224
225 $ echo '[blackbox]' >> .hg/hgrc
225 $ echo '[blackbox]' >> .hg/hgrc
226 $ echo 'maxsize = 20 b' >> .hg/hgrc
226 $ echo 'maxsize = 20 b' >> .hg/hgrc
227 $ echo 'maxfiles = 3' >> .hg/hgrc
227 $ echo 'maxfiles = 3' >> .hg/hgrc
228 $ hg status
228 $ hg status
229 $ hg status
229 $ hg status
230 $ hg status
230 $ hg status
231 $ hg tip -q
231 $ hg tip -q
232 2:d02f48003e62
232 2:d02f48003e62
233 $ ls .hg/blackbox.log*
233 $ ls .hg/blackbox.log*
234 .hg/blackbox.log
234 .hg/blackbox.log
235 .hg/blackbox.log.1
235 .hg/blackbox.log.1
236 .hg/blackbox.log.2
236 .hg/blackbox.log.2
237 $ cd ..
237 $ cd ..
238
238
239 $ hg init blackboxtest3
239 $ hg init blackboxtest3
240 $ cd blackboxtest3
240 $ cd blackboxtest3
241 $ hg blackbox
241 $ hg blackbox
242 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest3 exited 0 after * seconds (glob)
242 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest3 exited 0 after * seconds (glob)
243 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
243 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
244 $ mv .hg/blackbox.log .hg/blackbox.log-
244 $ mv .hg/blackbox.log .hg/blackbox.log-
245 $ mkdir .hg/blackbox.log
245 $ mkdir .hg/blackbox.log
246 $ sed -e 's/\(.*test1.*\)/#\1/; s#\(.*commit2.*\)#os.rmdir(".hg/blackbox.log")\
246 $ sed -e 's/\(.*test1.*\)/#\1/; s#\(.*commit2.*\)#os.rmdir(".hg/blackbox.log")\
247 > os.rename(".hg/blackbox.log-", ".hg/blackbox.log")\
247 > os.rename(".hg/blackbox.log-", ".hg/blackbox.log")\
248 > \1#' $TESTDIR/test-dispatch.py > ../test-dispatch.py
248 > \1#' $TESTDIR/test-dispatch.py > ../test-dispatch.py
249 $ "$PYTHON" $TESTDIR/blackbox-readonly-dispatch.py
249 $ "$PYTHON" $TESTDIR/blackbox-readonly-dispatch.py
250 running: --debug add foo
250 running: --debug add foo
251 warning: cannot write to blackbox.log: Is a directory (no-windows !)
251 warning: cannot write to blackbox.log: Is a directory (no-windows !)
252 warning: cannot write to blackbox.log: $TESTTMP/blackboxtest3/.hg/blackbox.log: Access is denied (windows !)
252 warning: cannot write to blackbox.log: $TESTTMP/blackboxtest3/.hg/blackbox.log: Access is denied (windows !)
253 adding foo
253 adding foo
254 result: 0
254 result: 0
255 running: --debug commit -m commit1 -d 2000-01-01 foo
255 running: --debug commit -m commit1 -d 2000-01-01 foo
256 warning: cannot write to blackbox.log: Is a directory (no-windows !)
256 warning: cannot write to blackbox.log: Is a directory (no-windows !)
257 warning: cannot write to blackbox.log: $TESTTMP/blackboxtest3/.hg/blackbox.log: Access is denied (windows !)
257 warning: cannot write to blackbox.log: $TESTTMP/blackboxtest3/.hg/blackbox.log: Access is denied (windows !)
258 committing files:
258 committing files:
259 foo
259 foo
260 committing manifest
260 committing manifest
261 committing changelog
261 committing changelog
262 updating the branch cache
262 updating the branch cache
263 committed changeset 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
263 committed changeset 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
264 result: 0
264 result: 0
265 running: --debug commit -m commit2 -d 2000-01-02 foo
265 running: --debug commit -m commit2 -d 2000-01-02 foo
266 committing files:
266 committing files:
267 foo
267 foo
268 committing manifest
268 committing manifest
269 committing changelog
269 committing changelog
270 updating the branch cache
270 updating the branch cache
271 committed changeset 1:45589e459b2edfbf3dbde7e01f611d2c1e7453d7
271 committed changeset 1:45589e459b2edfbf3dbde7e01f611d2c1e7453d7
272 result: 0
272 result: 0
273 running: --debug log -r 0
273 running: --debug log -r 0
274 changeset: 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
274 changeset: 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
275 phase: draft
275 phase: draft
276 parent: -1:0000000000000000000000000000000000000000
276 parent: -1:0000000000000000000000000000000000000000
277 parent: -1:0000000000000000000000000000000000000000
277 parent: -1:0000000000000000000000000000000000000000
278 manifest: 0:9091aa5df980aea60860a2e39c95182e68d1ddec
278 manifest: 0:9091aa5df980aea60860a2e39c95182e68d1ddec
279 user: test
279 user: test
280 date: Sat Jan 01 00:00:00 2000 +0000
280 date: Sat Jan 01 00:00:00 2000 +0000
281 files+: foo
281 files+: foo
282 extra: branch=default
282 extra: branch=default
283 description:
283 description:
284 commit1
284 commit1
285
285
286
286
287 result: 0
287 result: 0
288 running: --debug log -r tip
288 running: --debug log -r tip
289 changeset: 1:45589e459b2edfbf3dbde7e01f611d2c1e7453d7
289 changeset: 1:45589e459b2edfbf3dbde7e01f611d2c1e7453d7
290 tag: tip
290 tag: tip
291 phase: draft
291 phase: draft
292 parent: 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
292 parent: 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
293 parent: -1:0000000000000000000000000000000000000000
293 parent: -1:0000000000000000000000000000000000000000
294 manifest: 1:895aa9b7886f89dd017a6d62524e1f9180b04df9
294 manifest: 1:895aa9b7886f89dd017a6d62524e1f9180b04df9
295 user: test
295 user: test
296 date: Sun Jan 02 00:00:00 2000 +0000
296 date: Sun Jan 02 00:00:00 2000 +0000
297 files: foo
297 files: foo
298 extra: branch=default
298 extra: branch=default
299 description:
299 description:
300 commit2
300 commit2
301
301
302
302
303 result: 0
303 result: 0
304 $ hg blackbox
304 $ hg blackbox
305 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> updating the branch cache
305 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> updating the branch cache
306 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> updated served branch cache in * seconds (glob)
306 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> updated served branch cache in * seconds (glob)
307 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> wrote served branch cache with 1 labels and 1 nodes
307 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> wrote served branch cache with 1 labels and 1 nodes
308 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug commit -m commit2 -d 2000-01-02 foo exited 0 after *.?? seconds (glob)
308 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug commit -m commit2 -d 2000-01-02 foo exited 0 after *.?? seconds (glob)
309 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r 0
309 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r 0
310 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> writing .hg/cache/tags2-visible with 0 tags
310 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> writing .hg/cache/tags2-visible with 0 tags
311 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r 0 exited 0 after *.?? seconds (glob)
311 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r 0 exited 0 after *.?? seconds (glob)
312 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r tip
312 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r tip
313 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r tip exited 0 after *.?? seconds (glob)
313 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r tip exited 0 after *.?? seconds (glob)
314 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> blackbox
314 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> blackbox
315
315
316 Test log recursion from dirty status check
316 Test log recursion from dirty status check
317
317
318 $ cat > ../r.py <<EOF
318 $ cat > ../r.py <<EOF
319 > from mercurial import context, error, extensions
319 > from mercurial import context, error, extensions
320 > x=[False]
320 > x=[False]
321 > def status(orig, *args, **opts):
321 > def status(orig, *args, **opts):
322 > args[0].repo().ui.log(b"broken", b"recursion?")
322 > args[0].repo().ui.log(b"broken", b"recursion?")
323 > return orig(*args, **opts)
323 > return orig(*args, **opts)
324 > def reposetup(ui, repo):
324 > def reposetup(ui, repo):
325 > extensions.wrapfunction(context.basectx, 'status', status)
325 > extensions.wrapfunction(context.basectx, 'status', status)
326 > EOF
326 > EOF
327 $ hg id --config extensions.x=../r.py --config blackbox.dirty=True
327 $ hg id --config extensions.x=../r.py --config blackbox.dirty=True
328 45589e459b2e tip
328 45589e459b2e tip
329
329
330 cleanup
330 cleanup
331 $ cd ..
331 $ cd ..
332
332
333 Test missing log directory, which shouldn't be created automatically
333 Test missing log directory, which shouldn't be created automatically
334
334
335 $ cat <<'EOF' > closeremove.py
335 $ cat <<'EOF' > closeremove.py
336 > def reposetup(ui, repo):
336 > def reposetup(ui, repo):
337 > class rmrepo(repo.__class__):
337 > class rmrepo(repo.__class__):
338 > def close(self):
338 > def close(self):
339 > super(rmrepo, self).close()
339 > super(rmrepo, self).close()
340 > self.ui.debug(b'removing %s\n' % self.vfs.base)
340 > self.ui.debug(b'removing %s\n' % self.vfs.base)
341 > self.vfs.rmtree()
341 > self.vfs.rmtree()
342 > repo.__class__ = rmrepo
342 > repo.__class__ = rmrepo
343 > EOF
343 > EOF
344
344
345 $ hg init gone
345 $ hg init gone
346 $ cd gone
346 $ cd gone
347 $ cat <<'EOF' > .hg/hgrc
347 $ cat <<'EOF' > .hg/hgrc
348 > [extensions]
348 > [extensions]
349 > closeremove = ../closeremove.py
349 > closeremove = ../closeremove.py
350 > EOF
350 > EOF
351 $ hg log --debug
351 $ hg log --debug
352 removing $TESTTMP/gone/.hg
352 removing $TESTTMP/gone/.hg
353 warning: cannot write to blackbox.log: $ENOENT$ (no-windows !)
353 warning: cannot write to blackbox.log: $ENOENT$ (no-windows !)
354 warning: cannot write to blackbox.log: $TESTTMP/gone/.hg/blackbox.log: $ENOTDIR$ (windows !)
354 warning: cannot write to blackbox.log: $TESTTMP/gone/.hg/blackbox.log: $ENOTDIR$ (windows !)
355 $ cd ..
355 $ cd ..
356
356
357 blackbox should disable itself if track is empty
357 blackbox should disable itself if track is empty
358
358
359 $ hg --config blackbox.track= init nothing_tracked
359 $ hg --config blackbox.track= init nothing_tracked
360 $ cd nothing_tracked
360 $ cd nothing_tracked
361 $ cat >> .hg/hgrc << EOF
361 $ cat >> .hg/hgrc << EOF
362 > [blackbox]
362 > [blackbox]
363 > track =
363 > track =
364 > EOF
364 > EOF
365 $ hg blackbox
365 $ hg blackbox
366 $ cd $TESTTMP
366 $ cd $TESTTMP
367
367
368 a '*' entry in blackbox.track is interpreted as log everything
368 a '*' entry in blackbox.track is interpreted as log everything
369
369
370 $ hg --config blackbox.track='*' \
370 $ hg --config blackbox.track='*' \
371 > --config blackbox.logsource=True \
371 > --config blackbox.logsource=True \
372 > init track_star
372 > init track_star
373 $ cd track_star
373 $ cd track_star
374 $ cat >> .hg/hgrc << EOF
374 $ cat >> .hg/hgrc << EOF
375 > [blackbox]
375 > [blackbox]
376 > logsource = True
376 > logsource = True
377 > track = *
377 > track = *
378 > EOF
378 > EOF
379 (only look for entries with specific logged sources, otherwise this test is
379 (only look for entries with specific logged sources, otherwise this test is
380 pretty brittle)
380 pretty brittle)
381 $ hg blackbox | egrep '\[command(finish)?\]'
381 $ hg blackbox | egrep '\[command(finish)?\]'
382 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000) [commandfinish]> --config *blackbox.track=* --config *blackbox.logsource=True* init track_star exited 0 after * seconds (glob)
382 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000) [commandfinish]> --config *blackbox.track=* --config *blackbox.logsource=True* init track_star exited 0 after * seconds (glob)
383 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000) [command]> blackbox
383 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000) [command]> blackbox
384 $ cd $TESTTMP
384 $ cd $TESTTMP
385
385
386 #if chg
386 #if chg
387
387
388 when using chg, blackbox.log should get rotated correctly
388 when using chg, blackbox.log should get rotated correctly
389
389
390 $ cat > $TESTTMP/noop.py << EOF
390 $ cat > $TESTTMP/noop.py << EOF
391 > from __future__ import absolute_import
391 > from __future__ import absolute_import
392 > import time
392 > import time
393 > from mercurial import registrar, scmutil
393 > from mercurial import registrar, scmutil
394 > cmdtable = {}
394 > cmdtable = {}
395 > command = registrar.command(cmdtable)
395 > command = registrar.command(cmdtable)
396 > @command('noop')
396 > @command('noop')
397 > def noop(ui, repo):
397 > def noop(ui, repo):
398 > pass
398 > pass
399 > EOF
399 > EOF
400
400
401 $ hg init blackbox-chg
401 $ hg init blackbox-chg
402 $ cd blackbox-chg
402 $ cd blackbox-chg
403
403
404 $ cat > .hg/hgrc << EOF
404 $ cat > .hg/hgrc << EOF
405 > [blackbox]
405 > [blackbox]
406 > maxsize = 500B
406 > maxsize = 500B
407 > [extensions]
407 > [extensions]
408 > # extension change forces chg to restart
408 > # extension change forces chg to restart
409 > noop=$TESTTMP/noop.py
409 > noop=$TESTTMP/noop.py
410 > EOF
410 > EOF
411
411
412 $ "$PYTHON" -c 'print("a" * 400)' > .hg/blackbox.log
412 $ "$PYTHON" -c 'print("a" * 400)' > .hg/blackbox.log
413 $ chg noop
413 $ chg noop
414 $ chg noop
414 $ chg noop
415 $ chg noop
415 $ chg noop
416 $ chg noop
416 $ chg noop
417 $ chg noop
417 $ chg noop
418
418
419 $ cat > showsize.py << 'EOF'
419 $ cat > showsize.py << 'EOF'
420 > import os
420 > import os
421 > import sys
421 > import sys
422 > limit = 500
422 > limit = 500
423 > for p in sys.argv[1:]:
423 > for p in sys.argv[1:]:
424 > size = os.stat(p).st_size
424 > size = os.stat(p).st_size
425 > if size >= limit:
425 > if size >= limit:
426 > desc = '>='
426 > desc = '>='
427 > else:
427 > else:
428 > desc = '<'
428 > desc = '<'
429 > print('%s: %s %d' % (p, desc, limit))
429 > print('%s: %s %d' % (p, desc, limit))
430 > EOF
430 > EOF
431
431
432 $ "$PYTHON" showsize.py .hg/blackbox*
432 $ "$PYTHON" showsize.py .hg/blackbox*
433 .hg/blackbox.log: < 500
433 .hg/blackbox.log: < 500
434 .hg/blackbox.log.1: >= 500
434 .hg/blackbox.log.1: >= 500
435 .hg/blackbox.log.2: >= 500
435 .hg/blackbox.log.2: >= 500
436
436
437 $ cd ..
437 $ cd ..
438
438
439 With chg, blackbox should not create the log file if the repo is gone
439 With chg, blackbox should not create the log file if the repo is gone
440
440
441 $ hg init repo1
441 $ hg init repo1
442 $ hg --config extensions.a=! -R repo1 log
442 $ hg --config extensions.a=! -R repo1 log
443 $ rm -rf $TESTTMP/repo1
443 $ rm -rf $TESTTMP/repo1
444 $ hg --config extensions.a=! init repo1
444 $ hg --config extensions.a=! init repo1
445
445
446 #endif
446 #endif
447
447
448 blackbox should work if repo.ui.log is not called (issue5518)
448 blackbox should work if repo.ui.log is not called (issue5518)
449
449
450 $ cat > $TESTTMP/raise.py << EOF
450 $ cat > $TESTTMP/raise.py << EOF
451 > from __future__ import absolute_import
451 > from __future__ import absolute_import
452 > from mercurial import registrar, scmutil
452 > from mercurial import registrar, scmutil
453 > cmdtable = {}
453 > cmdtable = {}
454 > command = registrar.command(cmdtable)
454 > command = registrar.command(cmdtable)
455 > @command(b'raise')
455 > @command(b'raise')
456 > def raisecmd(*args):
456 > def raisecmd(*args):
457 > raise RuntimeError('raise')
457 > raise RuntimeError('raise')
458 > EOF
458 > EOF
459
459
460 $ cat >> $HGRCPATH << EOF
460 $ cat >> $HGRCPATH << EOF
461 > [blackbox]
461 > [blackbox]
462 > track = commandexception
462 > track = commandexception
463 > [extensions]
463 > [extensions]
464 > raise=$TESTTMP/raise.py
464 > raise=$TESTTMP/raise.py
465 > EOF
465 > EOF
466
466
467 $ hg init $TESTTMP/blackbox-exception-only
467 $ hg init $TESTTMP/blackbox-exception-only
468 $ cd $TESTTMP/blackbox-exception-only
468 $ cd $TESTTMP/blackbox-exception-only
469
469
470 #if chg
470 #if chg
471 (chg exits 255 because it fails to receive an exit code)
471 (chg exits 255 because it fails to receive an exit code)
472 $ hg raise 2>/dev/null
472 $ hg raise 2>/dev/null
473 [255]
473 [255]
474 #else
474 #else
475 (hg exits 1 because Python default exit code for uncaught exception is 1)
475 (hg exits 1 because Python default exit code for uncaught exception is 1)
476 $ hg raise 2>/dev/null
476 $ hg raise 2>/dev/null
477 [1]
477 [1]
478 #endif
478 #endif
479
479
480 $ head -1 .hg/blackbox.log
480 $ head -1 .hg/blackbox.log
481 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> ** Unknown exception encountered with possibly-broken third-party extension mock
481 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> ** Unknown exception encountered with possibly-broken third-party extension mock
482 $ tail -2 .hg/blackbox.log
482 $ tail -2 .hg/blackbox.log
483 RuntimeError: raise
483 RuntimeError: raise
484
484
@@ -1,418 +1,421 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 abort
3 add
4 add
4 addremove
5 addremove
5 annotate
6 annotate
6 archive
7 archive
7 backout
8 backout
8 bisect
9 bisect
9 bookmarks
10 bookmarks
10 branch
11 branch
11 branches
12 branches
12 bundle
13 bundle
13 cat
14 cat
14 clone
15 clone
15 commit
16 commit
16 config
17 config
17 copy
18 copy
18 diff
19 diff
19 export
20 export
20 files
21 files
21 forget
22 forget
22 graft
23 graft
23 grep
24 grep
24 heads
25 heads
25 help
26 help
26 identify
27 identify
27 import
28 import
28 incoming
29 incoming
29 init
30 init
30 locate
31 locate
31 log
32 log
32 manifest
33 manifest
33 merge
34 merge
34 outgoing
35 outgoing
35 parents
36 parents
36 paths
37 paths
37 phase
38 phase
38 pull
39 pull
39 push
40 push
40 recover
41 recover
41 remove
42 remove
42 rename
43 rename
43 resolve
44 resolve
44 revert
45 revert
45 rollback
46 rollback
46 root
47 root
47 serve
48 serve
48 shelve
49 shelve
49 status
50 status
50 summary
51 summary
51 tag
52 tag
52 tags
53 tags
53 tip
54 tip
54 unbundle
55 unbundle
55 unshelve
56 unshelve
56 update
57 update
57 verify
58 verify
58 version
59 version
59
60
60 Show all commands that start with "a"
61 Show all commands that start with "a"
61 $ hg debugcomplete a
62 $ hg debugcomplete a
63 abort
62 add
64 add
63 addremove
65 addremove
64 annotate
66 annotate
65 archive
67 archive
66
68
67 Do not show debug commands if there are other candidates
69 Do not show debug commands if there are other candidates
68 $ hg debugcomplete d
70 $ hg debugcomplete d
69 diff
71 diff
70
72
71 Show debug commands if there are no other candidates
73 Show debug commands if there are no other candidates
72 $ hg debugcomplete debug
74 $ hg debugcomplete debug
73 debugancestor
75 debugancestor
74 debugapplystreamclonebundle
76 debugapplystreamclonebundle
75 debugbuilddag
77 debugbuilddag
76 debugbundle
78 debugbundle
77 debugcapabilities
79 debugcapabilities
78 debugcheckstate
80 debugcheckstate
79 debugcolor
81 debugcolor
80 debugcommands
82 debugcommands
81 debugcomplete
83 debugcomplete
82 debugconfig
84 debugconfig
83 debugcreatestreamclonebundle
85 debugcreatestreamclonebundle
84 debugdag
86 debugdag
85 debugdata
87 debugdata
86 debugdate
88 debugdate
87 debugdeltachain
89 debugdeltachain
88 debugdirstate
90 debugdirstate
89 debugdiscovery
91 debugdiscovery
90 debugdownload
92 debugdownload
91 debugextensions
93 debugextensions
92 debugfileset
94 debugfileset
93 debugformat
95 debugformat
94 debugfsinfo
96 debugfsinfo
95 debuggetbundle
97 debuggetbundle
96 debugignore
98 debugignore
97 debugindex
99 debugindex
98 debugindexdot
100 debugindexdot
99 debugindexstats
101 debugindexstats
100 debuginstall
102 debuginstall
101 debugknown
103 debugknown
102 debuglabelcomplete
104 debuglabelcomplete
103 debuglocks
105 debuglocks
104 debugmanifestfulltextcache
106 debugmanifestfulltextcache
105 debugmergestate
107 debugmergestate
106 debugnamecomplete
108 debugnamecomplete
107 debugobsolete
109 debugobsolete
108 debugp1copies
110 debugp1copies
109 debugp2copies
111 debugp2copies
110 debugpathcomplete
112 debugpathcomplete
111 debugpathcopies
113 debugpathcopies
112 debugpeer
114 debugpeer
113 debugpickmergetool
115 debugpickmergetool
114 debugpushkey
116 debugpushkey
115 debugpvec
117 debugpvec
116 debugrebuilddirstate
118 debugrebuilddirstate
117 debugrebuildfncache
119 debugrebuildfncache
118 debugrename
120 debugrename
119 debugrevlog
121 debugrevlog
120 debugrevlogindex
122 debugrevlogindex
121 debugrevspec
123 debugrevspec
122 debugserve
124 debugserve
123 debugsetparents
125 debugsetparents
124 debugssl
126 debugssl
125 debugsub
127 debugsub
126 debugsuccessorssets
128 debugsuccessorssets
127 debugtemplate
129 debugtemplate
128 debuguigetpass
130 debuguigetpass
129 debuguiprompt
131 debuguiprompt
130 debugupdatecaches
132 debugupdatecaches
131 debugupgraderepo
133 debugupgraderepo
132 debugwalk
134 debugwalk
133 debugwhyunstable
135 debugwhyunstable
134 debugwireargs
136 debugwireargs
135 debugwireproto
137 debugwireproto
136
138
137 Do not show the alias of a debug command if there are other candidates
139 Do not show the alias of a debug command if there are other candidates
138 (this should hide rawcommit)
140 (this should hide rawcommit)
139 $ hg debugcomplete r
141 $ hg debugcomplete r
140 recover
142 recover
141 remove
143 remove
142 rename
144 rename
143 resolve
145 resolve
144 revert
146 revert
145 rollback
147 rollback
146 root
148 root
147 Show the alias of a debug command if there are no other candidates
149 Show the alias of a debug command if there are no other candidates
148 $ hg debugcomplete rawc
150 $ hg debugcomplete rawc
149
151
150
152
151 Show the global options
153 Show the global options
152 $ hg debugcomplete --options | sort
154 $ hg debugcomplete --options | sort
153 --color
155 --color
154 --config
156 --config
155 --cwd
157 --cwd
156 --debug
158 --debug
157 --debugger
159 --debugger
158 --encoding
160 --encoding
159 --encodingmode
161 --encodingmode
160 --help
162 --help
161 --hidden
163 --hidden
162 --noninteractive
164 --noninteractive
163 --pager
165 --pager
164 --profile
166 --profile
165 --quiet
167 --quiet
166 --repository
168 --repository
167 --time
169 --time
168 --traceback
170 --traceback
169 --verbose
171 --verbose
170 --version
172 --version
171 -R
173 -R
172 -h
174 -h
173 -q
175 -q
174 -v
176 -v
175 -y
177 -y
176
178
177 Show the options for the "serve" command
179 Show the options for the "serve" command
178 $ hg debugcomplete --options serve | sort
180 $ hg debugcomplete --options serve | sort
179 --accesslog
181 --accesslog
180 --address
182 --address
181 --certificate
183 --certificate
182 --cmdserver
184 --cmdserver
183 --color
185 --color
184 --config
186 --config
185 --cwd
187 --cwd
186 --daemon
188 --daemon
187 --daemon-postexec
189 --daemon-postexec
188 --debug
190 --debug
189 --debugger
191 --debugger
190 --encoding
192 --encoding
191 --encodingmode
193 --encodingmode
192 --errorlog
194 --errorlog
193 --help
195 --help
194 --hidden
196 --hidden
195 --ipv6
197 --ipv6
196 --name
198 --name
197 --noninteractive
199 --noninteractive
198 --pager
200 --pager
199 --pid-file
201 --pid-file
200 --port
202 --port
201 --prefix
203 --prefix
202 --print-url
204 --print-url
203 --profile
205 --profile
204 --quiet
206 --quiet
205 --repository
207 --repository
206 --stdio
208 --stdio
207 --style
209 --style
208 --subrepos
210 --subrepos
209 --templates
211 --templates
210 --time
212 --time
211 --traceback
213 --traceback
212 --verbose
214 --verbose
213 --version
215 --version
214 --web-conf
216 --web-conf
215 -6
217 -6
216 -A
218 -A
217 -E
219 -E
218 -R
220 -R
219 -S
221 -S
220 -a
222 -a
221 -d
223 -d
222 -h
224 -h
223 -n
225 -n
224 -p
226 -p
225 -q
227 -q
226 -t
228 -t
227 -v
229 -v
228 -y
230 -y
229
231
230 Show an error if we use --options with an ambiguous abbreviation
232 Show an error if we use --options with an ambiguous abbreviation
231 $ hg debugcomplete --options s
233 $ hg debugcomplete --options s
232 hg: command 's' is ambiguous:
234 hg: command 's' is ambiguous:
233 serve shelve showconfig status summary
235 serve shelve showconfig status summary
234 [255]
236 [255]
235
237
236 Show all commands + options
238 Show all commands + options
237 $ hg debugcommands
239 $ hg debugcommands
240 abort: dry-run
238 add: include, exclude, subrepos, dry-run
241 add: include, exclude, subrepos, dry-run
239 addremove: similarity, subrepos, include, exclude, dry-run
242 addremove: similarity, subrepos, include, exclude, dry-run
240 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
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
241 archive: no-decode, prefix, rev, type, subrepos, include, exclude
244 archive: no-decode, prefix, rev, type, subrepos, include, exclude
242 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
245 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
243 bisect: reset, good, bad, skip, extend, command, noupdate
246 bisect: reset, good, bad, skip, extend, command, noupdate
244 bookmarks: force, rev, delete, rename, inactive, list, template
247 bookmarks: force, rev, delete, rename, inactive, list, template
245 branch: force, clean, rev
248 branch: force, clean, rev
246 branches: active, closed, rev, template
249 branches: active, closed, rev, template
247 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
250 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
248 cat: output, rev, decode, include, exclude, template
251 cat: output, rev, decode, include, exclude, template
249 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
252 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
250 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
253 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
251 config: untrusted, edit, local, global, template
254 config: untrusted, edit, local, global, template
252 copy: after, force, include, exclude, dry-run
255 copy: after, force, include, exclude, dry-run
253 debugancestor:
256 debugancestor:
254 debugapplystreamclonebundle:
257 debugapplystreamclonebundle:
255 debugbuilddag: mergeable-file, overwritten-file, new-file
258 debugbuilddag: mergeable-file, overwritten-file, new-file
256 debugbundle: all, part-type, spec
259 debugbundle: all, part-type, spec
257 debugcapabilities:
260 debugcapabilities:
258 debugcheckstate:
261 debugcheckstate:
259 debugcolor: style
262 debugcolor: style
260 debugcommands:
263 debugcommands:
261 debugcomplete: options
264 debugcomplete: options
262 debugcreatestreamclonebundle:
265 debugcreatestreamclonebundle:
263 debugdag: tags, branches, dots, spaces
266 debugdag: tags, branches, dots, spaces
264 debugdata: changelog, manifest, dir
267 debugdata: changelog, manifest, dir
265 debugdate: extended
268 debugdate: extended
266 debugdeltachain: changelog, manifest, dir, template
269 debugdeltachain: changelog, manifest, dir, template
267 debugdirstate: nodates, dates, datesort
270 debugdirstate: nodates, dates, datesort
268 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
271 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
269 debugdownload: output
272 debugdownload: output
270 debugextensions: template
273 debugextensions: template
271 debugfileset: rev, all-files, show-matcher, show-stage
274 debugfileset: rev, all-files, show-matcher, show-stage
272 debugformat: template
275 debugformat: template
273 debugfsinfo:
276 debugfsinfo:
274 debuggetbundle: head, common, type
277 debuggetbundle: head, common, type
275 debugignore:
278 debugignore:
276 debugindex: changelog, manifest, dir, template
279 debugindex: changelog, manifest, dir, template
277 debugindexdot: changelog, manifest, dir
280 debugindexdot: changelog, manifest, dir
278 debugindexstats:
281 debugindexstats:
279 debuginstall: template
282 debuginstall: template
280 debugknown:
283 debugknown:
281 debuglabelcomplete:
284 debuglabelcomplete:
282 debuglocks: force-lock, force-wlock, set-lock, set-wlock
285 debuglocks: force-lock, force-wlock, set-lock, set-wlock
283 debugmanifestfulltextcache: clear, add
286 debugmanifestfulltextcache: clear, add
284 debugmergestate:
287 debugmergestate:
285 debugnamecomplete:
288 debugnamecomplete:
286 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
289 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
287 debugp1copies: rev
290 debugp1copies: rev
288 debugp2copies: rev
291 debugp2copies: rev
289 debugpathcomplete: full, normal, added, removed
292 debugpathcomplete: full, normal, added, removed
290 debugpathcopies: include, exclude
293 debugpathcopies: include, exclude
291 debugpeer:
294 debugpeer:
292 debugpickmergetool: rev, changedelete, include, exclude, tool
295 debugpickmergetool: rev, changedelete, include, exclude, tool
293 debugpushkey:
296 debugpushkey:
294 debugpvec:
297 debugpvec:
295 debugrebuilddirstate: rev, minimal
298 debugrebuilddirstate: rev, minimal
296 debugrebuildfncache:
299 debugrebuildfncache:
297 debugrename: rev
300 debugrename: rev
298 debugrevlog: changelog, manifest, dir, dump
301 debugrevlog: changelog, manifest, dir, dump
299 debugrevlogindex: changelog, manifest, dir, format
302 debugrevlogindex: changelog, manifest, dir, format
300 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
303 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
301 debugserve: sshstdio, logiofd, logiofile
304 debugserve: sshstdio, logiofd, logiofile
302 debugsetparents:
305 debugsetparents:
303 debugssl:
306 debugssl:
304 debugsub: rev
307 debugsub: rev
305 debugsuccessorssets: closest
308 debugsuccessorssets: closest
306 debugtemplate: rev, define
309 debugtemplate: rev, define
307 debuguigetpass: prompt
310 debuguigetpass: prompt
308 debuguiprompt: prompt
311 debuguiprompt: prompt
309 debugupdatecaches:
312 debugupdatecaches:
310 debugupgraderepo: optimize, run, backup
313 debugupgraderepo: optimize, run, backup
311 debugwalk: include, exclude
314 debugwalk: include, exclude
312 debugwhyunstable:
315 debugwhyunstable:
313 debugwireargs: three, four, five, ssh, remotecmd, insecure
316 debugwireargs: three, four, five, ssh, remotecmd, insecure
314 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
317 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
315 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
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
316 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
319 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
317 files: rev, print0, include, exclude, template, subrepos
320 files: rev, print0, include, exclude, template, subrepos
318 forget: interactive, include, exclude, dry-run
321 forget: interactive, include, exclude, dry-run
319 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
322 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
320 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
323 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
321 heads: rev, topo, active, closed, style, template
324 heads: rev, topo, active, closed, style, template
322 help: extension, command, keyword, system
325 help: extension, command, keyword, system
323 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
326 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
324 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
327 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
325 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
328 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
326 init: ssh, remotecmd, insecure
329 init: ssh, remotecmd, insecure
327 locate: rev, print0, fullpath, include, exclude
330 locate: rev, print0, fullpath, include, exclude
328 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
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
329 manifest: rev, all, template
332 manifest: rev, all, template
330 merge: force, rev, preview, abort, tool
333 merge: force, rev, preview, abort, tool
331 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
334 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
332 parents: rev, style, template
335 parents: rev, style, template
333 paths: template
336 paths: template
334 phase: public, draft, secret, force, rev
337 phase: public, draft, secret, force, rev
335 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
338 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
336 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
339 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
337 recover: verify
340 recover: verify
338 remove: after, force, subrepos, include, exclude, dry-run
341 remove: after, force, subrepos, include, exclude, dry-run
339 rename: after, force, include, exclude, dry-run
342 rename: after, force, include, exclude, dry-run
340 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
343 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
341 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
344 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
342 rollback: dry-run, force
345 rollback: dry-run, force
343 root: template
346 root: template
344 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
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
345 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
348 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
346 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
349 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
347 summary: remote
350 summary: remote
348 tag: force, local, rev, remove, edit, message, date, user
351 tag: force, local, rev, remove, edit, message, date, user
349 tags: template
352 tags: template
350 tip: patch, git, style, template
353 tip: patch, git, style, template
351 unbundle: update
354 unbundle: update
352 unshelve: abort, continue, keep, name, tool, date
355 unshelve: abort, continue, keep, name, tool, date
353 update: clean, check, merge, date, rev, tool
356 update: clean, check, merge, date, rev, tool
354 verify: full
357 verify: full
355 version: template
358 version: template
356
359
357 $ hg init a
360 $ hg init a
358 $ cd a
361 $ cd a
359 $ echo fee > fee
362 $ echo fee > fee
360 $ hg ci -q -Amfee
363 $ hg ci -q -Amfee
361 $ hg tag fee
364 $ hg tag fee
362 $ mkdir fie
365 $ mkdir fie
363 $ echo dead > fie/dead
366 $ echo dead > fie/dead
364 $ echo live > fie/live
367 $ echo live > fie/live
365 $ hg bookmark fo
368 $ hg bookmark fo
366 $ hg branch -q fie
369 $ hg branch -q fie
367 $ hg ci -q -Amfie
370 $ hg ci -q -Amfie
368 $ echo fo > fo
371 $ echo fo > fo
369 $ hg branch -qf default
372 $ hg branch -qf default
370 $ hg ci -q -Amfo
373 $ hg ci -q -Amfo
371 $ echo Fum > Fum
374 $ echo Fum > Fum
372 $ hg ci -q -AmFum
375 $ hg ci -q -AmFum
373 $ hg bookmark Fum
376 $ hg bookmark Fum
374
377
375 Test debugpathcomplete
378 Test debugpathcomplete
376
379
377 $ hg debugpathcomplete f
380 $ hg debugpathcomplete f
378 fee
381 fee
379 fie
382 fie
380 fo
383 fo
381 $ hg debugpathcomplete -f f
384 $ hg debugpathcomplete -f f
382 fee
385 fee
383 fie/dead
386 fie/dead
384 fie/live
387 fie/live
385 fo
388 fo
386
389
387 $ hg rm Fum
390 $ hg rm Fum
388 $ hg debugpathcomplete -r F
391 $ hg debugpathcomplete -r F
389 Fum
392 Fum
390
393
391 Test debugnamecomplete
394 Test debugnamecomplete
392
395
393 $ hg debugnamecomplete
396 $ hg debugnamecomplete
394 Fum
397 Fum
395 default
398 default
396 fee
399 fee
397 fie
400 fie
398 fo
401 fo
399 tip
402 tip
400 $ hg debugnamecomplete f
403 $ hg debugnamecomplete f
401 fee
404 fee
402 fie
405 fie
403 fo
406 fo
404
407
405 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
408 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
406 used for completions in some shells.
409 used for completions in some shells.
407
410
408 $ hg debuglabelcomplete
411 $ hg debuglabelcomplete
409 Fum
412 Fum
410 default
413 default
411 fee
414 fee
412 fie
415 fie
413 fo
416 fo
414 tip
417 tip
415 $ hg debuglabelcomplete f
418 $ hg debuglabelcomplete f
416 fee
419 fee
417 fie
420 fie
418 fo
421 fo
@@ -1,3875 +1,3883 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 add add the specified files on the next commit
406 add add the specified files on the next commit
406 annotate, blame
407 annotate, blame
407 show changeset information by line for each file
408 show changeset information by line for each file
408 clone make a copy of an existing repository
409 clone make a copy of an existing repository
409 commit, ci commit the specified files or all outstanding changes
410 commit, ci commit the specified files or all outstanding changes
410 diff diff repository (or selected files)
411 diff diff repository (or selected files)
411 export dump the header and diffs for one or more changesets
412 export dump the header and diffs for one or more changesets
412 forget forget the specified files on the next commit
413 forget forget the specified files on the next commit
413 init create a new repository in the given directory
414 init create a new repository in the given directory
414 log, history show revision history of entire repository or files
415 log, history show revision history of entire repository or files
415 merge merge another revision into working directory
416 merge merge another revision into working directory
416 pull pull changes from the specified source
417 pull pull changes from the specified source
417 push push changes to the specified destination
418 push push changes to the specified destination
418 remove, rm remove the specified files on the next commit
419 remove, rm remove the specified files on the next commit
419 serve start stand-alone webserver
420 serve start stand-alone webserver
420 status, st show changed files in the working directory
421 status, st show changed files in the working directory
421 summary, sum summarize working directory state
422 summary, sum summarize working directory state
422 update, up, checkout, co
423 update, up, checkout, co
423 update working directory (or switch revisions)
424 update working directory (or switch revisions)
424
425
425 global options ([+] can be repeated):
426 global options ([+] can be repeated):
426
427
427 -R --repository REPO repository root directory or name of overlay bundle
428 -R --repository REPO repository root directory or name of overlay bundle
428 file
429 file
429 --cwd DIR change working directory
430 --cwd DIR change working directory
430 -y --noninteractive do not prompt, automatically pick the first choice for
431 -y --noninteractive do not prompt, automatically pick the first choice for
431 all prompts
432 all prompts
432 -q --quiet suppress output
433 -q --quiet suppress output
433 -v --verbose enable additional output
434 -v --verbose enable additional output
434 --color TYPE when to colorize (boolean, always, auto, never, or
435 --color TYPE when to colorize (boolean, always, auto, never, or
435 debug)
436 debug)
436 --config CONFIG [+] set/override config option (use 'section.name=value')
437 --config CONFIG [+] set/override config option (use 'section.name=value')
437 --debug enable debugging output
438 --debug enable debugging output
438 --debugger start debugger
439 --debugger start debugger
439 --encoding ENCODE set the charset encoding (default: ascii)
440 --encoding ENCODE set the charset encoding (default: ascii)
440 --encodingmode MODE set the charset encoding mode (default: strict)
441 --encodingmode MODE set the charset encoding mode (default: strict)
441 --traceback always print a traceback on exception
442 --traceback always print a traceback on exception
442 --time time how long the command takes
443 --time time how long the command takes
443 --profile print command execution profile
444 --profile print command execution profile
444 --version output version information and exit
445 --version output version information and exit
445 -h --help display help and exit
446 -h --help display help and exit
446 --hidden consider hidden changesets
447 --hidden consider hidden changesets
447 --pager TYPE when to paginate (boolean, always, auto, or never)
448 --pager TYPE when to paginate (boolean, always, auto, or never)
448 (default: auto)
449 (default: auto)
449
450
450 (use 'hg help' for the full list of commands)
451 (use 'hg help' for the full list of commands)
451
452
452 $ hg add -h
453 $ hg add -h
453 hg add [OPTION]... [FILE]...
454 hg add [OPTION]... [FILE]...
454
455
455 add the specified files on the next commit
456 add the specified files on the next commit
456
457
457 Schedule files to be version controlled and added to the repository.
458 Schedule files to be version controlled and added to the repository.
458
459
459 The files will be added to the repository at the next commit. To undo an
460 The files will be added to the repository at the next commit. To undo an
460 add before that, see 'hg forget'.
461 add before that, see 'hg forget'.
461
462
462 If no names are given, add all files to the repository (except files
463 If no names are given, add all files to the repository (except files
463 matching ".hgignore").
464 matching ".hgignore").
464
465
465 Returns 0 if all files are successfully added.
466 Returns 0 if all files are successfully added.
466
467
467 options ([+] can be repeated):
468 options ([+] can be repeated):
468
469
469 -I --include PATTERN [+] include names matching the given patterns
470 -I --include PATTERN [+] include names matching the given patterns
470 -X --exclude PATTERN [+] exclude names matching the given patterns
471 -X --exclude PATTERN [+] exclude names matching the given patterns
471 -S --subrepos recurse into subrepositories
472 -S --subrepos recurse into subrepositories
472 -n --dry-run do not perform actions, just print output
473 -n --dry-run do not perform actions, just print output
473
474
474 (some details hidden, use --verbose to show complete help)
475 (some details hidden, use --verbose to show complete help)
475
476
476 Verbose help for add
477 Verbose help for add
477
478
478 $ hg add -hv
479 $ hg add -hv
479 hg add [OPTION]... [FILE]...
480 hg add [OPTION]... [FILE]...
480
481
481 add the specified files on the next commit
482 add the specified files on the next commit
482
483
483 Schedule files to be version controlled and added to the repository.
484 Schedule files to be version controlled and added to the repository.
484
485
485 The files will be added to the repository at the next commit. To undo an
486 The files will be added to the repository at the next commit. To undo an
486 add before that, see 'hg forget'.
487 add before that, see 'hg forget'.
487
488
488 If no names are given, add all files to the repository (except files
489 If no names are given, add all files to the repository (except files
489 matching ".hgignore").
490 matching ".hgignore").
490
491
491 Examples:
492 Examples:
492
493
493 - New (unknown) files are added automatically by 'hg add':
494 - New (unknown) files are added automatically by 'hg add':
494
495
495 $ ls
496 $ ls
496 foo.c
497 foo.c
497 $ hg status
498 $ hg status
498 ? foo.c
499 ? foo.c
499 $ hg add
500 $ hg add
500 adding foo.c
501 adding foo.c
501 $ hg status
502 $ hg status
502 A foo.c
503 A foo.c
503
504
504 - Specific files to be added can be specified:
505 - Specific files to be added can be specified:
505
506
506 $ ls
507 $ ls
507 bar.c foo.c
508 bar.c foo.c
508 $ hg status
509 $ hg status
509 ? bar.c
510 ? bar.c
510 ? foo.c
511 ? foo.c
511 $ hg add bar.c
512 $ hg add bar.c
512 $ hg status
513 $ hg status
513 A bar.c
514 A bar.c
514 ? foo.c
515 ? foo.c
515
516
516 Returns 0 if all files are successfully added.
517 Returns 0 if all files are successfully added.
517
518
518 options ([+] can be repeated):
519 options ([+] can be repeated):
519
520
520 -I --include PATTERN [+] include names matching the given patterns
521 -I --include PATTERN [+] include names matching the given patterns
521 -X --exclude PATTERN [+] exclude names matching the given patterns
522 -X --exclude PATTERN [+] exclude names matching the given patterns
522 -S --subrepos recurse into subrepositories
523 -S --subrepos recurse into subrepositories
523 -n --dry-run do not perform actions, just print output
524 -n --dry-run do not perform actions, just print output
524
525
525 global options ([+] can be repeated):
526 global options ([+] can be repeated):
526
527
527 -R --repository REPO repository root directory or name of overlay bundle
528 -R --repository REPO repository root directory or name of overlay bundle
528 file
529 file
529 --cwd DIR change working directory
530 --cwd DIR change working directory
530 -y --noninteractive do not prompt, automatically pick the first choice for
531 -y --noninteractive do not prompt, automatically pick the first choice for
531 all prompts
532 all prompts
532 -q --quiet suppress output
533 -q --quiet suppress output
533 -v --verbose enable additional output
534 -v --verbose enable additional output
534 --color TYPE when to colorize (boolean, always, auto, never, or
535 --color TYPE when to colorize (boolean, always, auto, never, or
535 debug)
536 debug)
536 --config CONFIG [+] set/override config option (use 'section.name=value')
537 --config CONFIG [+] set/override config option (use 'section.name=value')
537 --debug enable debugging output
538 --debug enable debugging output
538 --debugger start debugger
539 --debugger start debugger
539 --encoding ENCODE set the charset encoding (default: ascii)
540 --encoding ENCODE set the charset encoding (default: ascii)
540 --encodingmode MODE set the charset encoding mode (default: strict)
541 --encodingmode MODE set the charset encoding mode (default: strict)
541 --traceback always print a traceback on exception
542 --traceback always print a traceback on exception
542 --time time how long the command takes
543 --time time how long the command takes
543 --profile print command execution profile
544 --profile print command execution profile
544 --version output version information and exit
545 --version output version information and exit
545 -h --help display help and exit
546 -h --help display help and exit
546 --hidden consider hidden changesets
547 --hidden consider hidden changesets
547 --pager TYPE when to paginate (boolean, always, auto, or never)
548 --pager TYPE when to paginate (boolean, always, auto, or never)
548 (default: auto)
549 (default: auto)
549
550
550 Test the textwidth config option
551 Test the textwidth config option
551
552
552 $ hg root -h --config ui.textwidth=50
553 $ hg root -h --config ui.textwidth=50
553 hg root
554 hg root
554
555
555 print the root (top) of the current working
556 print the root (top) of the current working
556 directory
557 directory
557
558
558 Print the root directory of the current
559 Print the root directory of the current
559 repository.
560 repository.
560
561
561 Returns 0 on success.
562 Returns 0 on success.
562
563
563 options:
564 options:
564
565
565 -T --template TEMPLATE display with template
566 -T --template TEMPLATE display with template
566
567
567 (some details hidden, use --verbose to show
568 (some details hidden, use --verbose to show
568 complete help)
569 complete help)
569
570
570 Test help option with version option
571 Test help option with version option
571
572
572 $ hg add -h --version
573 $ hg add -h --version
573 Mercurial Distributed SCM (version *) (glob)
574 Mercurial Distributed SCM (version *) (glob)
574 (see https://mercurial-scm.org for more information)
575 (see https://mercurial-scm.org for more information)
575
576
576 Copyright (C) 2005-* Matt Mackall and others (glob)
577 Copyright (C) 2005-* Matt Mackall and others (glob)
577 This is free software; see the source for copying conditions. There is NO
578 This is free software; see the source for copying conditions. There is NO
578 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
579 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
579
580
580 $ hg add --skjdfks
581 $ hg add --skjdfks
581 hg add: option --skjdfks not recognized
582 hg add: option --skjdfks not recognized
582 hg add [OPTION]... [FILE]...
583 hg add [OPTION]... [FILE]...
583
584
584 add the specified files on the next commit
585 add the specified files on the next commit
585
586
586 options ([+] can be repeated):
587 options ([+] can be repeated):
587
588
588 -I --include PATTERN [+] include names matching the given patterns
589 -I --include PATTERN [+] include names matching the given patterns
589 -X --exclude PATTERN [+] exclude names matching the given patterns
590 -X --exclude PATTERN [+] exclude names matching the given patterns
590 -S --subrepos recurse into subrepositories
591 -S --subrepos recurse into subrepositories
591 -n --dry-run do not perform actions, just print output
592 -n --dry-run do not perform actions, just print output
592
593
593 (use 'hg add -h' to show more help)
594 (use 'hg add -h' to show more help)
594 [255]
595 [255]
595
596
596 Test ambiguous command help
597 Test ambiguous command help
597
598
598 $ hg help ad
599 $ hg help ad
599 list of commands:
600 list of commands:
600
601
601 add add the specified files on the next commit
602 add add the specified files on the next commit
602 addremove add all new files, delete all missing files
603 addremove add all new files, delete all missing files
603
604
604 (use 'hg help -v ad' to show built-in aliases and global options)
605 (use 'hg help -v ad' to show built-in aliases and global options)
605
606
606 Test command without options
607 Test command without options
607
608
608 $ hg help verify
609 $ hg help verify
609 hg verify
610 hg verify
610
611
611 verify the integrity of the repository
612 verify the integrity of the repository
612
613
613 Verify the integrity of the current repository.
614 Verify the integrity of the current repository.
614
615
615 This will perform an extensive check of the repository's integrity,
616 This will perform an extensive check of the repository's integrity,
616 validating the hashes and checksums of each entry in the changelog,
617 validating the hashes and checksums of each entry in the changelog,
617 manifest, and tracked files, as well as the integrity of their crosslinks
618 manifest, and tracked files, as well as the integrity of their crosslinks
618 and indices.
619 and indices.
619
620
620 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
621 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
621 information about recovery from corruption of the repository.
622 information about recovery from corruption of the repository.
622
623
623 Returns 0 on success, 1 if errors are encountered.
624 Returns 0 on success, 1 if errors are encountered.
624
625
625 options:
626 options:
626
627
627 (some details hidden, use --verbose to show complete help)
628 (some details hidden, use --verbose to show complete help)
628
629
629 $ hg help diff
630 $ hg help diff
630 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
631 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
631
632
632 diff repository (or selected files)
633 diff repository (or selected files)
633
634
634 Show differences between revisions for the specified files.
635 Show differences between revisions for the specified files.
635
636
636 Differences between files are shown using the unified diff format.
637 Differences between files are shown using the unified diff format.
637
638
638 Note:
639 Note:
639 'hg diff' may generate unexpected results for merges, as it will
640 'hg diff' may generate unexpected results for merges, as it will
640 default to comparing against the working directory's first parent
641 default to comparing against the working directory's first parent
641 changeset if no revisions are specified.
642 changeset if no revisions are specified.
642
643
643 When two revision arguments are given, then changes are shown between
644 When two revision arguments are given, then changes are shown between
644 those revisions. If only one revision is specified then that revision is
645 those revisions. If only one revision is specified then that revision is
645 compared to the working directory, and, when no revisions are specified,
646 compared to the working directory, and, when no revisions are specified,
646 the working directory files are compared to its first parent.
647 the working directory files are compared to its first parent.
647
648
648 Alternatively you can specify -c/--change with a revision to see the
649 Alternatively you can specify -c/--change with a revision to see the
649 changes in that changeset relative to its first parent.
650 changes in that changeset relative to its first parent.
650
651
651 Without the -a/--text option, diff will avoid generating diffs of files it
652 Without the -a/--text option, diff will avoid generating diffs of files it
652 detects as binary. With -a, diff will generate a diff anyway, probably
653 detects as binary. With -a, diff will generate a diff anyway, probably
653 with undesirable results.
654 with undesirable results.
654
655
655 Use the -g/--git option to generate diffs in the git extended diff format.
656 Use the -g/--git option to generate diffs in the git extended diff format.
656 For more information, read 'hg help diffs'.
657 For more information, read 'hg help diffs'.
657
658
658 Returns 0 on success.
659 Returns 0 on success.
659
660
660 options ([+] can be repeated):
661 options ([+] can be repeated):
661
662
662 -r --rev REV [+] revision
663 -r --rev REV [+] revision
663 -c --change REV change made by revision
664 -c --change REV change made by revision
664 -a --text treat all files as text
665 -a --text treat all files as text
665 -g --git use git extended diff format
666 -g --git use git extended diff format
666 --binary generate binary diffs in git mode (default)
667 --binary generate binary diffs in git mode (default)
667 --nodates omit dates from diff headers
668 --nodates omit dates from diff headers
668 --noprefix omit a/ and b/ prefixes from filenames
669 --noprefix omit a/ and b/ prefixes from filenames
669 -p --show-function show which function each change is in
670 -p --show-function show which function each change is in
670 --reverse produce a diff that undoes the changes
671 --reverse produce a diff that undoes the changes
671 -w --ignore-all-space ignore white space when comparing lines
672 -w --ignore-all-space ignore white space when comparing lines
672 -b --ignore-space-change ignore changes in the amount of white space
673 -b --ignore-space-change ignore changes in the amount of white space
673 -B --ignore-blank-lines ignore changes whose lines are all blank
674 -B --ignore-blank-lines ignore changes whose lines are all blank
674 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
675 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
675 -U --unified NUM number of lines of context to show
676 -U --unified NUM number of lines of context to show
676 --stat output diffstat-style summary of changes
677 --stat output diffstat-style summary of changes
677 --root DIR produce diffs relative to subdirectory
678 --root DIR produce diffs relative to subdirectory
678 -I --include PATTERN [+] include names matching the given patterns
679 -I --include PATTERN [+] include names matching the given patterns
679 -X --exclude PATTERN [+] exclude names matching the given patterns
680 -X --exclude PATTERN [+] exclude names matching the given patterns
680 -S --subrepos recurse into subrepositories
681 -S --subrepos recurse into subrepositories
681
682
682 (some details hidden, use --verbose to show complete help)
683 (some details hidden, use --verbose to show complete help)
683
684
684 $ hg help status
685 $ hg help status
685 hg status [OPTION]... [FILE]...
686 hg status [OPTION]... [FILE]...
686
687
687 aliases: st
688 aliases: st
688
689
689 show changed files in the working directory
690 show changed files in the working directory
690
691
691 Show status of files in the repository. If names are given, only files
692 Show status of files in the repository. If names are given, only files
692 that match are shown. Files that are clean or ignored or the source of a
693 that match are shown. Files that are clean or ignored or the source of a
693 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
694 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
694 -C/--copies or -A/--all are given. Unless options described with "show
695 -C/--copies or -A/--all are given. Unless options described with "show
695 only ..." are given, the options -mardu are used.
696 only ..." are given, the options -mardu are used.
696
697
697 Option -q/--quiet hides untracked (unknown and ignored) files unless
698 Option -q/--quiet hides untracked (unknown and ignored) files unless
698 explicitly requested with -u/--unknown or -i/--ignored.
699 explicitly requested with -u/--unknown or -i/--ignored.
699
700
700 Note:
701 Note:
701 'hg status' may appear to disagree with diff if permissions have
702 'hg status' may appear to disagree with diff if permissions have
702 changed or a merge has occurred. The standard diff format does not
703 changed or a merge has occurred. The standard diff format does not
703 report permission changes and diff only reports changes relative to one
704 report permission changes and diff only reports changes relative to one
704 merge parent.
705 merge parent.
705
706
706 If one revision is given, it is used as the base revision. If two
707 If one revision is given, it is used as the base revision. If two
707 revisions are given, the differences between them are shown. The --change
708 revisions are given, the differences between them are shown. The --change
708 option can also be used as a shortcut to list the changed files of a
709 option can also be used as a shortcut to list the changed files of a
709 revision from its first parent.
710 revision from its first parent.
710
711
711 The codes used to show the status of files are:
712 The codes used to show the status of files are:
712
713
713 M = modified
714 M = modified
714 A = added
715 A = added
715 R = removed
716 R = removed
716 C = clean
717 C = clean
717 ! = missing (deleted by non-hg command, but still tracked)
718 ! = missing (deleted by non-hg command, but still tracked)
718 ? = not tracked
719 ? = not tracked
719 I = ignored
720 I = ignored
720 = origin of the previous file (with --copies)
721 = origin of the previous file (with --copies)
721
722
722 Returns 0 on success.
723 Returns 0 on success.
723
724
724 options ([+] can be repeated):
725 options ([+] can be repeated):
725
726
726 -A --all show status of all files
727 -A --all show status of all files
727 -m --modified show only modified files
728 -m --modified show only modified files
728 -a --added show only added files
729 -a --added show only added files
729 -r --removed show only removed files
730 -r --removed show only removed files
730 -d --deleted show only deleted (but tracked) files
731 -d --deleted show only deleted (but tracked) files
731 -c --clean show only files without changes
732 -c --clean show only files without changes
732 -u --unknown show only unknown (not tracked) files
733 -u --unknown show only unknown (not tracked) files
733 -i --ignored show only ignored files
734 -i --ignored show only ignored files
734 -n --no-status hide status prefix
735 -n --no-status hide status prefix
735 -C --copies show source of copied files
736 -C --copies show source of copied files
736 -0 --print0 end filenames with NUL, for use with xargs
737 -0 --print0 end filenames with NUL, for use with xargs
737 --rev REV [+] show difference from revision
738 --rev REV [+] show difference from revision
738 --change REV list the changed files of a revision
739 --change REV list the changed files of a revision
739 -I --include PATTERN [+] include names matching the given patterns
740 -I --include PATTERN [+] include names matching the given patterns
740 -X --exclude PATTERN [+] exclude names matching the given patterns
741 -X --exclude PATTERN [+] exclude names matching the given patterns
741 -S --subrepos recurse into subrepositories
742 -S --subrepos recurse into subrepositories
742 -T --template TEMPLATE display with template
743 -T --template TEMPLATE display with template
743
744
744 (some details hidden, use --verbose to show complete help)
745 (some details hidden, use --verbose to show complete help)
745
746
746 $ hg -q help status
747 $ hg -q help status
747 hg status [OPTION]... [FILE]...
748 hg status [OPTION]... [FILE]...
748
749
749 show changed files in the working directory
750 show changed files in the working directory
750
751
751 $ hg help foo
752 $ hg help foo
752 abort: no such help topic: foo
753 abort: no such help topic: foo
753 (try 'hg help --keyword foo')
754 (try 'hg help --keyword foo')
754 [255]
755 [255]
755
756
756 $ hg skjdfks
757 $ hg skjdfks
757 hg: unknown command 'skjdfks'
758 hg: unknown command 'skjdfks'
758 (use 'hg help' for a list of commands)
759 (use 'hg help' for a list of commands)
759 [255]
760 [255]
760
761
761 Typoed command gives suggestion
762 Typoed command gives suggestion
762 $ hg puls
763 $ hg puls
763 hg: unknown command 'puls'
764 hg: unknown command 'puls'
764 (did you mean one of pull, push?)
765 (did you mean one of pull, push?)
765 [255]
766 [255]
766
767
767 Not enabled extension gets suggested
768 Not enabled extension gets suggested
768
769
769 $ hg rebase
770 $ hg rebase
770 hg: unknown command 'rebase'
771 hg: unknown command 'rebase'
771 'rebase' is provided by the following extension:
772 'rebase' is provided by the following extension:
772
773
773 rebase command to move sets of revisions to a different ancestor
774 rebase command to move sets of revisions to a different ancestor
774
775
775 (use 'hg help extensions' for information on enabling extensions)
776 (use 'hg help extensions' for information on enabling extensions)
776 [255]
777 [255]
777
778
778 Disabled extension gets suggested
779 Disabled extension gets suggested
779 $ hg --config extensions.rebase=! rebase
780 $ hg --config extensions.rebase=! rebase
780 hg: unknown command 'rebase'
781 hg: unknown command 'rebase'
781 'rebase' is provided by the following extension:
782 'rebase' is provided by the following extension:
782
783
783 rebase command to move sets of revisions to a different ancestor
784 rebase command to move sets of revisions to a different ancestor
784
785
785 (use 'hg help extensions' for information on enabling extensions)
786 (use 'hg help extensions' for information on enabling extensions)
786 [255]
787 [255]
787
788
788 Make sure that we don't run afoul of the help system thinking that
789 Make sure that we don't run afoul of the help system thinking that
789 this is a section and erroring out weirdly.
790 this is a section and erroring out weirdly.
790
791
791 $ hg .log
792 $ hg .log
792 hg: unknown command '.log'
793 hg: unknown command '.log'
793 (did you mean log?)
794 (did you mean log?)
794 [255]
795 [255]
795
796
796 $ hg log.
797 $ hg log.
797 hg: unknown command 'log.'
798 hg: unknown command 'log.'
798 (did you mean log?)
799 (did you mean log?)
799 [255]
800 [255]
800 $ hg pu.lh
801 $ hg pu.lh
801 hg: unknown command 'pu.lh'
802 hg: unknown command 'pu.lh'
802 (did you mean one of pull, push?)
803 (did you mean one of pull, push?)
803 [255]
804 [255]
804
805
805 $ cat > helpext.py <<EOF
806 $ cat > helpext.py <<EOF
806 > import os
807 > import os
807 > from mercurial import commands, fancyopts, registrar
808 > from mercurial import commands, fancyopts, registrar
808 >
809 >
809 > def func(arg):
810 > def func(arg):
810 > return '%sfoo' % arg
811 > return '%sfoo' % arg
811 > class customopt(fancyopts.customopt):
812 > class customopt(fancyopts.customopt):
812 > def newstate(self, oldstate, newparam, abort):
813 > def newstate(self, oldstate, newparam, abort):
813 > return '%sbar' % oldstate
814 > return '%sbar' % oldstate
814 > cmdtable = {}
815 > cmdtable = {}
815 > command = registrar.command(cmdtable)
816 > command = registrar.command(cmdtable)
816 >
817 >
817 > @command(b'nohelp',
818 > @command(b'nohelp',
818 > [(b'', b'longdesc', 3, b'x'*67),
819 > [(b'', b'longdesc', 3, b'x'*67),
819 > (b'n', b'', None, b'normal desc'),
820 > (b'n', b'', None, b'normal desc'),
820 > (b'', b'newline', b'', b'line1\nline2'),
821 > (b'', b'newline', b'', b'line1\nline2'),
821 > (b'', b'default-off', False, b'enable X'),
822 > (b'', b'default-off', False, b'enable X'),
822 > (b'', b'default-on', True, b'enable Y'),
823 > (b'', b'default-on', True, b'enable Y'),
823 > (b'', b'callableopt', func, b'adds foo'),
824 > (b'', b'callableopt', func, b'adds foo'),
824 > (b'', b'customopt', customopt(''), b'adds bar'),
825 > (b'', b'customopt', customopt(''), b'adds bar'),
825 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
826 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
826 > b'hg nohelp',
827 > b'hg nohelp',
827 > norepo=True)
828 > norepo=True)
828 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
829 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
829 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
830 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
830 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
831 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
831 > def nohelp(ui, *args, **kwargs):
832 > def nohelp(ui, *args, **kwargs):
832 > pass
833 > pass
833 >
834 >
834 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
835 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
835 > def hashelp(ui, *args, **kwargs):
836 > def hashelp(ui, *args, **kwargs):
836 > """Extension command's help"""
837 > """Extension command's help"""
837 >
838 >
838 > def uisetup(ui):
839 > def uisetup(ui):
839 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
840 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
840 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
841 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
841 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
842 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
842 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
843 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
843 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
844 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
844 >
845 >
845 > EOF
846 > EOF
846 $ echo '[extensions]' >> $HGRCPATH
847 $ echo '[extensions]' >> $HGRCPATH
847 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
848 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
848
849
849 Test for aliases
850 Test for aliases
850
851
851 $ hg help | grep hgalias
852 $ hg help | grep hgalias
852 hgalias My doc
853 hgalias My doc
853
854
854 $ hg help hgalias
855 $ hg help hgalias
855 hg hgalias [--remote]
856 hg hgalias [--remote]
856
857
857 alias for: hg summary
858 alias for: hg summary
858
859
859 My doc
860 My doc
860
861
861 defined by: helpext
862 defined by: helpext
862
863
863 options:
864 options:
864
865
865 --remote check for push and pull
866 --remote check for push and pull
866
867
867 (some details hidden, use --verbose to show complete help)
868 (some details hidden, use --verbose to show complete help)
868 $ hg help hgaliasnodoc
869 $ hg help hgaliasnodoc
869 hg hgaliasnodoc [--remote]
870 hg hgaliasnodoc [--remote]
870
871
871 alias for: hg summary
872 alias for: hg summary
872
873
873 summarize working directory state
874 summarize working directory state
874
875
875 This generates a brief summary of the working directory state, including
876 This generates a brief summary of the working directory state, including
876 parents, branch, commit status, phase and available updates.
877 parents, branch, commit status, phase and available updates.
877
878
878 With the --remote option, this will check the default paths for incoming
879 With the --remote option, this will check the default paths for incoming
879 and outgoing changes. This can be time-consuming.
880 and outgoing changes. This can be time-consuming.
880
881
881 Returns 0 on success.
882 Returns 0 on success.
882
883
883 defined by: helpext
884 defined by: helpext
884
885
885 options:
886 options:
886
887
887 --remote check for push and pull
888 --remote check for push and pull
888
889
889 (some details hidden, use --verbose to show complete help)
890 (some details hidden, use --verbose to show complete help)
890
891
891 $ hg help shellalias
892 $ hg help shellalias
892 hg shellalias
893 hg shellalias
893
894
894 shell alias for: echo hi
895 shell alias for: echo hi
895
896
896 (no help text available)
897 (no help text available)
897
898
898 defined by: helpext
899 defined by: helpext
899
900
900 (some details hidden, use --verbose to show complete help)
901 (some details hidden, use --verbose to show complete help)
901
902
902 Test command with no help text
903 Test command with no help text
903
904
904 $ hg help nohelp
905 $ hg help nohelp
905 hg nohelp
906 hg nohelp
906
907
907 (no help text available)
908 (no help text available)
908
909
909 options:
910 options:
910
911
911 --longdesc VALUE
912 --longdesc VALUE
912 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
913 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
913 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
914 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
914 -n -- normal desc
915 -n -- normal desc
915 --newline VALUE line1 line2
916 --newline VALUE line1 line2
916 --default-off enable X
917 --default-off enable X
917 --[no-]default-on enable Y (default: on)
918 --[no-]default-on enable Y (default: on)
918 --callableopt VALUE adds foo
919 --callableopt VALUE adds foo
919 --customopt VALUE adds bar
920 --customopt VALUE adds bar
920 --customopt-withdefault VALUE adds bar (default: foo)
921 --customopt-withdefault VALUE adds bar (default: foo)
921
922
922 (some details hidden, use --verbose to show complete help)
923 (some details hidden, use --verbose to show complete help)
923
924
924 Test that default list of commands includes extension commands that have help,
925 Test that default list of commands includes extension commands that have help,
925 but not those that don't, except in verbose mode, when a keyword is passed, or
926 but not those that don't, except in verbose mode, when a keyword is passed, or
926 when help about the extension is requested.
927 when help about the extension is requested.
927
928
928 #if no-extraextensions
929 #if no-extraextensions
929
930
930 $ hg help | grep hashelp
931 $ hg help | grep hashelp
931 hashelp Extension command's help
932 hashelp Extension command's help
932 $ hg help | grep nohelp
933 $ hg help | grep nohelp
933 [1]
934 [1]
934 $ hg help -v | grep nohelp
935 $ hg help -v | grep nohelp
935 nohelp (no help text available)
936 nohelp (no help text available)
936
937
937 $ hg help -k nohelp
938 $ hg help -k nohelp
938 Commands:
939 Commands:
939
940
940 nohelp hg nohelp
941 nohelp hg nohelp
941
942
942 Extension Commands:
943 Extension Commands:
943
944
944 nohelp (no help text available)
945 nohelp (no help text available)
945
946
946 $ hg help helpext
947 $ hg help helpext
947 helpext extension - no help text available
948 helpext extension - no help text available
948
949
949 list of commands:
950 list of commands:
950
951
951 hashelp Extension command's help
952 hashelp Extension command's help
952 nohelp (no help text available)
953 nohelp (no help text available)
953
954
954 (use 'hg help -v helpext' to show built-in aliases and global options)
955 (use 'hg help -v helpext' to show built-in aliases and global options)
955
956
956 #endif
957 #endif
957
958
958 Test list of internal help commands
959 Test list of internal help commands
959
960
960 $ hg help debug
961 $ hg help debug
961 debug commands (internal and unsupported):
962 debug commands (internal and unsupported):
962
963
963 debugancestor
964 debugancestor
964 find the ancestor revision of two revisions in a given index
965 find the ancestor revision of two revisions in a given index
965 debugapplystreamclonebundle
966 debugapplystreamclonebundle
966 apply a stream clone bundle file
967 apply a stream clone bundle file
967 debugbuilddag
968 debugbuilddag
968 builds a repo with a given DAG from scratch in the current
969 builds a repo with a given DAG from scratch in the current
969 empty repo
970 empty repo
970 debugbundle lists the contents of a bundle
971 debugbundle lists the contents of a bundle
971 debugcapabilities
972 debugcapabilities
972 lists the capabilities of a remote peer
973 lists the capabilities of a remote peer
973 debugcheckstate
974 debugcheckstate
974 validate the correctness of the current dirstate
975 validate the correctness of the current dirstate
975 debugcolor show available color, effects or style
976 debugcolor show available color, effects or style
976 debugcommands
977 debugcommands
977 list all available commands and options
978 list all available commands and options
978 debugcomplete
979 debugcomplete
979 returns the completion list associated with the given command
980 returns the completion list associated with the given command
980 debugcreatestreamclonebundle
981 debugcreatestreamclonebundle
981 create a stream clone bundle file
982 create a stream clone bundle file
982 debugdag format the changelog or an index DAG as a concise textual
983 debugdag format the changelog or an index DAG as a concise textual
983 description
984 description
984 debugdata dump the contents of a data file revision
985 debugdata dump the contents of a data file revision
985 debugdate parse and display a date
986 debugdate parse and display a date
986 debugdeltachain
987 debugdeltachain
987 dump information about delta chains in a revlog
988 dump information about delta chains in a revlog
988 debugdirstate
989 debugdirstate
989 show the contents of the current dirstate
990 show the contents of the current dirstate
990 debugdiscovery
991 debugdiscovery
991 runs the changeset discovery protocol in isolation
992 runs the changeset discovery protocol in isolation
992 debugdownload
993 debugdownload
993 download a resource using Mercurial logic and config
994 download a resource using Mercurial logic and config
994 debugextensions
995 debugextensions
995 show information about active extensions
996 show information about active extensions
996 debugfileset parse and apply a fileset specification
997 debugfileset parse and apply a fileset specification
997 debugformat display format information about the current repository
998 debugformat display format information about the current repository
998 debugfsinfo show information detected about current filesystem
999 debugfsinfo show information detected about current filesystem
999 debuggetbundle
1000 debuggetbundle
1000 retrieves a bundle from a repo
1001 retrieves a bundle from a repo
1001 debugignore display the combined ignore pattern and information about
1002 debugignore display the combined ignore pattern and information about
1002 ignored files
1003 ignored files
1003 debugindex dump index data for a storage primitive
1004 debugindex dump index data for a storage primitive
1004 debugindexdot
1005 debugindexdot
1005 dump an index DAG as a graphviz dot file
1006 dump an index DAG as a graphviz dot file
1006 debugindexstats
1007 debugindexstats
1007 show stats related to the changelog index
1008 show stats related to the changelog index
1008 debuginstall test Mercurial installation
1009 debuginstall test Mercurial installation
1009 debugknown test whether node ids are known to a repo
1010 debugknown test whether node ids are known to a repo
1010 debuglocks show or modify state of locks
1011 debuglocks show or modify state of locks
1011 debugmanifestfulltextcache
1012 debugmanifestfulltextcache
1012 show, clear or amend the contents of the manifest fulltext
1013 show, clear or amend the contents of the manifest fulltext
1013 cache
1014 cache
1014 debugmergestate
1015 debugmergestate
1015 print merge state
1016 print merge state
1016 debugnamecomplete
1017 debugnamecomplete
1017 complete "names" - tags, open branch names, bookmark names
1018 complete "names" - tags, open branch names, bookmark names
1018 debugobsolete
1019 debugobsolete
1019 create arbitrary obsolete marker
1020 create arbitrary obsolete marker
1020 debugoptADV (no help text available)
1021 debugoptADV (no help text available)
1021 debugoptDEP (no help text available)
1022 debugoptDEP (no help text available)
1022 debugoptEXP (no help text available)
1023 debugoptEXP (no help text available)
1023 debugp1copies
1024 debugp1copies
1024 dump copy information compared to p1
1025 dump copy information compared to p1
1025 debugp2copies
1026 debugp2copies
1026 dump copy information compared to p2
1027 dump copy information compared to p2
1027 debugpathcomplete
1028 debugpathcomplete
1028 complete part or all of a tracked path
1029 complete part or all of a tracked path
1029 debugpathcopies
1030 debugpathcopies
1030 show copies between two revisions
1031 show copies between two revisions
1031 debugpeer establish a connection to a peer repository
1032 debugpeer establish a connection to a peer repository
1032 debugpickmergetool
1033 debugpickmergetool
1033 examine which merge tool is chosen for specified file
1034 examine which merge tool is chosen for specified file
1034 debugpushkey access the pushkey key/value protocol
1035 debugpushkey access the pushkey key/value protocol
1035 debugpvec (no help text available)
1036 debugpvec (no help text available)
1036 debugrebuilddirstate
1037 debugrebuilddirstate
1037 rebuild the dirstate as it would look like for the given
1038 rebuild the dirstate as it would look like for the given
1038 revision
1039 revision
1039 debugrebuildfncache
1040 debugrebuildfncache
1040 rebuild the fncache file
1041 rebuild the fncache file
1041 debugrename dump rename information
1042 debugrename dump rename information
1042 debugrevlog show data and statistics about a revlog
1043 debugrevlog show data and statistics about a revlog
1043 debugrevlogindex
1044 debugrevlogindex
1044 dump the contents of a revlog index
1045 dump the contents of a revlog index
1045 debugrevspec parse and apply a revision specification
1046 debugrevspec parse and apply a revision specification
1046 debugserve run a server with advanced settings
1047 debugserve run a server with advanced settings
1047 debugsetparents
1048 debugsetparents
1048 manually set the parents of the current working directory
1049 manually set the parents of the current working directory
1049 debugssl test a secure connection to a server
1050 debugssl test a secure connection to a server
1050 debugsub (no help text available)
1051 debugsub (no help text available)
1051 debugsuccessorssets
1052 debugsuccessorssets
1052 show set of successors for revision
1053 show set of successors for revision
1053 debugtemplate
1054 debugtemplate
1054 parse and apply a template
1055 parse and apply a template
1055 debuguigetpass
1056 debuguigetpass
1056 show prompt to type password
1057 show prompt to type password
1057 debuguiprompt
1058 debuguiprompt
1058 show plain prompt
1059 show plain prompt
1059 debugupdatecaches
1060 debugupdatecaches
1060 warm all known caches in the repository
1061 warm all known caches in the repository
1061 debugupgraderepo
1062 debugupgraderepo
1062 upgrade a repository to use different features
1063 upgrade a repository to use different features
1063 debugwalk show how files match on given patterns
1064 debugwalk show how files match on given patterns
1064 debugwhyunstable
1065 debugwhyunstable
1065 explain instabilities of a changeset
1066 explain instabilities of a changeset
1066 debugwireargs
1067 debugwireargs
1067 (no help text available)
1068 (no help text available)
1068 debugwireproto
1069 debugwireproto
1069 send wire protocol commands to a server
1070 send wire protocol commands to a server
1070
1071
1071 (use 'hg help -v debug' to show built-in aliases and global options)
1072 (use 'hg help -v debug' to show built-in aliases and global options)
1072
1073
1073 internals topic renders index of available sub-topics
1074 internals topic renders index of available sub-topics
1074
1075
1075 $ hg help internals
1076 $ hg help internals
1076 Technical implementation topics
1077 Technical implementation topics
1077 """""""""""""""""""""""""""""""
1078 """""""""""""""""""""""""""""""
1078
1079
1079 To access a subtopic, use "hg help internals.{subtopic-name}"
1080 To access a subtopic, use "hg help internals.{subtopic-name}"
1080
1081
1081 bundle2 Bundle2
1082 bundle2 Bundle2
1082 bundles Bundles
1083 bundles Bundles
1083 cbor CBOR
1084 cbor CBOR
1084 censor Censor
1085 censor Censor
1085 changegroups Changegroups
1086 changegroups Changegroups
1086 config Config Registrar
1087 config Config Registrar
1087 extensions Extension API
1088 extensions Extension API
1088 mergestate Mergestate
1089 mergestate Mergestate
1089 requirements Repository Requirements
1090 requirements Repository Requirements
1090 revlogs Revision Logs
1091 revlogs Revision Logs
1091 wireprotocol Wire Protocol
1092 wireprotocol Wire Protocol
1092 wireprotocolrpc
1093 wireprotocolrpc
1093 Wire Protocol RPC
1094 Wire Protocol RPC
1094 wireprotocolv2
1095 wireprotocolv2
1095 Wire Protocol Version 2
1096 Wire Protocol Version 2
1096
1097
1097 sub-topics can be accessed
1098 sub-topics can be accessed
1098
1099
1099 $ hg help internals.changegroups
1100 $ hg help internals.changegroups
1100 Changegroups
1101 Changegroups
1101 """"""""""""
1102 """"""""""""
1102
1103
1103 Changegroups are representations of repository revlog data, specifically
1104 Changegroups are representations of repository revlog data, specifically
1104 the changelog data, root/flat manifest data, treemanifest data, and
1105 the changelog data, root/flat manifest data, treemanifest data, and
1105 filelogs.
1106 filelogs.
1106
1107
1107 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1108 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1108 level, versions "1" and "2" are almost exactly the same, with the only
1109 level, versions "1" and "2" are almost exactly the same, with the only
1109 difference being an additional item in the *delta header*. Version "3"
1110 difference being an additional item in the *delta header*. Version "3"
1110 adds support for storage flags in the *delta header* and optionally
1111 adds support for storage flags in the *delta header* and optionally
1111 exchanging treemanifests (enabled by setting an option on the
1112 exchanging treemanifests (enabled by setting an option on the
1112 "changegroup" part in the bundle2).
1113 "changegroup" part in the bundle2).
1113
1114
1114 Changegroups when not exchanging treemanifests consist of 3 logical
1115 Changegroups when not exchanging treemanifests consist of 3 logical
1115 segments:
1116 segments:
1116
1117
1117 +---------------------------------+
1118 +---------------------------------+
1118 | | | |
1119 | | | |
1119 | changeset | manifest | filelogs |
1120 | changeset | manifest | filelogs |
1120 | | | |
1121 | | | |
1121 | | | |
1122 | | | |
1122 +---------------------------------+
1123 +---------------------------------+
1123
1124
1124 When exchanging treemanifests, there are 4 logical segments:
1125 When exchanging treemanifests, there are 4 logical segments:
1125
1126
1126 +-------------------------------------------------+
1127 +-------------------------------------------------+
1127 | | | | |
1128 | | | | |
1128 | changeset | root | treemanifests | filelogs |
1129 | changeset | root | treemanifests | filelogs |
1129 | | manifest | | |
1130 | | manifest | | |
1130 | | | | |
1131 | | | | |
1131 +-------------------------------------------------+
1132 +-------------------------------------------------+
1132
1133
1133 The principle building block of each segment is a *chunk*. A *chunk* is a
1134 The principle building block of each segment is a *chunk*. A *chunk* is a
1134 framed piece of data:
1135 framed piece of data:
1135
1136
1136 +---------------------------------------+
1137 +---------------------------------------+
1137 | | |
1138 | | |
1138 | length | data |
1139 | length | data |
1139 | (4 bytes) | (<length - 4> bytes) |
1140 | (4 bytes) | (<length - 4> bytes) |
1140 | | |
1141 | | |
1141 +---------------------------------------+
1142 +---------------------------------------+
1142
1143
1143 All integers are big-endian signed integers. Each chunk starts with a
1144 All integers are big-endian signed integers. Each chunk starts with a
1144 32-bit integer indicating the length of the entire chunk (including the
1145 32-bit integer indicating the length of the entire chunk (including the
1145 length field itself).
1146 length field itself).
1146
1147
1147 There is a special case chunk that has a value of 0 for the length
1148 There is a special case chunk that has a value of 0 for the length
1148 ("0x00000000"). We call this an *empty chunk*.
1149 ("0x00000000"). We call this an *empty chunk*.
1149
1150
1150 Delta Groups
1151 Delta Groups
1151 ============
1152 ============
1152
1153
1153 A *delta group* expresses the content of a revlog as a series of deltas,
1154 A *delta group* expresses the content of a revlog as a series of deltas,
1154 or patches against previous revisions.
1155 or patches against previous revisions.
1155
1156
1156 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1157 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1157 to signal the end of the delta group:
1158 to signal the end of the delta group:
1158
1159
1159 +------------------------------------------------------------------------+
1160 +------------------------------------------------------------------------+
1160 | | | | | |
1161 | | | | | |
1161 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1162 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1162 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1163 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1163 | | | | | |
1164 | | | | | |
1164 +------------------------------------------------------------------------+
1165 +------------------------------------------------------------------------+
1165
1166
1166 Each *chunk*'s data consists of the following:
1167 Each *chunk*'s data consists of the following:
1167
1168
1168 +---------------------------------------+
1169 +---------------------------------------+
1169 | | |
1170 | | |
1170 | delta header | delta data |
1171 | delta header | delta data |
1171 | (various by version) | (various) |
1172 | (various by version) | (various) |
1172 | | |
1173 | | |
1173 +---------------------------------------+
1174 +---------------------------------------+
1174
1175
1175 The *delta data* is a series of *delta*s that describe a diff from an
1176 The *delta data* is a series of *delta*s that describe a diff from an
1176 existing entry (either that the recipient already has, or previously
1177 existing entry (either that the recipient already has, or previously
1177 specified in the bundle/changegroup).
1178 specified in the bundle/changegroup).
1178
1179
1179 The *delta header* is different between versions "1", "2", and "3" of the
1180 The *delta header* is different between versions "1", "2", and "3" of the
1180 changegroup format.
1181 changegroup format.
1181
1182
1182 Version 1 (headerlen=80):
1183 Version 1 (headerlen=80):
1183
1184
1184 +------------------------------------------------------+
1185 +------------------------------------------------------+
1185 | | | | |
1186 | | | | |
1186 | node | p1 node | p2 node | link node |
1187 | node | p1 node | p2 node | link node |
1187 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1188 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1188 | | | | |
1189 | | | | |
1189 +------------------------------------------------------+
1190 +------------------------------------------------------+
1190
1191
1191 Version 2 (headerlen=100):
1192 Version 2 (headerlen=100):
1192
1193
1193 +------------------------------------------------------------------+
1194 +------------------------------------------------------------------+
1194 | | | | | |
1195 | | | | | |
1195 | node | p1 node | p2 node | base node | link node |
1196 | node | p1 node | p2 node | base node | link node |
1196 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1197 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1197 | | | | | |
1198 | | | | | |
1198 +------------------------------------------------------------------+
1199 +------------------------------------------------------------------+
1199
1200
1200 Version 3 (headerlen=102):
1201 Version 3 (headerlen=102):
1201
1202
1202 +------------------------------------------------------------------------------+
1203 +------------------------------------------------------------------------------+
1203 | | | | | | |
1204 | | | | | | |
1204 | node | p1 node | p2 node | base node | link node | flags |
1205 | node | p1 node | p2 node | base node | link node | flags |
1205 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1206 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1206 | | | | | | |
1207 | | | | | | |
1207 +------------------------------------------------------------------------------+
1208 +------------------------------------------------------------------------------+
1208
1209
1209 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1210 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1210 contain a series of *delta*s, densely packed (no separators). These deltas
1211 contain a series of *delta*s, densely packed (no separators). These deltas
1211 describe a diff from an existing entry (either that the recipient already
1212 describe a diff from an existing entry (either that the recipient already
1212 has, or previously specified in the bundle/changegroup). The format is
1213 has, or previously specified in the bundle/changegroup). The format is
1213 described more fully in "hg help internals.bdiff", but briefly:
1214 described more fully in "hg help internals.bdiff", but briefly:
1214
1215
1215 +---------------------------------------------------------------+
1216 +---------------------------------------------------------------+
1216 | | | | |
1217 | | | | |
1217 | start offset | end offset | new length | content |
1218 | start offset | end offset | new length | content |
1218 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1219 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1219 | | | | |
1220 | | | | |
1220 +---------------------------------------------------------------+
1221 +---------------------------------------------------------------+
1221
1222
1222 Please note that the length field in the delta data does *not* include
1223 Please note that the length field in the delta data does *not* include
1223 itself.
1224 itself.
1224
1225
1225 In version 1, the delta is always applied against the previous node from
1226 In version 1, the delta is always applied against the previous node from
1226 the changegroup or the first parent if this is the first entry in the
1227 the changegroup or the first parent if this is the first entry in the
1227 changegroup.
1228 changegroup.
1228
1229
1229 In version 2 and up, the delta base node is encoded in the entry in the
1230 In version 2 and up, the delta base node is encoded in the entry in the
1230 changegroup. This allows the delta to be expressed against any parent,
1231 changegroup. This allows the delta to be expressed against any parent,
1231 which can result in smaller deltas and more efficient encoding of data.
1232 which can result in smaller deltas and more efficient encoding of data.
1232
1233
1233 The *flags* field holds bitwise flags affecting the processing of revision
1234 The *flags* field holds bitwise flags affecting the processing of revision
1234 data. The following flags are defined:
1235 data. The following flags are defined:
1235
1236
1236 32768
1237 32768
1237 Censored revision. The revision's fulltext has been replaced by censor
1238 Censored revision. The revision's fulltext has been replaced by censor
1238 metadata. May only occur on file revisions.
1239 metadata. May only occur on file revisions.
1239
1240
1240 16384
1241 16384
1241 Ellipsis revision. Revision hash does not match data (likely due to
1242 Ellipsis revision. Revision hash does not match data (likely due to
1242 rewritten parents).
1243 rewritten parents).
1243
1244
1244 8192
1245 8192
1245 Externally stored. The revision fulltext contains "key:value" "\n"
1246 Externally stored. The revision fulltext contains "key:value" "\n"
1246 delimited metadata defining an object stored elsewhere. Used by the LFS
1247 delimited metadata defining an object stored elsewhere. Used by the LFS
1247 extension.
1248 extension.
1248
1249
1249 For historical reasons, the integer values are identical to revlog version
1250 For historical reasons, the integer values are identical to revlog version
1250 1 per-revision storage flags and correspond to bits being set in this
1251 1 per-revision storage flags and correspond to bits being set in this
1251 2-byte field. Bits were allocated starting from the most-significant bit,
1252 2-byte field. Bits were allocated starting from the most-significant bit,
1252 hence the reverse ordering and allocation of these flags.
1253 hence the reverse ordering and allocation of these flags.
1253
1254
1254 Changeset Segment
1255 Changeset Segment
1255 =================
1256 =================
1256
1257
1257 The *changeset segment* consists of a single *delta group* holding
1258 The *changeset segment* consists of a single *delta group* holding
1258 changelog data. The *empty chunk* at the end of the *delta group* denotes
1259 changelog data. The *empty chunk* at the end of the *delta group* denotes
1259 the boundary to the *manifest segment*.
1260 the boundary to the *manifest segment*.
1260
1261
1261 Manifest Segment
1262 Manifest Segment
1262 ================
1263 ================
1263
1264
1264 The *manifest segment* consists of a single *delta group* holding manifest
1265 The *manifest segment* consists of a single *delta group* holding manifest
1265 data. If treemanifests are in use, it contains only the manifest for the
1266 data. If treemanifests are in use, it contains only the manifest for the
1266 root directory of the repository. Otherwise, it contains the entire
1267 root directory of the repository. Otherwise, it contains the entire
1267 manifest data. The *empty chunk* at the end of the *delta group* denotes
1268 manifest data. The *empty chunk* at the end of the *delta group* denotes
1268 the boundary to the next segment (either the *treemanifests segment* or
1269 the boundary to the next segment (either the *treemanifests segment* or
1269 the *filelogs segment*, depending on version and the request options).
1270 the *filelogs segment*, depending on version and the request options).
1270
1271
1271 Treemanifests Segment
1272 Treemanifests Segment
1272 ---------------------
1273 ---------------------
1273
1274
1274 The *treemanifests segment* only exists in changegroup version "3", and
1275 The *treemanifests segment* only exists in changegroup version "3", and
1275 only if the 'treemanifest' param is part of the bundle2 changegroup part
1276 only if the 'treemanifest' param is part of the bundle2 changegroup part
1276 (it is not possible to use changegroup version 3 outside of bundle2).
1277 (it is not possible to use changegroup version 3 outside of bundle2).
1277 Aside from the filenames in the *treemanifests segment* containing a
1278 Aside from the filenames in the *treemanifests segment* containing a
1278 trailing "/" character, it behaves identically to the *filelogs segment*
1279 trailing "/" character, it behaves identically to the *filelogs segment*
1279 (see below). The final sub-segment is followed by an *empty chunk*
1280 (see below). The final sub-segment is followed by an *empty chunk*
1280 (logically, a sub-segment with filename size 0). This denotes the boundary
1281 (logically, a sub-segment with filename size 0). This denotes the boundary
1281 to the *filelogs segment*.
1282 to the *filelogs segment*.
1282
1283
1283 Filelogs Segment
1284 Filelogs Segment
1284 ================
1285 ================
1285
1286
1286 The *filelogs segment* consists of multiple sub-segments, each
1287 The *filelogs segment* consists of multiple sub-segments, each
1287 corresponding to an individual file whose data is being described:
1288 corresponding to an individual file whose data is being described:
1288
1289
1289 +--------------------------------------------------+
1290 +--------------------------------------------------+
1290 | | | | | |
1291 | | | | | |
1291 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1292 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1292 | | | | | (4 bytes) |
1293 | | | | | (4 bytes) |
1293 | | | | | |
1294 | | | | | |
1294 +--------------------------------------------------+
1295 +--------------------------------------------------+
1295
1296
1296 The final filelog sub-segment is followed by an *empty chunk* (logically,
1297 The final filelog sub-segment is followed by an *empty chunk* (logically,
1297 a sub-segment with filename size 0). This denotes the end of the segment
1298 a sub-segment with filename size 0). This denotes the end of the segment
1298 and of the overall changegroup.
1299 and of the overall changegroup.
1299
1300
1300 Each filelog sub-segment consists of the following:
1301 Each filelog sub-segment consists of the following:
1301
1302
1302 +------------------------------------------------------+
1303 +------------------------------------------------------+
1303 | | | |
1304 | | | |
1304 | filename length | filename | delta group |
1305 | filename length | filename | delta group |
1305 | (4 bytes) | (<length - 4> bytes) | (various) |
1306 | (4 bytes) | (<length - 4> bytes) | (various) |
1306 | | | |
1307 | | | |
1307 +------------------------------------------------------+
1308 +------------------------------------------------------+
1308
1309
1309 That is, a *chunk* consisting of the filename (not terminated or padded)
1310 That is, a *chunk* consisting of the filename (not terminated or padded)
1310 followed by N chunks constituting the *delta group* for this file. The
1311 followed by N chunks constituting the *delta group* for this file. The
1311 *empty chunk* at the end of each *delta group* denotes the boundary to the
1312 *empty chunk* at the end of each *delta group* denotes the boundary to the
1312 next filelog sub-segment.
1313 next filelog sub-segment.
1313
1314
1314 non-existent subtopics print an error
1315 non-existent subtopics print an error
1315
1316
1316 $ hg help internals.foo
1317 $ hg help internals.foo
1317 abort: no such help topic: internals.foo
1318 abort: no such help topic: internals.foo
1318 (try 'hg help --keyword foo')
1319 (try 'hg help --keyword foo')
1319 [255]
1320 [255]
1320
1321
1321 test advanced, deprecated and experimental options are hidden in command help
1322 test advanced, deprecated and experimental options are hidden in command help
1322 $ hg help debugoptADV
1323 $ hg help debugoptADV
1323 hg debugoptADV
1324 hg debugoptADV
1324
1325
1325 (no help text available)
1326 (no help text available)
1326
1327
1327 options:
1328 options:
1328
1329
1329 (some details hidden, use --verbose to show complete help)
1330 (some details hidden, use --verbose to show complete help)
1330 $ hg help debugoptDEP
1331 $ hg help debugoptDEP
1331 hg debugoptDEP
1332 hg debugoptDEP
1332
1333
1333 (no help text available)
1334 (no help text available)
1334
1335
1335 options:
1336 options:
1336
1337
1337 (some details hidden, use --verbose to show complete help)
1338 (some details hidden, use --verbose to show complete help)
1338
1339
1339 $ hg help debugoptEXP
1340 $ hg help debugoptEXP
1340 hg debugoptEXP
1341 hg debugoptEXP
1341
1342
1342 (no help text available)
1343 (no help text available)
1343
1344
1344 options:
1345 options:
1345
1346
1346 (some details hidden, use --verbose to show complete help)
1347 (some details hidden, use --verbose to show complete help)
1347
1348
1348 test advanced, deprecated and experimental options are shown with -v
1349 test advanced, deprecated and experimental options are shown with -v
1349 $ hg help -v debugoptADV | grep aopt
1350 $ hg help -v debugoptADV | grep aopt
1350 --aopt option is (ADVANCED)
1351 --aopt option is (ADVANCED)
1351 $ hg help -v debugoptDEP | grep dopt
1352 $ hg help -v debugoptDEP | grep dopt
1352 --dopt option is (DEPRECATED)
1353 --dopt option is (DEPRECATED)
1353 $ hg help -v debugoptEXP | grep eopt
1354 $ hg help -v debugoptEXP | grep eopt
1354 --eopt option is (EXPERIMENTAL)
1355 --eopt option is (EXPERIMENTAL)
1355
1356
1356 #if gettext
1357 #if gettext
1357 test deprecated option is hidden with translation with untranslated description
1358 test deprecated option is hidden with translation with untranslated description
1358 (use many globy for not failing on changed transaction)
1359 (use many globy for not failing on changed transaction)
1359 $ LANGUAGE=sv hg help debugoptDEP
1360 $ LANGUAGE=sv hg help debugoptDEP
1360 hg debugoptDEP
1361 hg debugoptDEP
1361
1362
1362 (*) (glob)
1363 (*) (glob)
1363
1364
1364 options:
1365 options:
1365
1366
1366 (some details hidden, use --verbose to show complete help)
1367 (some details hidden, use --verbose to show complete help)
1367 #endif
1368 #endif
1368
1369
1369 Test commands that collide with topics (issue4240)
1370 Test commands that collide with topics (issue4240)
1370
1371
1371 $ hg config -hq
1372 $ hg config -hq
1372 hg config [-u] [NAME]...
1373 hg config [-u] [NAME]...
1373
1374
1374 show combined config settings from all hgrc files
1375 show combined config settings from all hgrc files
1375 $ hg showconfig -hq
1376 $ hg showconfig -hq
1376 hg config [-u] [NAME]...
1377 hg config [-u] [NAME]...
1377
1378
1378 show combined config settings from all hgrc files
1379 show combined config settings from all hgrc files
1379
1380
1380 Test a help topic
1381 Test a help topic
1381
1382
1382 $ hg help dates
1383 $ hg help dates
1383 Date Formats
1384 Date Formats
1384 """"""""""""
1385 """"""""""""
1385
1386
1386 Some commands allow the user to specify a date, e.g.:
1387 Some commands allow the user to specify a date, e.g.:
1387
1388
1388 - backout, commit, import, tag: Specify the commit date.
1389 - backout, commit, import, tag: Specify the commit date.
1389 - log, revert, update: Select revision(s) by date.
1390 - log, revert, update: Select revision(s) by date.
1390
1391
1391 Many date formats are valid. Here are some examples:
1392 Many date formats are valid. Here are some examples:
1392
1393
1393 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1394 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1394 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1395 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1395 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1396 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1396 - "Dec 6" (midnight)
1397 - "Dec 6" (midnight)
1397 - "13:18" (today assumed)
1398 - "13:18" (today assumed)
1398 - "3:39" (3:39AM assumed)
1399 - "3:39" (3:39AM assumed)
1399 - "3:39pm" (15:39)
1400 - "3:39pm" (15:39)
1400 - "2006-12-06 13:18:29" (ISO 8601 format)
1401 - "2006-12-06 13:18:29" (ISO 8601 format)
1401 - "2006-12-6 13:18"
1402 - "2006-12-6 13:18"
1402 - "2006-12-6"
1403 - "2006-12-6"
1403 - "12-6"
1404 - "12-6"
1404 - "12/6"
1405 - "12/6"
1405 - "12/6/6" (Dec 6 2006)
1406 - "12/6/6" (Dec 6 2006)
1406 - "today" (midnight)
1407 - "today" (midnight)
1407 - "yesterday" (midnight)
1408 - "yesterday" (midnight)
1408 - "now" - right now
1409 - "now" - right now
1409
1410
1410 Lastly, there is Mercurial's internal format:
1411 Lastly, there is Mercurial's internal format:
1411
1412
1412 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1413 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1413
1414
1414 This is the internal representation format for dates. The first number is
1415 This is the internal representation format for dates. The first number is
1415 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1416 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1416 is the offset of the local timezone, in seconds west of UTC (negative if
1417 is the offset of the local timezone, in seconds west of UTC (negative if
1417 the timezone is east of UTC).
1418 the timezone is east of UTC).
1418
1419
1419 The log command also accepts date ranges:
1420 The log command also accepts date ranges:
1420
1421
1421 - "<DATE" - at or before a given date/time
1422 - "<DATE" - at or before a given date/time
1422 - ">DATE" - on or after a given date/time
1423 - ">DATE" - on or after a given date/time
1423 - "DATE to DATE" - a date range, inclusive
1424 - "DATE to DATE" - a date range, inclusive
1424 - "-DAYS" - within a given number of days of today
1425 - "-DAYS" - within a given number of days of today
1425
1426
1426 Test repeated config section name
1427 Test repeated config section name
1427
1428
1428 $ hg help config.host
1429 $ hg help config.host
1429 "http_proxy.host"
1430 "http_proxy.host"
1430 Host name and (optional) port of the proxy server, for example
1431 Host name and (optional) port of the proxy server, for example
1431 "myproxy:8000".
1432 "myproxy:8000".
1432
1433
1433 "smtp.host"
1434 "smtp.host"
1434 Host name of mail server, e.g. "mail.example.com".
1435 Host name of mail server, e.g. "mail.example.com".
1435
1436
1436
1437
1437 Test section name with dot
1438 Test section name with dot
1438
1439
1439 $ hg help config.ui.username
1440 $ hg help config.ui.username
1440 "ui.username"
1441 "ui.username"
1441 The committer of a changeset created when running "commit". Typically
1442 The committer of a changeset created when running "commit". Typically
1442 a person's name and email address, e.g. "Fred Widget
1443 a person's name and email address, e.g. "Fred Widget
1443 <fred@example.com>". Environment variables in the username are
1444 <fred@example.com>". Environment variables in the username are
1444 expanded.
1445 expanded.
1445
1446
1446 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1447 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1447 empty, e.g. if the system admin set "username =" in the system hgrc,
1448 empty, e.g. if the system admin set "username =" in the system hgrc,
1448 it has to be specified manually or in a different hgrc file)
1449 it has to be specified manually or in a different hgrc file)
1449
1450
1450
1451
1451 $ hg help config.annotate.git
1452 $ hg help config.annotate.git
1452 abort: help section not found: config.annotate.git
1453 abort: help section not found: config.annotate.git
1453 [255]
1454 [255]
1454
1455
1455 $ hg help config.update.check
1456 $ hg help config.update.check
1456 "commands.update.check"
1457 "commands.update.check"
1457 Determines what level of checking 'hg update' will perform before
1458 Determines what level of checking 'hg update' will perform before
1458 moving to a destination revision. Valid values are "abort", "none",
1459 moving to a destination revision. Valid values are "abort", "none",
1459 "linear", and "noconflict". "abort" always fails if the working
1460 "linear", and "noconflict". "abort" always fails if the working
1460 directory has uncommitted changes. "none" performs no checking, and
1461 directory has uncommitted changes. "none" performs no checking, and
1461 may result in a merge with uncommitted changes. "linear" allows any
1462 may result in a merge with uncommitted changes. "linear" allows any
1462 update as long as it follows a straight line in the revision history,
1463 update as long as it follows a straight line in the revision history,
1463 and may trigger a merge with uncommitted changes. "noconflict" will
1464 and may trigger a merge with uncommitted changes. "noconflict" will
1464 allow any update which would not trigger a merge with uncommitted
1465 allow any update which would not trigger a merge with uncommitted
1465 changes, if any are present. (default: "linear")
1466 changes, if any are present. (default: "linear")
1466
1467
1467
1468
1468 $ hg help config.commands.update.check
1469 $ hg help config.commands.update.check
1469 "commands.update.check"
1470 "commands.update.check"
1470 Determines what level of checking 'hg update' will perform before
1471 Determines what level of checking 'hg update' will perform before
1471 moving to a destination revision. Valid values are "abort", "none",
1472 moving to a destination revision. Valid values are "abort", "none",
1472 "linear", and "noconflict". "abort" always fails if the working
1473 "linear", and "noconflict". "abort" always fails if the working
1473 directory has uncommitted changes. "none" performs no checking, and
1474 directory has uncommitted changes. "none" performs no checking, and
1474 may result in a merge with uncommitted changes. "linear" allows any
1475 may result in a merge with uncommitted changes. "linear" allows any
1475 update as long as it follows a straight line in the revision history,
1476 update as long as it follows a straight line in the revision history,
1476 and may trigger a merge with uncommitted changes. "noconflict" will
1477 and may trigger a merge with uncommitted changes. "noconflict" will
1477 allow any update which would not trigger a merge with uncommitted
1478 allow any update which would not trigger a merge with uncommitted
1478 changes, if any are present. (default: "linear")
1479 changes, if any are present. (default: "linear")
1479
1480
1480
1481
1481 $ hg help config.ommands.update.check
1482 $ hg help config.ommands.update.check
1482 abort: help section not found: config.ommands.update.check
1483 abort: help section not found: config.ommands.update.check
1483 [255]
1484 [255]
1484
1485
1485 Unrelated trailing paragraphs shouldn't be included
1486 Unrelated trailing paragraphs shouldn't be included
1486
1487
1487 $ hg help config.extramsg | grep '^$'
1488 $ hg help config.extramsg | grep '^$'
1488
1489
1489
1490
1490 Test capitalized section name
1491 Test capitalized section name
1491
1492
1492 $ hg help scripting.HGPLAIN > /dev/null
1493 $ hg help scripting.HGPLAIN > /dev/null
1493
1494
1494 Help subsection:
1495 Help subsection:
1495
1496
1496 $ hg help config.charsets |grep "Email example:" > /dev/null
1497 $ hg help config.charsets |grep "Email example:" > /dev/null
1497 [1]
1498 [1]
1498
1499
1499 Show nested definitions
1500 Show nested definitions
1500 ("profiling.type"[break]"ls"[break]"stat"[break])
1501 ("profiling.type"[break]"ls"[break]"stat"[break])
1501
1502
1502 $ hg help config.type | egrep '^$'|wc -l
1503 $ hg help config.type | egrep '^$'|wc -l
1503 \s*3 (re)
1504 \s*3 (re)
1504
1505
1505 $ hg help config.profiling.type.ls
1506 $ hg help config.profiling.type.ls
1506 "profiling.type.ls"
1507 "profiling.type.ls"
1507 Use Python's built-in instrumenting profiler. This profiler works on
1508 Use Python's built-in instrumenting profiler. This profiler works on
1508 all platforms, but each line number it reports is the first line of
1509 all platforms, but each line number it reports is the first line of
1509 a function. This restriction makes it difficult to identify the
1510 a function. This restriction makes it difficult to identify the
1510 expensive parts of a non-trivial function.
1511 expensive parts of a non-trivial function.
1511
1512
1512
1513
1513 Separate sections from subsections
1514 Separate sections from subsections
1514
1515
1515 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1516 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1516 "format"
1517 "format"
1517 --------
1518 --------
1518
1519
1519 "usegeneraldelta"
1520 "usegeneraldelta"
1520
1521
1521 "dotencode"
1522 "dotencode"
1522
1523
1523 "usefncache"
1524 "usefncache"
1524
1525
1525 "usestore"
1526 "usestore"
1526
1527
1527 "sparse-revlog"
1528 "sparse-revlog"
1528
1529
1529 "revlog-compression"
1530 "revlog-compression"
1530
1531
1531 "bookmarks-in-store"
1532 "bookmarks-in-store"
1532
1533
1533 "profiling"
1534 "profiling"
1534 -----------
1535 -----------
1535
1536
1536 "format"
1537 "format"
1537
1538
1538 "progress"
1539 "progress"
1539 ----------
1540 ----------
1540
1541
1541 "format"
1542 "format"
1542
1543
1543
1544
1544 Last item in help config.*:
1545 Last item in help config.*:
1545
1546
1546 $ hg help config.`hg help config|grep '^ "'| \
1547 $ hg help config.`hg help config|grep '^ "'| \
1547 > tail -1|sed 's![ "]*!!g'`| \
1548 > tail -1|sed 's![ "]*!!g'`| \
1548 > grep 'hg help -c config' > /dev/null
1549 > grep 'hg help -c config' > /dev/null
1549 [1]
1550 [1]
1550
1551
1551 note to use help -c for general hg help config:
1552 note to use help -c for general hg help config:
1552
1553
1553 $ hg help config |grep 'hg help -c config' > /dev/null
1554 $ hg help config |grep 'hg help -c config' > /dev/null
1554
1555
1555 Test templating help
1556 Test templating help
1556
1557
1557 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1558 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1558 desc String. The text of the changeset description.
1559 desc String. The text of the changeset description.
1559 diffstat String. Statistics of changes with the following format:
1560 diffstat String. Statistics of changes with the following format:
1560 firstline Any text. Returns the first line of text.
1561 firstline Any text. Returns the first line of text.
1561 nonempty Any text. Returns '(none)' if the string is empty.
1562 nonempty Any text. Returns '(none)' if the string is empty.
1562
1563
1563 Test deprecated items
1564 Test deprecated items
1564
1565
1565 $ hg help -v templating | grep currentbookmark
1566 $ hg help -v templating | grep currentbookmark
1566 currentbookmark
1567 currentbookmark
1567 $ hg help templating | (grep currentbookmark || true)
1568 $ hg help templating | (grep currentbookmark || true)
1568
1569
1569 Test help hooks
1570 Test help hooks
1570
1571
1571 $ cat > helphook1.py <<EOF
1572 $ cat > helphook1.py <<EOF
1572 > from mercurial import help
1573 > from mercurial import help
1573 >
1574 >
1574 > def rewrite(ui, topic, doc):
1575 > def rewrite(ui, topic, doc):
1575 > return doc + b'\nhelphook1\n'
1576 > return doc + b'\nhelphook1\n'
1576 >
1577 >
1577 > def extsetup(ui):
1578 > def extsetup(ui):
1578 > help.addtopichook(b'revisions', rewrite)
1579 > help.addtopichook(b'revisions', rewrite)
1579 > EOF
1580 > EOF
1580 $ cat > helphook2.py <<EOF
1581 $ cat > helphook2.py <<EOF
1581 > from mercurial import help
1582 > from mercurial import help
1582 >
1583 >
1583 > def rewrite(ui, topic, doc):
1584 > def rewrite(ui, topic, doc):
1584 > return doc + b'\nhelphook2\n'
1585 > return doc + b'\nhelphook2\n'
1585 >
1586 >
1586 > def extsetup(ui):
1587 > def extsetup(ui):
1587 > help.addtopichook(b'revisions', rewrite)
1588 > help.addtopichook(b'revisions', rewrite)
1588 > EOF
1589 > EOF
1589 $ echo '[extensions]' >> $HGRCPATH
1590 $ echo '[extensions]' >> $HGRCPATH
1590 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1591 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1591 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1592 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1592 $ hg help revsets | grep helphook
1593 $ hg help revsets | grep helphook
1593 helphook1
1594 helphook1
1594 helphook2
1595 helphook2
1595
1596
1596 help -c should only show debug --debug
1597 help -c should only show debug --debug
1597
1598
1598 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1599 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1599 [1]
1600 [1]
1600
1601
1601 help -c should only show deprecated for -v
1602 help -c should only show deprecated for -v
1602
1603
1603 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1604 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1604 [1]
1605 [1]
1605
1606
1606 Test -s / --system
1607 Test -s / --system
1607
1608
1608 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1609 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1609 > wc -l | sed -e 's/ //g'
1610 > wc -l | sed -e 's/ //g'
1610 0
1611 0
1611 $ hg help config.files --system unix | grep 'USER' | \
1612 $ hg help config.files --system unix | grep 'USER' | \
1612 > wc -l | sed -e 's/ //g'
1613 > wc -l | sed -e 's/ //g'
1613 0
1614 0
1614
1615
1615 Test -e / -c / -k combinations
1616 Test -e / -c / -k combinations
1616
1617
1617 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1618 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1618 Commands:
1619 Commands:
1619 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1620 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1620 Extensions:
1621 Extensions:
1621 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1622 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1622 Topics:
1623 Topics:
1623 Commands:
1624 Commands:
1624 Extensions:
1625 Extensions:
1625 Extension Commands:
1626 Extension Commands:
1626 $ hg help -c schemes
1627 $ hg help -c schemes
1627 abort: no such help topic: schemes
1628 abort: no such help topic: schemes
1628 (try 'hg help --keyword schemes')
1629 (try 'hg help --keyword schemes')
1629 [255]
1630 [255]
1630 $ hg help -e schemes |head -1
1631 $ hg help -e schemes |head -1
1631 schemes extension - extend schemes with shortcuts to repository swarms
1632 schemes extension - extend schemes with shortcuts to repository swarms
1632 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1633 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1633 Commands:
1634 Commands:
1634 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1635 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1635 Extensions:
1636 Extensions:
1636 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1637 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1637 Extensions:
1638 Extensions:
1638 Commands:
1639 Commands:
1639 $ hg help -c commit > /dev/null
1640 $ hg help -c commit > /dev/null
1640 $ hg help -e -c commit > /dev/null
1641 $ hg help -e -c commit > /dev/null
1641 $ hg help -e commit
1642 $ hg help -e commit
1642 abort: no such help topic: commit
1643 abort: no such help topic: commit
1643 (try 'hg help --keyword commit')
1644 (try 'hg help --keyword commit')
1644 [255]
1645 [255]
1645
1646
1646 Test keyword search help
1647 Test keyword search help
1647
1648
1648 $ cat > prefixedname.py <<EOF
1649 $ cat > prefixedname.py <<EOF
1649 > '''matched against word "clone"
1650 > '''matched against word "clone"
1650 > '''
1651 > '''
1651 > EOF
1652 > EOF
1652 $ echo '[extensions]' >> $HGRCPATH
1653 $ echo '[extensions]' >> $HGRCPATH
1653 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1654 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1654 $ hg help -k clone
1655 $ hg help -k clone
1655 Topics:
1656 Topics:
1656
1657
1657 config Configuration Files
1658 config Configuration Files
1658 extensions Using Additional Features
1659 extensions Using Additional Features
1659 glossary Glossary
1660 glossary Glossary
1660 phases Working with Phases
1661 phases Working with Phases
1661 subrepos Subrepositories
1662 subrepos Subrepositories
1662 urls URL Paths
1663 urls URL Paths
1663
1664
1664 Commands:
1665 Commands:
1665
1666
1666 bookmarks create a new bookmark or list existing bookmarks
1667 bookmarks create a new bookmark or list existing bookmarks
1667 clone make a copy of an existing repository
1668 clone make a copy of an existing repository
1668 paths show aliases for remote repositories
1669 paths show aliases for remote repositories
1669 pull pull changes from the specified source
1670 pull pull changes from the specified source
1670 update update working directory (or switch revisions)
1671 update update working directory (or switch revisions)
1671
1672
1672 Extensions:
1673 Extensions:
1673
1674
1674 clonebundles advertise pre-generated bundles to seed clones
1675 clonebundles advertise pre-generated bundles to seed clones
1675 narrow create clones which fetch history data for subset of files
1676 narrow create clones which fetch history data for subset of files
1676 (EXPERIMENTAL)
1677 (EXPERIMENTAL)
1677 prefixedname matched against word "clone"
1678 prefixedname matched against word "clone"
1678 relink recreates hardlinks between repository clones
1679 relink recreates hardlinks between repository clones
1679
1680
1680 Extension Commands:
1681 Extension Commands:
1681
1682
1682 qclone clone main and patch repository at same time
1683 qclone clone main and patch repository at same time
1683
1684
1684 Test unfound topic
1685 Test unfound topic
1685
1686
1686 $ hg help nonexistingtopicthatwillneverexisteverever
1687 $ hg help nonexistingtopicthatwillneverexisteverever
1687 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1688 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1688 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1689 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1689 [255]
1690 [255]
1690
1691
1691 Test unfound keyword
1692 Test unfound keyword
1692
1693
1693 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1694 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1694 abort: no matches
1695 abort: no matches
1695 (try 'hg help' for a list of topics)
1696 (try 'hg help' for a list of topics)
1696 [255]
1697 [255]
1697
1698
1698 Test omit indicating for help
1699 Test omit indicating for help
1699
1700
1700 $ cat > addverboseitems.py <<EOF
1701 $ cat > addverboseitems.py <<EOF
1701 > r'''extension to test omit indicating.
1702 > r'''extension to test omit indicating.
1702 >
1703 >
1703 > This paragraph is never omitted (for extension)
1704 > This paragraph is never omitted (for extension)
1704 >
1705 >
1705 > .. container:: verbose
1706 > .. container:: verbose
1706 >
1707 >
1707 > This paragraph is omitted,
1708 > This paragraph is omitted,
1708 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1709 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1709 >
1710 >
1710 > This paragraph is never omitted, too (for extension)
1711 > This paragraph is never omitted, too (for extension)
1711 > '''
1712 > '''
1712 > from __future__ import absolute_import
1713 > from __future__ import absolute_import
1713 > from mercurial import commands, help
1714 > from mercurial import commands, help
1714 > testtopic = br"""This paragraph is never omitted (for topic).
1715 > testtopic = br"""This paragraph is never omitted (for topic).
1715 >
1716 >
1716 > .. container:: verbose
1717 > .. container:: verbose
1717 >
1718 >
1718 > This paragraph is omitted,
1719 > This paragraph is omitted,
1719 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1720 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1720 >
1721 >
1721 > This paragraph is never omitted, too (for topic)
1722 > This paragraph is never omitted, too (for topic)
1722 > """
1723 > """
1723 > def extsetup(ui):
1724 > def extsetup(ui):
1724 > help.helptable.append(([b"topic-containing-verbose"],
1725 > help.helptable.append(([b"topic-containing-verbose"],
1725 > b"This is the topic to test omit indicating.",
1726 > b"This is the topic to test omit indicating.",
1726 > lambda ui: testtopic))
1727 > lambda ui: testtopic))
1727 > EOF
1728 > EOF
1728 $ echo '[extensions]' >> $HGRCPATH
1729 $ echo '[extensions]' >> $HGRCPATH
1729 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1730 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1730 $ hg help addverboseitems
1731 $ hg help addverboseitems
1731 addverboseitems extension - extension to test omit indicating.
1732 addverboseitems extension - extension to test omit indicating.
1732
1733
1733 This paragraph is never omitted (for extension)
1734 This paragraph is never omitted (for extension)
1734
1735
1735 This paragraph is never omitted, too (for extension)
1736 This paragraph is never omitted, too (for extension)
1736
1737
1737 (some details hidden, use --verbose to show complete help)
1738 (some details hidden, use --verbose to show complete help)
1738
1739
1739 no commands defined
1740 no commands defined
1740 $ hg help -v addverboseitems
1741 $ hg help -v addverboseitems
1741 addverboseitems extension - extension to test omit indicating.
1742 addverboseitems extension - extension to test omit indicating.
1742
1743
1743 This paragraph is never omitted (for extension)
1744 This paragraph is never omitted (for extension)
1744
1745
1745 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1746 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1746 extension)
1747 extension)
1747
1748
1748 This paragraph is never omitted, too (for extension)
1749 This paragraph is never omitted, too (for extension)
1749
1750
1750 no commands defined
1751 no commands defined
1751 $ hg help topic-containing-verbose
1752 $ hg help topic-containing-verbose
1752 This is the topic to test omit indicating.
1753 This is the topic to test omit indicating.
1753 """"""""""""""""""""""""""""""""""""""""""
1754 """"""""""""""""""""""""""""""""""""""""""
1754
1755
1755 This paragraph is never omitted (for topic).
1756 This paragraph is never omitted (for topic).
1756
1757
1757 This paragraph is never omitted, too (for topic)
1758 This paragraph is never omitted, too (for topic)
1758
1759
1759 (some details hidden, use --verbose to show complete help)
1760 (some details hidden, use --verbose to show complete help)
1760 $ hg help -v topic-containing-verbose
1761 $ hg help -v topic-containing-verbose
1761 This is the topic to test omit indicating.
1762 This is the topic to test omit indicating.
1762 """"""""""""""""""""""""""""""""""""""""""
1763 """"""""""""""""""""""""""""""""""""""""""
1763
1764
1764 This paragraph is never omitted (for topic).
1765 This paragraph is never omitted (for topic).
1765
1766
1766 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1767 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1767 topic)
1768 topic)
1768
1769
1769 This paragraph is never omitted, too (for topic)
1770 This paragraph is never omitted, too (for topic)
1770
1771
1771 Test section lookup
1772 Test section lookup
1772
1773
1773 $ hg help revset.merge
1774 $ hg help revset.merge
1774 "merge()"
1775 "merge()"
1775 Changeset is a merge changeset.
1776 Changeset is a merge changeset.
1776
1777
1777 $ hg help glossary.dag
1778 $ hg help glossary.dag
1778 DAG
1779 DAG
1779 The repository of changesets of a distributed version control system
1780 The repository of changesets of a distributed version control system
1780 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1781 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1781 of nodes and edges, where nodes correspond to changesets and edges
1782 of nodes and edges, where nodes correspond to changesets and edges
1782 imply a parent -> child relation. This graph can be visualized by
1783 imply a parent -> child relation. This graph can be visualized by
1783 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1784 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1784 limited by the requirement for children to have at most two parents.
1785 limited by the requirement for children to have at most two parents.
1785
1786
1786
1787
1787 $ hg help hgrc.paths
1788 $ hg help hgrc.paths
1788 "paths"
1789 "paths"
1789 -------
1790 -------
1790
1791
1791 Assigns symbolic names and behavior to repositories.
1792 Assigns symbolic names and behavior to repositories.
1792
1793
1793 Options are symbolic names defining the URL or directory that is the
1794 Options are symbolic names defining the URL or directory that is the
1794 location of the repository. Example:
1795 location of the repository. Example:
1795
1796
1796 [paths]
1797 [paths]
1797 my_server = https://example.com/my_repo
1798 my_server = https://example.com/my_repo
1798 local_path = /home/me/repo
1799 local_path = /home/me/repo
1799
1800
1800 These symbolic names can be used from the command line. To pull from
1801 These symbolic names can be used from the command line. To pull from
1801 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1802 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1802 local_path'.
1803 local_path'.
1803
1804
1804 Options containing colons (":") denote sub-options that can influence
1805 Options containing colons (":") denote sub-options that can influence
1805 behavior for that specific path. Example:
1806 behavior for that specific path. Example:
1806
1807
1807 [paths]
1808 [paths]
1808 my_server = https://example.com/my_path
1809 my_server = https://example.com/my_path
1809 my_server:pushurl = ssh://example.com/my_path
1810 my_server:pushurl = ssh://example.com/my_path
1810
1811
1811 The following sub-options can be defined:
1812 The following sub-options can be defined:
1812
1813
1813 "pushurl"
1814 "pushurl"
1814 The URL to use for push operations. If not defined, the location
1815 The URL to use for push operations. If not defined, the location
1815 defined by the path's main entry is used.
1816 defined by the path's main entry is used.
1816
1817
1817 "pushrev"
1818 "pushrev"
1818 A revset defining which revisions to push by default.
1819 A revset defining which revisions to push by default.
1819
1820
1820 When 'hg push' is executed without a "-r" argument, the revset defined
1821 When 'hg push' is executed without a "-r" argument, the revset defined
1821 by this sub-option is evaluated to determine what to push.
1822 by this sub-option is evaluated to determine what to push.
1822
1823
1823 For example, a value of "." will push the working directory's revision
1824 For example, a value of "." will push the working directory's revision
1824 by default.
1825 by default.
1825
1826
1826 Revsets specifying bookmarks will not result in the bookmark being
1827 Revsets specifying bookmarks will not result in the bookmark being
1827 pushed.
1828 pushed.
1828
1829
1829 The following special named paths exist:
1830 The following special named paths exist:
1830
1831
1831 "default"
1832 "default"
1832 The URL or directory to use when no source or remote is specified.
1833 The URL or directory to use when no source or remote is specified.
1833
1834
1834 'hg clone' will automatically define this path to the location the
1835 'hg clone' will automatically define this path to the location the
1835 repository was cloned from.
1836 repository was cloned from.
1836
1837
1837 "default-push"
1838 "default-push"
1838 (deprecated) The URL or directory for the default 'hg push' location.
1839 (deprecated) The URL or directory for the default 'hg push' location.
1839 "default:pushurl" should be used instead.
1840 "default:pushurl" should be used instead.
1840
1841
1841 $ hg help glossary.mcguffin
1842 $ hg help glossary.mcguffin
1842 abort: help section not found: glossary.mcguffin
1843 abort: help section not found: glossary.mcguffin
1843 [255]
1844 [255]
1844
1845
1845 $ hg help glossary.mc.guffin
1846 $ hg help glossary.mc.guffin
1846 abort: help section not found: glossary.mc.guffin
1847 abort: help section not found: glossary.mc.guffin
1847 [255]
1848 [255]
1848
1849
1849 $ hg help template.files
1850 $ hg help template.files
1850 files List of strings. All files modified, added, or removed by
1851 files List of strings. All files modified, added, or removed by
1851 this changeset.
1852 this changeset.
1852 files(pattern)
1853 files(pattern)
1853 All files of the current changeset matching the pattern. See
1854 All files of the current changeset matching the pattern. See
1854 'hg help patterns'.
1855 'hg help patterns'.
1855
1856
1856 Test section lookup by translated message
1857 Test section lookup by translated message
1857
1858
1858 str.lower() instead of encoding.lower(str) on translated message might
1859 str.lower() instead of encoding.lower(str) on translated message might
1859 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1860 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1860 as the second or later byte of multi-byte character.
1861 as the second or later byte of multi-byte character.
1861
1862
1862 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1863 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1863 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1864 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1864 replacement makes message meaningless.
1865 replacement makes message meaningless.
1865
1866
1866 This tests that section lookup by translated string isn't broken by
1867 This tests that section lookup by translated string isn't broken by
1867 such str.lower().
1868 such str.lower().
1868
1869
1869 $ "$PYTHON" <<EOF
1870 $ "$PYTHON" <<EOF
1870 > def escape(s):
1871 > def escape(s):
1871 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1872 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1872 > # translation of "record" in ja_JP.cp932
1873 > # translation of "record" in ja_JP.cp932
1873 > upper = b"\x8bL\x98^"
1874 > upper = b"\x8bL\x98^"
1874 > # str.lower()-ed section name should be treated as different one
1875 > # str.lower()-ed section name should be treated as different one
1875 > lower = b"\x8bl\x98^"
1876 > lower = b"\x8bl\x98^"
1876 > with open('ambiguous.py', 'wb') as fp:
1877 > with open('ambiguous.py', 'wb') as fp:
1877 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1878 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1878 > u'''summary of extension
1879 > u'''summary of extension
1879 >
1880 >
1880 > %s
1881 > %s
1881 > ----
1882 > ----
1882 >
1883 >
1883 > Upper name should show only this message
1884 > Upper name should show only this message
1884 >
1885 >
1885 > %s
1886 > %s
1886 > ----
1887 > ----
1887 >
1888 >
1888 > Lower name should show only this message
1889 > Lower name should show only this message
1889 >
1890 >
1890 > subsequent section
1891 > subsequent section
1891 > ------------------
1892 > ------------------
1892 >
1893 >
1893 > This should be hidden at 'hg help ambiguous' with section name.
1894 > This should be hidden at 'hg help ambiguous' with section name.
1894 > '''
1895 > '''
1895 > """ % (escape(upper), escape(lower)))
1896 > """ % (escape(upper), escape(lower)))
1896 > EOF
1897 > EOF
1897
1898
1898 $ cat >> $HGRCPATH <<EOF
1899 $ cat >> $HGRCPATH <<EOF
1899 > [extensions]
1900 > [extensions]
1900 > ambiguous = ./ambiguous.py
1901 > ambiguous = ./ambiguous.py
1901 > EOF
1902 > EOF
1902
1903
1903 $ "$PYTHON" <<EOF | sh
1904 $ "$PYTHON" <<EOF | sh
1904 > from mercurial import pycompat
1905 > from mercurial import pycompat
1905 > upper = b"\x8bL\x98^"
1906 > upper = b"\x8bL\x98^"
1906 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1907 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1907 > EOF
1908 > EOF
1908 \x8bL\x98^ (esc)
1909 \x8bL\x98^ (esc)
1909 ----
1910 ----
1910
1911
1911 Upper name should show only this message
1912 Upper name should show only this message
1912
1913
1913
1914
1914 $ "$PYTHON" <<EOF | sh
1915 $ "$PYTHON" <<EOF | sh
1915 > from mercurial import pycompat
1916 > from mercurial import pycompat
1916 > lower = b"\x8bl\x98^"
1917 > lower = b"\x8bl\x98^"
1917 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1918 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1918 > EOF
1919 > EOF
1919 \x8bl\x98^ (esc)
1920 \x8bl\x98^ (esc)
1920 ----
1921 ----
1921
1922
1922 Lower name should show only this message
1923 Lower name should show only this message
1923
1924
1924
1925
1925 $ cat >> $HGRCPATH <<EOF
1926 $ cat >> $HGRCPATH <<EOF
1926 > [extensions]
1927 > [extensions]
1927 > ambiguous = !
1928 > ambiguous = !
1928 > EOF
1929 > EOF
1929
1930
1930 Show help content of disabled extensions
1931 Show help content of disabled extensions
1931
1932
1932 $ cat >> $HGRCPATH <<EOF
1933 $ cat >> $HGRCPATH <<EOF
1933 > [extensions]
1934 > [extensions]
1934 > ambiguous = !./ambiguous.py
1935 > ambiguous = !./ambiguous.py
1935 > EOF
1936 > EOF
1936 $ hg help -e ambiguous
1937 $ hg help -e ambiguous
1937 ambiguous extension - (no help text available)
1938 ambiguous extension - (no help text available)
1938
1939
1939 (use 'hg help extensions' for information on enabling extensions)
1940 (use 'hg help extensions' for information on enabling extensions)
1940
1941
1941 Test dynamic list of merge tools only shows up once
1942 Test dynamic list of merge tools only shows up once
1942 $ hg help merge-tools
1943 $ hg help merge-tools
1943 Merge Tools
1944 Merge Tools
1944 """""""""""
1945 """""""""""
1945
1946
1946 To merge files Mercurial uses merge tools.
1947 To merge files Mercurial uses merge tools.
1947
1948
1948 A merge tool combines two different versions of a file into a merged file.
1949 A merge tool combines two different versions of a file into a merged file.
1949 Merge tools are given the two files and the greatest common ancestor of
1950 Merge tools are given the two files and the greatest common ancestor of
1950 the two file versions, so they can determine the changes made on both
1951 the two file versions, so they can determine the changes made on both
1951 branches.
1952 branches.
1952
1953
1953 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1954 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1954 backout' and in several extensions.
1955 backout' and in several extensions.
1955
1956
1956 Usually, the merge tool tries to automatically reconcile the files by
1957 Usually, the merge tool tries to automatically reconcile the files by
1957 combining all non-overlapping changes that occurred separately in the two
1958 combining all non-overlapping changes that occurred separately in the two
1958 different evolutions of the same initial base file. Furthermore, some
1959 different evolutions of the same initial base file. Furthermore, some
1959 interactive merge programs make it easier to manually resolve conflicting
1960 interactive merge programs make it easier to manually resolve conflicting
1960 merges, either in a graphical way, or by inserting some conflict markers.
1961 merges, either in a graphical way, or by inserting some conflict markers.
1961 Mercurial does not include any interactive merge programs but relies on
1962 Mercurial does not include any interactive merge programs but relies on
1962 external tools for that.
1963 external tools for that.
1963
1964
1964 Available merge tools
1965 Available merge tools
1965 =====================
1966 =====================
1966
1967
1967 External merge tools and their properties are configured in the merge-
1968 External merge tools and their properties are configured in the merge-
1968 tools configuration section - see hgrc(5) - but they can often just be
1969 tools configuration section - see hgrc(5) - but they can often just be
1969 named by their executable.
1970 named by their executable.
1970
1971
1971 A merge tool is generally usable if its executable can be found on the
1972 A merge tool is generally usable if its executable can be found on the
1972 system and if it can handle the merge. The executable is found if it is an
1973 system and if it can handle the merge. The executable is found if it is an
1973 absolute or relative executable path or the name of an application in the
1974 absolute or relative executable path or the name of an application in the
1974 executable search path. The tool is assumed to be able to handle the merge
1975 executable search path. The tool is assumed to be able to handle the merge
1975 if it can handle symlinks if the file is a symlink, if it can handle
1976 if it can handle symlinks if the file is a symlink, if it can handle
1976 binary files if the file is binary, and if a GUI is available if the tool
1977 binary files if the file is binary, and if a GUI is available if the tool
1977 requires a GUI.
1978 requires a GUI.
1978
1979
1979 There are some internal merge tools which can be used. The internal merge
1980 There are some internal merge tools which can be used. The internal merge
1980 tools are:
1981 tools are:
1981
1982
1982 ":dump"
1983 ":dump"
1983 Creates three versions of the files to merge, containing the contents of
1984 Creates three versions of the files to merge, containing the contents of
1984 local, other and base. These files can then be used to perform a merge
1985 local, other and base. These files can then be used to perform a merge
1985 manually. If the file to be merged is named "a.txt", these files will
1986 manually. If the file to be merged is named "a.txt", these files will
1986 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1987 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1987 they will be placed in the same directory as "a.txt".
1988 they will be placed in the same directory as "a.txt".
1988
1989
1989 This implies premerge. Therefore, files aren't dumped, if premerge runs
1990 This implies premerge. Therefore, files aren't dumped, if premerge runs
1990 successfully. Use :forcedump to forcibly write files out.
1991 successfully. Use :forcedump to forcibly write files out.
1991
1992
1992 (actual capabilities: binary, symlink)
1993 (actual capabilities: binary, symlink)
1993
1994
1994 ":fail"
1995 ":fail"
1995 Rather than attempting to merge files that were modified on both
1996 Rather than attempting to merge files that were modified on both
1996 branches, it marks them as unresolved. The resolve command must be used
1997 branches, it marks them as unresolved. The resolve command must be used
1997 to resolve these conflicts.
1998 to resolve these conflicts.
1998
1999
1999 (actual capabilities: binary, symlink)
2000 (actual capabilities: binary, symlink)
2000
2001
2001 ":forcedump"
2002 ":forcedump"
2002 Creates three versions of the files as same as :dump, but omits
2003 Creates three versions of the files as same as :dump, but omits
2003 premerge.
2004 premerge.
2004
2005
2005 (actual capabilities: binary, symlink)
2006 (actual capabilities: binary, symlink)
2006
2007
2007 ":local"
2008 ":local"
2008 Uses the local 'p1()' version of files as the merged version.
2009 Uses the local 'p1()' version of files as the merged version.
2009
2010
2010 (actual capabilities: binary, symlink)
2011 (actual capabilities: binary, symlink)
2011
2012
2012 ":merge"
2013 ":merge"
2013 Uses the internal non-interactive simple merge algorithm for merging
2014 Uses the internal non-interactive simple merge algorithm for merging
2014 files. It will fail if there are any conflicts and leave markers in the
2015 files. It will fail if there are any conflicts and leave markers in the
2015 partially merged file. Markers will have two sections, one for each side
2016 partially merged file. Markers will have two sections, one for each side
2016 of merge.
2017 of merge.
2017
2018
2018 ":merge-local"
2019 ":merge-local"
2019 Like :merge, but resolve all conflicts non-interactively in favor of the
2020 Like :merge, but resolve all conflicts non-interactively in favor of the
2020 local 'p1()' changes.
2021 local 'p1()' changes.
2021
2022
2022 ":merge-other"
2023 ":merge-other"
2023 Like :merge, but resolve all conflicts non-interactively in favor of the
2024 Like :merge, but resolve all conflicts non-interactively in favor of the
2024 other 'p2()' changes.
2025 other 'p2()' changes.
2025
2026
2026 ":merge3"
2027 ":merge3"
2027 Uses the internal non-interactive simple merge algorithm for merging
2028 Uses the internal non-interactive simple merge algorithm for merging
2028 files. It will fail if there are any conflicts and leave markers in the
2029 files. It will fail if there are any conflicts and leave markers in the
2029 partially merged file. Marker will have three sections, one from each
2030 partially merged file. Marker will have three sections, one from each
2030 side of the merge and one for the base content.
2031 side of the merge and one for the base content.
2031
2032
2032 ":other"
2033 ":other"
2033 Uses the other 'p2()' version of files as the merged version.
2034 Uses the other 'p2()' version of files as the merged version.
2034
2035
2035 (actual capabilities: binary, symlink)
2036 (actual capabilities: binary, symlink)
2036
2037
2037 ":prompt"
2038 ":prompt"
2038 Asks the user which of the local 'p1()' or the other 'p2()' version to
2039 Asks the user which of the local 'p1()' or the other 'p2()' version to
2039 keep as the merged version.
2040 keep as the merged version.
2040
2041
2041 (actual capabilities: binary, symlink)
2042 (actual capabilities: binary, symlink)
2042
2043
2043 ":tagmerge"
2044 ":tagmerge"
2044 Uses the internal tag merge algorithm (experimental).
2045 Uses the internal tag merge algorithm (experimental).
2045
2046
2046 ":union"
2047 ":union"
2047 Uses the internal non-interactive simple merge algorithm for merging
2048 Uses the internal non-interactive simple merge algorithm for merging
2048 files. It will use both left and right sides for conflict regions. No
2049 files. It will use both left and right sides for conflict regions. No
2049 markers are inserted.
2050 markers are inserted.
2050
2051
2051 Internal tools are always available and do not require a GUI but will by
2052 Internal tools are always available and do not require a GUI but will by
2052 default not handle symlinks or binary files. See next section for detail
2053 default not handle symlinks or binary files. See next section for detail
2053 about "actual capabilities" described above.
2054 about "actual capabilities" described above.
2054
2055
2055 Choosing a merge tool
2056 Choosing a merge tool
2056 =====================
2057 =====================
2057
2058
2058 Mercurial uses these rules when deciding which merge tool to use:
2059 Mercurial uses these rules when deciding which merge tool to use:
2059
2060
2060 1. If a tool has been specified with the --tool option to merge or
2061 1. If a tool has been specified with the --tool option to merge or
2061 resolve, it is used. If it is the name of a tool in the merge-tools
2062 resolve, it is used. If it is the name of a tool in the merge-tools
2062 configuration, its configuration is used. Otherwise the specified tool
2063 configuration, its configuration is used. Otherwise the specified tool
2063 must be executable by the shell.
2064 must be executable by the shell.
2064 2. If the "HGMERGE" environment variable is present, its value is used and
2065 2. If the "HGMERGE" environment variable is present, its value is used and
2065 must be executable by the shell.
2066 must be executable by the shell.
2066 3. If the filename of the file to be merged matches any of the patterns in
2067 3. If the filename of the file to be merged matches any of the patterns in
2067 the merge-patterns configuration section, the first usable merge tool
2068 the merge-patterns configuration section, the first usable merge tool
2068 corresponding to a matching pattern is used.
2069 corresponding to a matching pattern is used.
2069 4. If ui.merge is set it will be considered next. If the value is not the
2070 4. If ui.merge is set it will be considered next. If the value is not the
2070 name of a configured tool, the specified value is used and must be
2071 name of a configured tool, the specified value is used and must be
2071 executable by the shell. Otherwise the named tool is used if it is
2072 executable by the shell. Otherwise the named tool is used if it is
2072 usable.
2073 usable.
2073 5. If any usable merge tools are present in the merge-tools configuration
2074 5. If any usable merge tools are present in the merge-tools configuration
2074 section, the one with the highest priority is used.
2075 section, the one with the highest priority is used.
2075 6. If a program named "hgmerge" can be found on the system, it is used -
2076 6. If a program named "hgmerge" can be found on the system, it is used -
2076 but it will by default not be used for symlinks and binary files.
2077 but it will by default not be used for symlinks and binary files.
2077 7. If the file to be merged is not binary and is not a symlink, then
2078 7. If the file to be merged is not binary and is not a symlink, then
2078 internal ":merge" is used.
2079 internal ":merge" is used.
2079 8. Otherwise, ":prompt" is used.
2080 8. Otherwise, ":prompt" is used.
2080
2081
2081 For historical reason, Mercurial treats merge tools as below while
2082 For historical reason, Mercurial treats merge tools as below while
2082 examining rules above.
2083 examining rules above.
2083
2084
2084 step specified via binary symlink
2085 step specified via binary symlink
2085 ----------------------------------
2086 ----------------------------------
2086 1. --tool o/o o/o
2087 1. --tool o/o o/o
2087 2. HGMERGE o/o o/o
2088 2. HGMERGE o/o o/o
2088 3. merge-patterns o/o(*) x/?(*)
2089 3. merge-patterns o/o(*) x/?(*)
2089 4. ui.merge x/?(*) x/?(*)
2090 4. ui.merge x/?(*) x/?(*)
2090
2091
2091 Each capability column indicates Mercurial behavior for internal/external
2092 Each capability column indicates Mercurial behavior for internal/external
2092 merge tools at examining each rule.
2093 merge tools at examining each rule.
2093
2094
2094 - "o": "assume that a tool has capability"
2095 - "o": "assume that a tool has capability"
2095 - "x": "assume that a tool does not have capability"
2096 - "x": "assume that a tool does not have capability"
2096 - "?": "check actual capability of a tool"
2097 - "?": "check actual capability of a tool"
2097
2098
2098 If "merge.strict-capability-check" configuration is true, Mercurial checks
2099 If "merge.strict-capability-check" configuration is true, Mercurial checks
2099 capabilities of merge tools strictly in (*) cases above (= each capability
2100 capabilities of merge tools strictly in (*) cases above (= each capability
2100 column becomes "?/?"). It is false by default for backward compatibility.
2101 column becomes "?/?"). It is false by default for backward compatibility.
2101
2102
2102 Note:
2103 Note:
2103 After selecting a merge program, Mercurial will by default attempt to
2104 After selecting a merge program, Mercurial will by default attempt to
2104 merge the files using a simple merge algorithm first. Only if it
2105 merge the files using a simple merge algorithm first. Only if it
2105 doesn't succeed because of conflicting changes will Mercurial actually
2106 doesn't succeed because of conflicting changes will Mercurial actually
2106 execute the merge program. Whether to use the simple merge algorithm
2107 execute the merge program. Whether to use the simple merge algorithm
2107 first can be controlled by the premerge setting of the merge tool.
2108 first can be controlled by the premerge setting of the merge tool.
2108 Premerge is enabled by default unless the file is binary or a symlink.
2109 Premerge is enabled by default unless the file is binary or a symlink.
2109
2110
2110 See the merge-tools and ui sections of hgrc(5) for details on the
2111 See the merge-tools and ui sections of hgrc(5) for details on the
2111 configuration of merge tools.
2112 configuration of merge tools.
2112
2113
2113 Compression engines listed in `hg help bundlespec`
2114 Compression engines listed in `hg help bundlespec`
2114
2115
2115 $ hg help bundlespec | grep gzip
2116 $ hg help bundlespec | grep gzip
2116 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2117 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2117 An algorithm that produces smaller bundles than "gzip".
2118 An algorithm that produces smaller bundles than "gzip".
2118 This engine will likely produce smaller bundles than "gzip" but will be
2119 This engine will likely produce smaller bundles than "gzip" but will be
2119 "gzip"
2120 "gzip"
2120 better compression than "gzip". It also frequently yields better (?)
2121 better compression than "gzip". It also frequently yields better (?)
2121
2122
2122 Test usage of section marks in help documents
2123 Test usage of section marks in help documents
2123
2124
2124 $ cd "$TESTDIR"/../doc
2125 $ cd "$TESTDIR"/../doc
2125 $ "$PYTHON" check-seclevel.py
2126 $ "$PYTHON" check-seclevel.py
2126 $ cd $TESTTMP
2127 $ cd $TESTTMP
2127
2128
2128 #if serve
2129 #if serve
2129
2130
2130 Test the help pages in hgweb.
2131 Test the help pages in hgweb.
2131
2132
2132 Dish up an empty repo; serve it cold.
2133 Dish up an empty repo; serve it cold.
2133
2134
2134 $ hg init "$TESTTMP/test"
2135 $ hg init "$TESTTMP/test"
2135 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2136 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2136 $ cat hg.pid >> $DAEMON_PIDS
2137 $ cat hg.pid >> $DAEMON_PIDS
2137
2138
2138 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2139 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2139 200 Script output follows
2140 200 Script output follows
2140
2141
2141 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2142 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2142 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2143 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2143 <head>
2144 <head>
2144 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2145 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2145 <meta name="robots" content="index, nofollow" />
2146 <meta name="robots" content="index, nofollow" />
2146 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2147 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2147 <script type="text/javascript" src="/static/mercurial.js"></script>
2148 <script type="text/javascript" src="/static/mercurial.js"></script>
2148
2149
2149 <title>Help: Index</title>
2150 <title>Help: Index</title>
2150 </head>
2151 </head>
2151 <body>
2152 <body>
2152
2153
2153 <div class="container">
2154 <div class="container">
2154 <div class="menu">
2155 <div class="menu">
2155 <div class="logo">
2156 <div class="logo">
2156 <a href="https://mercurial-scm.org/">
2157 <a href="https://mercurial-scm.org/">
2157 <img src="/static/hglogo.png" alt="mercurial" /></a>
2158 <img src="/static/hglogo.png" alt="mercurial" /></a>
2158 </div>
2159 </div>
2159 <ul>
2160 <ul>
2160 <li><a href="/shortlog">log</a></li>
2161 <li><a href="/shortlog">log</a></li>
2161 <li><a href="/graph">graph</a></li>
2162 <li><a href="/graph">graph</a></li>
2162 <li><a href="/tags">tags</a></li>
2163 <li><a href="/tags">tags</a></li>
2163 <li><a href="/bookmarks">bookmarks</a></li>
2164 <li><a href="/bookmarks">bookmarks</a></li>
2164 <li><a href="/branches">branches</a></li>
2165 <li><a href="/branches">branches</a></li>
2165 </ul>
2166 </ul>
2166 <ul>
2167 <ul>
2167 <li class="active">help</li>
2168 <li class="active">help</li>
2168 </ul>
2169 </ul>
2169 </div>
2170 </div>
2170
2171
2171 <div class="main">
2172 <div class="main">
2172 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2173 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2173
2174
2174 <form class="search" action="/log">
2175 <form class="search" action="/log">
2175
2176
2176 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2177 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2177 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2178 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2178 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2179 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2179 </form>
2180 </form>
2180 <table class="bigtable">
2181 <table class="bigtable">
2181 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2182 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2182
2183
2183 <tr><td>
2184 <tr><td>
2184 <a href="/help/bundlespec">
2185 <a href="/help/bundlespec">
2185 bundlespec
2186 bundlespec
2186 </a>
2187 </a>
2187 </td><td>
2188 </td><td>
2188 Bundle File Formats
2189 Bundle File Formats
2189 </td></tr>
2190 </td></tr>
2190 <tr><td>
2191 <tr><td>
2191 <a href="/help/color">
2192 <a href="/help/color">
2192 color
2193 color
2193 </a>
2194 </a>
2194 </td><td>
2195 </td><td>
2195 Colorizing Outputs
2196 Colorizing Outputs
2196 </td></tr>
2197 </td></tr>
2197 <tr><td>
2198 <tr><td>
2198 <a href="/help/config">
2199 <a href="/help/config">
2199 config
2200 config
2200 </a>
2201 </a>
2201 </td><td>
2202 </td><td>
2202 Configuration Files
2203 Configuration Files
2203 </td></tr>
2204 </td></tr>
2204 <tr><td>
2205 <tr><td>
2205 <a href="/help/dates">
2206 <a href="/help/dates">
2206 dates
2207 dates
2207 </a>
2208 </a>
2208 </td><td>
2209 </td><td>
2209 Date Formats
2210 Date Formats
2210 </td></tr>
2211 </td></tr>
2211 <tr><td>
2212 <tr><td>
2212 <a href="/help/deprecated">
2213 <a href="/help/deprecated">
2213 deprecated
2214 deprecated
2214 </a>
2215 </a>
2215 </td><td>
2216 </td><td>
2216 Deprecated Features
2217 Deprecated Features
2217 </td></tr>
2218 </td></tr>
2218 <tr><td>
2219 <tr><td>
2219 <a href="/help/diffs">
2220 <a href="/help/diffs">
2220 diffs
2221 diffs
2221 </a>
2222 </a>
2222 </td><td>
2223 </td><td>
2223 Diff Formats
2224 Diff Formats
2224 </td></tr>
2225 </td></tr>
2225 <tr><td>
2226 <tr><td>
2226 <a href="/help/environment">
2227 <a href="/help/environment">
2227 environment
2228 environment
2228 </a>
2229 </a>
2229 </td><td>
2230 </td><td>
2230 Environment Variables
2231 Environment Variables
2231 </td></tr>
2232 </td></tr>
2232 <tr><td>
2233 <tr><td>
2233 <a href="/help/extensions">
2234 <a href="/help/extensions">
2234 extensions
2235 extensions
2235 </a>
2236 </a>
2236 </td><td>
2237 </td><td>
2237 Using Additional Features
2238 Using Additional Features
2238 </td></tr>
2239 </td></tr>
2239 <tr><td>
2240 <tr><td>
2240 <a href="/help/filesets">
2241 <a href="/help/filesets">
2241 filesets
2242 filesets
2242 </a>
2243 </a>
2243 </td><td>
2244 </td><td>
2244 Specifying File Sets
2245 Specifying File Sets
2245 </td></tr>
2246 </td></tr>
2246 <tr><td>
2247 <tr><td>
2247 <a href="/help/flags">
2248 <a href="/help/flags">
2248 flags
2249 flags
2249 </a>
2250 </a>
2250 </td><td>
2251 </td><td>
2251 Command-line flags
2252 Command-line flags
2252 </td></tr>
2253 </td></tr>
2253 <tr><td>
2254 <tr><td>
2254 <a href="/help/glossary">
2255 <a href="/help/glossary">
2255 glossary
2256 glossary
2256 </a>
2257 </a>
2257 </td><td>
2258 </td><td>
2258 Glossary
2259 Glossary
2259 </td></tr>
2260 </td></tr>
2260 <tr><td>
2261 <tr><td>
2261 <a href="/help/hgignore">
2262 <a href="/help/hgignore">
2262 hgignore
2263 hgignore
2263 </a>
2264 </a>
2264 </td><td>
2265 </td><td>
2265 Syntax for Mercurial Ignore Files
2266 Syntax for Mercurial Ignore Files
2266 </td></tr>
2267 </td></tr>
2267 <tr><td>
2268 <tr><td>
2268 <a href="/help/hgweb">
2269 <a href="/help/hgweb">
2269 hgweb
2270 hgweb
2270 </a>
2271 </a>
2271 </td><td>
2272 </td><td>
2272 Configuring hgweb
2273 Configuring hgweb
2273 </td></tr>
2274 </td></tr>
2274 <tr><td>
2275 <tr><td>
2275 <a href="/help/internals">
2276 <a href="/help/internals">
2276 internals
2277 internals
2277 </a>
2278 </a>
2278 </td><td>
2279 </td><td>
2279 Technical implementation topics
2280 Technical implementation topics
2280 </td></tr>
2281 </td></tr>
2281 <tr><td>
2282 <tr><td>
2282 <a href="/help/merge-tools">
2283 <a href="/help/merge-tools">
2283 merge-tools
2284 merge-tools
2284 </a>
2285 </a>
2285 </td><td>
2286 </td><td>
2286 Merge Tools
2287 Merge Tools
2287 </td></tr>
2288 </td></tr>
2288 <tr><td>
2289 <tr><td>
2289 <a href="/help/pager">
2290 <a href="/help/pager">
2290 pager
2291 pager
2291 </a>
2292 </a>
2292 </td><td>
2293 </td><td>
2293 Pager Support
2294 Pager Support
2294 </td></tr>
2295 </td></tr>
2295 <tr><td>
2296 <tr><td>
2296 <a href="/help/patterns">
2297 <a href="/help/patterns">
2297 patterns
2298 patterns
2298 </a>
2299 </a>
2299 </td><td>
2300 </td><td>
2300 File Name Patterns
2301 File Name Patterns
2301 </td></tr>
2302 </td></tr>
2302 <tr><td>
2303 <tr><td>
2303 <a href="/help/phases">
2304 <a href="/help/phases">
2304 phases
2305 phases
2305 </a>
2306 </a>
2306 </td><td>
2307 </td><td>
2307 Working with Phases
2308 Working with Phases
2308 </td></tr>
2309 </td></tr>
2309 <tr><td>
2310 <tr><td>
2310 <a href="/help/revisions">
2311 <a href="/help/revisions">
2311 revisions
2312 revisions
2312 </a>
2313 </a>
2313 </td><td>
2314 </td><td>
2314 Specifying Revisions
2315 Specifying Revisions
2315 </td></tr>
2316 </td></tr>
2316 <tr><td>
2317 <tr><td>
2317 <a href="/help/scripting">
2318 <a href="/help/scripting">
2318 scripting
2319 scripting
2319 </a>
2320 </a>
2320 </td><td>
2321 </td><td>
2321 Using Mercurial from scripts and automation
2322 Using Mercurial from scripts and automation
2322 </td></tr>
2323 </td></tr>
2323 <tr><td>
2324 <tr><td>
2324 <a href="/help/subrepos">
2325 <a href="/help/subrepos">
2325 subrepos
2326 subrepos
2326 </a>
2327 </a>
2327 </td><td>
2328 </td><td>
2328 Subrepositories
2329 Subrepositories
2329 </td></tr>
2330 </td></tr>
2330 <tr><td>
2331 <tr><td>
2331 <a href="/help/templating">
2332 <a href="/help/templating">
2332 templating
2333 templating
2333 </a>
2334 </a>
2334 </td><td>
2335 </td><td>
2335 Template Usage
2336 Template Usage
2336 </td></tr>
2337 </td></tr>
2337 <tr><td>
2338 <tr><td>
2338 <a href="/help/urls">
2339 <a href="/help/urls">
2339 urls
2340 urls
2340 </a>
2341 </a>
2341 </td><td>
2342 </td><td>
2342 URL Paths
2343 URL Paths
2343 </td></tr>
2344 </td></tr>
2344 <tr><td>
2345 <tr><td>
2345 <a href="/help/topic-containing-verbose">
2346 <a href="/help/topic-containing-verbose">
2346 topic-containing-verbose
2347 topic-containing-verbose
2347 </a>
2348 </a>
2348 </td><td>
2349 </td><td>
2349 This is the topic to test omit indicating.
2350 This is the topic to test omit indicating.
2350 </td></tr>
2351 </td></tr>
2351
2352
2352
2353
2353 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2354 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2354
2355
2355 <tr><td>
2356 <tr><td>
2357 <a href="/help/abort">
2358 abort
2359 </a>
2360 </td><td>
2361 abort an unfinished operation (EXPERIMENTAL)
2362 </td></tr>
2363 <tr><td>
2356 <a href="/help/add">
2364 <a href="/help/add">
2357 add
2365 add
2358 </a>
2366 </a>
2359 </td><td>
2367 </td><td>
2360 add the specified files on the next commit
2368 add the specified files on the next commit
2361 </td></tr>
2369 </td></tr>
2362 <tr><td>
2370 <tr><td>
2363 <a href="/help/annotate">
2371 <a href="/help/annotate">
2364 annotate
2372 annotate
2365 </a>
2373 </a>
2366 </td><td>
2374 </td><td>
2367 show changeset information by line for each file
2375 show changeset information by line for each file
2368 </td></tr>
2376 </td></tr>
2369 <tr><td>
2377 <tr><td>
2370 <a href="/help/clone">
2378 <a href="/help/clone">
2371 clone
2379 clone
2372 </a>
2380 </a>
2373 </td><td>
2381 </td><td>
2374 make a copy of an existing repository
2382 make a copy of an existing repository
2375 </td></tr>
2383 </td></tr>
2376 <tr><td>
2384 <tr><td>
2377 <a href="/help/commit">
2385 <a href="/help/commit">
2378 commit
2386 commit
2379 </a>
2387 </a>
2380 </td><td>
2388 </td><td>
2381 commit the specified files or all outstanding changes
2389 commit the specified files or all outstanding changes
2382 </td></tr>
2390 </td></tr>
2383 <tr><td>
2391 <tr><td>
2384 <a href="/help/diff">
2392 <a href="/help/diff">
2385 diff
2393 diff
2386 </a>
2394 </a>
2387 </td><td>
2395 </td><td>
2388 diff repository (or selected files)
2396 diff repository (or selected files)
2389 </td></tr>
2397 </td></tr>
2390 <tr><td>
2398 <tr><td>
2391 <a href="/help/export">
2399 <a href="/help/export">
2392 export
2400 export
2393 </a>
2401 </a>
2394 </td><td>
2402 </td><td>
2395 dump the header and diffs for one or more changesets
2403 dump the header and diffs for one or more changesets
2396 </td></tr>
2404 </td></tr>
2397 <tr><td>
2405 <tr><td>
2398 <a href="/help/forget">
2406 <a href="/help/forget">
2399 forget
2407 forget
2400 </a>
2408 </a>
2401 </td><td>
2409 </td><td>
2402 forget the specified files on the next commit
2410 forget the specified files on the next commit
2403 </td></tr>
2411 </td></tr>
2404 <tr><td>
2412 <tr><td>
2405 <a href="/help/init">
2413 <a href="/help/init">
2406 init
2414 init
2407 </a>
2415 </a>
2408 </td><td>
2416 </td><td>
2409 create a new repository in the given directory
2417 create a new repository in the given directory
2410 </td></tr>
2418 </td></tr>
2411 <tr><td>
2419 <tr><td>
2412 <a href="/help/log">
2420 <a href="/help/log">
2413 log
2421 log
2414 </a>
2422 </a>
2415 </td><td>
2423 </td><td>
2416 show revision history of entire repository or files
2424 show revision history of entire repository or files
2417 </td></tr>
2425 </td></tr>
2418 <tr><td>
2426 <tr><td>
2419 <a href="/help/merge">
2427 <a href="/help/merge">
2420 merge
2428 merge
2421 </a>
2429 </a>
2422 </td><td>
2430 </td><td>
2423 merge another revision into working directory
2431 merge another revision into working directory
2424 </td></tr>
2432 </td></tr>
2425 <tr><td>
2433 <tr><td>
2426 <a href="/help/pull">
2434 <a href="/help/pull">
2427 pull
2435 pull
2428 </a>
2436 </a>
2429 </td><td>
2437 </td><td>
2430 pull changes from the specified source
2438 pull changes from the specified source
2431 </td></tr>
2439 </td></tr>
2432 <tr><td>
2440 <tr><td>
2433 <a href="/help/push">
2441 <a href="/help/push">
2434 push
2442 push
2435 </a>
2443 </a>
2436 </td><td>
2444 </td><td>
2437 push changes to the specified destination
2445 push changes to the specified destination
2438 </td></tr>
2446 </td></tr>
2439 <tr><td>
2447 <tr><td>
2440 <a href="/help/remove">
2448 <a href="/help/remove">
2441 remove
2449 remove
2442 </a>
2450 </a>
2443 </td><td>
2451 </td><td>
2444 remove the specified files on the next commit
2452 remove the specified files on the next commit
2445 </td></tr>
2453 </td></tr>
2446 <tr><td>
2454 <tr><td>
2447 <a href="/help/serve">
2455 <a href="/help/serve">
2448 serve
2456 serve
2449 </a>
2457 </a>
2450 </td><td>
2458 </td><td>
2451 start stand-alone webserver
2459 start stand-alone webserver
2452 </td></tr>
2460 </td></tr>
2453 <tr><td>
2461 <tr><td>
2454 <a href="/help/status">
2462 <a href="/help/status">
2455 status
2463 status
2456 </a>
2464 </a>
2457 </td><td>
2465 </td><td>
2458 show changed files in the working directory
2466 show changed files in the working directory
2459 </td></tr>
2467 </td></tr>
2460 <tr><td>
2468 <tr><td>
2461 <a href="/help/summary">
2469 <a href="/help/summary">
2462 summary
2470 summary
2463 </a>
2471 </a>
2464 </td><td>
2472 </td><td>
2465 summarize working directory state
2473 summarize working directory state
2466 </td></tr>
2474 </td></tr>
2467 <tr><td>
2475 <tr><td>
2468 <a href="/help/update">
2476 <a href="/help/update">
2469 update
2477 update
2470 </a>
2478 </a>
2471 </td><td>
2479 </td><td>
2472 update working directory (or switch revisions)
2480 update working directory (or switch revisions)
2473 </td></tr>
2481 </td></tr>
2474
2482
2475
2483
2476
2484
2477 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2485 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2478
2486
2479 <tr><td>
2487 <tr><td>
2480 <a href="/help/addremove">
2488 <a href="/help/addremove">
2481 addremove
2489 addremove
2482 </a>
2490 </a>
2483 </td><td>
2491 </td><td>
2484 add all new files, delete all missing files
2492 add all new files, delete all missing files
2485 </td></tr>
2493 </td></tr>
2486 <tr><td>
2494 <tr><td>
2487 <a href="/help/archive">
2495 <a href="/help/archive">
2488 archive
2496 archive
2489 </a>
2497 </a>
2490 </td><td>
2498 </td><td>
2491 create an unversioned archive of a repository revision
2499 create an unversioned archive of a repository revision
2492 </td></tr>
2500 </td></tr>
2493 <tr><td>
2501 <tr><td>
2494 <a href="/help/backout">
2502 <a href="/help/backout">
2495 backout
2503 backout
2496 </a>
2504 </a>
2497 </td><td>
2505 </td><td>
2498 reverse effect of earlier changeset
2506 reverse effect of earlier changeset
2499 </td></tr>
2507 </td></tr>
2500 <tr><td>
2508 <tr><td>
2501 <a href="/help/bisect">
2509 <a href="/help/bisect">
2502 bisect
2510 bisect
2503 </a>
2511 </a>
2504 </td><td>
2512 </td><td>
2505 subdivision search of changesets
2513 subdivision search of changesets
2506 </td></tr>
2514 </td></tr>
2507 <tr><td>
2515 <tr><td>
2508 <a href="/help/bookmarks">
2516 <a href="/help/bookmarks">
2509 bookmarks
2517 bookmarks
2510 </a>
2518 </a>
2511 </td><td>
2519 </td><td>
2512 create a new bookmark or list existing bookmarks
2520 create a new bookmark or list existing bookmarks
2513 </td></tr>
2521 </td></tr>
2514 <tr><td>
2522 <tr><td>
2515 <a href="/help/branch">
2523 <a href="/help/branch">
2516 branch
2524 branch
2517 </a>
2525 </a>
2518 </td><td>
2526 </td><td>
2519 set or show the current branch name
2527 set or show the current branch name
2520 </td></tr>
2528 </td></tr>
2521 <tr><td>
2529 <tr><td>
2522 <a href="/help/branches">
2530 <a href="/help/branches">
2523 branches
2531 branches
2524 </a>
2532 </a>
2525 </td><td>
2533 </td><td>
2526 list repository named branches
2534 list repository named branches
2527 </td></tr>
2535 </td></tr>
2528 <tr><td>
2536 <tr><td>
2529 <a href="/help/bundle">
2537 <a href="/help/bundle">
2530 bundle
2538 bundle
2531 </a>
2539 </a>
2532 </td><td>
2540 </td><td>
2533 create a bundle file
2541 create a bundle file
2534 </td></tr>
2542 </td></tr>
2535 <tr><td>
2543 <tr><td>
2536 <a href="/help/cat">
2544 <a href="/help/cat">
2537 cat
2545 cat
2538 </a>
2546 </a>
2539 </td><td>
2547 </td><td>
2540 output the current or given revision of files
2548 output the current or given revision of files
2541 </td></tr>
2549 </td></tr>
2542 <tr><td>
2550 <tr><td>
2543 <a href="/help/config">
2551 <a href="/help/config">
2544 config
2552 config
2545 </a>
2553 </a>
2546 </td><td>
2554 </td><td>
2547 show combined config settings from all hgrc files
2555 show combined config settings from all hgrc files
2548 </td></tr>
2556 </td></tr>
2549 <tr><td>
2557 <tr><td>
2550 <a href="/help/copy">
2558 <a href="/help/copy">
2551 copy
2559 copy
2552 </a>
2560 </a>
2553 </td><td>
2561 </td><td>
2554 mark files as copied for the next commit
2562 mark files as copied for the next commit
2555 </td></tr>
2563 </td></tr>
2556 <tr><td>
2564 <tr><td>
2557 <a href="/help/files">
2565 <a href="/help/files">
2558 files
2566 files
2559 </a>
2567 </a>
2560 </td><td>
2568 </td><td>
2561 list tracked files
2569 list tracked files
2562 </td></tr>
2570 </td></tr>
2563 <tr><td>
2571 <tr><td>
2564 <a href="/help/graft">
2572 <a href="/help/graft">
2565 graft
2573 graft
2566 </a>
2574 </a>
2567 </td><td>
2575 </td><td>
2568 copy changes from other branches onto the current branch
2576 copy changes from other branches onto the current branch
2569 </td></tr>
2577 </td></tr>
2570 <tr><td>
2578 <tr><td>
2571 <a href="/help/grep">
2579 <a href="/help/grep">
2572 grep
2580 grep
2573 </a>
2581 </a>
2574 </td><td>
2582 </td><td>
2575 search revision history for a pattern in specified files
2583 search revision history for a pattern in specified files
2576 </td></tr>
2584 </td></tr>
2577 <tr><td>
2585 <tr><td>
2578 <a href="/help/hashelp">
2586 <a href="/help/hashelp">
2579 hashelp
2587 hashelp
2580 </a>
2588 </a>
2581 </td><td>
2589 </td><td>
2582 Extension command's help
2590 Extension command's help
2583 </td></tr>
2591 </td></tr>
2584 <tr><td>
2592 <tr><td>
2585 <a href="/help/heads">
2593 <a href="/help/heads">
2586 heads
2594 heads
2587 </a>
2595 </a>
2588 </td><td>
2596 </td><td>
2589 show branch heads
2597 show branch heads
2590 </td></tr>
2598 </td></tr>
2591 <tr><td>
2599 <tr><td>
2592 <a href="/help/help">
2600 <a href="/help/help">
2593 help
2601 help
2594 </a>
2602 </a>
2595 </td><td>
2603 </td><td>
2596 show help for a given topic or a help overview
2604 show help for a given topic or a help overview
2597 </td></tr>
2605 </td></tr>
2598 <tr><td>
2606 <tr><td>
2599 <a href="/help/hgalias">
2607 <a href="/help/hgalias">
2600 hgalias
2608 hgalias
2601 </a>
2609 </a>
2602 </td><td>
2610 </td><td>
2603 My doc
2611 My doc
2604 </td></tr>
2612 </td></tr>
2605 <tr><td>
2613 <tr><td>
2606 <a href="/help/hgaliasnodoc">
2614 <a href="/help/hgaliasnodoc">
2607 hgaliasnodoc
2615 hgaliasnodoc
2608 </a>
2616 </a>
2609 </td><td>
2617 </td><td>
2610 summarize working directory state
2618 summarize working directory state
2611 </td></tr>
2619 </td></tr>
2612 <tr><td>
2620 <tr><td>
2613 <a href="/help/identify">
2621 <a href="/help/identify">
2614 identify
2622 identify
2615 </a>
2623 </a>
2616 </td><td>
2624 </td><td>
2617 identify the working directory or specified revision
2625 identify the working directory or specified revision
2618 </td></tr>
2626 </td></tr>
2619 <tr><td>
2627 <tr><td>
2620 <a href="/help/import">
2628 <a href="/help/import">
2621 import
2629 import
2622 </a>
2630 </a>
2623 </td><td>
2631 </td><td>
2624 import an ordered set of patches
2632 import an ordered set of patches
2625 </td></tr>
2633 </td></tr>
2626 <tr><td>
2634 <tr><td>
2627 <a href="/help/incoming">
2635 <a href="/help/incoming">
2628 incoming
2636 incoming
2629 </a>
2637 </a>
2630 </td><td>
2638 </td><td>
2631 show new changesets found in source
2639 show new changesets found in source
2632 </td></tr>
2640 </td></tr>
2633 <tr><td>
2641 <tr><td>
2634 <a href="/help/manifest">
2642 <a href="/help/manifest">
2635 manifest
2643 manifest
2636 </a>
2644 </a>
2637 </td><td>
2645 </td><td>
2638 output the current or given revision of the project manifest
2646 output the current or given revision of the project manifest
2639 </td></tr>
2647 </td></tr>
2640 <tr><td>
2648 <tr><td>
2641 <a href="/help/nohelp">
2649 <a href="/help/nohelp">
2642 nohelp
2650 nohelp
2643 </a>
2651 </a>
2644 </td><td>
2652 </td><td>
2645 (no help text available)
2653 (no help text available)
2646 </td></tr>
2654 </td></tr>
2647 <tr><td>
2655 <tr><td>
2648 <a href="/help/outgoing">
2656 <a href="/help/outgoing">
2649 outgoing
2657 outgoing
2650 </a>
2658 </a>
2651 </td><td>
2659 </td><td>
2652 show changesets not found in the destination
2660 show changesets not found in the destination
2653 </td></tr>
2661 </td></tr>
2654 <tr><td>
2662 <tr><td>
2655 <a href="/help/paths">
2663 <a href="/help/paths">
2656 paths
2664 paths
2657 </a>
2665 </a>
2658 </td><td>
2666 </td><td>
2659 show aliases for remote repositories
2667 show aliases for remote repositories
2660 </td></tr>
2668 </td></tr>
2661 <tr><td>
2669 <tr><td>
2662 <a href="/help/phase">
2670 <a href="/help/phase">
2663 phase
2671 phase
2664 </a>
2672 </a>
2665 </td><td>
2673 </td><td>
2666 set or show the current phase name
2674 set or show the current phase name
2667 </td></tr>
2675 </td></tr>
2668 <tr><td>
2676 <tr><td>
2669 <a href="/help/recover">
2677 <a href="/help/recover">
2670 recover
2678 recover
2671 </a>
2679 </a>
2672 </td><td>
2680 </td><td>
2673 roll back an interrupted transaction
2681 roll back an interrupted transaction
2674 </td></tr>
2682 </td></tr>
2675 <tr><td>
2683 <tr><td>
2676 <a href="/help/rename">
2684 <a href="/help/rename">
2677 rename
2685 rename
2678 </a>
2686 </a>
2679 </td><td>
2687 </td><td>
2680 rename files; equivalent of copy + remove
2688 rename files; equivalent of copy + remove
2681 </td></tr>
2689 </td></tr>
2682 <tr><td>
2690 <tr><td>
2683 <a href="/help/resolve">
2691 <a href="/help/resolve">
2684 resolve
2692 resolve
2685 </a>
2693 </a>
2686 </td><td>
2694 </td><td>
2687 redo merges or set/view the merge status of files
2695 redo merges or set/view the merge status of files
2688 </td></tr>
2696 </td></tr>
2689 <tr><td>
2697 <tr><td>
2690 <a href="/help/revert">
2698 <a href="/help/revert">
2691 revert
2699 revert
2692 </a>
2700 </a>
2693 </td><td>
2701 </td><td>
2694 restore files to their checkout state
2702 restore files to their checkout state
2695 </td></tr>
2703 </td></tr>
2696 <tr><td>
2704 <tr><td>
2697 <a href="/help/root">
2705 <a href="/help/root">
2698 root
2706 root
2699 </a>
2707 </a>
2700 </td><td>
2708 </td><td>
2701 print the root (top) of the current working directory
2709 print the root (top) of the current working directory
2702 </td></tr>
2710 </td></tr>
2703 <tr><td>
2711 <tr><td>
2704 <a href="/help/shellalias">
2712 <a href="/help/shellalias">
2705 shellalias
2713 shellalias
2706 </a>
2714 </a>
2707 </td><td>
2715 </td><td>
2708 (no help text available)
2716 (no help text available)
2709 </td></tr>
2717 </td></tr>
2710 <tr><td>
2718 <tr><td>
2711 <a href="/help/shelve">
2719 <a href="/help/shelve">
2712 shelve
2720 shelve
2713 </a>
2721 </a>
2714 </td><td>
2722 </td><td>
2715 save and set aside changes from the working directory
2723 save and set aside changes from the working directory
2716 </td></tr>
2724 </td></tr>
2717 <tr><td>
2725 <tr><td>
2718 <a href="/help/tag">
2726 <a href="/help/tag">
2719 tag
2727 tag
2720 </a>
2728 </a>
2721 </td><td>
2729 </td><td>
2722 add one or more tags for the current or given revision
2730 add one or more tags for the current or given revision
2723 </td></tr>
2731 </td></tr>
2724 <tr><td>
2732 <tr><td>
2725 <a href="/help/tags">
2733 <a href="/help/tags">
2726 tags
2734 tags
2727 </a>
2735 </a>
2728 </td><td>
2736 </td><td>
2729 list repository tags
2737 list repository tags
2730 </td></tr>
2738 </td></tr>
2731 <tr><td>
2739 <tr><td>
2732 <a href="/help/unbundle">
2740 <a href="/help/unbundle">
2733 unbundle
2741 unbundle
2734 </a>
2742 </a>
2735 </td><td>
2743 </td><td>
2736 apply one or more bundle files
2744 apply one or more bundle files
2737 </td></tr>
2745 </td></tr>
2738 <tr><td>
2746 <tr><td>
2739 <a href="/help/unshelve">
2747 <a href="/help/unshelve">
2740 unshelve
2748 unshelve
2741 </a>
2749 </a>
2742 </td><td>
2750 </td><td>
2743 restore a shelved change to the working directory
2751 restore a shelved change to the working directory
2744 </td></tr>
2752 </td></tr>
2745 <tr><td>
2753 <tr><td>
2746 <a href="/help/verify">
2754 <a href="/help/verify">
2747 verify
2755 verify
2748 </a>
2756 </a>
2749 </td><td>
2757 </td><td>
2750 verify the integrity of the repository
2758 verify the integrity of the repository
2751 </td></tr>
2759 </td></tr>
2752 <tr><td>
2760 <tr><td>
2753 <a href="/help/version">
2761 <a href="/help/version">
2754 version
2762 version
2755 </a>
2763 </a>
2756 </td><td>
2764 </td><td>
2757 output version and copyright information
2765 output version and copyright information
2758 </td></tr>
2766 </td></tr>
2759
2767
2760
2768
2761 </table>
2769 </table>
2762 </div>
2770 </div>
2763 </div>
2771 </div>
2764
2772
2765
2773
2766
2774
2767 </body>
2775 </body>
2768 </html>
2776 </html>
2769
2777
2770
2778
2771 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2779 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2772 200 Script output follows
2780 200 Script output follows
2773
2781
2774 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2782 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2775 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2783 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2776 <head>
2784 <head>
2777 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2785 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2778 <meta name="robots" content="index, nofollow" />
2786 <meta name="robots" content="index, nofollow" />
2779 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2787 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2780 <script type="text/javascript" src="/static/mercurial.js"></script>
2788 <script type="text/javascript" src="/static/mercurial.js"></script>
2781
2789
2782 <title>Help: add</title>
2790 <title>Help: add</title>
2783 </head>
2791 </head>
2784 <body>
2792 <body>
2785
2793
2786 <div class="container">
2794 <div class="container">
2787 <div class="menu">
2795 <div class="menu">
2788 <div class="logo">
2796 <div class="logo">
2789 <a href="https://mercurial-scm.org/">
2797 <a href="https://mercurial-scm.org/">
2790 <img src="/static/hglogo.png" alt="mercurial" /></a>
2798 <img src="/static/hglogo.png" alt="mercurial" /></a>
2791 </div>
2799 </div>
2792 <ul>
2800 <ul>
2793 <li><a href="/shortlog">log</a></li>
2801 <li><a href="/shortlog">log</a></li>
2794 <li><a href="/graph">graph</a></li>
2802 <li><a href="/graph">graph</a></li>
2795 <li><a href="/tags">tags</a></li>
2803 <li><a href="/tags">tags</a></li>
2796 <li><a href="/bookmarks">bookmarks</a></li>
2804 <li><a href="/bookmarks">bookmarks</a></li>
2797 <li><a href="/branches">branches</a></li>
2805 <li><a href="/branches">branches</a></li>
2798 </ul>
2806 </ul>
2799 <ul>
2807 <ul>
2800 <li class="active"><a href="/help">help</a></li>
2808 <li class="active"><a href="/help">help</a></li>
2801 </ul>
2809 </ul>
2802 </div>
2810 </div>
2803
2811
2804 <div class="main">
2812 <div class="main">
2805 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2813 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2806 <h3>Help: add</h3>
2814 <h3>Help: add</h3>
2807
2815
2808 <form class="search" action="/log">
2816 <form class="search" action="/log">
2809
2817
2810 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2818 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2811 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2819 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2812 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2820 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2813 </form>
2821 </form>
2814 <div id="doc">
2822 <div id="doc">
2815 <p>
2823 <p>
2816 hg add [OPTION]... [FILE]...
2824 hg add [OPTION]... [FILE]...
2817 </p>
2825 </p>
2818 <p>
2826 <p>
2819 add the specified files on the next commit
2827 add the specified files on the next commit
2820 </p>
2828 </p>
2821 <p>
2829 <p>
2822 Schedule files to be version controlled and added to the
2830 Schedule files to be version controlled and added to the
2823 repository.
2831 repository.
2824 </p>
2832 </p>
2825 <p>
2833 <p>
2826 The files will be added to the repository at the next commit. To
2834 The files will be added to the repository at the next commit. To
2827 undo an add before that, see 'hg forget'.
2835 undo an add before that, see 'hg forget'.
2828 </p>
2836 </p>
2829 <p>
2837 <p>
2830 If no names are given, add all files to the repository (except
2838 If no names are given, add all files to the repository (except
2831 files matching &quot;.hgignore&quot;).
2839 files matching &quot;.hgignore&quot;).
2832 </p>
2840 </p>
2833 <p>
2841 <p>
2834 Examples:
2842 Examples:
2835 </p>
2843 </p>
2836 <ul>
2844 <ul>
2837 <li> New (unknown) files are added automatically by 'hg add':
2845 <li> New (unknown) files are added automatically by 'hg add':
2838 <pre>
2846 <pre>
2839 \$ ls (re)
2847 \$ ls (re)
2840 foo.c
2848 foo.c
2841 \$ hg status (re)
2849 \$ hg status (re)
2842 ? foo.c
2850 ? foo.c
2843 \$ hg add (re)
2851 \$ hg add (re)
2844 adding foo.c
2852 adding foo.c
2845 \$ hg status (re)
2853 \$ hg status (re)
2846 A foo.c
2854 A foo.c
2847 </pre>
2855 </pre>
2848 <li> Specific files to be added can be specified:
2856 <li> Specific files to be added can be specified:
2849 <pre>
2857 <pre>
2850 \$ ls (re)
2858 \$ ls (re)
2851 bar.c foo.c
2859 bar.c foo.c
2852 \$ hg status (re)
2860 \$ hg status (re)
2853 ? bar.c
2861 ? bar.c
2854 ? foo.c
2862 ? foo.c
2855 \$ hg add bar.c (re)
2863 \$ hg add bar.c (re)
2856 \$ hg status (re)
2864 \$ hg status (re)
2857 A bar.c
2865 A bar.c
2858 ? foo.c
2866 ? foo.c
2859 </pre>
2867 </pre>
2860 </ul>
2868 </ul>
2861 <p>
2869 <p>
2862 Returns 0 if all files are successfully added.
2870 Returns 0 if all files are successfully added.
2863 </p>
2871 </p>
2864 <p>
2872 <p>
2865 options ([+] can be repeated):
2873 options ([+] can be repeated):
2866 </p>
2874 </p>
2867 <table>
2875 <table>
2868 <tr><td>-I</td>
2876 <tr><td>-I</td>
2869 <td>--include PATTERN [+]</td>
2877 <td>--include PATTERN [+]</td>
2870 <td>include names matching the given patterns</td></tr>
2878 <td>include names matching the given patterns</td></tr>
2871 <tr><td>-X</td>
2879 <tr><td>-X</td>
2872 <td>--exclude PATTERN [+]</td>
2880 <td>--exclude PATTERN [+]</td>
2873 <td>exclude names matching the given patterns</td></tr>
2881 <td>exclude names matching the given patterns</td></tr>
2874 <tr><td>-S</td>
2882 <tr><td>-S</td>
2875 <td>--subrepos</td>
2883 <td>--subrepos</td>
2876 <td>recurse into subrepositories</td></tr>
2884 <td>recurse into subrepositories</td></tr>
2877 <tr><td>-n</td>
2885 <tr><td>-n</td>
2878 <td>--dry-run</td>
2886 <td>--dry-run</td>
2879 <td>do not perform actions, just print output</td></tr>
2887 <td>do not perform actions, just print output</td></tr>
2880 </table>
2888 </table>
2881 <p>
2889 <p>
2882 global options ([+] can be repeated):
2890 global options ([+] can be repeated):
2883 </p>
2891 </p>
2884 <table>
2892 <table>
2885 <tr><td>-R</td>
2893 <tr><td>-R</td>
2886 <td>--repository REPO</td>
2894 <td>--repository REPO</td>
2887 <td>repository root directory or name of overlay bundle file</td></tr>
2895 <td>repository root directory or name of overlay bundle file</td></tr>
2888 <tr><td></td>
2896 <tr><td></td>
2889 <td>--cwd DIR</td>
2897 <td>--cwd DIR</td>
2890 <td>change working directory</td></tr>
2898 <td>change working directory</td></tr>
2891 <tr><td>-y</td>
2899 <tr><td>-y</td>
2892 <td>--noninteractive</td>
2900 <td>--noninteractive</td>
2893 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2901 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2894 <tr><td>-q</td>
2902 <tr><td>-q</td>
2895 <td>--quiet</td>
2903 <td>--quiet</td>
2896 <td>suppress output</td></tr>
2904 <td>suppress output</td></tr>
2897 <tr><td>-v</td>
2905 <tr><td>-v</td>
2898 <td>--verbose</td>
2906 <td>--verbose</td>
2899 <td>enable additional output</td></tr>
2907 <td>enable additional output</td></tr>
2900 <tr><td></td>
2908 <tr><td></td>
2901 <td>--color TYPE</td>
2909 <td>--color TYPE</td>
2902 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2910 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2903 <tr><td></td>
2911 <tr><td></td>
2904 <td>--config CONFIG [+]</td>
2912 <td>--config CONFIG [+]</td>
2905 <td>set/override config option (use 'section.name=value')</td></tr>
2913 <td>set/override config option (use 'section.name=value')</td></tr>
2906 <tr><td></td>
2914 <tr><td></td>
2907 <td>--debug</td>
2915 <td>--debug</td>
2908 <td>enable debugging output</td></tr>
2916 <td>enable debugging output</td></tr>
2909 <tr><td></td>
2917 <tr><td></td>
2910 <td>--debugger</td>
2918 <td>--debugger</td>
2911 <td>start debugger</td></tr>
2919 <td>start debugger</td></tr>
2912 <tr><td></td>
2920 <tr><td></td>
2913 <td>--encoding ENCODE</td>
2921 <td>--encoding ENCODE</td>
2914 <td>set the charset encoding (default: ascii)</td></tr>
2922 <td>set the charset encoding (default: ascii)</td></tr>
2915 <tr><td></td>
2923 <tr><td></td>
2916 <td>--encodingmode MODE</td>
2924 <td>--encodingmode MODE</td>
2917 <td>set the charset encoding mode (default: strict)</td></tr>
2925 <td>set the charset encoding mode (default: strict)</td></tr>
2918 <tr><td></td>
2926 <tr><td></td>
2919 <td>--traceback</td>
2927 <td>--traceback</td>
2920 <td>always print a traceback on exception</td></tr>
2928 <td>always print a traceback on exception</td></tr>
2921 <tr><td></td>
2929 <tr><td></td>
2922 <td>--time</td>
2930 <td>--time</td>
2923 <td>time how long the command takes</td></tr>
2931 <td>time how long the command takes</td></tr>
2924 <tr><td></td>
2932 <tr><td></td>
2925 <td>--profile</td>
2933 <td>--profile</td>
2926 <td>print command execution profile</td></tr>
2934 <td>print command execution profile</td></tr>
2927 <tr><td></td>
2935 <tr><td></td>
2928 <td>--version</td>
2936 <td>--version</td>
2929 <td>output version information and exit</td></tr>
2937 <td>output version information and exit</td></tr>
2930 <tr><td>-h</td>
2938 <tr><td>-h</td>
2931 <td>--help</td>
2939 <td>--help</td>
2932 <td>display help and exit</td></tr>
2940 <td>display help and exit</td></tr>
2933 <tr><td></td>
2941 <tr><td></td>
2934 <td>--hidden</td>
2942 <td>--hidden</td>
2935 <td>consider hidden changesets</td></tr>
2943 <td>consider hidden changesets</td></tr>
2936 <tr><td></td>
2944 <tr><td></td>
2937 <td>--pager TYPE</td>
2945 <td>--pager TYPE</td>
2938 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2946 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2939 </table>
2947 </table>
2940
2948
2941 </div>
2949 </div>
2942 </div>
2950 </div>
2943 </div>
2951 </div>
2944
2952
2945
2953
2946
2954
2947 </body>
2955 </body>
2948 </html>
2956 </html>
2949
2957
2950
2958
2951 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2959 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2952 200 Script output follows
2960 200 Script output follows
2953
2961
2954 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2962 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2955 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2963 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2956 <head>
2964 <head>
2957 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2965 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2958 <meta name="robots" content="index, nofollow" />
2966 <meta name="robots" content="index, nofollow" />
2959 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2967 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2960 <script type="text/javascript" src="/static/mercurial.js"></script>
2968 <script type="text/javascript" src="/static/mercurial.js"></script>
2961
2969
2962 <title>Help: remove</title>
2970 <title>Help: remove</title>
2963 </head>
2971 </head>
2964 <body>
2972 <body>
2965
2973
2966 <div class="container">
2974 <div class="container">
2967 <div class="menu">
2975 <div class="menu">
2968 <div class="logo">
2976 <div class="logo">
2969 <a href="https://mercurial-scm.org/">
2977 <a href="https://mercurial-scm.org/">
2970 <img src="/static/hglogo.png" alt="mercurial" /></a>
2978 <img src="/static/hglogo.png" alt="mercurial" /></a>
2971 </div>
2979 </div>
2972 <ul>
2980 <ul>
2973 <li><a href="/shortlog">log</a></li>
2981 <li><a href="/shortlog">log</a></li>
2974 <li><a href="/graph">graph</a></li>
2982 <li><a href="/graph">graph</a></li>
2975 <li><a href="/tags">tags</a></li>
2983 <li><a href="/tags">tags</a></li>
2976 <li><a href="/bookmarks">bookmarks</a></li>
2984 <li><a href="/bookmarks">bookmarks</a></li>
2977 <li><a href="/branches">branches</a></li>
2985 <li><a href="/branches">branches</a></li>
2978 </ul>
2986 </ul>
2979 <ul>
2987 <ul>
2980 <li class="active"><a href="/help">help</a></li>
2988 <li class="active"><a href="/help">help</a></li>
2981 </ul>
2989 </ul>
2982 </div>
2990 </div>
2983
2991
2984 <div class="main">
2992 <div class="main">
2985 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2993 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2986 <h3>Help: remove</h3>
2994 <h3>Help: remove</h3>
2987
2995
2988 <form class="search" action="/log">
2996 <form class="search" action="/log">
2989
2997
2990 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2998 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2991 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2999 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2992 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3000 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2993 </form>
3001 </form>
2994 <div id="doc">
3002 <div id="doc">
2995 <p>
3003 <p>
2996 hg remove [OPTION]... FILE...
3004 hg remove [OPTION]... FILE...
2997 </p>
3005 </p>
2998 <p>
3006 <p>
2999 aliases: rm
3007 aliases: rm
3000 </p>
3008 </p>
3001 <p>
3009 <p>
3002 remove the specified files on the next commit
3010 remove the specified files on the next commit
3003 </p>
3011 </p>
3004 <p>
3012 <p>
3005 Schedule the indicated files for removal from the current branch.
3013 Schedule the indicated files for removal from the current branch.
3006 </p>
3014 </p>
3007 <p>
3015 <p>
3008 This command schedules the files to be removed at the next commit.
3016 This command schedules the files to be removed at the next commit.
3009 To undo a remove before that, see 'hg revert'. To undo added
3017 To undo a remove before that, see 'hg revert'. To undo added
3010 files, see 'hg forget'.
3018 files, see 'hg forget'.
3011 </p>
3019 </p>
3012 <p>
3020 <p>
3013 -A/--after can be used to remove only files that have already
3021 -A/--after can be used to remove only files that have already
3014 been deleted, -f/--force can be used to force deletion, and -Af
3022 been deleted, -f/--force can be used to force deletion, and -Af
3015 can be used to remove files from the next revision without
3023 can be used to remove files from the next revision without
3016 deleting them from the working directory.
3024 deleting them from the working directory.
3017 </p>
3025 </p>
3018 <p>
3026 <p>
3019 The following table details the behavior of remove for different
3027 The following table details the behavior of remove for different
3020 file states (columns) and option combinations (rows). The file
3028 file states (columns) and option combinations (rows). The file
3021 states are Added [A], Clean [C], Modified [M] and Missing [!]
3029 states are Added [A], Clean [C], Modified [M] and Missing [!]
3022 (as reported by 'hg status'). The actions are Warn, Remove
3030 (as reported by 'hg status'). The actions are Warn, Remove
3023 (from branch) and Delete (from disk):
3031 (from branch) and Delete (from disk):
3024 </p>
3032 </p>
3025 <table>
3033 <table>
3026 <tr><td>opt/state</td>
3034 <tr><td>opt/state</td>
3027 <td>A</td>
3035 <td>A</td>
3028 <td>C</td>
3036 <td>C</td>
3029 <td>M</td>
3037 <td>M</td>
3030 <td>!</td></tr>
3038 <td>!</td></tr>
3031 <tr><td>none</td>
3039 <tr><td>none</td>
3032 <td>W</td>
3040 <td>W</td>
3033 <td>RD</td>
3041 <td>RD</td>
3034 <td>W</td>
3042 <td>W</td>
3035 <td>R</td></tr>
3043 <td>R</td></tr>
3036 <tr><td>-f</td>
3044 <tr><td>-f</td>
3037 <td>R</td>
3045 <td>R</td>
3038 <td>RD</td>
3046 <td>RD</td>
3039 <td>RD</td>
3047 <td>RD</td>
3040 <td>R</td></tr>
3048 <td>R</td></tr>
3041 <tr><td>-A</td>
3049 <tr><td>-A</td>
3042 <td>W</td>
3050 <td>W</td>
3043 <td>W</td>
3051 <td>W</td>
3044 <td>W</td>
3052 <td>W</td>
3045 <td>R</td></tr>
3053 <td>R</td></tr>
3046 <tr><td>-Af</td>
3054 <tr><td>-Af</td>
3047 <td>R</td>
3055 <td>R</td>
3048 <td>R</td>
3056 <td>R</td>
3049 <td>R</td>
3057 <td>R</td>
3050 <td>R</td></tr>
3058 <td>R</td></tr>
3051 </table>
3059 </table>
3052 <p>
3060 <p>
3053 <b>Note:</b>
3061 <b>Note:</b>
3054 </p>
3062 </p>
3055 <p>
3063 <p>
3056 'hg remove' never deletes files in Added [A] state from the
3064 'hg remove' never deletes files in Added [A] state from the
3057 working directory, not even if &quot;--force&quot; is specified.
3065 working directory, not even if &quot;--force&quot; is specified.
3058 </p>
3066 </p>
3059 <p>
3067 <p>
3060 Returns 0 on success, 1 if any warnings encountered.
3068 Returns 0 on success, 1 if any warnings encountered.
3061 </p>
3069 </p>
3062 <p>
3070 <p>
3063 options ([+] can be repeated):
3071 options ([+] can be repeated):
3064 </p>
3072 </p>
3065 <table>
3073 <table>
3066 <tr><td>-A</td>
3074 <tr><td>-A</td>
3067 <td>--after</td>
3075 <td>--after</td>
3068 <td>record delete for missing files</td></tr>
3076 <td>record delete for missing files</td></tr>
3069 <tr><td>-f</td>
3077 <tr><td>-f</td>
3070 <td>--force</td>
3078 <td>--force</td>
3071 <td>forget added files, delete modified files</td></tr>
3079 <td>forget added files, delete modified files</td></tr>
3072 <tr><td>-S</td>
3080 <tr><td>-S</td>
3073 <td>--subrepos</td>
3081 <td>--subrepos</td>
3074 <td>recurse into subrepositories</td></tr>
3082 <td>recurse into subrepositories</td></tr>
3075 <tr><td>-I</td>
3083 <tr><td>-I</td>
3076 <td>--include PATTERN [+]</td>
3084 <td>--include PATTERN [+]</td>
3077 <td>include names matching the given patterns</td></tr>
3085 <td>include names matching the given patterns</td></tr>
3078 <tr><td>-X</td>
3086 <tr><td>-X</td>
3079 <td>--exclude PATTERN [+]</td>
3087 <td>--exclude PATTERN [+]</td>
3080 <td>exclude names matching the given patterns</td></tr>
3088 <td>exclude names matching the given patterns</td></tr>
3081 <tr><td>-n</td>
3089 <tr><td>-n</td>
3082 <td>--dry-run</td>
3090 <td>--dry-run</td>
3083 <td>do not perform actions, just print output</td></tr>
3091 <td>do not perform actions, just print output</td></tr>
3084 </table>
3092 </table>
3085 <p>
3093 <p>
3086 global options ([+] can be repeated):
3094 global options ([+] can be repeated):
3087 </p>
3095 </p>
3088 <table>
3096 <table>
3089 <tr><td>-R</td>
3097 <tr><td>-R</td>
3090 <td>--repository REPO</td>
3098 <td>--repository REPO</td>
3091 <td>repository root directory or name of overlay bundle file</td></tr>
3099 <td>repository root directory or name of overlay bundle file</td></tr>
3092 <tr><td></td>
3100 <tr><td></td>
3093 <td>--cwd DIR</td>
3101 <td>--cwd DIR</td>
3094 <td>change working directory</td></tr>
3102 <td>change working directory</td></tr>
3095 <tr><td>-y</td>
3103 <tr><td>-y</td>
3096 <td>--noninteractive</td>
3104 <td>--noninteractive</td>
3097 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3105 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3098 <tr><td>-q</td>
3106 <tr><td>-q</td>
3099 <td>--quiet</td>
3107 <td>--quiet</td>
3100 <td>suppress output</td></tr>
3108 <td>suppress output</td></tr>
3101 <tr><td>-v</td>
3109 <tr><td>-v</td>
3102 <td>--verbose</td>
3110 <td>--verbose</td>
3103 <td>enable additional output</td></tr>
3111 <td>enable additional output</td></tr>
3104 <tr><td></td>
3112 <tr><td></td>
3105 <td>--color TYPE</td>
3113 <td>--color TYPE</td>
3106 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3114 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3107 <tr><td></td>
3115 <tr><td></td>
3108 <td>--config CONFIG [+]</td>
3116 <td>--config CONFIG [+]</td>
3109 <td>set/override config option (use 'section.name=value')</td></tr>
3117 <td>set/override config option (use 'section.name=value')</td></tr>
3110 <tr><td></td>
3118 <tr><td></td>
3111 <td>--debug</td>
3119 <td>--debug</td>
3112 <td>enable debugging output</td></tr>
3120 <td>enable debugging output</td></tr>
3113 <tr><td></td>
3121 <tr><td></td>
3114 <td>--debugger</td>
3122 <td>--debugger</td>
3115 <td>start debugger</td></tr>
3123 <td>start debugger</td></tr>
3116 <tr><td></td>
3124 <tr><td></td>
3117 <td>--encoding ENCODE</td>
3125 <td>--encoding ENCODE</td>
3118 <td>set the charset encoding (default: ascii)</td></tr>
3126 <td>set the charset encoding (default: ascii)</td></tr>
3119 <tr><td></td>
3127 <tr><td></td>
3120 <td>--encodingmode MODE</td>
3128 <td>--encodingmode MODE</td>
3121 <td>set the charset encoding mode (default: strict)</td></tr>
3129 <td>set the charset encoding mode (default: strict)</td></tr>
3122 <tr><td></td>
3130 <tr><td></td>
3123 <td>--traceback</td>
3131 <td>--traceback</td>
3124 <td>always print a traceback on exception</td></tr>
3132 <td>always print a traceback on exception</td></tr>
3125 <tr><td></td>
3133 <tr><td></td>
3126 <td>--time</td>
3134 <td>--time</td>
3127 <td>time how long the command takes</td></tr>
3135 <td>time how long the command takes</td></tr>
3128 <tr><td></td>
3136 <tr><td></td>
3129 <td>--profile</td>
3137 <td>--profile</td>
3130 <td>print command execution profile</td></tr>
3138 <td>print command execution profile</td></tr>
3131 <tr><td></td>
3139 <tr><td></td>
3132 <td>--version</td>
3140 <td>--version</td>
3133 <td>output version information and exit</td></tr>
3141 <td>output version information and exit</td></tr>
3134 <tr><td>-h</td>
3142 <tr><td>-h</td>
3135 <td>--help</td>
3143 <td>--help</td>
3136 <td>display help and exit</td></tr>
3144 <td>display help and exit</td></tr>
3137 <tr><td></td>
3145 <tr><td></td>
3138 <td>--hidden</td>
3146 <td>--hidden</td>
3139 <td>consider hidden changesets</td></tr>
3147 <td>consider hidden changesets</td></tr>
3140 <tr><td></td>
3148 <tr><td></td>
3141 <td>--pager TYPE</td>
3149 <td>--pager TYPE</td>
3142 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3150 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3143 </table>
3151 </table>
3144
3152
3145 </div>
3153 </div>
3146 </div>
3154 </div>
3147 </div>
3155 </div>
3148
3156
3149
3157
3150
3158
3151 </body>
3159 </body>
3152 </html>
3160 </html>
3153
3161
3154
3162
3155 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3163 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3156 200 Script output follows
3164 200 Script output follows
3157
3165
3158 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3166 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3159 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3167 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3160 <head>
3168 <head>
3161 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3169 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3162 <meta name="robots" content="index, nofollow" />
3170 <meta name="robots" content="index, nofollow" />
3163 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3171 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3164 <script type="text/javascript" src="/static/mercurial.js"></script>
3172 <script type="text/javascript" src="/static/mercurial.js"></script>
3165
3173
3166 <title>Help: dates</title>
3174 <title>Help: dates</title>
3167 </head>
3175 </head>
3168 <body>
3176 <body>
3169
3177
3170 <div class="container">
3178 <div class="container">
3171 <div class="menu">
3179 <div class="menu">
3172 <div class="logo">
3180 <div class="logo">
3173 <a href="https://mercurial-scm.org/">
3181 <a href="https://mercurial-scm.org/">
3174 <img src="/static/hglogo.png" alt="mercurial" /></a>
3182 <img src="/static/hglogo.png" alt="mercurial" /></a>
3175 </div>
3183 </div>
3176 <ul>
3184 <ul>
3177 <li><a href="/shortlog">log</a></li>
3185 <li><a href="/shortlog">log</a></li>
3178 <li><a href="/graph">graph</a></li>
3186 <li><a href="/graph">graph</a></li>
3179 <li><a href="/tags">tags</a></li>
3187 <li><a href="/tags">tags</a></li>
3180 <li><a href="/bookmarks">bookmarks</a></li>
3188 <li><a href="/bookmarks">bookmarks</a></li>
3181 <li><a href="/branches">branches</a></li>
3189 <li><a href="/branches">branches</a></li>
3182 </ul>
3190 </ul>
3183 <ul>
3191 <ul>
3184 <li class="active"><a href="/help">help</a></li>
3192 <li class="active"><a href="/help">help</a></li>
3185 </ul>
3193 </ul>
3186 </div>
3194 </div>
3187
3195
3188 <div class="main">
3196 <div class="main">
3189 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3197 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3190 <h3>Help: dates</h3>
3198 <h3>Help: dates</h3>
3191
3199
3192 <form class="search" action="/log">
3200 <form class="search" action="/log">
3193
3201
3194 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3202 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3195 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3203 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3196 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3204 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3197 </form>
3205 </form>
3198 <div id="doc">
3206 <div id="doc">
3199 <h1>Date Formats</h1>
3207 <h1>Date Formats</h1>
3200 <p>
3208 <p>
3201 Some commands allow the user to specify a date, e.g.:
3209 Some commands allow the user to specify a date, e.g.:
3202 </p>
3210 </p>
3203 <ul>
3211 <ul>
3204 <li> backout, commit, import, tag: Specify the commit date.
3212 <li> backout, commit, import, tag: Specify the commit date.
3205 <li> log, revert, update: Select revision(s) by date.
3213 <li> log, revert, update: Select revision(s) by date.
3206 </ul>
3214 </ul>
3207 <p>
3215 <p>
3208 Many date formats are valid. Here are some examples:
3216 Many date formats are valid. Here are some examples:
3209 </p>
3217 </p>
3210 <ul>
3218 <ul>
3211 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3219 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3212 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3220 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3213 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3221 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3214 <li> &quot;Dec 6&quot; (midnight)
3222 <li> &quot;Dec 6&quot; (midnight)
3215 <li> &quot;13:18&quot; (today assumed)
3223 <li> &quot;13:18&quot; (today assumed)
3216 <li> &quot;3:39&quot; (3:39AM assumed)
3224 <li> &quot;3:39&quot; (3:39AM assumed)
3217 <li> &quot;3:39pm&quot; (15:39)
3225 <li> &quot;3:39pm&quot; (15:39)
3218 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3226 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3219 <li> &quot;2006-12-6 13:18&quot;
3227 <li> &quot;2006-12-6 13:18&quot;
3220 <li> &quot;2006-12-6&quot;
3228 <li> &quot;2006-12-6&quot;
3221 <li> &quot;12-6&quot;
3229 <li> &quot;12-6&quot;
3222 <li> &quot;12/6&quot;
3230 <li> &quot;12/6&quot;
3223 <li> &quot;12/6/6&quot; (Dec 6 2006)
3231 <li> &quot;12/6/6&quot; (Dec 6 2006)
3224 <li> &quot;today&quot; (midnight)
3232 <li> &quot;today&quot; (midnight)
3225 <li> &quot;yesterday&quot; (midnight)
3233 <li> &quot;yesterday&quot; (midnight)
3226 <li> &quot;now&quot; - right now
3234 <li> &quot;now&quot; - right now
3227 </ul>
3235 </ul>
3228 <p>
3236 <p>
3229 Lastly, there is Mercurial's internal format:
3237 Lastly, there is Mercurial's internal format:
3230 </p>
3238 </p>
3231 <ul>
3239 <ul>
3232 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3240 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3233 </ul>
3241 </ul>
3234 <p>
3242 <p>
3235 This is the internal representation format for dates. The first number
3243 This is the internal representation format for dates. The first number
3236 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3244 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3237 second is the offset of the local timezone, in seconds west of UTC
3245 second is the offset of the local timezone, in seconds west of UTC
3238 (negative if the timezone is east of UTC).
3246 (negative if the timezone is east of UTC).
3239 </p>
3247 </p>
3240 <p>
3248 <p>
3241 The log command also accepts date ranges:
3249 The log command also accepts date ranges:
3242 </p>
3250 </p>
3243 <ul>
3251 <ul>
3244 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3252 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3245 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3253 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3246 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3254 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3247 <li> &quot;-DAYS&quot; - within a given number of days of today
3255 <li> &quot;-DAYS&quot; - within a given number of days of today
3248 </ul>
3256 </ul>
3249
3257
3250 </div>
3258 </div>
3251 </div>
3259 </div>
3252 </div>
3260 </div>
3253
3261
3254
3262
3255
3263
3256 </body>
3264 </body>
3257 </html>
3265 </html>
3258
3266
3259
3267
3260 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3268 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3261 200 Script output follows
3269 200 Script output follows
3262
3270
3263 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3271 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3264 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3272 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3265 <head>
3273 <head>
3266 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3274 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3267 <meta name="robots" content="index, nofollow" />
3275 <meta name="robots" content="index, nofollow" />
3268 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3276 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3269 <script type="text/javascript" src="/static/mercurial.js"></script>
3277 <script type="text/javascript" src="/static/mercurial.js"></script>
3270
3278
3271 <title>Help: pager</title>
3279 <title>Help: pager</title>
3272 </head>
3280 </head>
3273 <body>
3281 <body>
3274
3282
3275 <div class="container">
3283 <div class="container">
3276 <div class="menu">
3284 <div class="menu">
3277 <div class="logo">
3285 <div class="logo">
3278 <a href="https://mercurial-scm.org/">
3286 <a href="https://mercurial-scm.org/">
3279 <img src="/static/hglogo.png" alt="mercurial" /></a>
3287 <img src="/static/hglogo.png" alt="mercurial" /></a>
3280 </div>
3288 </div>
3281 <ul>
3289 <ul>
3282 <li><a href="/shortlog">log</a></li>
3290 <li><a href="/shortlog">log</a></li>
3283 <li><a href="/graph">graph</a></li>
3291 <li><a href="/graph">graph</a></li>
3284 <li><a href="/tags">tags</a></li>
3292 <li><a href="/tags">tags</a></li>
3285 <li><a href="/bookmarks">bookmarks</a></li>
3293 <li><a href="/bookmarks">bookmarks</a></li>
3286 <li><a href="/branches">branches</a></li>
3294 <li><a href="/branches">branches</a></li>
3287 </ul>
3295 </ul>
3288 <ul>
3296 <ul>
3289 <li class="active"><a href="/help">help</a></li>
3297 <li class="active"><a href="/help">help</a></li>
3290 </ul>
3298 </ul>
3291 </div>
3299 </div>
3292
3300
3293 <div class="main">
3301 <div class="main">
3294 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3302 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3295 <h3>Help: pager</h3>
3303 <h3>Help: pager</h3>
3296
3304
3297 <form class="search" action="/log">
3305 <form class="search" action="/log">
3298
3306
3299 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3307 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3300 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3308 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3301 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3309 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3302 </form>
3310 </form>
3303 <div id="doc">
3311 <div id="doc">
3304 <h1>Pager Support</h1>
3312 <h1>Pager Support</h1>
3305 <p>
3313 <p>
3306 Some Mercurial commands can produce a lot of output, and Mercurial will
3314 Some Mercurial commands can produce a lot of output, and Mercurial will
3307 attempt to use a pager to make those commands more pleasant.
3315 attempt to use a pager to make those commands more pleasant.
3308 </p>
3316 </p>
3309 <p>
3317 <p>
3310 To set the pager that should be used, set the application variable:
3318 To set the pager that should be used, set the application variable:
3311 </p>
3319 </p>
3312 <pre>
3320 <pre>
3313 [pager]
3321 [pager]
3314 pager = less -FRX
3322 pager = less -FRX
3315 </pre>
3323 </pre>
3316 <p>
3324 <p>
3317 If no pager is set in the user or repository configuration, Mercurial uses the
3325 If no pager is set in the user or repository configuration, Mercurial uses the
3318 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3326 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3319 or system configuration is used. If none of these are set, a default pager will
3327 or system configuration is used. If none of these are set, a default pager will
3320 be used, typically 'less' on Unix and 'more' on Windows.
3328 be used, typically 'less' on Unix and 'more' on Windows.
3321 </p>
3329 </p>
3322 <p>
3330 <p>
3323 You can disable the pager for certain commands by adding them to the
3331 You can disable the pager for certain commands by adding them to the
3324 pager.ignore list:
3332 pager.ignore list:
3325 </p>
3333 </p>
3326 <pre>
3334 <pre>
3327 [pager]
3335 [pager]
3328 ignore = version, help, update
3336 ignore = version, help, update
3329 </pre>
3337 </pre>
3330 <p>
3338 <p>
3331 To ignore global commands like 'hg version' or 'hg help', you have
3339 To ignore global commands like 'hg version' or 'hg help', you have
3332 to specify them in your user configuration file.
3340 to specify them in your user configuration file.
3333 </p>
3341 </p>
3334 <p>
3342 <p>
3335 To control whether the pager is used at all for an individual command,
3343 To control whether the pager is used at all for an individual command,
3336 you can use --pager=&lt;value&gt;:
3344 you can use --pager=&lt;value&gt;:
3337 </p>
3345 </p>
3338 <ul>
3346 <ul>
3339 <li> use as needed: 'auto'.
3347 <li> use as needed: 'auto'.
3340 <li> require the pager: 'yes' or 'on'.
3348 <li> require the pager: 'yes' or 'on'.
3341 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3349 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3342 </ul>
3350 </ul>
3343 <p>
3351 <p>
3344 To globally turn off all attempts to use a pager, set:
3352 To globally turn off all attempts to use a pager, set:
3345 </p>
3353 </p>
3346 <pre>
3354 <pre>
3347 [ui]
3355 [ui]
3348 paginate = never
3356 paginate = never
3349 </pre>
3357 </pre>
3350 <p>
3358 <p>
3351 which will prevent the pager from running.
3359 which will prevent the pager from running.
3352 </p>
3360 </p>
3353
3361
3354 </div>
3362 </div>
3355 </div>
3363 </div>
3356 </div>
3364 </div>
3357
3365
3358
3366
3359
3367
3360 </body>
3368 </body>
3361 </html>
3369 </html>
3362
3370
3363
3371
3364 Sub-topic indexes rendered properly
3372 Sub-topic indexes rendered properly
3365
3373
3366 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3374 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3367 200 Script output follows
3375 200 Script output follows
3368
3376
3369 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3377 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3370 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3378 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3371 <head>
3379 <head>
3372 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3380 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3373 <meta name="robots" content="index, nofollow" />
3381 <meta name="robots" content="index, nofollow" />
3374 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3382 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3375 <script type="text/javascript" src="/static/mercurial.js"></script>
3383 <script type="text/javascript" src="/static/mercurial.js"></script>
3376
3384
3377 <title>Help: internals</title>
3385 <title>Help: internals</title>
3378 </head>
3386 </head>
3379 <body>
3387 <body>
3380
3388
3381 <div class="container">
3389 <div class="container">
3382 <div class="menu">
3390 <div class="menu">
3383 <div class="logo">
3391 <div class="logo">
3384 <a href="https://mercurial-scm.org/">
3392 <a href="https://mercurial-scm.org/">
3385 <img src="/static/hglogo.png" alt="mercurial" /></a>
3393 <img src="/static/hglogo.png" alt="mercurial" /></a>
3386 </div>
3394 </div>
3387 <ul>
3395 <ul>
3388 <li><a href="/shortlog">log</a></li>
3396 <li><a href="/shortlog">log</a></li>
3389 <li><a href="/graph">graph</a></li>
3397 <li><a href="/graph">graph</a></li>
3390 <li><a href="/tags">tags</a></li>
3398 <li><a href="/tags">tags</a></li>
3391 <li><a href="/bookmarks">bookmarks</a></li>
3399 <li><a href="/bookmarks">bookmarks</a></li>
3392 <li><a href="/branches">branches</a></li>
3400 <li><a href="/branches">branches</a></li>
3393 </ul>
3401 </ul>
3394 <ul>
3402 <ul>
3395 <li><a href="/help">help</a></li>
3403 <li><a href="/help">help</a></li>
3396 </ul>
3404 </ul>
3397 </div>
3405 </div>
3398
3406
3399 <div class="main">
3407 <div class="main">
3400 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3408 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3401
3409
3402 <form class="search" action="/log">
3410 <form class="search" action="/log">
3403
3411
3404 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3412 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3405 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3413 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3406 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3414 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3407 </form>
3415 </form>
3408 <table class="bigtable">
3416 <table class="bigtable">
3409 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3417 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3410
3418
3411 <tr><td>
3419 <tr><td>
3412 <a href="/help/internals.bundle2">
3420 <a href="/help/internals.bundle2">
3413 bundle2
3421 bundle2
3414 </a>
3422 </a>
3415 </td><td>
3423 </td><td>
3416 Bundle2
3424 Bundle2
3417 </td></tr>
3425 </td></tr>
3418 <tr><td>
3426 <tr><td>
3419 <a href="/help/internals.bundles">
3427 <a href="/help/internals.bundles">
3420 bundles
3428 bundles
3421 </a>
3429 </a>
3422 </td><td>
3430 </td><td>
3423 Bundles
3431 Bundles
3424 </td></tr>
3432 </td></tr>
3425 <tr><td>
3433 <tr><td>
3426 <a href="/help/internals.cbor">
3434 <a href="/help/internals.cbor">
3427 cbor
3435 cbor
3428 </a>
3436 </a>
3429 </td><td>
3437 </td><td>
3430 CBOR
3438 CBOR
3431 </td></tr>
3439 </td></tr>
3432 <tr><td>
3440 <tr><td>
3433 <a href="/help/internals.censor">
3441 <a href="/help/internals.censor">
3434 censor
3442 censor
3435 </a>
3443 </a>
3436 </td><td>
3444 </td><td>
3437 Censor
3445 Censor
3438 </td></tr>
3446 </td></tr>
3439 <tr><td>
3447 <tr><td>
3440 <a href="/help/internals.changegroups">
3448 <a href="/help/internals.changegroups">
3441 changegroups
3449 changegroups
3442 </a>
3450 </a>
3443 </td><td>
3451 </td><td>
3444 Changegroups
3452 Changegroups
3445 </td></tr>
3453 </td></tr>
3446 <tr><td>
3454 <tr><td>
3447 <a href="/help/internals.config">
3455 <a href="/help/internals.config">
3448 config
3456 config
3449 </a>
3457 </a>
3450 </td><td>
3458 </td><td>
3451 Config Registrar
3459 Config Registrar
3452 </td></tr>
3460 </td></tr>
3453 <tr><td>
3461 <tr><td>
3454 <a href="/help/internals.extensions">
3462 <a href="/help/internals.extensions">
3455 extensions
3463 extensions
3456 </a>
3464 </a>
3457 </td><td>
3465 </td><td>
3458 Extension API
3466 Extension API
3459 </td></tr>
3467 </td></tr>
3460 <tr><td>
3468 <tr><td>
3461 <a href="/help/internals.mergestate">
3469 <a href="/help/internals.mergestate">
3462 mergestate
3470 mergestate
3463 </a>
3471 </a>
3464 </td><td>
3472 </td><td>
3465 Mergestate
3473 Mergestate
3466 </td></tr>
3474 </td></tr>
3467 <tr><td>
3475 <tr><td>
3468 <a href="/help/internals.requirements">
3476 <a href="/help/internals.requirements">
3469 requirements
3477 requirements
3470 </a>
3478 </a>
3471 </td><td>
3479 </td><td>
3472 Repository Requirements
3480 Repository Requirements
3473 </td></tr>
3481 </td></tr>
3474 <tr><td>
3482 <tr><td>
3475 <a href="/help/internals.revlogs">
3483 <a href="/help/internals.revlogs">
3476 revlogs
3484 revlogs
3477 </a>
3485 </a>
3478 </td><td>
3486 </td><td>
3479 Revision Logs
3487 Revision Logs
3480 </td></tr>
3488 </td></tr>
3481 <tr><td>
3489 <tr><td>
3482 <a href="/help/internals.wireprotocol">
3490 <a href="/help/internals.wireprotocol">
3483 wireprotocol
3491 wireprotocol
3484 </a>
3492 </a>
3485 </td><td>
3493 </td><td>
3486 Wire Protocol
3494 Wire Protocol
3487 </td></tr>
3495 </td></tr>
3488 <tr><td>
3496 <tr><td>
3489 <a href="/help/internals.wireprotocolrpc">
3497 <a href="/help/internals.wireprotocolrpc">
3490 wireprotocolrpc
3498 wireprotocolrpc
3491 </a>
3499 </a>
3492 </td><td>
3500 </td><td>
3493 Wire Protocol RPC
3501 Wire Protocol RPC
3494 </td></tr>
3502 </td></tr>
3495 <tr><td>
3503 <tr><td>
3496 <a href="/help/internals.wireprotocolv2">
3504 <a href="/help/internals.wireprotocolv2">
3497 wireprotocolv2
3505 wireprotocolv2
3498 </a>
3506 </a>
3499 </td><td>
3507 </td><td>
3500 Wire Protocol Version 2
3508 Wire Protocol Version 2
3501 </td></tr>
3509 </td></tr>
3502
3510
3503
3511
3504
3512
3505
3513
3506
3514
3507 </table>
3515 </table>
3508 </div>
3516 </div>
3509 </div>
3517 </div>
3510
3518
3511
3519
3512
3520
3513 </body>
3521 </body>
3514 </html>
3522 </html>
3515
3523
3516
3524
3517 Sub-topic topics rendered properly
3525 Sub-topic topics rendered properly
3518
3526
3519 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3527 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3520 200 Script output follows
3528 200 Script output follows
3521
3529
3522 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3530 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3523 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3531 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3524 <head>
3532 <head>
3525 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3533 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3526 <meta name="robots" content="index, nofollow" />
3534 <meta name="robots" content="index, nofollow" />
3527 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3535 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3528 <script type="text/javascript" src="/static/mercurial.js"></script>
3536 <script type="text/javascript" src="/static/mercurial.js"></script>
3529
3537
3530 <title>Help: internals.changegroups</title>
3538 <title>Help: internals.changegroups</title>
3531 </head>
3539 </head>
3532 <body>
3540 <body>
3533
3541
3534 <div class="container">
3542 <div class="container">
3535 <div class="menu">
3543 <div class="menu">
3536 <div class="logo">
3544 <div class="logo">
3537 <a href="https://mercurial-scm.org/">
3545 <a href="https://mercurial-scm.org/">
3538 <img src="/static/hglogo.png" alt="mercurial" /></a>
3546 <img src="/static/hglogo.png" alt="mercurial" /></a>
3539 </div>
3547 </div>
3540 <ul>
3548 <ul>
3541 <li><a href="/shortlog">log</a></li>
3549 <li><a href="/shortlog">log</a></li>
3542 <li><a href="/graph">graph</a></li>
3550 <li><a href="/graph">graph</a></li>
3543 <li><a href="/tags">tags</a></li>
3551 <li><a href="/tags">tags</a></li>
3544 <li><a href="/bookmarks">bookmarks</a></li>
3552 <li><a href="/bookmarks">bookmarks</a></li>
3545 <li><a href="/branches">branches</a></li>
3553 <li><a href="/branches">branches</a></li>
3546 </ul>
3554 </ul>
3547 <ul>
3555 <ul>
3548 <li class="active"><a href="/help">help</a></li>
3556 <li class="active"><a href="/help">help</a></li>
3549 </ul>
3557 </ul>
3550 </div>
3558 </div>
3551
3559
3552 <div class="main">
3560 <div class="main">
3553 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3561 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3554 <h3>Help: internals.changegroups</h3>
3562 <h3>Help: internals.changegroups</h3>
3555
3563
3556 <form class="search" action="/log">
3564 <form class="search" action="/log">
3557
3565
3558 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3566 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3559 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3567 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3560 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3568 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3561 </form>
3569 </form>
3562 <div id="doc">
3570 <div id="doc">
3563 <h1>Changegroups</h1>
3571 <h1>Changegroups</h1>
3564 <p>
3572 <p>
3565 Changegroups are representations of repository revlog data, specifically
3573 Changegroups are representations of repository revlog data, specifically
3566 the changelog data, root/flat manifest data, treemanifest data, and
3574 the changelog data, root/flat manifest data, treemanifest data, and
3567 filelogs.
3575 filelogs.
3568 </p>
3576 </p>
3569 <p>
3577 <p>
3570 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3578 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3571 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3579 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3572 only difference being an additional item in the *delta header*. Version
3580 only difference being an additional item in the *delta header*. Version
3573 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3581 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3574 exchanging treemanifests (enabled by setting an option on the
3582 exchanging treemanifests (enabled by setting an option on the
3575 &quot;changegroup&quot; part in the bundle2).
3583 &quot;changegroup&quot; part in the bundle2).
3576 </p>
3584 </p>
3577 <p>
3585 <p>
3578 Changegroups when not exchanging treemanifests consist of 3 logical
3586 Changegroups when not exchanging treemanifests consist of 3 logical
3579 segments:
3587 segments:
3580 </p>
3588 </p>
3581 <pre>
3589 <pre>
3582 +---------------------------------+
3590 +---------------------------------+
3583 | | | |
3591 | | | |
3584 | changeset | manifest | filelogs |
3592 | changeset | manifest | filelogs |
3585 | | | |
3593 | | | |
3586 | | | |
3594 | | | |
3587 +---------------------------------+
3595 +---------------------------------+
3588 </pre>
3596 </pre>
3589 <p>
3597 <p>
3590 When exchanging treemanifests, there are 4 logical segments:
3598 When exchanging treemanifests, there are 4 logical segments:
3591 </p>
3599 </p>
3592 <pre>
3600 <pre>
3593 +-------------------------------------------------+
3601 +-------------------------------------------------+
3594 | | | | |
3602 | | | | |
3595 | changeset | root | treemanifests | filelogs |
3603 | changeset | root | treemanifests | filelogs |
3596 | | manifest | | |
3604 | | manifest | | |
3597 | | | | |
3605 | | | | |
3598 +-------------------------------------------------+
3606 +-------------------------------------------------+
3599 </pre>
3607 </pre>
3600 <p>
3608 <p>
3601 The principle building block of each segment is a *chunk*. A *chunk*
3609 The principle building block of each segment is a *chunk*. A *chunk*
3602 is a framed piece of data:
3610 is a framed piece of data:
3603 </p>
3611 </p>
3604 <pre>
3612 <pre>
3605 +---------------------------------------+
3613 +---------------------------------------+
3606 | | |
3614 | | |
3607 | length | data |
3615 | length | data |
3608 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3616 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3609 | | |
3617 | | |
3610 +---------------------------------------+
3618 +---------------------------------------+
3611 </pre>
3619 </pre>
3612 <p>
3620 <p>
3613 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3621 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3614 integer indicating the length of the entire chunk (including the length field
3622 integer indicating the length of the entire chunk (including the length field
3615 itself).
3623 itself).
3616 </p>
3624 </p>
3617 <p>
3625 <p>
3618 There is a special case chunk that has a value of 0 for the length
3626 There is a special case chunk that has a value of 0 for the length
3619 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3627 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3620 </p>
3628 </p>
3621 <h2>Delta Groups</h2>
3629 <h2>Delta Groups</h2>
3622 <p>
3630 <p>
3623 A *delta group* expresses the content of a revlog as a series of deltas,
3631 A *delta group* expresses the content of a revlog as a series of deltas,
3624 or patches against previous revisions.
3632 or patches against previous revisions.
3625 </p>
3633 </p>
3626 <p>
3634 <p>
3627 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3635 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3628 to signal the end of the delta group:
3636 to signal the end of the delta group:
3629 </p>
3637 </p>
3630 <pre>
3638 <pre>
3631 +------------------------------------------------------------------------+
3639 +------------------------------------------------------------------------+
3632 | | | | | |
3640 | | | | | |
3633 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3641 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3634 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3642 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3635 | | | | | |
3643 | | | | | |
3636 +------------------------------------------------------------------------+
3644 +------------------------------------------------------------------------+
3637 </pre>
3645 </pre>
3638 <p>
3646 <p>
3639 Each *chunk*'s data consists of the following:
3647 Each *chunk*'s data consists of the following:
3640 </p>
3648 </p>
3641 <pre>
3649 <pre>
3642 +---------------------------------------+
3650 +---------------------------------------+
3643 | | |
3651 | | |
3644 | delta header | delta data |
3652 | delta header | delta data |
3645 | (various by version) | (various) |
3653 | (various by version) | (various) |
3646 | | |
3654 | | |
3647 +---------------------------------------+
3655 +---------------------------------------+
3648 </pre>
3656 </pre>
3649 <p>
3657 <p>
3650 The *delta data* is a series of *delta*s that describe a diff from an existing
3658 The *delta data* is a series of *delta*s that describe a diff from an existing
3651 entry (either that the recipient already has, or previously specified in the
3659 entry (either that the recipient already has, or previously specified in the
3652 bundle/changegroup).
3660 bundle/changegroup).
3653 </p>
3661 </p>
3654 <p>
3662 <p>
3655 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3663 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3656 &quot;3&quot; of the changegroup format.
3664 &quot;3&quot; of the changegroup format.
3657 </p>
3665 </p>
3658 <p>
3666 <p>
3659 Version 1 (headerlen=80):
3667 Version 1 (headerlen=80):
3660 </p>
3668 </p>
3661 <pre>
3669 <pre>
3662 +------------------------------------------------------+
3670 +------------------------------------------------------+
3663 | | | | |
3671 | | | | |
3664 | node | p1 node | p2 node | link node |
3672 | node | p1 node | p2 node | link node |
3665 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3673 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3666 | | | | |
3674 | | | | |
3667 +------------------------------------------------------+
3675 +------------------------------------------------------+
3668 </pre>
3676 </pre>
3669 <p>
3677 <p>
3670 Version 2 (headerlen=100):
3678 Version 2 (headerlen=100):
3671 </p>
3679 </p>
3672 <pre>
3680 <pre>
3673 +------------------------------------------------------------------+
3681 +------------------------------------------------------------------+
3674 | | | | | |
3682 | | | | | |
3675 | node | p1 node | p2 node | base node | link node |
3683 | node | p1 node | p2 node | base node | link node |
3676 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3684 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3677 | | | | | |
3685 | | | | | |
3678 +------------------------------------------------------------------+
3686 +------------------------------------------------------------------+
3679 </pre>
3687 </pre>
3680 <p>
3688 <p>
3681 Version 3 (headerlen=102):
3689 Version 3 (headerlen=102):
3682 </p>
3690 </p>
3683 <pre>
3691 <pre>
3684 +------------------------------------------------------------------------------+
3692 +------------------------------------------------------------------------------+
3685 | | | | | | |
3693 | | | | | | |
3686 | node | p1 node | p2 node | base node | link node | flags |
3694 | node | p1 node | p2 node | base node | link node | flags |
3687 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3695 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3688 | | | | | | |
3696 | | | | | | |
3689 +------------------------------------------------------------------------------+
3697 +------------------------------------------------------------------------------+
3690 </pre>
3698 </pre>
3691 <p>
3699 <p>
3692 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3700 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3693 series of *delta*s, densely packed (no separators). These deltas describe a diff
3701 series of *delta*s, densely packed (no separators). These deltas describe a diff
3694 from an existing entry (either that the recipient already has, or previously
3702 from an existing entry (either that the recipient already has, or previously
3695 specified in the bundle/changegroup). The format is described more fully in
3703 specified in the bundle/changegroup). The format is described more fully in
3696 &quot;hg help internals.bdiff&quot;, but briefly:
3704 &quot;hg help internals.bdiff&quot;, but briefly:
3697 </p>
3705 </p>
3698 <pre>
3706 <pre>
3699 +---------------------------------------------------------------+
3707 +---------------------------------------------------------------+
3700 | | | | |
3708 | | | | |
3701 | start offset | end offset | new length | content |
3709 | start offset | end offset | new length | content |
3702 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3710 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3703 | | | | |
3711 | | | | |
3704 +---------------------------------------------------------------+
3712 +---------------------------------------------------------------+
3705 </pre>
3713 </pre>
3706 <p>
3714 <p>
3707 Please note that the length field in the delta data does *not* include itself.
3715 Please note that the length field in the delta data does *not* include itself.
3708 </p>
3716 </p>
3709 <p>
3717 <p>
3710 In version 1, the delta is always applied against the previous node from
3718 In version 1, the delta is always applied against the previous node from
3711 the changegroup or the first parent if this is the first entry in the
3719 the changegroup or the first parent if this is the first entry in the
3712 changegroup.
3720 changegroup.
3713 </p>
3721 </p>
3714 <p>
3722 <p>
3715 In version 2 and up, the delta base node is encoded in the entry in the
3723 In version 2 and up, the delta base node is encoded in the entry in the
3716 changegroup. This allows the delta to be expressed against any parent,
3724 changegroup. This allows the delta to be expressed against any parent,
3717 which can result in smaller deltas and more efficient encoding of data.
3725 which can result in smaller deltas and more efficient encoding of data.
3718 </p>
3726 </p>
3719 <p>
3727 <p>
3720 The *flags* field holds bitwise flags affecting the processing of revision
3728 The *flags* field holds bitwise flags affecting the processing of revision
3721 data. The following flags are defined:
3729 data. The following flags are defined:
3722 </p>
3730 </p>
3723 <dl>
3731 <dl>
3724 <dt>32768
3732 <dt>32768
3725 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3733 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3726 <dt>16384
3734 <dt>16384
3727 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3735 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3728 <dt>8192
3736 <dt>8192
3729 <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.
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.
3730 </dl>
3738 </dl>
3731 <p>
3739 <p>
3732 For historical reasons, the integer values are identical to revlog version 1
3740 For historical reasons, the integer values are identical to revlog version 1
3733 per-revision storage flags and correspond to bits being set in this 2-byte
3741 per-revision storage flags and correspond to bits being set in this 2-byte
3734 field. Bits were allocated starting from the most-significant bit, hence the
3742 field. Bits were allocated starting from the most-significant bit, hence the
3735 reverse ordering and allocation of these flags.
3743 reverse ordering and allocation of these flags.
3736 </p>
3744 </p>
3737 <h2>Changeset Segment</h2>
3745 <h2>Changeset Segment</h2>
3738 <p>
3746 <p>
3739 The *changeset segment* consists of a single *delta group* holding
3747 The *changeset segment* consists of a single *delta group* holding
3740 changelog data. The *empty chunk* at the end of the *delta group* denotes
3748 changelog data. The *empty chunk* at the end of the *delta group* denotes
3741 the boundary to the *manifest segment*.
3749 the boundary to the *manifest segment*.
3742 </p>
3750 </p>
3743 <h2>Manifest Segment</h2>
3751 <h2>Manifest Segment</h2>
3744 <p>
3752 <p>
3745 The *manifest segment* consists of a single *delta group* holding manifest
3753 The *manifest segment* consists of a single *delta group* holding manifest
3746 data. If treemanifests are in use, it contains only the manifest for the
3754 data. If treemanifests are in use, it contains only the manifest for the
3747 root directory of the repository. Otherwise, it contains the entire
3755 root directory of the repository. Otherwise, it contains the entire
3748 manifest data. The *empty chunk* at the end of the *delta group* denotes
3756 manifest data. The *empty chunk* at the end of the *delta group* denotes
3749 the boundary to the next segment (either the *treemanifests segment* or the
3757 the boundary to the next segment (either the *treemanifests segment* or the
3750 *filelogs segment*, depending on version and the request options).
3758 *filelogs segment*, depending on version and the request options).
3751 </p>
3759 </p>
3752 <h3>Treemanifests Segment</h3>
3760 <h3>Treemanifests Segment</h3>
3753 <p>
3761 <p>
3754 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3762 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3755 only if the 'treemanifest' param is part of the bundle2 changegroup part
3763 only if the 'treemanifest' param is part of the bundle2 changegroup part
3756 (it is not possible to use changegroup version 3 outside of bundle2).
3764 (it is not possible to use changegroup version 3 outside of bundle2).
3757 Aside from the filenames in the *treemanifests segment* containing a
3765 Aside from the filenames in the *treemanifests segment* containing a
3758 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3766 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3759 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3767 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3760 a sub-segment with filename size 0). This denotes the boundary to the
3768 a sub-segment with filename size 0). This denotes the boundary to the
3761 *filelogs segment*.
3769 *filelogs segment*.
3762 </p>
3770 </p>
3763 <h2>Filelogs Segment</h2>
3771 <h2>Filelogs Segment</h2>
3764 <p>
3772 <p>
3765 The *filelogs segment* consists of multiple sub-segments, each
3773 The *filelogs segment* consists of multiple sub-segments, each
3766 corresponding to an individual file whose data is being described:
3774 corresponding to an individual file whose data is being described:
3767 </p>
3775 </p>
3768 <pre>
3776 <pre>
3769 +--------------------------------------------------+
3777 +--------------------------------------------------+
3770 | | | | | |
3778 | | | | | |
3771 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3779 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3772 | | | | | (4 bytes) |
3780 | | | | | (4 bytes) |
3773 | | | | | |
3781 | | | | | |
3774 +--------------------------------------------------+
3782 +--------------------------------------------------+
3775 </pre>
3783 </pre>
3776 <p>
3784 <p>
3777 The final filelog sub-segment is followed by an *empty chunk* (logically,
3785 The final filelog sub-segment is followed by an *empty chunk* (logically,
3778 a sub-segment with filename size 0). This denotes the end of the segment
3786 a sub-segment with filename size 0). This denotes the end of the segment
3779 and of the overall changegroup.
3787 and of the overall changegroup.
3780 </p>
3788 </p>
3781 <p>
3789 <p>
3782 Each filelog sub-segment consists of the following:
3790 Each filelog sub-segment consists of the following:
3783 </p>
3791 </p>
3784 <pre>
3792 <pre>
3785 +------------------------------------------------------+
3793 +------------------------------------------------------+
3786 | | | |
3794 | | | |
3787 | filename length | filename | delta group |
3795 | filename length | filename | delta group |
3788 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3796 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3789 | | | |
3797 | | | |
3790 +------------------------------------------------------+
3798 +------------------------------------------------------+
3791 </pre>
3799 </pre>
3792 <p>
3800 <p>
3793 That is, a *chunk* consisting of the filename (not terminated or padded)
3801 That is, a *chunk* consisting of the filename (not terminated or padded)
3794 followed by N chunks constituting the *delta group* for this file. The
3802 followed by N chunks constituting the *delta group* for this file. The
3795 *empty chunk* at the end of each *delta group* denotes the boundary to the
3803 *empty chunk* at the end of each *delta group* denotes the boundary to the
3796 next filelog sub-segment.
3804 next filelog sub-segment.
3797 </p>
3805 </p>
3798
3806
3799 </div>
3807 </div>
3800 </div>
3808 </div>
3801 </div>
3809 </div>
3802
3810
3803
3811
3804
3812
3805 </body>
3813 </body>
3806 </html>
3814 </html>
3807
3815
3808
3816
3809 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3817 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3810 404 Not Found
3818 404 Not Found
3811
3819
3812 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3820 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3813 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3821 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3814 <head>
3822 <head>
3815 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3823 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3816 <meta name="robots" content="index, nofollow" />
3824 <meta name="robots" content="index, nofollow" />
3817 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3825 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3818 <script type="text/javascript" src="/static/mercurial.js"></script>
3826 <script type="text/javascript" src="/static/mercurial.js"></script>
3819
3827
3820 <title>test: error</title>
3828 <title>test: error</title>
3821 </head>
3829 </head>
3822 <body>
3830 <body>
3823
3831
3824 <div class="container">
3832 <div class="container">
3825 <div class="menu">
3833 <div class="menu">
3826 <div class="logo">
3834 <div class="logo">
3827 <a href="https://mercurial-scm.org/">
3835 <a href="https://mercurial-scm.org/">
3828 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3836 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3829 </div>
3837 </div>
3830 <ul>
3838 <ul>
3831 <li><a href="/shortlog">log</a></li>
3839 <li><a href="/shortlog">log</a></li>
3832 <li><a href="/graph">graph</a></li>
3840 <li><a href="/graph">graph</a></li>
3833 <li><a href="/tags">tags</a></li>
3841 <li><a href="/tags">tags</a></li>
3834 <li><a href="/bookmarks">bookmarks</a></li>
3842 <li><a href="/bookmarks">bookmarks</a></li>
3835 <li><a href="/branches">branches</a></li>
3843 <li><a href="/branches">branches</a></li>
3836 </ul>
3844 </ul>
3837 <ul>
3845 <ul>
3838 <li><a href="/help">help</a></li>
3846 <li><a href="/help">help</a></li>
3839 </ul>
3847 </ul>
3840 </div>
3848 </div>
3841
3849
3842 <div class="main">
3850 <div class="main">
3843
3851
3844 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3852 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3845 <h3>error</h3>
3853 <h3>error</h3>
3846
3854
3847
3855
3848 <form class="search" action="/log">
3856 <form class="search" action="/log">
3849
3857
3850 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3858 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3851 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3859 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3852 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3860 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3853 </form>
3861 </form>
3854
3862
3855 <div class="description">
3863 <div class="description">
3856 <p>
3864 <p>
3857 An error occurred while processing your request:
3865 An error occurred while processing your request:
3858 </p>
3866 </p>
3859 <p>
3867 <p>
3860 Not Found
3868 Not Found
3861 </p>
3869 </p>
3862 </div>
3870 </div>
3863 </div>
3871 </div>
3864 </div>
3872 </div>
3865
3873
3866
3874
3867
3875
3868 </body>
3876 </body>
3869 </html>
3877 </html>
3870
3878
3871 [1]
3879 [1]
3872
3880
3873 $ killdaemons.py
3881 $ killdaemons.py
3874
3882
3875 #endif
3883 #endif
@@ -1,2228 +1,2232 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)",
1879 "topic": "abort"
1880 },
1881 {
1878 "summary": "add the specified files on the next commit",
1882 "summary": "add the specified files on the next commit",
1879 "topic": "add"
1883 "topic": "add"
1880 },
1884 },
1881 {
1885 {
1882 "summary": "show changeset information by line for each file",
1886 "summary": "show changeset information by line for each file",
1883 "topic": "annotate"
1887 "topic": "annotate"
1884 },
1888 },
1885 {
1889 {
1886 "summary": "make a copy of an existing repository",
1890 "summary": "make a copy of an existing repository",
1887 "topic": "clone"
1891 "topic": "clone"
1888 },
1892 },
1889 {
1893 {
1890 "summary": "commit the specified files or all outstanding changes",
1894 "summary": "commit the specified files or all outstanding changes",
1891 "topic": "commit"
1895 "topic": "commit"
1892 },
1896 },
1893 {
1897 {
1894 "summary": "diff repository (or selected files)",
1898 "summary": "diff repository (or selected files)",
1895 "topic": "diff"
1899 "topic": "diff"
1896 },
1900 },
1897 {
1901 {
1898 "summary": "dump the header and diffs for one or more changesets",
1902 "summary": "dump the header and diffs for one or more changesets",
1899 "topic": "export"
1903 "topic": "export"
1900 },
1904 },
1901 {
1905 {
1902 "summary": "forget the specified files on the next commit",
1906 "summary": "forget the specified files on the next commit",
1903 "topic": "forget"
1907 "topic": "forget"
1904 },
1908 },
1905 {
1909 {
1906 "summary": "create a new repository in the given directory",
1910 "summary": "create a new repository in the given directory",
1907 "topic": "init"
1911 "topic": "init"
1908 },
1912 },
1909 {
1913 {
1910 "summary": "show revision history of entire repository or files",
1914 "summary": "show revision history of entire repository or files",
1911 "topic": "log"
1915 "topic": "log"
1912 },
1916 },
1913 {
1917 {
1914 "summary": "merge another revision into working directory",
1918 "summary": "merge another revision into working directory",
1915 "topic": "merge"
1919 "topic": "merge"
1916 },
1920 },
1917 {
1921 {
1918 "summary": "pull changes from the specified source",
1922 "summary": "pull changes from the specified source",
1919 "topic": "pull"
1923 "topic": "pull"
1920 },
1924 },
1921 {
1925 {
1922 "summary": "push changes to the specified destination",
1926 "summary": "push changes to the specified destination",
1923 "topic": "push"
1927 "topic": "push"
1924 },
1928 },
1925 {
1929 {
1926 "summary": "remove the specified files on the next commit",
1930 "summary": "remove the specified files on the next commit",
1927 "topic": "remove"
1931 "topic": "remove"
1928 },
1932 },
1929 {
1933 {
1930 "summary": "start stand-alone webserver",
1934 "summary": "start stand-alone webserver",
1931 "topic": "serve"
1935 "topic": "serve"
1932 },
1936 },
1933 {
1937 {
1934 "summary": "show changed files in the working directory",
1938 "summary": "show changed files in the working directory",
1935 "topic": "status"
1939 "topic": "status"
1936 },
1940 },
1937 {
1941 {
1938 "summary": "summarize working directory state",
1942 "summary": "summarize working directory state",
1939 "topic": "summary"
1943 "topic": "summary"
1940 },
1944 },
1941 {
1945 {
1942 "summary": "update working directory (or switch revisions)",
1946 "summary": "update working directory (or switch revisions)",
1943 "topic": "update"
1947 "topic": "update"
1944 }
1948 }
1945 ],
1949 ],
1946 "othercommands": [
1950 "othercommands": [
1947 {
1951 {
1948 "summary": "add all new files, delete all missing files",
1952 "summary": "add all new files, delete all missing files",
1949 "topic": "addremove"
1953 "topic": "addremove"
1950 },
1954 },
1951 {
1955 {
1952 "summary": "create an unversioned archive of a repository revision",
1956 "summary": "create an unversioned archive of a repository revision",
1953 "topic": "archive"
1957 "topic": "archive"
1954 },
1958 },
1955 {
1959 {
1956 "summary": "reverse effect of earlier changeset",
1960 "summary": "reverse effect of earlier changeset",
1957 "topic": "backout"
1961 "topic": "backout"
1958 },
1962 },
1959 {
1963 {
1960 "summary": "subdivision search of changesets",
1964 "summary": "subdivision search of changesets",
1961 "topic": "bisect"
1965 "topic": "bisect"
1962 },
1966 },
1963 {
1967 {
1964 "summary": "create a new bookmark or list existing bookmarks",
1968 "summary": "create a new bookmark or list existing bookmarks",
1965 "topic": "bookmarks"
1969 "topic": "bookmarks"
1966 },
1970 },
1967 {
1971 {
1968 "summary": "set or show the current branch name",
1972 "summary": "set or show the current branch name",
1969 "topic": "branch"
1973 "topic": "branch"
1970 },
1974 },
1971 {
1975 {
1972 "summary": "list repository named branches",
1976 "summary": "list repository named branches",
1973 "topic": "branches"
1977 "topic": "branches"
1974 },
1978 },
1975 {
1979 {
1976 "summary": "create a bundle file",
1980 "summary": "create a bundle file",
1977 "topic": "bundle"
1981 "topic": "bundle"
1978 },
1982 },
1979 {
1983 {
1980 "summary": "output the current or given revision of files",
1984 "summary": "output the current or given revision of files",
1981 "topic": "cat"
1985 "topic": "cat"
1982 },
1986 },
1983 {
1987 {
1984 "summary": "show combined config settings from all hgrc files",
1988 "summary": "show combined config settings from all hgrc files",
1985 "topic": "config"
1989 "topic": "config"
1986 },
1990 },
1987 {
1991 {
1988 "summary": "mark files as copied for the next commit",
1992 "summary": "mark files as copied for the next commit",
1989 "topic": "copy"
1993 "topic": "copy"
1990 },
1994 },
1991 {
1995 {
1992 "summary": "list tracked files",
1996 "summary": "list tracked files",
1993 "topic": "files"
1997 "topic": "files"
1994 },
1998 },
1995 {
1999 {
1996 "summary": "copy changes from other branches onto the current branch",
2000 "summary": "copy changes from other branches onto the current branch",
1997 "topic": "graft"
2001 "topic": "graft"
1998 },
2002 },
1999 {
2003 {
2000 "summary": "search revision history for a pattern in specified files",
2004 "summary": "search revision history for a pattern in specified files",
2001 "topic": "grep"
2005 "topic": "grep"
2002 },
2006 },
2003 {
2007 {
2004 "summary": "show branch heads",
2008 "summary": "show branch heads",
2005 "topic": "heads"
2009 "topic": "heads"
2006 },
2010 },
2007 {
2011 {
2008 "summary": "show help for a given topic or a help overview",
2012 "summary": "show help for a given topic or a help overview",
2009 "topic": "help"
2013 "topic": "help"
2010 },
2014 },
2011 {
2015 {
2012 "summary": "identify the working directory or specified revision",
2016 "summary": "identify the working directory or specified revision",
2013 "topic": "identify"
2017 "topic": "identify"
2014 },
2018 },
2015 {
2019 {
2016 "summary": "import an ordered set of patches",
2020 "summary": "import an ordered set of patches",
2017 "topic": "import"
2021 "topic": "import"
2018 },
2022 },
2019 {
2023 {
2020 "summary": "show new changesets found in source",
2024 "summary": "show new changesets found in source",
2021 "topic": "incoming"
2025 "topic": "incoming"
2022 },
2026 },
2023 {
2027 {
2024 "summary": "output the current or given revision of the project manifest",
2028 "summary": "output the current or given revision of the project manifest",
2025 "topic": "manifest"
2029 "topic": "manifest"
2026 },
2030 },
2027 {
2031 {
2028 "summary": "show changesets not found in the destination",
2032 "summary": "show changesets not found in the destination",
2029 "topic": "outgoing"
2033 "topic": "outgoing"
2030 },
2034 },
2031 {
2035 {
2032 "summary": "show aliases for remote repositories",
2036 "summary": "show aliases for remote repositories",
2033 "topic": "paths"
2037 "topic": "paths"
2034 },
2038 },
2035 {
2039 {
2036 "summary": "set or show the current phase name",
2040 "summary": "set or show the current phase name",
2037 "topic": "phase"
2041 "topic": "phase"
2038 },
2042 },
2039 {
2043 {
2040 "summary": "roll back an interrupted transaction",
2044 "summary": "roll back an interrupted transaction",
2041 "topic": "recover"
2045 "topic": "recover"
2042 },
2046 },
2043 {
2047 {
2044 "summary": "rename files; equivalent of copy + remove",
2048 "summary": "rename files; equivalent of copy + remove",
2045 "topic": "rename"
2049 "topic": "rename"
2046 },
2050 },
2047 {
2051 {
2048 "summary": "redo merges or set/view the merge status of files",
2052 "summary": "redo merges or set/view the merge status of files",
2049 "topic": "resolve"
2053 "topic": "resolve"
2050 },
2054 },
2051 {
2055 {
2052 "summary": "restore files to their checkout state",
2056 "summary": "restore files to their checkout state",
2053 "topic": "revert"
2057 "topic": "revert"
2054 },
2058 },
2055 {
2059 {
2056 "summary": "print the root (top) of the current working directory",
2060 "summary": "print the root (top) of the current working directory",
2057 "topic": "root"
2061 "topic": "root"
2058 },
2062 },
2059 {
2063 {
2060 "summary": "save and set aside changes from the working directory",
2064 "summary": "save and set aside changes from the working directory",
2061 "topic": "shelve"
2065 "topic": "shelve"
2062 },
2066 },
2063 {
2067 {
2064 "summary": "add one or more tags for the current or given revision",
2068 "summary": "add one or more tags for the current or given revision",
2065 "topic": "tag"
2069 "topic": "tag"
2066 },
2070 },
2067 {
2071 {
2068 "summary": "list repository tags",
2072 "summary": "list repository tags",
2069 "topic": "tags"
2073 "topic": "tags"
2070 },
2074 },
2071 {
2075 {
2072 "summary": "apply one or more bundle files",
2076 "summary": "apply one or more bundle files",
2073 "topic": "unbundle"
2077 "topic": "unbundle"
2074 },
2078 },
2075 {
2079 {
2076 "summary": "restore a shelved change to the working directory",
2080 "summary": "restore a shelved change to the working directory",
2077 "topic": "unshelve"
2081 "topic": "unshelve"
2078 },
2082 },
2079 {
2083 {
2080 "summary": "verify the integrity of the repository",
2084 "summary": "verify the integrity of the repository",
2081 "topic": "verify"
2085 "topic": "verify"
2082 },
2086 },
2083 {
2087 {
2084 "summary": "output version and copyright information",
2088 "summary": "output version and copyright information",
2085 "topic": "version"
2089 "topic": "version"
2086 }
2090 }
2087 ],
2091 ],
2088 "topics": [
2092 "topics": [
2089 {
2093 {
2090 "summary": "Bundle File Formats",
2094 "summary": "Bundle File Formats",
2091 "topic": "bundlespec"
2095 "topic": "bundlespec"
2092 },
2096 },
2093 {
2097 {
2094 "summary": "Colorizing Outputs",
2098 "summary": "Colorizing Outputs",
2095 "topic": "color"
2099 "topic": "color"
2096 },
2100 },
2097 {
2101 {
2098 "summary": "Configuration Files",
2102 "summary": "Configuration Files",
2099 "topic": "config"
2103 "topic": "config"
2100 },
2104 },
2101 {
2105 {
2102 "summary": "Date Formats",
2106 "summary": "Date Formats",
2103 "topic": "dates"
2107 "topic": "dates"
2104 },
2108 },
2105 {
2109 {
2106 "summary": "Deprecated Features",
2110 "summary": "Deprecated Features",
2107 "topic": "deprecated"
2111 "topic": "deprecated"
2108 },
2112 },
2109 {
2113 {
2110 "summary": "Diff Formats",
2114 "summary": "Diff Formats",
2111 "topic": "diffs"
2115 "topic": "diffs"
2112 },
2116 },
2113 {
2117 {
2114 "summary": "Environment Variables",
2118 "summary": "Environment Variables",
2115 "topic": "environment"
2119 "topic": "environment"
2116 },
2120 },
2117 {
2121 {
2118 "summary": "Using Additional Features",
2122 "summary": "Using Additional Features",
2119 "topic": "extensions"
2123 "topic": "extensions"
2120 },
2124 },
2121 {
2125 {
2122 "summary": "Specifying File Sets",
2126 "summary": "Specifying File Sets",
2123 "topic": "filesets"
2127 "topic": "filesets"
2124 },
2128 },
2125 {
2129 {
2126 "summary": "Command-line flags",
2130 "summary": "Command-line flags",
2127 "topic": "flags"
2131 "topic": "flags"
2128 },
2132 },
2129 {
2133 {
2130 "summary": "Glossary",
2134 "summary": "Glossary",
2131 "topic": "glossary"
2135 "topic": "glossary"
2132 },
2136 },
2133 {
2137 {
2134 "summary": "Syntax for Mercurial Ignore Files",
2138 "summary": "Syntax for Mercurial Ignore Files",
2135 "topic": "hgignore"
2139 "topic": "hgignore"
2136 },
2140 },
2137 {
2141 {
2138 "summary": "Configuring hgweb",
2142 "summary": "Configuring hgweb",
2139 "topic": "hgweb"
2143 "topic": "hgweb"
2140 },
2144 },
2141 {
2145 {
2142 "summary": "Technical implementation topics",
2146 "summary": "Technical implementation topics",
2143 "topic": "internals"
2147 "topic": "internals"
2144 },
2148 },
2145 {
2149 {
2146 "summary": "Merge Tools",
2150 "summary": "Merge Tools",
2147 "topic": "merge-tools"
2151 "topic": "merge-tools"
2148 },
2152 },
2149 {
2153 {
2150 "summary": "Pager Support",
2154 "summary": "Pager Support",
2151 "topic": "pager"
2155 "topic": "pager"
2152 },
2156 },
2153 {
2157 {
2154 "summary": "File Name Patterns",
2158 "summary": "File Name Patterns",
2155 "topic": "patterns"
2159 "topic": "patterns"
2156 },
2160 },
2157 {
2161 {
2158 "summary": "Working with Phases",
2162 "summary": "Working with Phases",
2159 "topic": "phases"
2163 "topic": "phases"
2160 },
2164 },
2161 {
2165 {
2162 "summary": "Specifying Revisions",
2166 "summary": "Specifying Revisions",
2163 "topic": "revisions"
2167 "topic": "revisions"
2164 },
2168 },
2165 {
2169 {
2166 "summary": "Using Mercurial from scripts and automation",
2170 "summary": "Using Mercurial from scripts and automation",
2167 "topic": "scripting"
2171 "topic": "scripting"
2168 },
2172 },
2169 {
2173 {
2170 "summary": "Subrepositories",
2174 "summary": "Subrepositories",
2171 "topic": "subrepos"
2175 "topic": "subrepos"
2172 },
2176 },
2173 {
2177 {
2174 "summary": "Template Usage",
2178 "summary": "Template Usage",
2175 "topic": "templating"
2179 "topic": "templating"
2176 },
2180 },
2177 {
2181 {
2178 "summary": "URL Paths",
2182 "summary": "URL Paths",
2179 "topic": "urls"
2183 "topic": "urls"
2180 }
2184 }
2181 ]
2185 ]
2182 }
2186 }
2183
2187
2184 help/{topic} shows an individual help topic
2188 help/{topic} shows an individual help topic
2185
2189
2186 $ request json-help/phases
2190 $ request json-help/phases
2187 200 Script output follows
2191 200 Script output follows
2188
2192
2189 {
2193 {
2190 "rawdoc": "Working with Phases\n*", (glob)
2194 "rawdoc": "Working with Phases\n*", (glob)
2191 "topic": "phases"
2195 "topic": "phases"
2192 }
2196 }
2193
2197
2194 Error page shouldn't crash
2198 Error page shouldn't crash
2195
2199
2196 $ request json-changeset/deadbeef
2200 $ request json-changeset/deadbeef
2197 404 Not Found
2201 404 Not Found
2198
2202
2199 {
2203 {
2200 "error": "unknown revision 'deadbeef'"
2204 "error": "unknown revision 'deadbeef'"
2201 }
2205 }
2202 [1]
2206 [1]
2203
2207
2204 Commit message with Japanese Kanji 'Noh', which ends with '\x5c'
2208 Commit message with Japanese Kanji 'Noh', which ends with '\x5c'
2205
2209
2206 $ echo foo >> da/foo
2210 $ echo foo >> da/foo
2207 >>> open('msg', 'wb').write(b'\x94\x5c\x0a') and None
2211 >>> open('msg', 'wb').write(b'\x94\x5c\x0a') and None
2208 $ HGENCODING=cp932 hg ci -l msg
2212 $ HGENCODING=cp932 hg ci -l msg
2209
2213
2210 Commit message with null character
2214 Commit message with null character
2211
2215
2212 $ echo foo >> da/foo
2216 $ echo foo >> da/foo
2213 >>> open('msg', 'wb').write(b'commit with null character: \0\n') and None
2217 >>> open('msg', 'wb').write(b'commit with null character: \0\n') and None
2214 $ hg ci -l msg
2218 $ hg ci -l msg
2215 $ rm msg
2219 $ rm msg
2216
2220
2217 Stop and restart with HGENCODING=cp932
2221 Stop and restart with HGENCODING=cp932
2218
2222
2219 $ killdaemons.py
2223 $ killdaemons.py
2220 $ HGENCODING=cp932 hg serve -p $HGPORT -d --pid-file=hg.pid \
2224 $ HGENCODING=cp932 hg serve -p $HGPORT -d --pid-file=hg.pid \
2221 > -A access.log -E error.log
2225 > -A access.log -E error.log
2222 $ cat hg.pid >> $DAEMON_PIDS
2226 $ cat hg.pid >> $DAEMON_PIDS
2223
2227
2224 Test json escape of multibyte characters
2228 Test json escape of multibyte characters
2225
2229
2226 $ request json-filelog/tip/da/foo?revcount=2 | grep '"desc":'
2230 $ request json-filelog/tip/da/foo?revcount=2 | grep '"desc":'
2227 "desc": "commit with null character: \u0000",
2231 "desc": "commit with null character: \u0000",
2228 "desc": "\u80fd",
2232 "desc": "\u80fd",
General Comments 0
You need to be logged in to leave comments. Login now