##// END OF EJS Templates
verify: introduce an experimental --full flag...
marmoute -
r42332:496ac8a0 default
parent child Browse files
Show More
@@ -1,6250 +1,6256 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 repair,
56 repair,
57 revsetlang,
57 revsetlang,
58 rewriteutil,
58 rewriteutil,
59 scmutil,
59 scmutil,
60 server,
60 server,
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 wireprotoserver,
67 wireprotoserver,
67 )
68 )
68 from .utils import (
69 from .utils import (
69 dateutil,
70 dateutil,
70 stringutil,
71 stringutil,
71 )
72 )
72
73
73 table = {}
74 table = {}
74 table.update(debugcommandsmod.command._table)
75 table.update(debugcommandsmod.command._table)
75
76
76 command = registrar.command(table)
77 command = registrar.command(table)
77 INTENT_READONLY = registrar.INTENT_READONLY
78 INTENT_READONLY = registrar.INTENT_READONLY
78
79
79 # common command options
80 # common command options
80
81
81 globalopts = [
82 globalopts = [
82 ('R', 'repository', '',
83 ('R', 'repository', '',
83 _('repository root directory or name of overlay bundle file'),
84 _('repository root directory or name of overlay bundle file'),
84 _('REPO')),
85 _('REPO')),
85 ('', 'cwd', '',
86 ('', 'cwd', '',
86 _('change working directory'), _('DIR')),
87 _('change working directory'), _('DIR')),
87 ('y', 'noninteractive', None,
88 ('y', 'noninteractive', None,
88 _('do not prompt, automatically pick the first choice for all prompts')),
89 _('do not prompt, automatically pick the first choice for all prompts')),
89 ('q', 'quiet', None, _('suppress output')),
90 ('q', 'quiet', None, _('suppress output')),
90 ('v', 'verbose', None, _('enable additional output')),
91 ('v', 'verbose', None, _('enable additional output')),
91 ('', 'color', '',
92 ('', 'color', '',
92 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
93 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
93 # and should not be translated
94 # and should not be translated
94 _("when to colorize (boolean, always, auto, never, or debug)"),
95 _("when to colorize (boolean, always, auto, never, or debug)"),
95 _('TYPE')),
96 _('TYPE')),
96 ('', 'config', [],
97 ('', 'config', [],
97 _('set/override config option (use \'section.name=value\')'),
98 _('set/override config option (use \'section.name=value\')'),
98 _('CONFIG')),
99 _('CONFIG')),
99 ('', 'debug', None, _('enable debugging output')),
100 ('', 'debug', None, _('enable debugging output')),
100 ('', 'debugger', None, _('start debugger')),
101 ('', 'debugger', None, _('start debugger')),
101 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
102 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
102 _('ENCODE')),
103 _('ENCODE')),
103 ('', 'encodingmode', encoding.encodingmode,
104 ('', 'encodingmode', encoding.encodingmode,
104 _('set the charset encoding mode'), _('MODE')),
105 _('set the charset encoding mode'), _('MODE')),
105 ('', 'traceback', None, _('always print a traceback on exception')),
106 ('', 'traceback', None, _('always print a traceback on exception')),
106 ('', 'time', None, _('time how long the command takes')),
107 ('', 'time', None, _('time how long the command takes')),
107 ('', 'profile', None, _('print command execution profile')),
108 ('', 'profile', None, _('print command execution profile')),
108 ('', 'version', None, _('output version information and exit')),
109 ('', 'version', None, _('output version information and exit')),
109 ('h', 'help', None, _('display help and exit')),
110 ('h', 'help', None, _('display help and exit')),
110 ('', 'hidden', False, _('consider hidden changesets')),
111 ('', 'hidden', False, _('consider hidden changesets')),
111 ('', 'pager', 'auto',
112 ('', 'pager', 'auto',
112 _("when to paginate (boolean, always, auto, or never)"), _('TYPE')),
113 _("when to paginate (boolean, always, auto, or never)"), _('TYPE')),
113 ]
114 ]
114
115
115 dryrunopts = cmdutil.dryrunopts
116 dryrunopts = cmdutil.dryrunopts
116 remoteopts = cmdutil.remoteopts
117 remoteopts = cmdutil.remoteopts
117 walkopts = cmdutil.walkopts
118 walkopts = cmdutil.walkopts
118 commitopts = cmdutil.commitopts
119 commitopts = cmdutil.commitopts
119 commitopts2 = cmdutil.commitopts2
120 commitopts2 = cmdutil.commitopts2
120 formatteropts = cmdutil.formatteropts
121 formatteropts = cmdutil.formatteropts
121 templateopts = cmdutil.templateopts
122 templateopts = cmdutil.templateopts
122 logopts = cmdutil.logopts
123 logopts = cmdutil.logopts
123 diffopts = cmdutil.diffopts
124 diffopts = cmdutil.diffopts
124 diffwsopts = cmdutil.diffwsopts
125 diffwsopts = cmdutil.diffwsopts
125 diffopts2 = cmdutil.diffopts2
126 diffopts2 = cmdutil.diffopts2
126 mergetoolopts = cmdutil.mergetoolopts
127 mergetoolopts = cmdutil.mergetoolopts
127 similarityopts = cmdutil.similarityopts
128 similarityopts = cmdutil.similarityopts
128 subrepoopts = cmdutil.subrepoopts
129 subrepoopts = cmdutil.subrepoopts
129 debugrevlogopts = cmdutil.debugrevlogopts
130 debugrevlogopts = cmdutil.debugrevlogopts
130
131
131 # Commands start here, listed alphabetically
132 # Commands start here, listed alphabetically
132
133
133 @command('add',
134 @command('add',
134 walkopts + subrepoopts + dryrunopts,
135 walkopts + subrepoopts + dryrunopts,
135 _('[OPTION]... [FILE]...'),
136 _('[OPTION]... [FILE]...'),
136 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
137 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
137 helpbasic=True, inferrepo=True)
138 helpbasic=True, inferrepo=True)
138 def add(ui, repo, *pats, **opts):
139 def add(ui, repo, *pats, **opts):
139 """add the specified files on the next commit
140 """add the specified files on the next commit
140
141
141 Schedule files to be version controlled and added to the
142 Schedule files to be version controlled and added to the
142 repository.
143 repository.
143
144
144 The files will be added to the repository at the next commit. To
145 The files will be added to the repository at the next commit. To
145 undo an add before that, see :hg:`forget`.
146 undo an add before that, see :hg:`forget`.
146
147
147 If no names are given, add all files to the repository (except
148 If no names are given, add all files to the repository (except
148 files matching ``.hgignore``).
149 files matching ``.hgignore``).
149
150
150 .. container:: verbose
151 .. container:: verbose
151
152
152 Examples:
153 Examples:
153
154
154 - New (unknown) files are added
155 - New (unknown) files are added
155 automatically by :hg:`add`::
156 automatically by :hg:`add`::
156
157
157 $ ls
158 $ ls
158 foo.c
159 foo.c
159 $ hg status
160 $ hg status
160 ? foo.c
161 ? foo.c
161 $ hg add
162 $ hg add
162 adding foo.c
163 adding foo.c
163 $ hg status
164 $ hg status
164 A foo.c
165 A foo.c
165
166
166 - Specific files to be added can be specified::
167 - Specific files to be added can be specified::
167
168
168 $ ls
169 $ ls
169 bar.c foo.c
170 bar.c foo.c
170 $ hg status
171 $ hg status
171 ? bar.c
172 ? bar.c
172 ? foo.c
173 ? foo.c
173 $ hg add bar.c
174 $ hg add bar.c
174 $ hg status
175 $ hg status
175 A bar.c
176 A bar.c
176 ? foo.c
177 ? foo.c
177
178
178 Returns 0 if all files are successfully added.
179 Returns 0 if all files are successfully added.
179 """
180 """
180
181
181 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
182 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
182 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
183 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
183 rejected = cmdutil.add(ui, repo, m, "", uipathfn, False, **opts)
184 rejected = cmdutil.add(ui, repo, m, "", uipathfn, False, **opts)
184 return rejected and 1 or 0
185 return rejected and 1 or 0
185
186
186 @command('addremove',
187 @command('addremove',
187 similarityopts + subrepoopts + walkopts + dryrunopts,
188 similarityopts + subrepoopts + walkopts + dryrunopts,
188 _('[OPTION]... [FILE]...'),
189 _('[OPTION]... [FILE]...'),
189 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
190 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
190 inferrepo=True)
191 inferrepo=True)
191 def addremove(ui, repo, *pats, **opts):
192 def addremove(ui, repo, *pats, **opts):
192 """add all new files, delete all missing files
193 """add all new files, delete all missing files
193
194
194 Add all new files and remove all missing files from the
195 Add all new files and remove all missing files from the
195 repository.
196 repository.
196
197
197 Unless names are given, new files are ignored if they match any of
198 Unless names are given, new files are ignored if they match any of
198 the patterns in ``.hgignore``. As with add, these changes take
199 the patterns in ``.hgignore``. As with add, these changes take
199 effect at the next commit.
200 effect at the next commit.
200
201
201 Use the -s/--similarity option to detect renamed files. This
202 Use the -s/--similarity option to detect renamed files. This
202 option takes a percentage between 0 (disabled) and 100 (files must
203 option takes a percentage between 0 (disabled) and 100 (files must
203 be identical) as its parameter. With a parameter greater than 0,
204 be identical) as its parameter. With a parameter greater than 0,
204 this compares every removed file with every added file and records
205 this compares every removed file with every added file and records
205 those similar enough as renames. Detecting renamed files this way
206 those similar enough as renames. Detecting renamed files this way
206 can be expensive. After using this option, :hg:`status -C` can be
207 can be expensive. After using this option, :hg:`status -C` can be
207 used to check which files were identified as moved or renamed. If
208 used to check which files were identified as moved or renamed. If
208 not specified, -s/--similarity defaults to 100 and only renames of
209 not specified, -s/--similarity defaults to 100 and only renames of
209 identical files are detected.
210 identical files are detected.
210
211
211 .. container:: verbose
212 .. container:: verbose
212
213
213 Examples:
214 Examples:
214
215
215 - A number of files (bar.c and foo.c) are new,
216 - A number of files (bar.c and foo.c) are new,
216 while foobar.c has been removed (without using :hg:`remove`)
217 while foobar.c has been removed (without using :hg:`remove`)
217 from the repository::
218 from the repository::
218
219
219 $ ls
220 $ ls
220 bar.c foo.c
221 bar.c foo.c
221 $ hg status
222 $ hg status
222 ! foobar.c
223 ! foobar.c
223 ? bar.c
224 ? bar.c
224 ? foo.c
225 ? foo.c
225 $ hg addremove
226 $ hg addremove
226 adding bar.c
227 adding bar.c
227 adding foo.c
228 adding foo.c
228 removing foobar.c
229 removing foobar.c
229 $ hg status
230 $ hg status
230 A bar.c
231 A bar.c
231 A foo.c
232 A foo.c
232 R foobar.c
233 R foobar.c
233
234
234 - A file foobar.c was moved to foo.c without using :hg:`rename`.
235 - A file foobar.c was moved to foo.c without using :hg:`rename`.
235 Afterwards, it was edited slightly::
236 Afterwards, it was edited slightly::
236
237
237 $ ls
238 $ ls
238 foo.c
239 foo.c
239 $ hg status
240 $ hg status
240 ! foobar.c
241 ! foobar.c
241 ? foo.c
242 ? foo.c
242 $ hg addremove --similarity 90
243 $ hg addremove --similarity 90
243 removing foobar.c
244 removing foobar.c
244 adding foo.c
245 adding foo.c
245 recording removal of foobar.c as rename to foo.c (94% similar)
246 recording removal of foobar.c as rename to foo.c (94% similar)
246 $ hg status -C
247 $ hg status -C
247 A foo.c
248 A foo.c
248 foobar.c
249 foobar.c
249 R foobar.c
250 R foobar.c
250
251
251 Returns 0 if all files are successfully added.
252 Returns 0 if all files are successfully added.
252 """
253 """
253 opts = pycompat.byteskwargs(opts)
254 opts = pycompat.byteskwargs(opts)
254 if not opts.get('similarity'):
255 if not opts.get('similarity'):
255 opts['similarity'] = '100'
256 opts['similarity'] = '100'
256 matcher = scmutil.match(repo[None], pats, opts)
257 matcher = scmutil.match(repo[None], pats, opts)
257 relative = scmutil.anypats(pats, opts)
258 relative = scmutil.anypats(pats, opts)
258 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
259 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
259 return scmutil.addremove(repo, matcher, "", uipathfn, opts)
260 return scmutil.addremove(repo, matcher, "", uipathfn, opts)
260
261
261 @command('annotate|blame',
262 @command('annotate|blame',
262 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
263 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
263 ('', 'follow', None,
264 ('', 'follow', None,
264 _('follow copies/renames and list the filename (DEPRECATED)')),
265 _('follow copies/renames and list the filename (DEPRECATED)')),
265 ('', 'no-follow', None, _("don't follow copies and renames")),
266 ('', 'no-follow', None, _("don't follow copies and renames")),
266 ('a', 'text', None, _('treat all files as text')),
267 ('a', 'text', None, _('treat all files as text')),
267 ('u', 'user', None, _('list the author (long with -v)')),
268 ('u', 'user', None, _('list the author (long with -v)')),
268 ('f', 'file', None, _('list the filename')),
269 ('f', 'file', None, _('list the filename')),
269 ('d', 'date', None, _('list the date (short with -q)')),
270 ('d', 'date', None, _('list the date (short with -q)')),
270 ('n', 'number', None, _('list the revision number (default)')),
271 ('n', 'number', None, _('list the revision number (default)')),
271 ('c', 'changeset', None, _('list the changeset')),
272 ('c', 'changeset', None, _('list the changeset')),
272 ('l', 'line-number', None, _('show line number at the first appearance')),
273 ('l', 'line-number', None, _('show line number at the first appearance')),
273 ('', 'skip', [], _('revision to not display (EXPERIMENTAL)'), _('REV')),
274 ('', 'skip', [], _('revision to not display (EXPERIMENTAL)'), _('REV')),
274 ] + diffwsopts + walkopts + formatteropts,
275 ] + diffwsopts + walkopts + formatteropts,
275 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
276 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
276 helpcategory=command.CATEGORY_FILE_CONTENTS,
277 helpcategory=command.CATEGORY_FILE_CONTENTS,
277 helpbasic=True, inferrepo=True)
278 helpbasic=True, inferrepo=True)
278 def annotate(ui, repo, *pats, **opts):
279 def annotate(ui, repo, *pats, **opts):
279 """show changeset information by line for each file
280 """show changeset information by line for each file
280
281
281 List changes in files, showing the revision id responsible for
282 List changes in files, showing the revision id responsible for
282 each line.
283 each line.
283
284
284 This command is useful for discovering when a change was made and
285 This command is useful for discovering when a change was made and
285 by whom.
286 by whom.
286
287
287 If you include --file, --user, or --date, the revision number is
288 If you include --file, --user, or --date, the revision number is
288 suppressed unless you also include --number.
289 suppressed unless you also include --number.
289
290
290 Without the -a/--text option, annotate will avoid processing files
291 Without the -a/--text option, annotate will avoid processing files
291 it detects as binary. With -a, annotate will annotate the file
292 it detects as binary. With -a, annotate will annotate the file
292 anyway, although the results will probably be neither useful
293 anyway, although the results will probably be neither useful
293 nor desirable.
294 nor desirable.
294
295
295 .. container:: verbose
296 .. container:: verbose
296
297
297 Template:
298 Template:
298
299
299 The following keywords are supported in addition to the common template
300 The following keywords are supported in addition to the common template
300 keywords and functions. See also :hg:`help templates`.
301 keywords and functions. See also :hg:`help templates`.
301
302
302 :lines: List of lines with annotation data.
303 :lines: List of lines with annotation data.
303 :path: String. Repository-absolute path of the specified file.
304 :path: String. Repository-absolute path of the specified file.
304
305
305 And each entry of ``{lines}`` provides the following sub-keywords in
306 And each entry of ``{lines}`` provides the following sub-keywords in
306 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
307 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
307
308
308 :line: String. Line content.
309 :line: String. Line content.
309 :lineno: Integer. Line number at that revision.
310 :lineno: Integer. Line number at that revision.
310 :path: String. Repository-absolute path of the file at that revision.
311 :path: String. Repository-absolute path of the file at that revision.
311
312
312 See :hg:`help templates.operators` for the list expansion syntax.
313 See :hg:`help templates.operators` for the list expansion syntax.
313
314
314 Returns 0 on success.
315 Returns 0 on success.
315 """
316 """
316 opts = pycompat.byteskwargs(opts)
317 opts = pycompat.byteskwargs(opts)
317 if not pats:
318 if not pats:
318 raise error.Abort(_('at least one filename or pattern is required'))
319 raise error.Abort(_('at least one filename or pattern is required'))
319
320
320 if opts.get('follow'):
321 if opts.get('follow'):
321 # --follow is deprecated and now just an alias for -f/--file
322 # --follow is deprecated and now just an alias for -f/--file
322 # to mimic the behavior of Mercurial before version 1.5
323 # to mimic the behavior of Mercurial before version 1.5
323 opts['file'] = True
324 opts['file'] = True
324
325
325 if (not opts.get('user') and not opts.get('changeset')
326 if (not opts.get('user') and not opts.get('changeset')
326 and not opts.get('date') and not opts.get('file')):
327 and not opts.get('date') and not opts.get('file')):
327 opts['number'] = True
328 opts['number'] = True
328
329
329 linenumber = opts.get('line_number') is not None
330 linenumber = opts.get('line_number') is not None
330 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
331 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
331 raise error.Abort(_('at least one of -n/-c is required for -l'))
332 raise error.Abort(_('at least one of -n/-c is required for -l'))
332
333
333 rev = opts.get('rev')
334 rev = opts.get('rev')
334 if rev:
335 if rev:
335 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
336 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
336 ctx = scmutil.revsingle(repo, rev)
337 ctx = scmutil.revsingle(repo, rev)
337
338
338 ui.pager('annotate')
339 ui.pager('annotate')
339 rootfm = ui.formatter('annotate', opts)
340 rootfm = ui.formatter('annotate', opts)
340 if ui.debugflag:
341 if ui.debugflag:
341 shorthex = pycompat.identity
342 shorthex = pycompat.identity
342 else:
343 else:
343 def shorthex(h):
344 def shorthex(h):
344 return h[:12]
345 return h[:12]
345 if ui.quiet:
346 if ui.quiet:
346 datefunc = dateutil.shortdate
347 datefunc = dateutil.shortdate
347 else:
348 else:
348 datefunc = dateutil.datestr
349 datefunc = dateutil.datestr
349 if ctx.rev() is None:
350 if ctx.rev() is None:
350 if opts.get('changeset'):
351 if opts.get('changeset'):
351 # omit "+" suffix which is appended to node hex
352 # omit "+" suffix which is appended to node hex
352 def formatrev(rev):
353 def formatrev(rev):
353 if rev == wdirrev:
354 if rev == wdirrev:
354 return '%d' % ctx.p1().rev()
355 return '%d' % ctx.p1().rev()
355 else:
356 else:
356 return '%d' % rev
357 return '%d' % rev
357 else:
358 else:
358 def formatrev(rev):
359 def formatrev(rev):
359 if rev == wdirrev:
360 if rev == wdirrev:
360 return '%d+' % ctx.p1().rev()
361 return '%d+' % ctx.p1().rev()
361 else:
362 else:
362 return '%d ' % rev
363 return '%d ' % rev
363 def formathex(h):
364 def formathex(h):
364 if h == wdirhex:
365 if h == wdirhex:
365 return '%s+' % shorthex(hex(ctx.p1().node()))
366 return '%s+' % shorthex(hex(ctx.p1().node()))
366 else:
367 else:
367 return '%s ' % shorthex(h)
368 return '%s ' % shorthex(h)
368 else:
369 else:
369 formatrev = b'%d'.__mod__
370 formatrev = b'%d'.__mod__
370 formathex = shorthex
371 formathex = shorthex
371
372
372 opmap = [
373 opmap = [
373 ('user', ' ', lambda x: x.fctx.user(), ui.shortuser),
374 ('user', ' ', lambda x: x.fctx.user(), ui.shortuser),
374 ('rev', ' ', lambda x: scmutil.intrev(x.fctx), formatrev),
375 ('rev', ' ', lambda x: scmutil.intrev(x.fctx), formatrev),
375 ('node', ' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
376 ('node', ' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
376 ('date', ' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
377 ('date', ' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
377 ('path', ' ', lambda x: x.fctx.path(), pycompat.bytestr),
378 ('path', ' ', lambda x: x.fctx.path(), pycompat.bytestr),
378 ('lineno', ':', lambda x: x.lineno, pycompat.bytestr),
379 ('lineno', ':', lambda x: x.lineno, pycompat.bytestr),
379 ]
380 ]
380 opnamemap = {
381 opnamemap = {
381 'rev': 'number',
382 'rev': 'number',
382 'node': 'changeset',
383 'node': 'changeset',
383 'path': 'file',
384 'path': 'file',
384 'lineno': 'line_number',
385 'lineno': 'line_number',
385 }
386 }
386
387
387 if rootfm.isplain():
388 if rootfm.isplain():
388 def makefunc(get, fmt):
389 def makefunc(get, fmt):
389 return lambda x: fmt(get(x))
390 return lambda x: fmt(get(x))
390 else:
391 else:
391 def makefunc(get, fmt):
392 def makefunc(get, fmt):
392 return get
393 return get
393 datahint = rootfm.datahint()
394 datahint = rootfm.datahint()
394 funcmap = [(makefunc(get, fmt), sep) for fn, sep, get, fmt in opmap
395 funcmap = [(makefunc(get, fmt), sep) for fn, sep, get, fmt in opmap
395 if opts.get(opnamemap.get(fn, fn)) or fn in datahint]
396 if opts.get(opnamemap.get(fn, fn)) or fn in datahint]
396 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
397 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
397 fields = ' '.join(fn for fn, sep, get, fmt in opmap
398 fields = ' '.join(fn for fn, sep, get, fmt in opmap
398 if opts.get(opnamemap.get(fn, fn)) or fn in datahint)
399 if opts.get(opnamemap.get(fn, fn)) or fn in datahint)
399
400
400 def bad(x, y):
401 def bad(x, y):
401 raise error.Abort("%s: %s" % (x, y))
402 raise error.Abort("%s: %s" % (x, y))
402
403
403 m = scmutil.match(ctx, pats, opts, badfn=bad)
404 m = scmutil.match(ctx, pats, opts, badfn=bad)
404
405
405 follow = not opts.get('no_follow')
406 follow = not opts.get('no_follow')
406 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
407 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
407 whitespace=True)
408 whitespace=True)
408 skiprevs = opts.get('skip')
409 skiprevs = opts.get('skip')
409 if skiprevs:
410 if skiprevs:
410 skiprevs = scmutil.revrange(repo, skiprevs)
411 skiprevs = scmutil.revrange(repo, skiprevs)
411
412
412 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
413 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
413 for abs in ctx.walk(m):
414 for abs in ctx.walk(m):
414 fctx = ctx[abs]
415 fctx = ctx[abs]
415 rootfm.startitem()
416 rootfm.startitem()
416 rootfm.data(path=abs)
417 rootfm.data(path=abs)
417 if not opts.get('text') and fctx.isbinary():
418 if not opts.get('text') and fctx.isbinary():
418 rootfm.plain(_("%s: binary file\n") % uipathfn(abs))
419 rootfm.plain(_("%s: binary file\n") % uipathfn(abs))
419 continue
420 continue
420
421
421 fm = rootfm.nested('lines', tmpl='{rev}: {line}')
422 fm = rootfm.nested('lines', tmpl='{rev}: {line}')
422 lines = fctx.annotate(follow=follow, skiprevs=skiprevs,
423 lines = fctx.annotate(follow=follow, skiprevs=skiprevs,
423 diffopts=diffopts)
424 diffopts=diffopts)
424 if not lines:
425 if not lines:
425 fm.end()
426 fm.end()
426 continue
427 continue
427 formats = []
428 formats = []
428 pieces = []
429 pieces = []
429
430
430 for f, sep in funcmap:
431 for f, sep in funcmap:
431 l = [f(n) for n in lines]
432 l = [f(n) for n in lines]
432 if fm.isplain():
433 if fm.isplain():
433 sizes = [encoding.colwidth(x) for x in l]
434 sizes = [encoding.colwidth(x) for x in l]
434 ml = max(sizes)
435 ml = max(sizes)
435 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
436 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
436 else:
437 else:
437 formats.append(['%s' for x in l])
438 formats.append(['%s' for x in l])
438 pieces.append(l)
439 pieces.append(l)
439
440
440 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
441 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
441 fm.startitem()
442 fm.startitem()
442 fm.context(fctx=n.fctx)
443 fm.context(fctx=n.fctx)
443 fm.write(fields, "".join(f), *p)
444 fm.write(fields, "".join(f), *p)
444 if n.skip:
445 if n.skip:
445 fmt = "* %s"
446 fmt = "* %s"
446 else:
447 else:
447 fmt = ": %s"
448 fmt = ": %s"
448 fm.write('line', fmt, n.text)
449 fm.write('line', fmt, n.text)
449
450
450 if not lines[-1].text.endswith('\n'):
451 if not lines[-1].text.endswith('\n'):
451 fm.plain('\n')
452 fm.plain('\n')
452 fm.end()
453 fm.end()
453
454
454 rootfm.end()
455 rootfm.end()
455
456
456 @command('archive',
457 @command('archive',
457 [('', 'no-decode', None, _('do not pass files through decoders')),
458 [('', 'no-decode', None, _('do not pass files through decoders')),
458 ('p', 'prefix', '', _('directory prefix for files in archive'),
459 ('p', 'prefix', '', _('directory prefix for files in archive'),
459 _('PREFIX')),
460 _('PREFIX')),
460 ('r', 'rev', '', _('revision to distribute'), _('REV')),
461 ('r', 'rev', '', _('revision to distribute'), _('REV')),
461 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
462 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
462 ] + subrepoopts + walkopts,
463 ] + subrepoopts + walkopts,
463 _('[OPTION]... DEST'),
464 _('[OPTION]... DEST'),
464 helpcategory=command.CATEGORY_IMPORT_EXPORT)
465 helpcategory=command.CATEGORY_IMPORT_EXPORT)
465 def archive(ui, repo, dest, **opts):
466 def archive(ui, repo, dest, **opts):
466 '''create an unversioned archive of a repository revision
467 '''create an unversioned archive of a repository revision
467
468
468 By default, the revision used is the parent of the working
469 By default, the revision used is the parent of the working
469 directory; use -r/--rev to specify a different revision.
470 directory; use -r/--rev to specify a different revision.
470
471
471 The archive type is automatically detected based on file
472 The archive type is automatically detected based on file
472 extension (to override, use -t/--type).
473 extension (to override, use -t/--type).
473
474
474 .. container:: verbose
475 .. container:: verbose
475
476
476 Examples:
477 Examples:
477
478
478 - create a zip file containing the 1.0 release::
479 - create a zip file containing the 1.0 release::
479
480
480 hg archive -r 1.0 project-1.0.zip
481 hg archive -r 1.0 project-1.0.zip
481
482
482 - create a tarball excluding .hg files::
483 - create a tarball excluding .hg files::
483
484
484 hg archive project.tar.gz -X ".hg*"
485 hg archive project.tar.gz -X ".hg*"
485
486
486 Valid types are:
487 Valid types are:
487
488
488 :``files``: a directory full of files (default)
489 :``files``: a directory full of files (default)
489 :``tar``: tar archive, uncompressed
490 :``tar``: tar archive, uncompressed
490 :``tbz2``: tar archive, compressed using bzip2
491 :``tbz2``: tar archive, compressed using bzip2
491 :``tgz``: tar archive, compressed using gzip
492 :``tgz``: tar archive, compressed using gzip
492 :``uzip``: zip archive, uncompressed
493 :``uzip``: zip archive, uncompressed
493 :``zip``: zip archive, compressed using deflate
494 :``zip``: zip archive, compressed using deflate
494
495
495 The exact name of the destination archive or directory is given
496 The exact name of the destination archive or directory is given
496 using a format string; see :hg:`help export` for details.
497 using a format string; see :hg:`help export` for details.
497
498
498 Each member added to an archive file has a directory prefix
499 Each member added to an archive file has a directory prefix
499 prepended. Use -p/--prefix to specify a format string for the
500 prepended. Use -p/--prefix to specify a format string for the
500 prefix. The default is the basename of the archive, with suffixes
501 prefix. The default is the basename of the archive, with suffixes
501 removed.
502 removed.
502
503
503 Returns 0 on success.
504 Returns 0 on success.
504 '''
505 '''
505
506
506 opts = pycompat.byteskwargs(opts)
507 opts = pycompat.byteskwargs(opts)
507 rev = opts.get('rev')
508 rev = opts.get('rev')
508 if rev:
509 if rev:
509 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
510 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
510 ctx = scmutil.revsingle(repo, rev)
511 ctx = scmutil.revsingle(repo, rev)
511 if not ctx:
512 if not ctx:
512 raise error.Abort(_('no working directory: please specify a revision'))
513 raise error.Abort(_('no working directory: please specify a revision'))
513 node = ctx.node()
514 node = ctx.node()
514 dest = cmdutil.makefilename(ctx, dest)
515 dest = cmdutil.makefilename(ctx, dest)
515 if os.path.realpath(dest) == repo.root:
516 if os.path.realpath(dest) == repo.root:
516 raise error.Abort(_('repository root cannot be destination'))
517 raise error.Abort(_('repository root cannot be destination'))
517
518
518 kind = opts.get('type') or archival.guesskind(dest) or 'files'
519 kind = opts.get('type') or archival.guesskind(dest) or 'files'
519 prefix = opts.get('prefix')
520 prefix = opts.get('prefix')
520
521
521 if dest == '-':
522 if dest == '-':
522 if kind == 'files':
523 if kind == 'files':
523 raise error.Abort(_('cannot archive plain files to stdout'))
524 raise error.Abort(_('cannot archive plain files to stdout'))
524 dest = cmdutil.makefileobj(ctx, dest)
525 dest = cmdutil.makefileobj(ctx, dest)
525 if not prefix:
526 if not prefix:
526 prefix = os.path.basename(repo.root) + '-%h'
527 prefix = os.path.basename(repo.root) + '-%h'
527
528
528 prefix = cmdutil.makefilename(ctx, prefix)
529 prefix = cmdutil.makefilename(ctx, prefix)
529 match = scmutil.match(ctx, [], opts)
530 match = scmutil.match(ctx, [], opts)
530 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
531 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
531 match, prefix, subrepos=opts.get('subrepos'))
532 match, prefix, subrepos=opts.get('subrepos'))
532
533
533 @command('backout',
534 @command('backout',
534 [('', 'merge', None, _('merge with old dirstate parent after backout')),
535 [('', 'merge', None, _('merge with old dirstate parent after backout')),
535 ('', 'commit', None,
536 ('', 'commit', None,
536 _('commit if no conflicts were encountered (DEPRECATED)')),
537 _('commit if no conflicts were encountered (DEPRECATED)')),
537 ('', 'no-commit', None, _('do not commit')),
538 ('', 'no-commit', None, _('do not commit')),
538 ('', 'parent', '',
539 ('', 'parent', '',
539 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
540 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
540 ('r', 'rev', '', _('revision to backout'), _('REV')),
541 ('r', 'rev', '', _('revision to backout'), _('REV')),
541 ('e', 'edit', False, _('invoke editor on commit messages')),
542 ('e', 'edit', False, _('invoke editor on commit messages')),
542 ] + mergetoolopts + walkopts + commitopts + commitopts2,
543 ] + mergetoolopts + walkopts + commitopts + commitopts2,
543 _('[OPTION]... [-r] REV'),
544 _('[OPTION]... [-r] REV'),
544 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
545 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
545 def backout(ui, repo, node=None, rev=None, **opts):
546 def backout(ui, repo, node=None, rev=None, **opts):
546 '''reverse effect of earlier changeset
547 '''reverse effect of earlier changeset
547
548
548 Prepare a new changeset with the effect of REV undone in the
549 Prepare a new changeset with the effect of REV undone in the
549 current working directory. If no conflicts were encountered,
550 current working directory. If no conflicts were encountered,
550 it will be committed immediately.
551 it will be committed immediately.
551
552
552 If REV is the parent of the working directory, then this new changeset
553 If REV is the parent of the working directory, then this new changeset
553 is committed automatically (unless --no-commit is specified).
554 is committed automatically (unless --no-commit is specified).
554
555
555 .. note::
556 .. note::
556
557
557 :hg:`backout` cannot be used to fix either an unwanted or
558 :hg:`backout` cannot be used to fix either an unwanted or
558 incorrect merge.
559 incorrect merge.
559
560
560 .. container:: verbose
561 .. container:: verbose
561
562
562 Examples:
563 Examples:
563
564
564 - Reverse the effect of the parent of the working directory.
565 - Reverse the effect of the parent of the working directory.
565 This backout will be committed immediately::
566 This backout will be committed immediately::
566
567
567 hg backout -r .
568 hg backout -r .
568
569
569 - Reverse the effect of previous bad revision 23::
570 - Reverse the effect of previous bad revision 23::
570
571
571 hg backout -r 23
572 hg backout -r 23
572
573
573 - Reverse the effect of previous bad revision 23 and
574 - Reverse the effect of previous bad revision 23 and
574 leave changes uncommitted::
575 leave changes uncommitted::
575
576
576 hg backout -r 23 --no-commit
577 hg backout -r 23 --no-commit
577 hg commit -m "Backout revision 23"
578 hg commit -m "Backout revision 23"
578
579
579 By default, the pending changeset will have one parent,
580 By default, the pending changeset will have one parent,
580 maintaining a linear history. With --merge, the pending
581 maintaining a linear history. With --merge, the pending
581 changeset will instead have two parents: the old parent of the
582 changeset will instead have two parents: the old parent of the
582 working directory and a new child of REV that simply undoes REV.
583 working directory and a new child of REV that simply undoes REV.
583
584
584 Before version 1.7, the behavior without --merge was equivalent
585 Before version 1.7, the behavior without --merge was equivalent
585 to specifying --merge followed by :hg:`update --clean .` to
586 to specifying --merge followed by :hg:`update --clean .` to
586 cancel the merge and leave the child of REV as a head to be
587 cancel the merge and leave the child of REV as a head to be
587 merged separately.
588 merged separately.
588
589
589 See :hg:`help dates` for a list of formats valid for -d/--date.
590 See :hg:`help dates` for a list of formats valid for -d/--date.
590
591
591 See :hg:`help revert` for a way to restore files to the state
592 See :hg:`help revert` for a way to restore files to the state
592 of another revision.
593 of another revision.
593
594
594 Returns 0 on success, 1 if nothing to backout or there are unresolved
595 Returns 0 on success, 1 if nothing to backout or there are unresolved
595 files.
596 files.
596 '''
597 '''
597 with repo.wlock(), repo.lock():
598 with repo.wlock(), repo.lock():
598 return _dobackout(ui, repo, node, rev, **opts)
599 return _dobackout(ui, repo, node, rev, **opts)
599
600
600 def _dobackout(ui, repo, node=None, rev=None, **opts):
601 def _dobackout(ui, repo, node=None, rev=None, **opts):
601 opts = pycompat.byteskwargs(opts)
602 opts = pycompat.byteskwargs(opts)
602 if opts.get('commit') and opts.get('no_commit'):
603 if opts.get('commit') and opts.get('no_commit'):
603 raise error.Abort(_("cannot use --commit with --no-commit"))
604 raise error.Abort(_("cannot use --commit with --no-commit"))
604 if opts.get('merge') and opts.get('no_commit'):
605 if opts.get('merge') and opts.get('no_commit'):
605 raise error.Abort(_("cannot use --merge with --no-commit"))
606 raise error.Abort(_("cannot use --merge with --no-commit"))
606
607
607 if rev and node:
608 if rev and node:
608 raise error.Abort(_("please specify just one revision"))
609 raise error.Abort(_("please specify just one revision"))
609
610
610 if not rev:
611 if not rev:
611 rev = node
612 rev = node
612
613
613 if not rev:
614 if not rev:
614 raise error.Abort(_("please specify a revision to backout"))
615 raise error.Abort(_("please specify a revision to backout"))
615
616
616 date = opts.get('date')
617 date = opts.get('date')
617 if date:
618 if date:
618 opts['date'] = dateutil.parsedate(date)
619 opts['date'] = dateutil.parsedate(date)
619
620
620 cmdutil.checkunfinished(repo)
621 cmdutil.checkunfinished(repo)
621 cmdutil.bailifchanged(repo)
622 cmdutil.bailifchanged(repo)
622 node = scmutil.revsingle(repo, rev).node()
623 node = scmutil.revsingle(repo, rev).node()
623
624
624 op1, op2 = repo.dirstate.parents()
625 op1, op2 = repo.dirstate.parents()
625 if not repo.changelog.isancestor(node, op1):
626 if not repo.changelog.isancestor(node, op1):
626 raise error.Abort(_('cannot backout change that is not an ancestor'))
627 raise error.Abort(_('cannot backout change that is not an ancestor'))
627
628
628 p1, p2 = repo.changelog.parents(node)
629 p1, p2 = repo.changelog.parents(node)
629 if p1 == nullid:
630 if p1 == nullid:
630 raise error.Abort(_('cannot backout a change with no parents'))
631 raise error.Abort(_('cannot backout a change with no parents'))
631 if p2 != nullid:
632 if p2 != nullid:
632 if not opts.get('parent'):
633 if not opts.get('parent'):
633 raise error.Abort(_('cannot backout a merge changeset'))
634 raise error.Abort(_('cannot backout a merge changeset'))
634 p = repo.lookup(opts['parent'])
635 p = repo.lookup(opts['parent'])
635 if p not in (p1, p2):
636 if p not in (p1, p2):
636 raise error.Abort(_('%s is not a parent of %s') %
637 raise error.Abort(_('%s is not a parent of %s') %
637 (short(p), short(node)))
638 (short(p), short(node)))
638 parent = p
639 parent = p
639 else:
640 else:
640 if opts.get('parent'):
641 if opts.get('parent'):
641 raise error.Abort(_('cannot use --parent on non-merge changeset'))
642 raise error.Abort(_('cannot use --parent on non-merge changeset'))
642 parent = p1
643 parent = p1
643
644
644 # the backout should appear on the same branch
645 # the backout should appear on the same branch
645 branch = repo.dirstate.branch()
646 branch = repo.dirstate.branch()
646 bheads = repo.branchheads(branch)
647 bheads = repo.branchheads(branch)
647 rctx = scmutil.revsingle(repo, hex(parent))
648 rctx = scmutil.revsingle(repo, hex(parent))
648 if not opts.get('merge') and op1 != node:
649 if not opts.get('merge') and op1 != node:
649 with dirstateguard.dirstateguard(repo, 'backout'):
650 with dirstateguard.dirstateguard(repo, 'backout'):
650 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
651 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
651 with ui.configoverride(overrides, 'backout'):
652 with ui.configoverride(overrides, 'backout'):
652 stats = mergemod.update(repo, parent, branchmerge=True,
653 stats = mergemod.update(repo, parent, branchmerge=True,
653 force=True, ancestor=node,
654 force=True, ancestor=node,
654 mergeancestor=False)
655 mergeancestor=False)
655 repo.setparents(op1, op2)
656 repo.setparents(op1, op2)
656 hg._showstats(repo, stats)
657 hg._showstats(repo, stats)
657 if stats.unresolvedcount:
658 if stats.unresolvedcount:
658 repo.ui.status(_("use 'hg resolve' to retry unresolved "
659 repo.ui.status(_("use 'hg resolve' to retry unresolved "
659 "file merges\n"))
660 "file merges\n"))
660 return 1
661 return 1
661 else:
662 else:
662 hg.clean(repo, node, show_stats=False)
663 hg.clean(repo, node, show_stats=False)
663 repo.dirstate.setbranch(branch)
664 repo.dirstate.setbranch(branch)
664 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
665 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
665
666
666 if opts.get('no_commit'):
667 if opts.get('no_commit'):
667 msg = _("changeset %s backed out, "
668 msg = _("changeset %s backed out, "
668 "don't forget to commit.\n")
669 "don't forget to commit.\n")
669 ui.status(msg % short(node))
670 ui.status(msg % short(node))
670 return 0
671 return 0
671
672
672 def commitfunc(ui, repo, message, match, opts):
673 def commitfunc(ui, repo, message, match, opts):
673 editform = 'backout'
674 editform = 'backout'
674 e = cmdutil.getcommiteditor(editform=editform,
675 e = cmdutil.getcommiteditor(editform=editform,
675 **pycompat.strkwargs(opts))
676 **pycompat.strkwargs(opts))
676 if not message:
677 if not message:
677 # we don't translate commit messages
678 # we don't translate commit messages
678 message = "Backed out changeset %s" % short(node)
679 message = "Backed out changeset %s" % short(node)
679 e = cmdutil.getcommiteditor(edit=True, editform=editform)
680 e = cmdutil.getcommiteditor(edit=True, editform=editform)
680 return repo.commit(message, opts.get('user'), opts.get('date'),
681 return repo.commit(message, opts.get('user'), opts.get('date'),
681 match, editor=e)
682 match, editor=e)
682 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
683 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
683 if not newnode:
684 if not newnode:
684 ui.status(_("nothing changed\n"))
685 ui.status(_("nothing changed\n"))
685 return 1
686 return 1
686 cmdutil.commitstatus(repo, newnode, branch, bheads)
687 cmdutil.commitstatus(repo, newnode, branch, bheads)
687
688
688 def nice(node):
689 def nice(node):
689 return '%d:%s' % (repo.changelog.rev(node), short(node))
690 return '%d:%s' % (repo.changelog.rev(node), short(node))
690 ui.status(_('changeset %s backs out changeset %s\n') %
691 ui.status(_('changeset %s backs out changeset %s\n') %
691 (nice(repo.changelog.tip()), nice(node)))
692 (nice(repo.changelog.tip()), nice(node)))
692 if opts.get('merge') and op1 != node:
693 if opts.get('merge') and op1 != node:
693 hg.clean(repo, op1, show_stats=False)
694 hg.clean(repo, op1, show_stats=False)
694 ui.status(_('merging with changeset %s\n')
695 ui.status(_('merging with changeset %s\n')
695 % nice(repo.changelog.tip()))
696 % nice(repo.changelog.tip()))
696 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
697 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
697 with ui.configoverride(overrides, 'backout'):
698 with ui.configoverride(overrides, 'backout'):
698 return hg.merge(repo, hex(repo.changelog.tip()))
699 return hg.merge(repo, hex(repo.changelog.tip()))
699 return 0
700 return 0
700
701
701 @command('bisect',
702 @command('bisect',
702 [('r', 'reset', False, _('reset bisect state')),
703 [('r', 'reset', False, _('reset bisect state')),
703 ('g', 'good', False, _('mark changeset good')),
704 ('g', 'good', False, _('mark changeset good')),
704 ('b', 'bad', False, _('mark changeset bad')),
705 ('b', 'bad', False, _('mark changeset bad')),
705 ('s', 'skip', False, _('skip testing changeset')),
706 ('s', 'skip', False, _('skip testing changeset')),
706 ('e', 'extend', False, _('extend the bisect range')),
707 ('e', 'extend', False, _('extend the bisect range')),
707 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
708 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
708 ('U', 'noupdate', False, _('do not update to target'))],
709 ('U', 'noupdate', False, _('do not update to target'))],
709 _("[-gbsr] [-U] [-c CMD] [REV]"),
710 _("[-gbsr] [-U] [-c CMD] [REV]"),
710 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
711 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
711 def bisect(ui, repo, rev=None, extra=None, command=None,
712 def bisect(ui, repo, rev=None, extra=None, command=None,
712 reset=None, good=None, bad=None, skip=None, extend=None,
713 reset=None, good=None, bad=None, skip=None, extend=None,
713 noupdate=None):
714 noupdate=None):
714 """subdivision search of changesets
715 """subdivision search of changesets
715
716
716 This command helps to find changesets which introduce problems. To
717 This command helps to find changesets which introduce problems. To
717 use, mark the earliest changeset you know exhibits the problem as
718 use, mark the earliest changeset you know exhibits the problem as
718 bad, then mark the latest changeset which is free from the problem
719 bad, then mark the latest changeset which is free from the problem
719 as good. Bisect will update your working directory to a revision
720 as good. Bisect will update your working directory to a revision
720 for testing (unless the -U/--noupdate option is specified). Once
721 for testing (unless the -U/--noupdate option is specified). Once
721 you have performed tests, mark the working directory as good or
722 you have performed tests, mark the working directory as good or
722 bad, and bisect will either update to another candidate changeset
723 bad, and bisect will either update to another candidate changeset
723 or announce that it has found the bad revision.
724 or announce that it has found the bad revision.
724
725
725 As a shortcut, you can also use the revision argument to mark a
726 As a shortcut, you can also use the revision argument to mark a
726 revision as good or bad without checking it out first.
727 revision as good or bad without checking it out first.
727
728
728 If you supply a command, it will be used for automatic bisection.
729 If you supply a command, it will be used for automatic bisection.
729 The environment variable HG_NODE will contain the ID of the
730 The environment variable HG_NODE will contain the ID of the
730 changeset being tested. The exit status of the command will be
731 changeset being tested. The exit status of the command will be
731 used to mark revisions as good or bad: status 0 means good, 125
732 used to mark revisions as good or bad: status 0 means good, 125
732 means to skip the revision, 127 (command not found) will abort the
733 means to skip the revision, 127 (command not found) will abort the
733 bisection, and any other non-zero exit status means the revision
734 bisection, and any other non-zero exit status means the revision
734 is bad.
735 is bad.
735
736
736 .. container:: verbose
737 .. container:: verbose
737
738
738 Some examples:
739 Some examples:
739
740
740 - start a bisection with known bad revision 34, and good revision 12::
741 - start a bisection with known bad revision 34, and good revision 12::
741
742
742 hg bisect --bad 34
743 hg bisect --bad 34
743 hg bisect --good 12
744 hg bisect --good 12
744
745
745 - advance the current bisection by marking current revision as good or
746 - advance the current bisection by marking current revision as good or
746 bad::
747 bad::
747
748
748 hg bisect --good
749 hg bisect --good
749 hg bisect --bad
750 hg bisect --bad
750
751
751 - mark the current revision, or a known revision, to be skipped (e.g. if
752 - mark the current revision, or a known revision, to be skipped (e.g. if
752 that revision is not usable because of another issue)::
753 that revision is not usable because of another issue)::
753
754
754 hg bisect --skip
755 hg bisect --skip
755 hg bisect --skip 23
756 hg bisect --skip 23
756
757
757 - skip all revisions that do not touch directories ``foo`` or ``bar``::
758 - skip all revisions that do not touch directories ``foo`` or ``bar``::
758
759
759 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
760 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
760
761
761 - forget the current bisection::
762 - forget the current bisection::
762
763
763 hg bisect --reset
764 hg bisect --reset
764
765
765 - use 'make && make tests' to automatically find the first broken
766 - use 'make && make tests' to automatically find the first broken
766 revision::
767 revision::
767
768
768 hg bisect --reset
769 hg bisect --reset
769 hg bisect --bad 34
770 hg bisect --bad 34
770 hg bisect --good 12
771 hg bisect --good 12
771 hg bisect --command "make && make tests"
772 hg bisect --command "make && make tests"
772
773
773 - see all changesets whose states are already known in the current
774 - see all changesets whose states are already known in the current
774 bisection::
775 bisection::
775
776
776 hg log -r "bisect(pruned)"
777 hg log -r "bisect(pruned)"
777
778
778 - see the changeset currently being bisected (especially useful
779 - see the changeset currently being bisected (especially useful
779 if running with -U/--noupdate)::
780 if running with -U/--noupdate)::
780
781
781 hg log -r "bisect(current)"
782 hg log -r "bisect(current)"
782
783
783 - see all changesets that took part in the current bisection::
784 - see all changesets that took part in the current bisection::
784
785
785 hg log -r "bisect(range)"
786 hg log -r "bisect(range)"
786
787
787 - you can even get a nice graph::
788 - you can even get a nice graph::
788
789
789 hg log --graph -r "bisect(range)"
790 hg log --graph -r "bisect(range)"
790
791
791 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
792 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
792
793
793 Returns 0 on success.
794 Returns 0 on success.
794 """
795 """
795 # backward compatibility
796 # backward compatibility
796 if rev in "good bad reset init".split():
797 if rev in "good bad reset init".split():
797 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
798 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
798 cmd, rev, extra = rev, extra, None
799 cmd, rev, extra = rev, extra, None
799 if cmd == "good":
800 if cmd == "good":
800 good = True
801 good = True
801 elif cmd == "bad":
802 elif cmd == "bad":
802 bad = True
803 bad = True
803 else:
804 else:
804 reset = True
805 reset = True
805 elif extra:
806 elif extra:
806 raise error.Abort(_('incompatible arguments'))
807 raise error.Abort(_('incompatible arguments'))
807
808
808 incompatibles = {
809 incompatibles = {
809 '--bad': bad,
810 '--bad': bad,
810 '--command': bool(command),
811 '--command': bool(command),
811 '--extend': extend,
812 '--extend': extend,
812 '--good': good,
813 '--good': good,
813 '--reset': reset,
814 '--reset': reset,
814 '--skip': skip,
815 '--skip': skip,
815 }
816 }
816
817
817 enabled = [x for x in incompatibles if incompatibles[x]]
818 enabled = [x for x in incompatibles if incompatibles[x]]
818
819
819 if len(enabled) > 1:
820 if len(enabled) > 1:
820 raise error.Abort(_('%s and %s are incompatible') %
821 raise error.Abort(_('%s and %s are incompatible') %
821 tuple(sorted(enabled)[0:2]))
822 tuple(sorted(enabled)[0:2]))
822
823
823 if reset:
824 if reset:
824 hbisect.resetstate(repo)
825 hbisect.resetstate(repo)
825 return
826 return
826
827
827 state = hbisect.load_state(repo)
828 state = hbisect.load_state(repo)
828
829
829 # update state
830 # update state
830 if good or bad or skip:
831 if good or bad or skip:
831 if rev:
832 if rev:
832 nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
833 nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
833 else:
834 else:
834 nodes = [repo.lookup('.')]
835 nodes = [repo.lookup('.')]
835 if good:
836 if good:
836 state['good'] += nodes
837 state['good'] += nodes
837 elif bad:
838 elif bad:
838 state['bad'] += nodes
839 state['bad'] += nodes
839 elif skip:
840 elif skip:
840 state['skip'] += nodes
841 state['skip'] += nodes
841 hbisect.save_state(repo, state)
842 hbisect.save_state(repo, state)
842 if not (state['good'] and state['bad']):
843 if not (state['good'] and state['bad']):
843 return
844 return
844
845
845 def mayupdate(repo, node, show_stats=True):
846 def mayupdate(repo, node, show_stats=True):
846 """common used update sequence"""
847 """common used update sequence"""
847 if noupdate:
848 if noupdate:
848 return
849 return
849 cmdutil.checkunfinished(repo)
850 cmdutil.checkunfinished(repo)
850 cmdutil.bailifchanged(repo)
851 cmdutil.bailifchanged(repo)
851 return hg.clean(repo, node, show_stats=show_stats)
852 return hg.clean(repo, node, show_stats=show_stats)
852
853
853 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
854 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
854
855
855 if command:
856 if command:
856 changesets = 1
857 changesets = 1
857 if noupdate:
858 if noupdate:
858 try:
859 try:
859 node = state['current'][0]
860 node = state['current'][0]
860 except LookupError:
861 except LookupError:
861 raise error.Abort(_('current bisect revision is unknown - '
862 raise error.Abort(_('current bisect revision is unknown - '
862 'start a new bisect to fix'))
863 'start a new bisect to fix'))
863 else:
864 else:
864 node, p2 = repo.dirstate.parents()
865 node, p2 = repo.dirstate.parents()
865 if p2 != nullid:
866 if p2 != nullid:
866 raise error.Abort(_('current bisect revision is a merge'))
867 raise error.Abort(_('current bisect revision is a merge'))
867 if rev:
868 if rev:
868 node = repo[scmutil.revsingle(repo, rev, node)].node()
869 node = repo[scmutil.revsingle(repo, rev, node)].node()
869 try:
870 try:
870 while changesets:
871 while changesets:
871 # update state
872 # update state
872 state['current'] = [node]
873 state['current'] = [node]
873 hbisect.save_state(repo, state)
874 hbisect.save_state(repo, state)
874 status = ui.system(command, environ={'HG_NODE': hex(node)},
875 status = ui.system(command, environ={'HG_NODE': hex(node)},
875 blockedtag='bisect_check')
876 blockedtag='bisect_check')
876 if status == 125:
877 if status == 125:
877 transition = "skip"
878 transition = "skip"
878 elif status == 0:
879 elif status == 0:
879 transition = "good"
880 transition = "good"
880 # status < 0 means process was killed
881 # status < 0 means process was killed
881 elif status == 127:
882 elif status == 127:
882 raise error.Abort(_("failed to execute %s") % command)
883 raise error.Abort(_("failed to execute %s") % command)
883 elif status < 0:
884 elif status < 0:
884 raise error.Abort(_("%s killed") % command)
885 raise error.Abort(_("%s killed") % command)
885 else:
886 else:
886 transition = "bad"
887 transition = "bad"
887 state[transition].append(node)
888 state[transition].append(node)
888 ctx = repo[node]
889 ctx = repo[node]
889 ui.status(_('changeset %d:%s: %s\n') % (ctx.rev(), ctx,
890 ui.status(_('changeset %d:%s: %s\n') % (ctx.rev(), ctx,
890 transition))
891 transition))
891 hbisect.checkstate(state)
892 hbisect.checkstate(state)
892 # bisect
893 # bisect
893 nodes, changesets, bgood = hbisect.bisect(repo, state)
894 nodes, changesets, bgood = hbisect.bisect(repo, state)
894 # update to next check
895 # update to next check
895 node = nodes[0]
896 node = nodes[0]
896 mayupdate(repo, node, show_stats=False)
897 mayupdate(repo, node, show_stats=False)
897 finally:
898 finally:
898 state['current'] = [node]
899 state['current'] = [node]
899 hbisect.save_state(repo, state)
900 hbisect.save_state(repo, state)
900 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
901 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
901 return
902 return
902
903
903 hbisect.checkstate(state)
904 hbisect.checkstate(state)
904
905
905 # actually bisect
906 # actually bisect
906 nodes, changesets, good = hbisect.bisect(repo, state)
907 nodes, changesets, good = hbisect.bisect(repo, state)
907 if extend:
908 if extend:
908 if not changesets:
909 if not changesets:
909 extendnode = hbisect.extendrange(repo, state, nodes, good)
910 extendnode = hbisect.extendrange(repo, state, nodes, good)
910 if extendnode is not None:
911 if extendnode is not None:
911 ui.write(_("Extending search to changeset %d:%s\n")
912 ui.write(_("Extending search to changeset %d:%s\n")
912 % (extendnode.rev(), extendnode))
913 % (extendnode.rev(), extendnode))
913 state['current'] = [extendnode.node()]
914 state['current'] = [extendnode.node()]
914 hbisect.save_state(repo, state)
915 hbisect.save_state(repo, state)
915 return mayupdate(repo, extendnode.node())
916 return mayupdate(repo, extendnode.node())
916 raise error.Abort(_("nothing to extend"))
917 raise error.Abort(_("nothing to extend"))
917
918
918 if changesets == 0:
919 if changesets == 0:
919 hbisect.printresult(ui, repo, state, displayer, nodes, good)
920 hbisect.printresult(ui, repo, state, displayer, nodes, good)
920 else:
921 else:
921 assert len(nodes) == 1 # only a single node can be tested next
922 assert len(nodes) == 1 # only a single node can be tested next
922 node = nodes[0]
923 node = nodes[0]
923 # compute the approximate number of remaining tests
924 # compute the approximate number of remaining tests
924 tests, size = 0, 2
925 tests, size = 0, 2
925 while size <= changesets:
926 while size <= changesets:
926 tests, size = tests + 1, size * 2
927 tests, size = tests + 1, size * 2
927 rev = repo.changelog.rev(node)
928 rev = repo.changelog.rev(node)
928 ui.write(_("Testing changeset %d:%s "
929 ui.write(_("Testing changeset %d:%s "
929 "(%d changesets remaining, ~%d tests)\n")
930 "(%d changesets remaining, ~%d tests)\n")
930 % (rev, short(node), changesets, tests))
931 % (rev, short(node), changesets, tests))
931 state['current'] = [node]
932 state['current'] = [node]
932 hbisect.save_state(repo, state)
933 hbisect.save_state(repo, state)
933 return mayupdate(repo, node)
934 return mayupdate(repo, node)
934
935
935 @command('bookmarks|bookmark',
936 @command('bookmarks|bookmark',
936 [('f', 'force', False, _('force')),
937 [('f', 'force', False, _('force')),
937 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
938 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
938 ('d', 'delete', False, _('delete a given bookmark')),
939 ('d', 'delete', False, _('delete a given bookmark')),
939 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
940 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
940 ('i', 'inactive', False, _('mark a bookmark inactive')),
941 ('i', 'inactive', False, _('mark a bookmark inactive')),
941 ('l', 'list', False, _('list existing bookmarks')),
942 ('l', 'list', False, _('list existing bookmarks')),
942 ] + formatteropts,
943 ] + formatteropts,
943 _('hg bookmarks [OPTIONS]... [NAME]...'),
944 _('hg bookmarks [OPTIONS]... [NAME]...'),
944 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
945 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
945 def bookmark(ui, repo, *names, **opts):
946 def bookmark(ui, repo, *names, **opts):
946 '''create a new bookmark or list existing bookmarks
947 '''create a new bookmark or list existing bookmarks
947
948
948 Bookmarks are labels on changesets to help track lines of development.
949 Bookmarks are labels on changesets to help track lines of development.
949 Bookmarks are unversioned and can be moved, renamed and deleted.
950 Bookmarks are unversioned and can be moved, renamed and deleted.
950 Deleting or moving a bookmark has no effect on the associated changesets.
951 Deleting or moving a bookmark has no effect on the associated changesets.
951
952
952 Creating or updating to a bookmark causes it to be marked as 'active'.
953 Creating or updating to a bookmark causes it to be marked as 'active'.
953 The active bookmark is indicated with a '*'.
954 The active bookmark is indicated with a '*'.
954 When a commit is made, the active bookmark will advance to the new commit.
955 When a commit is made, the active bookmark will advance to the new commit.
955 A plain :hg:`update` will also advance an active bookmark, if possible.
956 A plain :hg:`update` will also advance an active bookmark, if possible.
956 Updating away from a bookmark will cause it to be deactivated.
957 Updating away from a bookmark will cause it to be deactivated.
957
958
958 Bookmarks can be pushed and pulled between repositories (see
959 Bookmarks can be pushed and pulled between repositories (see
959 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
960 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
960 diverged, a new 'divergent bookmark' of the form 'name@path' will
961 diverged, a new 'divergent bookmark' of the form 'name@path' will
961 be created. Using :hg:`merge` will resolve the divergence.
962 be created. Using :hg:`merge` will resolve the divergence.
962
963
963 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
964 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
964 the active bookmark's name.
965 the active bookmark's name.
965
966
966 A bookmark named '@' has the special property that :hg:`clone` will
967 A bookmark named '@' has the special property that :hg:`clone` will
967 check it out by default if it exists.
968 check it out by default if it exists.
968
969
969 .. container:: verbose
970 .. container:: verbose
970
971
971 Template:
972 Template:
972
973
973 The following keywords are supported in addition to the common template
974 The following keywords are supported in addition to the common template
974 keywords and functions such as ``{bookmark}``. See also
975 keywords and functions such as ``{bookmark}``. See also
975 :hg:`help templates`.
976 :hg:`help templates`.
976
977
977 :active: Boolean. True if the bookmark is active.
978 :active: Boolean. True if the bookmark is active.
978
979
979 Examples:
980 Examples:
980
981
981 - create an active bookmark for a new line of development::
982 - create an active bookmark for a new line of development::
982
983
983 hg book new-feature
984 hg book new-feature
984
985
985 - create an inactive bookmark as a place marker::
986 - create an inactive bookmark as a place marker::
986
987
987 hg book -i reviewed
988 hg book -i reviewed
988
989
989 - create an inactive bookmark on another changeset::
990 - create an inactive bookmark on another changeset::
990
991
991 hg book -r .^ tested
992 hg book -r .^ tested
992
993
993 - rename bookmark turkey to dinner::
994 - rename bookmark turkey to dinner::
994
995
995 hg book -m turkey dinner
996 hg book -m turkey dinner
996
997
997 - move the '@' bookmark from another branch::
998 - move the '@' bookmark from another branch::
998
999
999 hg book -f @
1000 hg book -f @
1000
1001
1001 - print only the active bookmark name::
1002 - print only the active bookmark name::
1002
1003
1003 hg book -ql .
1004 hg book -ql .
1004 '''
1005 '''
1005 opts = pycompat.byteskwargs(opts)
1006 opts = pycompat.byteskwargs(opts)
1006 force = opts.get('force')
1007 force = opts.get('force')
1007 rev = opts.get('rev')
1008 rev = opts.get('rev')
1008 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark
1009 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark
1009
1010
1010 selactions = [k for k in ['delete', 'rename', 'list'] if opts.get(k)]
1011 selactions = [k for k in ['delete', 'rename', 'list'] if opts.get(k)]
1011 if len(selactions) > 1:
1012 if len(selactions) > 1:
1012 raise error.Abort(_('--%s and --%s are incompatible')
1013 raise error.Abort(_('--%s and --%s are incompatible')
1013 % tuple(selactions[:2]))
1014 % tuple(selactions[:2]))
1014 if selactions:
1015 if selactions:
1015 action = selactions[0]
1016 action = selactions[0]
1016 elif names or rev:
1017 elif names or rev:
1017 action = 'add'
1018 action = 'add'
1018 elif inactive:
1019 elif inactive:
1019 action = 'inactive' # meaning deactivate
1020 action = 'inactive' # meaning deactivate
1020 else:
1021 else:
1021 action = 'list'
1022 action = 'list'
1022
1023
1023 if rev and action in {'delete', 'rename', 'list'}:
1024 if rev and action in {'delete', 'rename', 'list'}:
1024 raise error.Abort(_("--rev is incompatible with --%s") % action)
1025 raise error.Abort(_("--rev is incompatible with --%s") % action)
1025 if inactive and action in {'delete', 'list'}:
1026 if inactive and action in {'delete', 'list'}:
1026 raise error.Abort(_("--inactive is incompatible with --%s") % action)
1027 raise error.Abort(_("--inactive is incompatible with --%s") % action)
1027 if not names and action in {'add', 'delete'}:
1028 if not names and action in {'add', 'delete'}:
1028 raise error.Abort(_("bookmark name required"))
1029 raise error.Abort(_("bookmark name required"))
1029
1030
1030 if action in {'add', 'delete', 'rename', 'inactive'}:
1031 if action in {'add', 'delete', 'rename', 'inactive'}:
1031 with repo.wlock(), repo.lock(), repo.transaction('bookmark') as tr:
1032 with repo.wlock(), repo.lock(), repo.transaction('bookmark') as tr:
1032 if action == 'delete':
1033 if action == 'delete':
1033 names = pycompat.maplist(repo._bookmarks.expandname, names)
1034 names = pycompat.maplist(repo._bookmarks.expandname, names)
1034 bookmarks.delete(repo, tr, names)
1035 bookmarks.delete(repo, tr, names)
1035 elif action == 'rename':
1036 elif action == 'rename':
1036 if not names:
1037 if not names:
1037 raise error.Abort(_("new bookmark name required"))
1038 raise error.Abort(_("new bookmark name required"))
1038 elif len(names) > 1:
1039 elif len(names) > 1:
1039 raise error.Abort(_("only one new bookmark name allowed"))
1040 raise error.Abort(_("only one new bookmark name allowed"))
1040 oldname = repo._bookmarks.expandname(opts['rename'])
1041 oldname = repo._bookmarks.expandname(opts['rename'])
1041 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1042 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1042 elif action == 'add':
1043 elif action == 'add':
1043 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1044 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1044 elif action == 'inactive':
1045 elif action == 'inactive':
1045 if len(repo._bookmarks) == 0:
1046 if len(repo._bookmarks) == 0:
1046 ui.status(_("no bookmarks set\n"))
1047 ui.status(_("no bookmarks set\n"))
1047 elif not repo._activebookmark:
1048 elif not repo._activebookmark:
1048 ui.status(_("no active bookmark\n"))
1049 ui.status(_("no active bookmark\n"))
1049 else:
1050 else:
1050 bookmarks.deactivate(repo)
1051 bookmarks.deactivate(repo)
1051 elif action == 'list':
1052 elif action == 'list':
1052 names = pycompat.maplist(repo._bookmarks.expandname, names)
1053 names = pycompat.maplist(repo._bookmarks.expandname, names)
1053 with ui.formatter('bookmarks', opts) as fm:
1054 with ui.formatter('bookmarks', opts) as fm:
1054 bookmarks.printbookmarks(ui, repo, fm, names)
1055 bookmarks.printbookmarks(ui, repo, fm, names)
1055 else:
1056 else:
1056 raise error.ProgrammingError('invalid action: %s' % action)
1057 raise error.ProgrammingError('invalid action: %s' % action)
1057
1058
1058 @command('branch',
1059 @command('branch',
1059 [('f', 'force', None,
1060 [('f', 'force', None,
1060 _('set branch name even if it shadows an existing branch')),
1061 _('set branch name even if it shadows an existing branch')),
1061 ('C', 'clean', None, _('reset branch name to parent branch name')),
1062 ('C', 'clean', None, _('reset branch name to parent branch name')),
1062 ('r', 'rev', [], _('change branches of the given revs (EXPERIMENTAL)')),
1063 ('r', 'rev', [], _('change branches of the given revs (EXPERIMENTAL)')),
1063 ],
1064 ],
1064 _('[-fC] [NAME]'),
1065 _('[-fC] [NAME]'),
1065 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
1066 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
1066 def branch(ui, repo, label=None, **opts):
1067 def branch(ui, repo, label=None, **opts):
1067 """set or show the current branch name
1068 """set or show the current branch name
1068
1069
1069 .. note::
1070 .. note::
1070
1071
1071 Branch names are permanent and global. Use :hg:`bookmark` to create a
1072 Branch names are permanent and global. Use :hg:`bookmark` to create a
1072 light-weight bookmark instead. See :hg:`help glossary` for more
1073 light-weight bookmark instead. See :hg:`help glossary` for more
1073 information about named branches and bookmarks.
1074 information about named branches and bookmarks.
1074
1075
1075 With no argument, show the current branch name. With one argument,
1076 With no argument, show the current branch name. With one argument,
1076 set the working directory branch name (the branch will not exist
1077 set the working directory branch name (the branch will not exist
1077 in the repository until the next commit). Standard practice
1078 in the repository until the next commit). Standard practice
1078 recommends that primary development take place on the 'default'
1079 recommends that primary development take place on the 'default'
1079 branch.
1080 branch.
1080
1081
1081 Unless -f/--force is specified, branch will not let you set a
1082 Unless -f/--force is specified, branch will not let you set a
1082 branch name that already exists.
1083 branch name that already exists.
1083
1084
1084 Use -C/--clean to reset the working directory branch to that of
1085 Use -C/--clean to reset the working directory branch to that of
1085 the parent of the working directory, negating a previous branch
1086 the parent of the working directory, negating a previous branch
1086 change.
1087 change.
1087
1088
1088 Use the command :hg:`update` to switch to an existing branch. Use
1089 Use the command :hg:`update` to switch to an existing branch. Use
1089 :hg:`commit --close-branch` to mark this branch head as closed.
1090 :hg:`commit --close-branch` to mark this branch head as closed.
1090 When all heads of a branch are closed, the branch will be
1091 When all heads of a branch are closed, the branch will be
1091 considered closed.
1092 considered closed.
1092
1093
1093 Returns 0 on success.
1094 Returns 0 on success.
1094 """
1095 """
1095 opts = pycompat.byteskwargs(opts)
1096 opts = pycompat.byteskwargs(opts)
1096 revs = opts.get('rev')
1097 revs = opts.get('rev')
1097 if label:
1098 if label:
1098 label = label.strip()
1099 label = label.strip()
1099
1100
1100 if not opts.get('clean') and not label:
1101 if not opts.get('clean') and not label:
1101 if revs:
1102 if revs:
1102 raise error.Abort(_("no branch name specified for the revisions"))
1103 raise error.Abort(_("no branch name specified for the revisions"))
1103 ui.write("%s\n" % repo.dirstate.branch())
1104 ui.write("%s\n" % repo.dirstate.branch())
1104 return
1105 return
1105
1106
1106 with repo.wlock():
1107 with repo.wlock():
1107 if opts.get('clean'):
1108 if opts.get('clean'):
1108 label = repo['.'].branch()
1109 label = repo['.'].branch()
1109 repo.dirstate.setbranch(label)
1110 repo.dirstate.setbranch(label)
1110 ui.status(_('reset working directory to branch %s\n') % label)
1111 ui.status(_('reset working directory to branch %s\n') % label)
1111 elif label:
1112 elif label:
1112
1113
1113 scmutil.checknewlabel(repo, label, 'branch')
1114 scmutil.checknewlabel(repo, label, 'branch')
1114 if revs:
1115 if revs:
1115 return cmdutil.changebranch(ui, repo, revs, label)
1116 return cmdutil.changebranch(ui, repo, revs, label)
1116
1117
1117 if not opts.get('force') and label in repo.branchmap():
1118 if not opts.get('force') and label in repo.branchmap():
1118 if label not in [p.branch() for p in repo[None].parents()]:
1119 if label not in [p.branch() for p in repo[None].parents()]:
1119 raise error.Abort(_('a branch of the same name already'
1120 raise error.Abort(_('a branch of the same name already'
1120 ' exists'),
1121 ' exists'),
1121 # i18n: "it" refers to an existing branch
1122 # i18n: "it" refers to an existing branch
1122 hint=_("use 'hg update' to switch to it"))
1123 hint=_("use 'hg update' to switch to it"))
1123
1124
1124 repo.dirstate.setbranch(label)
1125 repo.dirstate.setbranch(label)
1125 ui.status(_('marked working directory as branch %s\n') % label)
1126 ui.status(_('marked working directory as branch %s\n') % label)
1126
1127
1127 # find any open named branches aside from default
1128 # find any open named branches aside from default
1128 for n, h, t, c in repo.branchmap().iterbranches():
1129 for n, h, t, c in repo.branchmap().iterbranches():
1129 if n != "default" and not c:
1130 if n != "default" and not c:
1130 return 0
1131 return 0
1131 ui.status(_('(branches are permanent and global, '
1132 ui.status(_('(branches are permanent and global, '
1132 'did you want a bookmark?)\n'))
1133 'did you want a bookmark?)\n'))
1133
1134
1134 @command('branches',
1135 @command('branches',
1135 [('a', 'active', False,
1136 [('a', 'active', False,
1136 _('show only branches that have unmerged heads (DEPRECATED)')),
1137 _('show only branches that have unmerged heads (DEPRECATED)')),
1137 ('c', 'closed', False, _('show normal and closed branches')),
1138 ('c', 'closed', False, _('show normal and closed branches')),
1138 ('r', 'rev', [], _('show branch name(s) of the given rev'))
1139 ('r', 'rev', [], _('show branch name(s) of the given rev'))
1139 ] + formatteropts,
1140 ] + formatteropts,
1140 _('[-c]'),
1141 _('[-c]'),
1141 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1142 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1142 intents={INTENT_READONLY})
1143 intents={INTENT_READONLY})
1143 def branches(ui, repo, active=False, closed=False, **opts):
1144 def branches(ui, repo, active=False, closed=False, **opts):
1144 """list repository named branches
1145 """list repository named branches
1145
1146
1146 List the repository's named branches, indicating which ones are
1147 List the repository's named branches, indicating which ones are
1147 inactive. If -c/--closed is specified, also list branches which have
1148 inactive. If -c/--closed is specified, also list branches which have
1148 been marked closed (see :hg:`commit --close-branch`).
1149 been marked closed (see :hg:`commit --close-branch`).
1149
1150
1150 Use the command :hg:`update` to switch to an existing branch.
1151 Use the command :hg:`update` to switch to an existing branch.
1151
1152
1152 .. container:: verbose
1153 .. container:: verbose
1153
1154
1154 Template:
1155 Template:
1155
1156
1156 The following keywords are supported in addition to the common template
1157 The following keywords are supported in addition to the common template
1157 keywords and functions such as ``{branch}``. See also
1158 keywords and functions such as ``{branch}``. See also
1158 :hg:`help templates`.
1159 :hg:`help templates`.
1159
1160
1160 :active: Boolean. True if the branch is active.
1161 :active: Boolean. True if the branch is active.
1161 :closed: Boolean. True if the branch is closed.
1162 :closed: Boolean. True if the branch is closed.
1162 :current: Boolean. True if it is the current branch.
1163 :current: Boolean. True if it is the current branch.
1163
1164
1164 Returns 0.
1165 Returns 0.
1165 """
1166 """
1166
1167
1167 opts = pycompat.byteskwargs(opts)
1168 opts = pycompat.byteskwargs(opts)
1168 revs = opts.get('rev')
1169 revs = opts.get('rev')
1169 selectedbranches = None
1170 selectedbranches = None
1170 if revs:
1171 if revs:
1171 revs = scmutil.revrange(repo, revs)
1172 revs = scmutil.revrange(repo, revs)
1172 getbi = repo.revbranchcache().branchinfo
1173 getbi = repo.revbranchcache().branchinfo
1173 selectedbranches = {getbi(r)[0] for r in revs}
1174 selectedbranches = {getbi(r)[0] for r in revs}
1174
1175
1175 ui.pager('branches')
1176 ui.pager('branches')
1176 fm = ui.formatter('branches', opts)
1177 fm = ui.formatter('branches', opts)
1177 hexfunc = fm.hexfunc
1178 hexfunc = fm.hexfunc
1178
1179
1179 allheads = set(repo.heads())
1180 allheads = set(repo.heads())
1180 branches = []
1181 branches = []
1181 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1182 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1182 if selectedbranches is not None and tag not in selectedbranches:
1183 if selectedbranches is not None and tag not in selectedbranches:
1183 continue
1184 continue
1184 isactive = False
1185 isactive = False
1185 if not isclosed:
1186 if not isclosed:
1186 openheads = set(repo.branchmap().iteropen(heads))
1187 openheads = set(repo.branchmap().iteropen(heads))
1187 isactive = bool(openheads & allheads)
1188 isactive = bool(openheads & allheads)
1188 branches.append((tag, repo[tip], isactive, not isclosed))
1189 branches.append((tag, repo[tip], isactive, not isclosed))
1189 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1190 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1190 reverse=True)
1191 reverse=True)
1191
1192
1192 for tag, ctx, isactive, isopen in branches:
1193 for tag, ctx, isactive, isopen in branches:
1193 if active and not isactive:
1194 if active and not isactive:
1194 continue
1195 continue
1195 if isactive:
1196 if isactive:
1196 label = 'branches.active'
1197 label = 'branches.active'
1197 notice = ''
1198 notice = ''
1198 elif not isopen:
1199 elif not isopen:
1199 if not closed:
1200 if not closed:
1200 continue
1201 continue
1201 label = 'branches.closed'
1202 label = 'branches.closed'
1202 notice = _(' (closed)')
1203 notice = _(' (closed)')
1203 else:
1204 else:
1204 label = 'branches.inactive'
1205 label = 'branches.inactive'
1205 notice = _(' (inactive)')
1206 notice = _(' (inactive)')
1206 current = (tag == repo.dirstate.branch())
1207 current = (tag == repo.dirstate.branch())
1207 if current:
1208 if current:
1208 label = 'branches.current'
1209 label = 'branches.current'
1209
1210
1210 fm.startitem()
1211 fm.startitem()
1211 fm.write('branch', '%s', tag, label=label)
1212 fm.write('branch', '%s', tag, label=label)
1212 rev = ctx.rev()
1213 rev = ctx.rev()
1213 padsize = max(31 - len("%d" % rev) - encoding.colwidth(tag), 0)
1214 padsize = max(31 - len("%d" % rev) - encoding.colwidth(tag), 0)
1214 fmt = ' ' * padsize + ' %d:%s'
1215 fmt = ' ' * padsize + ' %d:%s'
1215 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1216 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1216 label='log.changeset changeset.%s' % ctx.phasestr())
1217 label='log.changeset changeset.%s' % ctx.phasestr())
1217 fm.context(ctx=ctx)
1218 fm.context(ctx=ctx)
1218 fm.data(active=isactive, closed=not isopen, current=current)
1219 fm.data(active=isactive, closed=not isopen, current=current)
1219 if not ui.quiet:
1220 if not ui.quiet:
1220 fm.plain(notice)
1221 fm.plain(notice)
1221 fm.plain('\n')
1222 fm.plain('\n')
1222 fm.end()
1223 fm.end()
1223
1224
1224 @command('bundle',
1225 @command('bundle',
1225 [('f', 'force', None, _('run even when the destination is unrelated')),
1226 [('f', 'force', None, _('run even when the destination is unrelated')),
1226 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1227 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1227 _('REV')),
1228 _('REV')),
1228 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1229 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1229 _('BRANCH')),
1230 _('BRANCH')),
1230 ('', 'base', [],
1231 ('', 'base', [],
1231 _('a base changeset assumed to be available at the destination'),
1232 _('a base changeset assumed to be available at the destination'),
1232 _('REV')),
1233 _('REV')),
1233 ('a', 'all', None, _('bundle all changesets in the repository')),
1234 ('a', 'all', None, _('bundle all changesets in the repository')),
1234 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1235 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1235 ] + remoteopts,
1236 ] + remoteopts,
1236 _('[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1237 _('[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1237 helpcategory=command.CATEGORY_IMPORT_EXPORT)
1238 helpcategory=command.CATEGORY_IMPORT_EXPORT)
1238 def bundle(ui, repo, fname, dest=None, **opts):
1239 def bundle(ui, repo, fname, dest=None, **opts):
1239 """create a bundle file
1240 """create a bundle file
1240
1241
1241 Generate a bundle file containing data to be transferred to another
1242 Generate a bundle file containing data to be transferred to another
1242 repository.
1243 repository.
1243
1244
1244 To create a bundle containing all changesets, use -a/--all
1245 To create a bundle containing all changesets, use -a/--all
1245 (or --base null). Otherwise, hg assumes the destination will have
1246 (or --base null). Otherwise, hg assumes the destination will have
1246 all the nodes you specify with --base parameters. Otherwise, hg
1247 all the nodes you specify with --base parameters. Otherwise, hg
1247 will assume the repository has all the nodes in destination, or
1248 will assume the repository has all the nodes in destination, or
1248 default-push/default if no destination is specified, where destination
1249 default-push/default if no destination is specified, where destination
1249 is the repository you provide through DEST option.
1250 is the repository you provide through DEST option.
1250
1251
1251 You can change bundle format with the -t/--type option. See
1252 You can change bundle format with the -t/--type option. See
1252 :hg:`help bundlespec` for documentation on this format. By default,
1253 :hg:`help bundlespec` for documentation on this format. By default,
1253 the most appropriate format is used and compression defaults to
1254 the most appropriate format is used and compression defaults to
1254 bzip2.
1255 bzip2.
1255
1256
1256 The bundle file can then be transferred using conventional means
1257 The bundle file can then be transferred using conventional means
1257 and applied to another repository with the unbundle or pull
1258 and applied to another repository with the unbundle or pull
1258 command. This is useful when direct push and pull are not
1259 command. This is useful when direct push and pull are not
1259 available or when exporting an entire repository is undesirable.
1260 available or when exporting an entire repository is undesirable.
1260
1261
1261 Applying bundles preserves all changeset contents including
1262 Applying bundles preserves all changeset contents including
1262 permissions, copy/rename information, and revision history.
1263 permissions, copy/rename information, and revision history.
1263
1264
1264 Returns 0 on success, 1 if no changes found.
1265 Returns 0 on success, 1 if no changes found.
1265 """
1266 """
1266 opts = pycompat.byteskwargs(opts)
1267 opts = pycompat.byteskwargs(opts)
1267 revs = None
1268 revs = None
1268 if 'rev' in opts:
1269 if 'rev' in opts:
1269 revstrings = opts['rev']
1270 revstrings = opts['rev']
1270 revs = scmutil.revrange(repo, revstrings)
1271 revs = scmutil.revrange(repo, revstrings)
1271 if revstrings and not revs:
1272 if revstrings and not revs:
1272 raise error.Abort(_('no commits to bundle'))
1273 raise error.Abort(_('no commits to bundle'))
1273
1274
1274 bundletype = opts.get('type', 'bzip2').lower()
1275 bundletype = opts.get('type', 'bzip2').lower()
1275 try:
1276 try:
1276 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
1277 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
1277 except error.UnsupportedBundleSpecification as e:
1278 except error.UnsupportedBundleSpecification as e:
1278 raise error.Abort(pycompat.bytestr(e),
1279 raise error.Abort(pycompat.bytestr(e),
1279 hint=_("see 'hg help bundlespec' for supported "
1280 hint=_("see 'hg help bundlespec' for supported "
1280 "values for --type"))
1281 "values for --type"))
1281 cgversion = bundlespec.contentopts["cg.version"]
1282 cgversion = bundlespec.contentopts["cg.version"]
1282
1283
1283 # Packed bundles are a pseudo bundle format for now.
1284 # Packed bundles are a pseudo bundle format for now.
1284 if cgversion == 's1':
1285 if cgversion == 's1':
1285 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1286 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1286 hint=_("use 'hg debugcreatestreamclonebundle'"))
1287 hint=_("use 'hg debugcreatestreamclonebundle'"))
1287
1288
1288 if opts.get('all'):
1289 if opts.get('all'):
1289 if dest:
1290 if dest:
1290 raise error.Abort(_("--all is incompatible with specifying "
1291 raise error.Abort(_("--all is incompatible with specifying "
1291 "a destination"))
1292 "a destination"))
1292 if opts.get('base'):
1293 if opts.get('base'):
1293 ui.warn(_("ignoring --base because --all was specified\n"))
1294 ui.warn(_("ignoring --base because --all was specified\n"))
1294 base = [nullrev]
1295 base = [nullrev]
1295 else:
1296 else:
1296 base = scmutil.revrange(repo, opts.get('base'))
1297 base = scmutil.revrange(repo, opts.get('base'))
1297 if cgversion not in changegroup.supportedoutgoingversions(repo):
1298 if cgversion not in changegroup.supportedoutgoingversions(repo):
1298 raise error.Abort(_("repository does not support bundle version %s") %
1299 raise error.Abort(_("repository does not support bundle version %s") %
1299 cgversion)
1300 cgversion)
1300
1301
1301 if base:
1302 if base:
1302 if dest:
1303 if dest:
1303 raise error.Abort(_("--base is incompatible with specifying "
1304 raise error.Abort(_("--base is incompatible with specifying "
1304 "a destination"))
1305 "a destination"))
1305 common = [repo[rev].node() for rev in base]
1306 common = [repo[rev].node() for rev in base]
1306 heads = [repo[r].node() for r in revs] if revs else None
1307 heads = [repo[r].node() for r in revs] if revs else None
1307 outgoing = discovery.outgoing(repo, common, heads)
1308 outgoing = discovery.outgoing(repo, common, heads)
1308 else:
1309 else:
1309 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1310 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1310 dest, branches = hg.parseurl(dest, opts.get('branch'))
1311 dest, branches = hg.parseurl(dest, opts.get('branch'))
1311 other = hg.peer(repo, opts, dest)
1312 other = hg.peer(repo, opts, dest)
1312 revs = [repo[r].hex() for r in revs]
1313 revs = [repo[r].hex() for r in revs]
1313 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1314 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1314 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1315 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1315 outgoing = discovery.findcommonoutgoing(repo, other,
1316 outgoing = discovery.findcommonoutgoing(repo, other,
1316 onlyheads=heads,
1317 onlyheads=heads,
1317 force=opts.get('force'),
1318 force=opts.get('force'),
1318 portable=True)
1319 portable=True)
1319
1320
1320 if not outgoing.missing:
1321 if not outgoing.missing:
1321 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1322 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1322 return 1
1323 return 1
1323
1324
1324 if cgversion == '01': #bundle1
1325 if cgversion == '01': #bundle1
1325 bversion = 'HG10' + bundlespec.wirecompression
1326 bversion = 'HG10' + bundlespec.wirecompression
1326 bcompression = None
1327 bcompression = None
1327 elif cgversion in ('02', '03'):
1328 elif cgversion in ('02', '03'):
1328 bversion = 'HG20'
1329 bversion = 'HG20'
1329 bcompression = bundlespec.wirecompression
1330 bcompression = bundlespec.wirecompression
1330 else:
1331 else:
1331 raise error.ProgrammingError(
1332 raise error.ProgrammingError(
1332 'bundle: unexpected changegroup version %s' % cgversion)
1333 'bundle: unexpected changegroup version %s' % cgversion)
1333
1334
1334 # TODO compression options should be derived from bundlespec parsing.
1335 # TODO compression options should be derived from bundlespec parsing.
1335 # This is a temporary hack to allow adjusting bundle compression
1336 # This is a temporary hack to allow adjusting bundle compression
1336 # level without a) formalizing the bundlespec changes to declare it
1337 # level without a) formalizing the bundlespec changes to declare it
1337 # b) introducing a command flag.
1338 # b) introducing a command flag.
1338 compopts = {}
1339 compopts = {}
1339 complevel = ui.configint('experimental',
1340 complevel = ui.configint('experimental',
1340 'bundlecomplevel.' + bundlespec.compression)
1341 'bundlecomplevel.' + bundlespec.compression)
1341 if complevel is None:
1342 if complevel is None:
1342 complevel = ui.configint('experimental', 'bundlecomplevel')
1343 complevel = ui.configint('experimental', 'bundlecomplevel')
1343 if complevel is not None:
1344 if complevel is not None:
1344 compopts['level'] = complevel
1345 compopts['level'] = complevel
1345
1346
1346 # Allow overriding the bundling of obsmarker in phases through
1347 # Allow overriding the bundling of obsmarker in phases through
1347 # configuration while we don't have a bundle version that include them
1348 # configuration while we don't have a bundle version that include them
1348 if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'):
1349 if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'):
1349 bundlespec.contentopts['obsolescence'] = True
1350 bundlespec.contentopts['obsolescence'] = True
1350 if repo.ui.configbool('experimental', 'bundle-phases'):
1351 if repo.ui.configbool('experimental', 'bundle-phases'):
1351 bundlespec.contentopts['phases'] = True
1352 bundlespec.contentopts['phases'] = True
1352
1353
1353 bundle2.writenewbundle(ui, repo, 'bundle', fname, bversion, outgoing,
1354 bundle2.writenewbundle(ui, repo, 'bundle', fname, bversion, outgoing,
1354 bundlespec.contentopts, compression=bcompression,
1355 bundlespec.contentopts, compression=bcompression,
1355 compopts=compopts)
1356 compopts=compopts)
1356
1357
1357 @command('cat',
1358 @command('cat',
1358 [('o', 'output', '',
1359 [('o', 'output', '',
1359 _('print output to file with formatted name'), _('FORMAT')),
1360 _('print output to file with formatted name'), _('FORMAT')),
1360 ('r', 'rev', '', _('print the given revision'), _('REV')),
1361 ('r', 'rev', '', _('print the given revision'), _('REV')),
1361 ('', 'decode', None, _('apply any matching decode filter')),
1362 ('', 'decode', None, _('apply any matching decode filter')),
1362 ] + walkopts + formatteropts,
1363 ] + walkopts + formatteropts,
1363 _('[OPTION]... FILE...'),
1364 _('[OPTION]... FILE...'),
1364 helpcategory=command.CATEGORY_FILE_CONTENTS,
1365 helpcategory=command.CATEGORY_FILE_CONTENTS,
1365 inferrepo=True,
1366 inferrepo=True,
1366 intents={INTENT_READONLY})
1367 intents={INTENT_READONLY})
1367 def cat(ui, repo, file1, *pats, **opts):
1368 def cat(ui, repo, file1, *pats, **opts):
1368 """output the current or given revision of files
1369 """output the current or given revision of files
1369
1370
1370 Print the specified files as they were at the given revision. If
1371 Print the specified files as they were at the given revision. If
1371 no revision is given, the parent of the working directory is used.
1372 no revision is given, the parent of the working directory is used.
1372
1373
1373 Output may be to a file, in which case the name of the file is
1374 Output may be to a file, in which case the name of the file is
1374 given using a template string. See :hg:`help templates`. In addition
1375 given using a template string. See :hg:`help templates`. In addition
1375 to the common template keywords, the following formatting rules are
1376 to the common template keywords, the following formatting rules are
1376 supported:
1377 supported:
1377
1378
1378 :``%%``: literal "%" character
1379 :``%%``: literal "%" character
1379 :``%s``: basename of file being printed
1380 :``%s``: basename of file being printed
1380 :``%d``: dirname of file being printed, or '.' if in repository root
1381 :``%d``: dirname of file being printed, or '.' if in repository root
1381 :``%p``: root-relative path name of file being printed
1382 :``%p``: root-relative path name of file being printed
1382 :``%H``: changeset hash (40 hexadecimal digits)
1383 :``%H``: changeset hash (40 hexadecimal digits)
1383 :``%R``: changeset revision number
1384 :``%R``: changeset revision number
1384 :``%h``: short-form changeset hash (12 hexadecimal digits)
1385 :``%h``: short-form changeset hash (12 hexadecimal digits)
1385 :``%r``: zero-padded changeset revision number
1386 :``%r``: zero-padded changeset revision number
1386 :``%b``: basename of the exporting repository
1387 :``%b``: basename of the exporting repository
1387 :``\\``: literal "\\" character
1388 :``\\``: literal "\\" character
1388
1389
1389 .. container:: verbose
1390 .. container:: verbose
1390
1391
1391 Template:
1392 Template:
1392
1393
1393 The following keywords are supported in addition to the common template
1394 The following keywords are supported in addition to the common template
1394 keywords and functions. See also :hg:`help templates`.
1395 keywords and functions. See also :hg:`help templates`.
1395
1396
1396 :data: String. File content.
1397 :data: String. File content.
1397 :path: String. Repository-absolute path of the file.
1398 :path: String. Repository-absolute path of the file.
1398
1399
1399 Returns 0 on success.
1400 Returns 0 on success.
1400 """
1401 """
1401 opts = pycompat.byteskwargs(opts)
1402 opts = pycompat.byteskwargs(opts)
1402 rev = opts.get('rev')
1403 rev = opts.get('rev')
1403 if rev:
1404 if rev:
1404 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
1405 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
1405 ctx = scmutil.revsingle(repo, rev)
1406 ctx = scmutil.revsingle(repo, rev)
1406 m = scmutil.match(ctx, (file1,) + pats, opts)
1407 m = scmutil.match(ctx, (file1,) + pats, opts)
1407 fntemplate = opts.pop('output', '')
1408 fntemplate = opts.pop('output', '')
1408 if cmdutil.isstdiofilename(fntemplate):
1409 if cmdutil.isstdiofilename(fntemplate):
1409 fntemplate = ''
1410 fntemplate = ''
1410
1411
1411 if fntemplate:
1412 if fntemplate:
1412 fm = formatter.nullformatter(ui, 'cat', opts)
1413 fm = formatter.nullformatter(ui, 'cat', opts)
1413 else:
1414 else:
1414 ui.pager('cat')
1415 ui.pager('cat')
1415 fm = ui.formatter('cat', opts)
1416 fm = ui.formatter('cat', opts)
1416 with fm:
1417 with fm:
1417 return cmdutil.cat(ui, repo, ctx, m, fm, fntemplate, '',
1418 return cmdutil.cat(ui, repo, ctx, m, fm, fntemplate, '',
1418 **pycompat.strkwargs(opts))
1419 **pycompat.strkwargs(opts))
1419
1420
1420 @command('clone',
1421 @command('clone',
1421 [('U', 'noupdate', None, _('the clone will include an empty working '
1422 [('U', 'noupdate', None, _('the clone will include an empty working '
1422 'directory (only a repository)')),
1423 'directory (only a repository)')),
1423 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1424 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1424 _('REV')),
1425 _('REV')),
1425 ('r', 'rev', [], _('do not clone everything, but include this changeset'
1426 ('r', 'rev', [], _('do not clone everything, but include this changeset'
1426 ' and its ancestors'), _('REV')),
1427 ' and its ancestors'), _('REV')),
1427 ('b', 'branch', [], _('do not clone everything, but include this branch\'s'
1428 ('b', 'branch', [], _('do not clone everything, but include this branch\'s'
1428 ' changesets and their ancestors'), _('BRANCH')),
1429 ' changesets and their ancestors'), _('BRANCH')),
1429 ('', 'pull', None, _('use pull protocol to copy metadata')),
1430 ('', 'pull', None, _('use pull protocol to copy metadata')),
1430 ('', 'uncompressed', None,
1431 ('', 'uncompressed', None,
1431 _('an alias to --stream (DEPRECATED)')),
1432 _('an alias to --stream (DEPRECATED)')),
1432 ('', 'stream', None,
1433 ('', 'stream', None,
1433 _('clone with minimal data processing')),
1434 _('clone with minimal data processing')),
1434 ] + remoteopts,
1435 ] + remoteopts,
1435 _('[OPTION]... SOURCE [DEST]'),
1436 _('[OPTION]... SOURCE [DEST]'),
1436 helpcategory=command.CATEGORY_REPO_CREATION,
1437 helpcategory=command.CATEGORY_REPO_CREATION,
1437 helpbasic=True, norepo=True)
1438 helpbasic=True, norepo=True)
1438 def clone(ui, source, dest=None, **opts):
1439 def clone(ui, source, dest=None, **opts):
1439 """make a copy of an existing repository
1440 """make a copy of an existing repository
1440
1441
1441 Create a copy of an existing repository in a new directory.
1442 Create a copy of an existing repository in a new directory.
1442
1443
1443 If no destination directory name is specified, it defaults to the
1444 If no destination directory name is specified, it defaults to the
1444 basename of the source.
1445 basename of the source.
1445
1446
1446 The location of the source is added to the new repository's
1447 The location of the source is added to the new repository's
1447 ``.hg/hgrc`` file, as the default to be used for future pulls.
1448 ``.hg/hgrc`` file, as the default to be used for future pulls.
1448
1449
1449 Only local paths and ``ssh://`` URLs are supported as
1450 Only local paths and ``ssh://`` URLs are supported as
1450 destinations. For ``ssh://`` destinations, no working directory or
1451 destinations. For ``ssh://`` destinations, no working directory or
1451 ``.hg/hgrc`` will be created on the remote side.
1452 ``.hg/hgrc`` will be created on the remote side.
1452
1453
1453 If the source repository has a bookmark called '@' set, that
1454 If the source repository has a bookmark called '@' set, that
1454 revision will be checked out in the new repository by default.
1455 revision will be checked out in the new repository by default.
1455
1456
1456 To check out a particular version, use -u/--update, or
1457 To check out a particular version, use -u/--update, or
1457 -U/--noupdate to create a clone with no working directory.
1458 -U/--noupdate to create a clone with no working directory.
1458
1459
1459 To pull only a subset of changesets, specify one or more revisions
1460 To pull only a subset of changesets, specify one or more revisions
1460 identifiers with -r/--rev or branches with -b/--branch. The
1461 identifiers with -r/--rev or branches with -b/--branch. The
1461 resulting clone will contain only the specified changesets and
1462 resulting clone will contain only the specified changesets and
1462 their ancestors. These options (or 'clone src#rev dest') imply
1463 their ancestors. These options (or 'clone src#rev dest') imply
1463 --pull, even for local source repositories.
1464 --pull, even for local source repositories.
1464
1465
1465 In normal clone mode, the remote normalizes repository data into a common
1466 In normal clone mode, the remote normalizes repository data into a common
1466 exchange format and the receiving end translates this data into its local
1467 exchange format and the receiving end translates this data into its local
1467 storage format. --stream activates a different clone mode that essentially
1468 storage format. --stream activates a different clone mode that essentially
1468 copies repository files from the remote with minimal data processing. This
1469 copies repository files from the remote with minimal data processing. This
1469 significantly reduces the CPU cost of a clone both remotely and locally.
1470 significantly reduces the CPU cost of a clone both remotely and locally.
1470 However, it often increases the transferred data size by 30-40%. This can
1471 However, it often increases the transferred data size by 30-40%. This can
1471 result in substantially faster clones where I/O throughput is plentiful,
1472 result in substantially faster clones where I/O throughput is plentiful,
1472 especially for larger repositories. A side-effect of --stream clones is
1473 especially for larger repositories. A side-effect of --stream clones is
1473 that storage settings and requirements on the remote are applied locally:
1474 that storage settings and requirements on the remote are applied locally:
1474 a modern client may inherit legacy or inefficient storage used by the
1475 a modern client may inherit legacy or inefficient storage used by the
1475 remote or a legacy Mercurial client may not be able to clone from a
1476 remote or a legacy Mercurial client may not be able to clone from a
1476 modern Mercurial remote.
1477 modern Mercurial remote.
1477
1478
1478 .. note::
1479 .. note::
1479
1480
1480 Specifying a tag will include the tagged changeset but not the
1481 Specifying a tag will include the tagged changeset but not the
1481 changeset containing the tag.
1482 changeset containing the tag.
1482
1483
1483 .. container:: verbose
1484 .. container:: verbose
1484
1485
1485 For efficiency, hardlinks are used for cloning whenever the
1486 For efficiency, hardlinks are used for cloning whenever the
1486 source and destination are on the same filesystem (note this
1487 source and destination are on the same filesystem (note this
1487 applies only to the repository data, not to the working
1488 applies only to the repository data, not to the working
1488 directory). Some filesystems, such as AFS, implement hardlinking
1489 directory). Some filesystems, such as AFS, implement hardlinking
1489 incorrectly, but do not report errors. In these cases, use the
1490 incorrectly, but do not report errors. In these cases, use the
1490 --pull option to avoid hardlinking.
1491 --pull option to avoid hardlinking.
1491
1492
1492 Mercurial will update the working directory to the first applicable
1493 Mercurial will update the working directory to the first applicable
1493 revision from this list:
1494 revision from this list:
1494
1495
1495 a) null if -U or the source repository has no changesets
1496 a) null if -U or the source repository has no changesets
1496 b) if -u . and the source repository is local, the first parent of
1497 b) if -u . and the source repository is local, the first parent of
1497 the source repository's working directory
1498 the source repository's working directory
1498 c) the changeset specified with -u (if a branch name, this means the
1499 c) the changeset specified with -u (if a branch name, this means the
1499 latest head of that branch)
1500 latest head of that branch)
1500 d) the changeset specified with -r
1501 d) the changeset specified with -r
1501 e) the tipmost head specified with -b
1502 e) the tipmost head specified with -b
1502 f) the tipmost head specified with the url#branch source syntax
1503 f) the tipmost head specified with the url#branch source syntax
1503 g) the revision marked with the '@' bookmark, if present
1504 g) the revision marked with the '@' bookmark, if present
1504 h) the tipmost head of the default branch
1505 h) the tipmost head of the default branch
1505 i) tip
1506 i) tip
1506
1507
1507 When cloning from servers that support it, Mercurial may fetch
1508 When cloning from servers that support it, Mercurial may fetch
1508 pre-generated data from a server-advertised URL or inline from the
1509 pre-generated data from a server-advertised URL or inline from the
1509 same stream. When this is done, hooks operating on incoming changesets
1510 same stream. When this is done, hooks operating on incoming changesets
1510 and changegroups may fire more than once, once for each pre-generated
1511 and changegroups may fire more than once, once for each pre-generated
1511 bundle and as well as for any additional remaining data. In addition,
1512 bundle and as well as for any additional remaining data. In addition,
1512 if an error occurs, the repository may be rolled back to a partial
1513 if an error occurs, the repository may be rolled back to a partial
1513 clone. This behavior may change in future releases.
1514 clone. This behavior may change in future releases.
1514 See :hg:`help -e clonebundles` for more.
1515 See :hg:`help -e clonebundles` for more.
1515
1516
1516 Examples:
1517 Examples:
1517
1518
1518 - clone a remote repository to a new directory named hg/::
1519 - clone a remote repository to a new directory named hg/::
1519
1520
1520 hg clone https://www.mercurial-scm.org/repo/hg/
1521 hg clone https://www.mercurial-scm.org/repo/hg/
1521
1522
1522 - create a lightweight local clone::
1523 - create a lightweight local clone::
1523
1524
1524 hg clone project/ project-feature/
1525 hg clone project/ project-feature/
1525
1526
1526 - clone from an absolute path on an ssh server (note double-slash)::
1527 - clone from an absolute path on an ssh server (note double-slash)::
1527
1528
1528 hg clone ssh://user@server//home/projects/alpha/
1529 hg clone ssh://user@server//home/projects/alpha/
1529
1530
1530 - do a streaming clone while checking out a specified version::
1531 - do a streaming clone while checking out a specified version::
1531
1532
1532 hg clone --stream http://server/repo -u 1.5
1533 hg clone --stream http://server/repo -u 1.5
1533
1534
1534 - create a repository without changesets after a particular revision::
1535 - create a repository without changesets after a particular revision::
1535
1536
1536 hg clone -r 04e544 experimental/ good/
1537 hg clone -r 04e544 experimental/ good/
1537
1538
1538 - clone (and track) a particular named branch::
1539 - clone (and track) a particular named branch::
1539
1540
1540 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1541 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1541
1542
1542 See :hg:`help urls` for details on specifying URLs.
1543 See :hg:`help urls` for details on specifying URLs.
1543
1544
1544 Returns 0 on success.
1545 Returns 0 on success.
1545 """
1546 """
1546 opts = pycompat.byteskwargs(opts)
1547 opts = pycompat.byteskwargs(opts)
1547 if opts.get('noupdate') and opts.get('updaterev'):
1548 if opts.get('noupdate') and opts.get('updaterev'):
1548 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1549 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1549
1550
1550 # --include/--exclude can come from narrow or sparse.
1551 # --include/--exclude can come from narrow or sparse.
1551 includepats, excludepats = None, None
1552 includepats, excludepats = None, None
1552
1553
1553 # hg.clone() differentiates between None and an empty set. So make sure
1554 # hg.clone() differentiates between None and an empty set. So make sure
1554 # patterns are sets if narrow is requested without patterns.
1555 # patterns are sets if narrow is requested without patterns.
1555 if opts.get('narrow'):
1556 if opts.get('narrow'):
1556 includepats = set()
1557 includepats = set()
1557 excludepats = set()
1558 excludepats = set()
1558
1559
1559 if opts.get('include'):
1560 if opts.get('include'):
1560 includepats = narrowspec.parsepatterns(opts.get('include'))
1561 includepats = narrowspec.parsepatterns(opts.get('include'))
1561 if opts.get('exclude'):
1562 if opts.get('exclude'):
1562 excludepats = narrowspec.parsepatterns(opts.get('exclude'))
1563 excludepats = narrowspec.parsepatterns(opts.get('exclude'))
1563
1564
1564 r = hg.clone(ui, opts, source, dest,
1565 r = hg.clone(ui, opts, source, dest,
1565 pull=opts.get('pull'),
1566 pull=opts.get('pull'),
1566 stream=opts.get('stream') or opts.get('uncompressed'),
1567 stream=opts.get('stream') or opts.get('uncompressed'),
1567 revs=opts.get('rev'),
1568 revs=opts.get('rev'),
1568 update=opts.get('updaterev') or not opts.get('noupdate'),
1569 update=opts.get('updaterev') or not opts.get('noupdate'),
1569 branch=opts.get('branch'),
1570 branch=opts.get('branch'),
1570 shareopts=opts.get('shareopts'),
1571 shareopts=opts.get('shareopts'),
1571 storeincludepats=includepats,
1572 storeincludepats=includepats,
1572 storeexcludepats=excludepats,
1573 storeexcludepats=excludepats,
1573 depth=opts.get('depth') or None)
1574 depth=opts.get('depth') or None)
1574
1575
1575 return r is None
1576 return r is None
1576
1577
1577 @command('commit|ci',
1578 @command('commit|ci',
1578 [('A', 'addremove', None,
1579 [('A', 'addremove', None,
1579 _('mark new/missing files as added/removed before committing')),
1580 _('mark new/missing files as added/removed before committing')),
1580 ('', 'close-branch', None,
1581 ('', 'close-branch', None,
1581 _('mark a branch head as closed')),
1582 _('mark a branch head as closed')),
1582 ('', 'amend', None, _('amend the parent of the working directory')),
1583 ('', 'amend', None, _('amend the parent of the working directory')),
1583 ('s', 'secret', None, _('use the secret phase for committing')),
1584 ('s', 'secret', None, _('use the secret phase for committing')),
1584 ('e', 'edit', None, _('invoke editor on commit messages')),
1585 ('e', 'edit', None, _('invoke editor on commit messages')),
1585 ('i', 'interactive', None, _('use interactive mode')),
1586 ('i', 'interactive', None, _('use interactive mode')),
1586 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1587 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1587 _('[OPTION]... [FILE]...'),
1588 _('[OPTION]... [FILE]...'),
1588 helpcategory=command.CATEGORY_COMMITTING, helpbasic=True,
1589 helpcategory=command.CATEGORY_COMMITTING, helpbasic=True,
1589 inferrepo=True)
1590 inferrepo=True)
1590 def commit(ui, repo, *pats, **opts):
1591 def commit(ui, repo, *pats, **opts):
1591 """commit the specified files or all outstanding changes
1592 """commit the specified files or all outstanding changes
1592
1593
1593 Commit changes to the given files into the repository. Unlike a
1594 Commit changes to the given files into the repository. Unlike a
1594 centralized SCM, this operation is a local operation. See
1595 centralized SCM, this operation is a local operation. See
1595 :hg:`push` for a way to actively distribute your changes.
1596 :hg:`push` for a way to actively distribute your changes.
1596
1597
1597 If a list of files is omitted, all changes reported by :hg:`status`
1598 If a list of files is omitted, all changes reported by :hg:`status`
1598 will be committed.
1599 will be committed.
1599
1600
1600 If you are committing the result of a merge, do not provide any
1601 If you are committing the result of a merge, do not provide any
1601 filenames or -I/-X filters.
1602 filenames or -I/-X filters.
1602
1603
1603 If no commit message is specified, Mercurial starts your
1604 If no commit message is specified, Mercurial starts your
1604 configured editor where you can enter a message. In case your
1605 configured editor where you can enter a message. In case your
1605 commit fails, you will find a backup of your message in
1606 commit fails, you will find a backup of your message in
1606 ``.hg/last-message.txt``.
1607 ``.hg/last-message.txt``.
1607
1608
1608 The --close-branch flag can be used to mark the current branch
1609 The --close-branch flag can be used to mark the current branch
1609 head closed. When all heads of a branch are closed, the branch
1610 head closed. When all heads of a branch are closed, the branch
1610 will be considered closed and no longer listed.
1611 will be considered closed and no longer listed.
1611
1612
1612 The --amend flag can be used to amend the parent of the
1613 The --amend flag can be used to amend the parent of the
1613 working directory with a new commit that contains the changes
1614 working directory with a new commit that contains the changes
1614 in the parent in addition to those currently reported by :hg:`status`,
1615 in the parent in addition to those currently reported by :hg:`status`,
1615 if there are any. The old commit is stored in a backup bundle in
1616 if there are any. The old commit is stored in a backup bundle in
1616 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1617 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1617 on how to restore it).
1618 on how to restore it).
1618
1619
1619 Message, user and date are taken from the amended commit unless
1620 Message, user and date are taken from the amended commit unless
1620 specified. When a message isn't specified on the command line,
1621 specified. When a message isn't specified on the command line,
1621 the editor will open with the message of the amended commit.
1622 the editor will open with the message of the amended commit.
1622
1623
1623 It is not possible to amend public changesets (see :hg:`help phases`)
1624 It is not possible to amend public changesets (see :hg:`help phases`)
1624 or changesets that have children.
1625 or changesets that have children.
1625
1626
1626 See :hg:`help dates` for a list of formats valid for -d/--date.
1627 See :hg:`help dates` for a list of formats valid for -d/--date.
1627
1628
1628 Returns 0 on success, 1 if nothing changed.
1629 Returns 0 on success, 1 if nothing changed.
1629
1630
1630 .. container:: verbose
1631 .. container:: verbose
1631
1632
1632 Examples:
1633 Examples:
1633
1634
1634 - commit all files ending in .py::
1635 - commit all files ending in .py::
1635
1636
1636 hg commit --include "set:**.py"
1637 hg commit --include "set:**.py"
1637
1638
1638 - commit all non-binary files::
1639 - commit all non-binary files::
1639
1640
1640 hg commit --exclude "set:binary()"
1641 hg commit --exclude "set:binary()"
1641
1642
1642 - amend the current commit and set the date to now::
1643 - amend the current commit and set the date to now::
1643
1644
1644 hg commit --amend --date now
1645 hg commit --amend --date now
1645 """
1646 """
1646 with repo.wlock(), repo.lock():
1647 with repo.wlock(), repo.lock():
1647 return _docommit(ui, repo, *pats, **opts)
1648 return _docommit(ui, repo, *pats, **opts)
1648
1649
1649 def _docommit(ui, repo, *pats, **opts):
1650 def _docommit(ui, repo, *pats, **opts):
1650 if opts.get(r'interactive'):
1651 if opts.get(r'interactive'):
1651 opts.pop(r'interactive')
1652 opts.pop(r'interactive')
1652 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1653 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1653 cmdutil.recordfilter, *pats,
1654 cmdutil.recordfilter, *pats,
1654 **opts)
1655 **opts)
1655 # ret can be 0 (no changes to record) or the value returned by
1656 # ret can be 0 (no changes to record) or the value returned by
1656 # commit(), 1 if nothing changed or None on success.
1657 # commit(), 1 if nothing changed or None on success.
1657 return 1 if ret == 0 else ret
1658 return 1 if ret == 0 else ret
1658
1659
1659 opts = pycompat.byteskwargs(opts)
1660 opts = pycompat.byteskwargs(opts)
1660 if opts.get('subrepos'):
1661 if opts.get('subrepos'):
1661 if opts.get('amend'):
1662 if opts.get('amend'):
1662 raise error.Abort(_('cannot amend with --subrepos'))
1663 raise error.Abort(_('cannot amend with --subrepos'))
1663 # Let --subrepos on the command line override config setting.
1664 # Let --subrepos on the command line override config setting.
1664 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1665 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1665
1666
1666 cmdutil.checkunfinished(repo, commit=True)
1667 cmdutil.checkunfinished(repo, commit=True)
1667
1668
1668 branch = repo[None].branch()
1669 branch = repo[None].branch()
1669 bheads = repo.branchheads(branch)
1670 bheads = repo.branchheads(branch)
1670
1671
1671 extra = {}
1672 extra = {}
1672 if opts.get('close_branch'):
1673 if opts.get('close_branch'):
1673 extra['close'] = '1'
1674 extra['close'] = '1'
1674
1675
1675 if not bheads:
1676 if not bheads:
1676 raise error.Abort(_('can only close branch heads'))
1677 raise error.Abort(_('can only close branch heads'))
1677 elif opts.get('amend'):
1678 elif opts.get('amend'):
1678 if (repo['.'].p1().branch() != branch and
1679 if (repo['.'].p1().branch() != branch and
1679 repo['.'].p2().branch() != branch):
1680 repo['.'].p2().branch() != branch):
1680 raise error.Abort(_('can only close branch heads'))
1681 raise error.Abort(_('can only close branch heads'))
1681
1682
1682 if opts.get('amend'):
1683 if opts.get('amend'):
1683 if ui.configbool('ui', 'commitsubrepos'):
1684 if ui.configbool('ui', 'commitsubrepos'):
1684 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1685 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1685
1686
1686 old = repo['.']
1687 old = repo['.']
1687 rewriteutil.precheck(repo, [old.rev()], 'amend')
1688 rewriteutil.precheck(repo, [old.rev()], 'amend')
1688
1689
1689 # Currently histedit gets confused if an amend happens while histedit
1690 # Currently histedit gets confused if an amend happens while histedit
1690 # is in progress. Since we have a checkunfinished command, we are
1691 # is in progress. Since we have a checkunfinished command, we are
1691 # temporarily honoring it.
1692 # temporarily honoring it.
1692 #
1693 #
1693 # Note: eventually this guard will be removed. Please do not expect
1694 # Note: eventually this guard will be removed. Please do not expect
1694 # this behavior to remain.
1695 # this behavior to remain.
1695 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1696 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1696 cmdutil.checkunfinished(repo)
1697 cmdutil.checkunfinished(repo)
1697
1698
1698 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
1699 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
1699 if node == old.node():
1700 if node == old.node():
1700 ui.status(_("nothing changed\n"))
1701 ui.status(_("nothing changed\n"))
1701 return 1
1702 return 1
1702 else:
1703 else:
1703 def commitfunc(ui, repo, message, match, opts):
1704 def commitfunc(ui, repo, message, match, opts):
1704 overrides = {}
1705 overrides = {}
1705 if opts.get('secret'):
1706 if opts.get('secret'):
1706 overrides[('phases', 'new-commit')] = 'secret'
1707 overrides[('phases', 'new-commit')] = 'secret'
1707
1708
1708 baseui = repo.baseui
1709 baseui = repo.baseui
1709 with baseui.configoverride(overrides, 'commit'):
1710 with baseui.configoverride(overrides, 'commit'):
1710 with ui.configoverride(overrides, 'commit'):
1711 with ui.configoverride(overrides, 'commit'):
1711 editform = cmdutil.mergeeditform(repo[None],
1712 editform = cmdutil.mergeeditform(repo[None],
1712 'commit.normal')
1713 'commit.normal')
1713 editor = cmdutil.getcommiteditor(
1714 editor = cmdutil.getcommiteditor(
1714 editform=editform, **pycompat.strkwargs(opts))
1715 editform=editform, **pycompat.strkwargs(opts))
1715 return repo.commit(message,
1716 return repo.commit(message,
1716 opts.get('user'),
1717 opts.get('user'),
1717 opts.get('date'),
1718 opts.get('date'),
1718 match,
1719 match,
1719 editor=editor,
1720 editor=editor,
1720 extra=extra)
1721 extra=extra)
1721
1722
1722 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1723 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1723
1724
1724 if not node:
1725 if not node:
1725 stat = cmdutil.postcommitstatus(repo, pats, opts)
1726 stat = cmdutil.postcommitstatus(repo, pats, opts)
1726 if stat[3]:
1727 if stat[3]:
1727 ui.status(_("nothing changed (%d missing files, see "
1728 ui.status(_("nothing changed (%d missing files, see "
1728 "'hg status')\n") % len(stat[3]))
1729 "'hg status')\n") % len(stat[3]))
1729 else:
1730 else:
1730 ui.status(_("nothing changed\n"))
1731 ui.status(_("nothing changed\n"))
1731 return 1
1732 return 1
1732
1733
1733 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1734 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1734
1735
1735 @command('config|showconfig|debugconfig',
1736 @command('config|showconfig|debugconfig',
1736 [('u', 'untrusted', None, _('show untrusted configuration options')),
1737 [('u', 'untrusted', None, _('show untrusted configuration options')),
1737 ('e', 'edit', None, _('edit user config')),
1738 ('e', 'edit', None, _('edit user config')),
1738 ('l', 'local', None, _('edit repository config')),
1739 ('l', 'local', None, _('edit repository config')),
1739 ('g', 'global', None, _('edit global config'))] + formatteropts,
1740 ('g', 'global', None, _('edit global config'))] + formatteropts,
1740 _('[-u] [NAME]...'),
1741 _('[-u] [NAME]...'),
1741 helpcategory=command.CATEGORY_HELP,
1742 helpcategory=command.CATEGORY_HELP,
1742 optionalrepo=True,
1743 optionalrepo=True,
1743 intents={INTENT_READONLY})
1744 intents={INTENT_READONLY})
1744 def config(ui, repo, *values, **opts):
1745 def config(ui, repo, *values, **opts):
1745 """show combined config settings from all hgrc files
1746 """show combined config settings from all hgrc files
1746
1747
1747 With no arguments, print names and values of all config items.
1748 With no arguments, print names and values of all config items.
1748
1749
1749 With one argument of the form section.name, print just the value
1750 With one argument of the form section.name, print just the value
1750 of that config item.
1751 of that config item.
1751
1752
1752 With multiple arguments, print names and values of all config
1753 With multiple arguments, print names and values of all config
1753 items with matching section names or section.names.
1754 items with matching section names or section.names.
1754
1755
1755 With --edit, start an editor on the user-level config file. With
1756 With --edit, start an editor on the user-level config file. With
1756 --global, edit the system-wide config file. With --local, edit the
1757 --global, edit the system-wide config file. With --local, edit the
1757 repository-level config file.
1758 repository-level config file.
1758
1759
1759 With --debug, the source (filename and line number) is printed
1760 With --debug, the source (filename and line number) is printed
1760 for each config item.
1761 for each config item.
1761
1762
1762 See :hg:`help config` for more information about config files.
1763 See :hg:`help config` for more information about config files.
1763
1764
1764 .. container:: verbose
1765 .. container:: verbose
1765
1766
1766 Template:
1767 Template:
1767
1768
1768 The following keywords are supported. See also :hg:`help templates`.
1769 The following keywords are supported. See also :hg:`help templates`.
1769
1770
1770 :name: String. Config name.
1771 :name: String. Config name.
1771 :source: String. Filename and line number where the item is defined.
1772 :source: String. Filename and line number where the item is defined.
1772 :value: String. Config value.
1773 :value: String. Config value.
1773
1774
1774 Returns 0 on success, 1 if NAME does not exist.
1775 Returns 0 on success, 1 if NAME does not exist.
1775
1776
1776 """
1777 """
1777
1778
1778 opts = pycompat.byteskwargs(opts)
1779 opts = pycompat.byteskwargs(opts)
1779 if opts.get('edit') or opts.get('local') or opts.get('global'):
1780 if opts.get('edit') or opts.get('local') or opts.get('global'):
1780 if opts.get('local') and opts.get('global'):
1781 if opts.get('local') and opts.get('global'):
1781 raise error.Abort(_("can't use --local and --global together"))
1782 raise error.Abort(_("can't use --local and --global together"))
1782
1783
1783 if opts.get('local'):
1784 if opts.get('local'):
1784 if not repo:
1785 if not repo:
1785 raise error.Abort(_("can't use --local outside a repository"))
1786 raise error.Abort(_("can't use --local outside a repository"))
1786 paths = [repo.vfs.join('hgrc')]
1787 paths = [repo.vfs.join('hgrc')]
1787 elif opts.get('global'):
1788 elif opts.get('global'):
1788 paths = rcutil.systemrcpath()
1789 paths = rcutil.systemrcpath()
1789 else:
1790 else:
1790 paths = rcutil.userrcpath()
1791 paths = rcutil.userrcpath()
1791
1792
1792 for f in paths:
1793 for f in paths:
1793 if os.path.exists(f):
1794 if os.path.exists(f):
1794 break
1795 break
1795 else:
1796 else:
1796 if opts.get('global'):
1797 if opts.get('global'):
1797 samplehgrc = uimod.samplehgrcs['global']
1798 samplehgrc = uimod.samplehgrcs['global']
1798 elif opts.get('local'):
1799 elif opts.get('local'):
1799 samplehgrc = uimod.samplehgrcs['local']
1800 samplehgrc = uimod.samplehgrcs['local']
1800 else:
1801 else:
1801 samplehgrc = uimod.samplehgrcs['user']
1802 samplehgrc = uimod.samplehgrcs['user']
1802
1803
1803 f = paths[0]
1804 f = paths[0]
1804 fp = open(f, "wb")
1805 fp = open(f, "wb")
1805 fp.write(util.tonativeeol(samplehgrc))
1806 fp.write(util.tonativeeol(samplehgrc))
1806 fp.close()
1807 fp.close()
1807
1808
1808 editor = ui.geteditor()
1809 editor = ui.geteditor()
1809 ui.system("%s \"%s\"" % (editor, f),
1810 ui.system("%s \"%s\"" % (editor, f),
1810 onerr=error.Abort, errprefix=_("edit failed"),
1811 onerr=error.Abort, errprefix=_("edit failed"),
1811 blockedtag='config_edit')
1812 blockedtag='config_edit')
1812 return
1813 return
1813 ui.pager('config')
1814 ui.pager('config')
1814 fm = ui.formatter('config', opts)
1815 fm = ui.formatter('config', opts)
1815 for t, f in rcutil.rccomponents():
1816 for t, f in rcutil.rccomponents():
1816 if t == 'path':
1817 if t == 'path':
1817 ui.debug('read config from: %s\n' % f)
1818 ui.debug('read config from: %s\n' % f)
1818 elif t == 'items':
1819 elif t == 'items':
1819 for section, name, value, source in f:
1820 for section, name, value, source in f:
1820 ui.debug('set config by: %s\n' % source)
1821 ui.debug('set config by: %s\n' % source)
1821 else:
1822 else:
1822 raise error.ProgrammingError('unknown rctype: %s' % t)
1823 raise error.ProgrammingError('unknown rctype: %s' % t)
1823 untrusted = bool(opts.get('untrusted'))
1824 untrusted = bool(opts.get('untrusted'))
1824
1825
1825 selsections = selentries = []
1826 selsections = selentries = []
1826 if values:
1827 if values:
1827 selsections = [v for v in values if '.' not in v]
1828 selsections = [v for v in values if '.' not in v]
1828 selentries = [v for v in values if '.' in v]
1829 selentries = [v for v in values if '.' in v]
1829 uniquesel = (len(selentries) == 1 and not selsections)
1830 uniquesel = (len(selentries) == 1 and not selsections)
1830 selsections = set(selsections)
1831 selsections = set(selsections)
1831 selentries = set(selentries)
1832 selentries = set(selentries)
1832
1833
1833 matched = False
1834 matched = False
1834 for section, name, value in ui.walkconfig(untrusted=untrusted):
1835 for section, name, value in ui.walkconfig(untrusted=untrusted):
1835 source = ui.configsource(section, name, untrusted)
1836 source = ui.configsource(section, name, untrusted)
1836 value = pycompat.bytestr(value)
1837 value = pycompat.bytestr(value)
1837 if fm.isplain():
1838 if fm.isplain():
1838 source = source or 'none'
1839 source = source or 'none'
1839 value = value.replace('\n', '\\n')
1840 value = value.replace('\n', '\\n')
1840 entryname = section + '.' + name
1841 entryname = section + '.' + name
1841 if values and not (section in selsections or entryname in selentries):
1842 if values and not (section in selsections or entryname in selentries):
1842 continue
1843 continue
1843 fm.startitem()
1844 fm.startitem()
1844 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1845 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1845 if uniquesel:
1846 if uniquesel:
1846 fm.data(name=entryname)
1847 fm.data(name=entryname)
1847 fm.write('value', '%s\n', value)
1848 fm.write('value', '%s\n', value)
1848 else:
1849 else:
1849 fm.write('name value', '%s=%s\n', entryname, value)
1850 fm.write('name value', '%s=%s\n', entryname, value)
1850 matched = True
1851 matched = True
1851 fm.end()
1852 fm.end()
1852 if matched:
1853 if matched:
1853 return 0
1854 return 0
1854 return 1
1855 return 1
1855
1856
1856 @command('copy|cp',
1857 @command('copy|cp',
1857 [('A', 'after', None, _('record a copy that has already occurred')),
1858 [('A', 'after', None, _('record a copy that has already occurred')),
1858 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1859 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1859 ] + walkopts + dryrunopts,
1860 ] + walkopts + dryrunopts,
1860 _('[OPTION]... [SOURCE]... DEST'),
1861 _('[OPTION]... [SOURCE]... DEST'),
1861 helpcategory=command.CATEGORY_FILE_CONTENTS)
1862 helpcategory=command.CATEGORY_FILE_CONTENTS)
1862 def copy(ui, repo, *pats, **opts):
1863 def copy(ui, repo, *pats, **opts):
1863 """mark files as copied for the next commit
1864 """mark files as copied for the next commit
1864
1865
1865 Mark dest as having copies of source files. If dest is a
1866 Mark dest as having copies of source files. If dest is a
1866 directory, copies are put in that directory. If dest is a file,
1867 directory, copies are put in that directory. If dest is a file,
1867 the source must be a single file.
1868 the source must be a single file.
1868
1869
1869 By default, this command copies the contents of files as they
1870 By default, this command copies the contents of files as they
1870 exist in the working directory. If invoked with -A/--after, the
1871 exist in the working directory. If invoked with -A/--after, the
1871 operation is recorded, but no copying is performed.
1872 operation is recorded, but no copying is performed.
1872
1873
1873 This command takes effect with the next commit. To undo a copy
1874 This command takes effect with the next commit. To undo a copy
1874 before that, see :hg:`revert`.
1875 before that, see :hg:`revert`.
1875
1876
1876 Returns 0 on success, 1 if errors are encountered.
1877 Returns 0 on success, 1 if errors are encountered.
1877 """
1878 """
1878 opts = pycompat.byteskwargs(opts)
1879 opts = pycompat.byteskwargs(opts)
1879 with repo.wlock(False):
1880 with repo.wlock(False):
1880 return cmdutil.copy(ui, repo, pats, opts)
1881 return cmdutil.copy(ui, repo, pats, opts)
1881
1882
1882 @command(
1883 @command(
1883 'debugcommands', [], _('[COMMAND]'),
1884 'debugcommands', [], _('[COMMAND]'),
1884 helpcategory=command.CATEGORY_HELP,
1885 helpcategory=command.CATEGORY_HELP,
1885 norepo=True)
1886 norepo=True)
1886 def debugcommands(ui, cmd='', *args):
1887 def debugcommands(ui, cmd='', *args):
1887 """list all available commands and options"""
1888 """list all available commands and options"""
1888 for cmd, vals in sorted(table.iteritems()):
1889 for cmd, vals in sorted(table.iteritems()):
1889 cmd = cmd.split('|')[0]
1890 cmd = cmd.split('|')[0]
1890 opts = ', '.join([i[1] for i in vals[1]])
1891 opts = ', '.join([i[1] for i in vals[1]])
1891 ui.write('%s: %s\n' % (cmd, opts))
1892 ui.write('%s: %s\n' % (cmd, opts))
1892
1893
1893 @command('debugcomplete',
1894 @command('debugcomplete',
1894 [('o', 'options', None, _('show the command options'))],
1895 [('o', 'options', None, _('show the command options'))],
1895 _('[-o] CMD'),
1896 _('[-o] CMD'),
1896 helpcategory=command.CATEGORY_HELP,
1897 helpcategory=command.CATEGORY_HELP,
1897 norepo=True)
1898 norepo=True)
1898 def debugcomplete(ui, cmd='', **opts):
1899 def debugcomplete(ui, cmd='', **opts):
1899 """returns the completion list associated with the given command"""
1900 """returns the completion list associated with the given command"""
1900
1901
1901 if opts.get(r'options'):
1902 if opts.get(r'options'):
1902 options = []
1903 options = []
1903 otables = [globalopts]
1904 otables = [globalopts]
1904 if cmd:
1905 if cmd:
1905 aliases, entry = cmdutil.findcmd(cmd, table, False)
1906 aliases, entry = cmdutil.findcmd(cmd, table, False)
1906 otables.append(entry[1])
1907 otables.append(entry[1])
1907 for t in otables:
1908 for t in otables:
1908 for o in t:
1909 for o in t:
1909 if "(DEPRECATED)" in o[3]:
1910 if "(DEPRECATED)" in o[3]:
1910 continue
1911 continue
1911 if o[0]:
1912 if o[0]:
1912 options.append('-%s' % o[0])
1913 options.append('-%s' % o[0])
1913 options.append('--%s' % o[1])
1914 options.append('--%s' % o[1])
1914 ui.write("%s\n" % "\n".join(options))
1915 ui.write("%s\n" % "\n".join(options))
1915 return
1916 return
1916
1917
1917 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
1918 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
1918 if ui.verbose:
1919 if ui.verbose:
1919 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1920 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1920 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1921 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1921
1922
1922 @command('diff',
1923 @command('diff',
1923 [('r', 'rev', [], _('revision'), _('REV')),
1924 [('r', 'rev', [], _('revision'), _('REV')),
1924 ('c', 'change', '', _('change made by revision'), _('REV'))
1925 ('c', 'change', '', _('change made by revision'), _('REV'))
1925 ] + diffopts + diffopts2 + walkopts + subrepoopts,
1926 ] + diffopts + diffopts2 + walkopts + subrepoopts,
1926 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1927 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1927 helpcategory=command.CATEGORY_FILE_CONTENTS,
1928 helpcategory=command.CATEGORY_FILE_CONTENTS,
1928 helpbasic=True, inferrepo=True, intents={INTENT_READONLY})
1929 helpbasic=True, inferrepo=True, intents={INTENT_READONLY})
1929 def diff(ui, repo, *pats, **opts):
1930 def diff(ui, repo, *pats, **opts):
1930 """diff repository (or selected files)
1931 """diff repository (or selected files)
1931
1932
1932 Show differences between revisions for the specified files.
1933 Show differences between revisions for the specified files.
1933
1934
1934 Differences between files are shown using the unified diff format.
1935 Differences between files are shown using the unified diff format.
1935
1936
1936 .. note::
1937 .. note::
1937
1938
1938 :hg:`diff` may generate unexpected results for merges, as it will
1939 :hg:`diff` may generate unexpected results for merges, as it will
1939 default to comparing against the working directory's first
1940 default to comparing against the working directory's first
1940 parent changeset if no revisions are specified.
1941 parent changeset if no revisions are specified.
1941
1942
1942 When two revision arguments are given, then changes are shown
1943 When two revision arguments are given, then changes are shown
1943 between those revisions. If only one revision is specified then
1944 between those revisions. If only one revision is specified then
1944 that revision is compared to the working directory, and, when no
1945 that revision is compared to the working directory, and, when no
1945 revisions are specified, the working directory files are compared
1946 revisions are specified, the working directory files are compared
1946 to its first parent.
1947 to its first parent.
1947
1948
1948 Alternatively you can specify -c/--change with a revision to see
1949 Alternatively you can specify -c/--change with a revision to see
1949 the changes in that changeset relative to its first parent.
1950 the changes in that changeset relative to its first parent.
1950
1951
1951 Without the -a/--text option, diff will avoid generating diffs of
1952 Without the -a/--text option, diff will avoid generating diffs of
1952 files it detects as binary. With -a, diff will generate a diff
1953 files it detects as binary. With -a, diff will generate a diff
1953 anyway, probably with undesirable results.
1954 anyway, probably with undesirable results.
1954
1955
1955 Use the -g/--git option to generate diffs in the git extended diff
1956 Use the -g/--git option to generate diffs in the git extended diff
1956 format. For more information, read :hg:`help diffs`.
1957 format. For more information, read :hg:`help diffs`.
1957
1958
1958 .. container:: verbose
1959 .. container:: verbose
1959
1960
1960 Examples:
1961 Examples:
1961
1962
1962 - compare a file in the current working directory to its parent::
1963 - compare a file in the current working directory to its parent::
1963
1964
1964 hg diff foo.c
1965 hg diff foo.c
1965
1966
1966 - compare two historical versions of a directory, with rename info::
1967 - compare two historical versions of a directory, with rename info::
1967
1968
1968 hg diff --git -r 1.0:1.2 lib/
1969 hg diff --git -r 1.0:1.2 lib/
1969
1970
1970 - get change stats relative to the last change on some date::
1971 - get change stats relative to the last change on some date::
1971
1972
1972 hg diff --stat -r "date('may 2')"
1973 hg diff --stat -r "date('may 2')"
1973
1974
1974 - diff all newly-added files that contain a keyword::
1975 - diff all newly-added files that contain a keyword::
1975
1976
1976 hg diff "set:added() and grep(GNU)"
1977 hg diff "set:added() and grep(GNU)"
1977
1978
1978 - compare a revision and its parents::
1979 - compare a revision and its parents::
1979
1980
1980 hg diff -c 9353 # compare against first parent
1981 hg diff -c 9353 # compare against first parent
1981 hg diff -r 9353^:9353 # same using revset syntax
1982 hg diff -r 9353^:9353 # same using revset syntax
1982 hg diff -r 9353^2:9353 # compare against the second parent
1983 hg diff -r 9353^2:9353 # compare against the second parent
1983
1984
1984 Returns 0 on success.
1985 Returns 0 on success.
1985 """
1986 """
1986
1987
1987 opts = pycompat.byteskwargs(opts)
1988 opts = pycompat.byteskwargs(opts)
1988 revs = opts.get('rev')
1989 revs = opts.get('rev')
1989 change = opts.get('change')
1990 change = opts.get('change')
1990 stat = opts.get('stat')
1991 stat = opts.get('stat')
1991 reverse = opts.get('reverse')
1992 reverse = opts.get('reverse')
1992
1993
1993 if revs and change:
1994 if revs and change:
1994 msg = _('cannot specify --rev and --change at the same time')
1995 msg = _('cannot specify --rev and --change at the same time')
1995 raise error.Abort(msg)
1996 raise error.Abort(msg)
1996 elif change:
1997 elif change:
1997 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
1998 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
1998 ctx2 = scmutil.revsingle(repo, change, None)
1999 ctx2 = scmutil.revsingle(repo, change, None)
1999 ctx1 = ctx2.p1()
2000 ctx1 = ctx2.p1()
2000 else:
2001 else:
2001 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
2002 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
2002 ctx1, ctx2 = scmutil.revpair(repo, revs)
2003 ctx1, ctx2 = scmutil.revpair(repo, revs)
2003 node1, node2 = ctx1.node(), ctx2.node()
2004 node1, node2 = ctx1.node(), ctx2.node()
2004
2005
2005 if reverse:
2006 if reverse:
2006 node1, node2 = node2, node1
2007 node1, node2 = node2, node1
2007
2008
2008 diffopts = patch.diffallopts(ui, opts)
2009 diffopts = patch.diffallopts(ui, opts)
2009 m = scmutil.match(ctx2, pats, opts)
2010 m = scmutil.match(ctx2, pats, opts)
2010 m = repo.narrowmatch(m)
2011 m = repo.narrowmatch(m)
2011 ui.pager('diff')
2012 ui.pager('diff')
2012 logcmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2013 logcmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2013 listsubrepos=opts.get('subrepos'),
2014 listsubrepos=opts.get('subrepos'),
2014 root=opts.get('root'))
2015 root=opts.get('root'))
2015
2016
2016 @command('export',
2017 @command('export',
2017 [('B', 'bookmark', '',
2018 [('B', 'bookmark', '',
2018 _('export changes only reachable by given bookmark'), _('BOOKMARK')),
2019 _('export changes only reachable by given bookmark'), _('BOOKMARK')),
2019 ('o', 'output', '',
2020 ('o', 'output', '',
2020 _('print output to file with formatted name'), _('FORMAT')),
2021 _('print output to file with formatted name'), _('FORMAT')),
2021 ('', 'switch-parent', None, _('diff against the second parent')),
2022 ('', 'switch-parent', None, _('diff against the second parent')),
2022 ('r', 'rev', [], _('revisions to export'), _('REV')),
2023 ('r', 'rev', [], _('revisions to export'), _('REV')),
2023 ] + diffopts + formatteropts,
2024 ] + diffopts + formatteropts,
2024 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2025 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2025 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2026 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2026 helpbasic=True, intents={INTENT_READONLY})
2027 helpbasic=True, intents={INTENT_READONLY})
2027 def export(ui, repo, *changesets, **opts):
2028 def export(ui, repo, *changesets, **opts):
2028 """dump the header and diffs for one or more changesets
2029 """dump the header and diffs for one or more changesets
2029
2030
2030 Print the changeset header and diffs for one or more revisions.
2031 Print the changeset header and diffs for one or more revisions.
2031 If no revision is given, the parent of the working directory is used.
2032 If no revision is given, the parent of the working directory is used.
2032
2033
2033 The information shown in the changeset header is: author, date,
2034 The information shown in the changeset header is: author, date,
2034 branch name (if non-default), changeset hash, parent(s) and commit
2035 branch name (if non-default), changeset hash, parent(s) and commit
2035 comment.
2036 comment.
2036
2037
2037 .. note::
2038 .. note::
2038
2039
2039 :hg:`export` may generate unexpected diff output for merge
2040 :hg:`export` may generate unexpected diff output for merge
2040 changesets, as it will compare the merge changeset against its
2041 changesets, as it will compare the merge changeset against its
2041 first parent only.
2042 first parent only.
2042
2043
2043 Output may be to a file, in which case the name of the file is
2044 Output may be to a file, in which case the name of the file is
2044 given using a template string. See :hg:`help templates`. In addition
2045 given using a template string. See :hg:`help templates`. In addition
2045 to the common template keywords, the following formatting rules are
2046 to the common template keywords, the following formatting rules are
2046 supported:
2047 supported:
2047
2048
2048 :``%%``: literal "%" character
2049 :``%%``: literal "%" character
2049 :``%H``: changeset hash (40 hexadecimal digits)
2050 :``%H``: changeset hash (40 hexadecimal digits)
2050 :``%N``: number of patches being generated
2051 :``%N``: number of patches being generated
2051 :``%R``: changeset revision number
2052 :``%R``: changeset revision number
2052 :``%b``: basename of the exporting repository
2053 :``%b``: basename of the exporting repository
2053 :``%h``: short-form changeset hash (12 hexadecimal digits)
2054 :``%h``: short-form changeset hash (12 hexadecimal digits)
2054 :``%m``: first line of the commit message (only alphanumeric characters)
2055 :``%m``: first line of the commit message (only alphanumeric characters)
2055 :``%n``: zero-padded sequence number, starting at 1
2056 :``%n``: zero-padded sequence number, starting at 1
2056 :``%r``: zero-padded changeset revision number
2057 :``%r``: zero-padded changeset revision number
2057 :``\\``: literal "\\" character
2058 :``\\``: literal "\\" character
2058
2059
2059 Without the -a/--text option, export will avoid generating diffs
2060 Without the -a/--text option, export will avoid generating diffs
2060 of files it detects as binary. With -a, export will generate a
2061 of files it detects as binary. With -a, export will generate a
2061 diff anyway, probably with undesirable results.
2062 diff anyway, probably with undesirable results.
2062
2063
2063 With -B/--bookmark changesets reachable by the given bookmark are
2064 With -B/--bookmark changesets reachable by the given bookmark are
2064 selected.
2065 selected.
2065
2066
2066 Use the -g/--git option to generate diffs in the git extended diff
2067 Use the -g/--git option to generate diffs in the git extended diff
2067 format. See :hg:`help diffs` for more information.
2068 format. See :hg:`help diffs` for more information.
2068
2069
2069 With the --switch-parent option, the diff will be against the
2070 With the --switch-parent option, the diff will be against the
2070 second parent. It can be useful to review a merge.
2071 second parent. It can be useful to review a merge.
2071
2072
2072 .. container:: verbose
2073 .. container:: verbose
2073
2074
2074 Template:
2075 Template:
2075
2076
2076 The following keywords are supported in addition to the common template
2077 The following keywords are supported in addition to the common template
2077 keywords and functions. See also :hg:`help templates`.
2078 keywords and functions. See also :hg:`help templates`.
2078
2079
2079 :diff: String. Diff content.
2080 :diff: String. Diff content.
2080 :parents: List of strings. Parent nodes of the changeset.
2081 :parents: List of strings. Parent nodes of the changeset.
2081
2082
2082 Examples:
2083 Examples:
2083
2084
2084 - use export and import to transplant a bugfix to the current
2085 - use export and import to transplant a bugfix to the current
2085 branch::
2086 branch::
2086
2087
2087 hg export -r 9353 | hg import -
2088 hg export -r 9353 | hg import -
2088
2089
2089 - export all the changesets between two revisions to a file with
2090 - export all the changesets between two revisions to a file with
2090 rename information::
2091 rename information::
2091
2092
2092 hg export --git -r 123:150 > changes.txt
2093 hg export --git -r 123:150 > changes.txt
2093
2094
2094 - split outgoing changes into a series of patches with
2095 - split outgoing changes into a series of patches with
2095 descriptive names::
2096 descriptive names::
2096
2097
2097 hg export -r "outgoing()" -o "%n-%m.patch"
2098 hg export -r "outgoing()" -o "%n-%m.patch"
2098
2099
2099 Returns 0 on success.
2100 Returns 0 on success.
2100 """
2101 """
2101 opts = pycompat.byteskwargs(opts)
2102 opts = pycompat.byteskwargs(opts)
2102 bookmark = opts.get('bookmark')
2103 bookmark = opts.get('bookmark')
2103 changesets += tuple(opts.get('rev', []))
2104 changesets += tuple(opts.get('rev', []))
2104
2105
2105 if bookmark and changesets:
2106 if bookmark and changesets:
2106 raise error.Abort(_("-r and -B are mutually exclusive"))
2107 raise error.Abort(_("-r and -B are mutually exclusive"))
2107
2108
2108 if bookmark:
2109 if bookmark:
2109 if bookmark not in repo._bookmarks:
2110 if bookmark not in repo._bookmarks:
2110 raise error.Abort(_("bookmark '%s' not found") % bookmark)
2111 raise error.Abort(_("bookmark '%s' not found") % bookmark)
2111
2112
2112 revs = scmutil.bookmarkrevs(repo, bookmark)
2113 revs = scmutil.bookmarkrevs(repo, bookmark)
2113 else:
2114 else:
2114 if not changesets:
2115 if not changesets:
2115 changesets = ['.']
2116 changesets = ['.']
2116
2117
2117 repo = scmutil.unhidehashlikerevs(repo, changesets, 'nowarn')
2118 repo = scmutil.unhidehashlikerevs(repo, changesets, 'nowarn')
2118 revs = scmutil.revrange(repo, changesets)
2119 revs = scmutil.revrange(repo, changesets)
2119
2120
2120 if not revs:
2121 if not revs:
2121 raise error.Abort(_("export requires at least one changeset"))
2122 raise error.Abort(_("export requires at least one changeset"))
2122 if len(revs) > 1:
2123 if len(revs) > 1:
2123 ui.note(_('exporting patches:\n'))
2124 ui.note(_('exporting patches:\n'))
2124 else:
2125 else:
2125 ui.note(_('exporting patch:\n'))
2126 ui.note(_('exporting patch:\n'))
2126
2127
2127 fntemplate = opts.get('output')
2128 fntemplate = opts.get('output')
2128 if cmdutil.isstdiofilename(fntemplate):
2129 if cmdutil.isstdiofilename(fntemplate):
2129 fntemplate = ''
2130 fntemplate = ''
2130
2131
2131 if fntemplate:
2132 if fntemplate:
2132 fm = formatter.nullformatter(ui, 'export', opts)
2133 fm = formatter.nullformatter(ui, 'export', opts)
2133 else:
2134 else:
2134 ui.pager('export')
2135 ui.pager('export')
2135 fm = ui.formatter('export', opts)
2136 fm = ui.formatter('export', opts)
2136 with fm:
2137 with fm:
2137 cmdutil.export(repo, revs, fm, fntemplate=fntemplate,
2138 cmdutil.export(repo, revs, fm, fntemplate=fntemplate,
2138 switch_parent=opts.get('switch_parent'),
2139 switch_parent=opts.get('switch_parent'),
2139 opts=patch.diffallopts(ui, opts))
2140 opts=patch.diffallopts(ui, opts))
2140
2141
2141 @command('files',
2142 @command('files',
2142 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2143 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2143 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2144 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2144 ] + walkopts + formatteropts + subrepoopts,
2145 ] + walkopts + formatteropts + subrepoopts,
2145 _('[OPTION]... [FILE]...'),
2146 _('[OPTION]... [FILE]...'),
2146 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2147 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2147 intents={INTENT_READONLY})
2148 intents={INTENT_READONLY})
2148 def files(ui, repo, *pats, **opts):
2149 def files(ui, repo, *pats, **opts):
2149 """list tracked files
2150 """list tracked files
2150
2151
2151 Print files under Mercurial control in the working directory or
2152 Print files under Mercurial control in the working directory or
2152 specified revision for given files (excluding removed files).
2153 specified revision for given files (excluding removed files).
2153 Files can be specified as filenames or filesets.
2154 Files can be specified as filenames or filesets.
2154
2155
2155 If no files are given to match, this command prints the names
2156 If no files are given to match, this command prints the names
2156 of all files under Mercurial control.
2157 of all files under Mercurial control.
2157
2158
2158 .. container:: verbose
2159 .. container:: verbose
2159
2160
2160 Template:
2161 Template:
2161
2162
2162 The following keywords are supported in addition to the common template
2163 The following keywords are supported in addition to the common template
2163 keywords and functions. See also :hg:`help templates`.
2164 keywords and functions. See also :hg:`help templates`.
2164
2165
2165 :flags: String. Character denoting file's symlink and executable bits.
2166 :flags: String. Character denoting file's symlink and executable bits.
2166 :path: String. Repository-absolute path of the file.
2167 :path: String. Repository-absolute path of the file.
2167 :size: Integer. Size of the file in bytes.
2168 :size: Integer. Size of the file in bytes.
2168
2169
2169 Examples:
2170 Examples:
2170
2171
2171 - list all files under the current directory::
2172 - list all files under the current directory::
2172
2173
2173 hg files .
2174 hg files .
2174
2175
2175 - shows sizes and flags for current revision::
2176 - shows sizes and flags for current revision::
2176
2177
2177 hg files -vr .
2178 hg files -vr .
2178
2179
2179 - list all files named README::
2180 - list all files named README::
2180
2181
2181 hg files -I "**/README"
2182 hg files -I "**/README"
2182
2183
2183 - list all binary files::
2184 - list all binary files::
2184
2185
2185 hg files "set:binary()"
2186 hg files "set:binary()"
2186
2187
2187 - find files containing a regular expression::
2188 - find files containing a regular expression::
2188
2189
2189 hg files "set:grep('bob')"
2190 hg files "set:grep('bob')"
2190
2191
2191 - search tracked file contents with xargs and grep::
2192 - search tracked file contents with xargs and grep::
2192
2193
2193 hg files -0 | xargs -0 grep foo
2194 hg files -0 | xargs -0 grep foo
2194
2195
2195 See :hg:`help patterns` and :hg:`help filesets` for more information
2196 See :hg:`help patterns` and :hg:`help filesets` for more information
2196 on specifying file patterns.
2197 on specifying file patterns.
2197
2198
2198 Returns 0 if a match is found, 1 otherwise.
2199 Returns 0 if a match is found, 1 otherwise.
2199
2200
2200 """
2201 """
2201
2202
2202 opts = pycompat.byteskwargs(opts)
2203 opts = pycompat.byteskwargs(opts)
2203 rev = opts.get('rev')
2204 rev = opts.get('rev')
2204 if rev:
2205 if rev:
2205 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
2206 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
2206 ctx = scmutil.revsingle(repo, rev, None)
2207 ctx = scmutil.revsingle(repo, rev, None)
2207
2208
2208 end = '\n'
2209 end = '\n'
2209 if opts.get('print0'):
2210 if opts.get('print0'):
2210 end = '\0'
2211 end = '\0'
2211 fmt = '%s' + end
2212 fmt = '%s' + end
2212
2213
2213 m = scmutil.match(ctx, pats, opts)
2214 m = scmutil.match(ctx, pats, opts)
2214 ui.pager('files')
2215 ui.pager('files')
2215 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2216 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2216 with ui.formatter('files', opts) as fm:
2217 with ui.formatter('files', opts) as fm:
2217 return cmdutil.files(ui, ctx, m, uipathfn, fm, fmt,
2218 return cmdutil.files(ui, ctx, m, uipathfn, fm, fmt,
2218 opts.get('subrepos'))
2219 opts.get('subrepos'))
2219
2220
2220 @command(
2221 @command(
2221 'forget',
2222 'forget',
2222 [('i', 'interactive', None, _('use interactive mode')),
2223 [('i', 'interactive', None, _('use interactive mode')),
2223 ] + walkopts + dryrunopts,
2224 ] + walkopts + dryrunopts,
2224 _('[OPTION]... FILE...'),
2225 _('[OPTION]... FILE...'),
2225 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2226 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2226 helpbasic=True, inferrepo=True)
2227 helpbasic=True, inferrepo=True)
2227 def forget(ui, repo, *pats, **opts):
2228 def forget(ui, repo, *pats, **opts):
2228 """forget the specified files on the next commit
2229 """forget the specified files on the next commit
2229
2230
2230 Mark the specified files so they will no longer be tracked
2231 Mark the specified files so they will no longer be tracked
2231 after the next commit.
2232 after the next commit.
2232
2233
2233 This only removes files from the current branch, not from the
2234 This only removes files from the current branch, not from the
2234 entire project history, and it does not delete them from the
2235 entire project history, and it does not delete them from the
2235 working directory.
2236 working directory.
2236
2237
2237 To delete the file from the working directory, see :hg:`remove`.
2238 To delete the file from the working directory, see :hg:`remove`.
2238
2239
2239 To undo a forget before the next commit, see :hg:`add`.
2240 To undo a forget before the next commit, see :hg:`add`.
2240
2241
2241 .. container:: verbose
2242 .. container:: verbose
2242
2243
2243 Examples:
2244 Examples:
2244
2245
2245 - forget newly-added binary files::
2246 - forget newly-added binary files::
2246
2247
2247 hg forget "set:added() and binary()"
2248 hg forget "set:added() and binary()"
2248
2249
2249 - forget files that would be excluded by .hgignore::
2250 - forget files that would be excluded by .hgignore::
2250
2251
2251 hg forget "set:hgignore()"
2252 hg forget "set:hgignore()"
2252
2253
2253 Returns 0 on success.
2254 Returns 0 on success.
2254 """
2255 """
2255
2256
2256 opts = pycompat.byteskwargs(opts)
2257 opts = pycompat.byteskwargs(opts)
2257 if not pats:
2258 if not pats:
2258 raise error.Abort(_('no files specified'))
2259 raise error.Abort(_('no files specified'))
2259
2260
2260 m = scmutil.match(repo[None], pats, opts)
2261 m = scmutil.match(repo[None], pats, opts)
2261 dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
2262 dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
2262 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2263 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2263 rejected = cmdutil.forget(ui, repo, m, prefix="", uipathfn=uipathfn,
2264 rejected = cmdutil.forget(ui, repo, m, prefix="", uipathfn=uipathfn,
2264 explicitonly=False, dryrun=dryrun,
2265 explicitonly=False, dryrun=dryrun,
2265 interactive=interactive)[0]
2266 interactive=interactive)[0]
2266 return rejected and 1 or 0
2267 return rejected and 1 or 0
2267
2268
2268 @command(
2269 @command(
2269 'graft',
2270 'graft',
2270 [('r', 'rev', [], _('revisions to graft'), _('REV')),
2271 [('r', 'rev', [], _('revisions to graft'), _('REV')),
2271 ('', 'base', '',
2272 ('', 'base', '',
2272 _('base revision when doing the graft merge (ADVANCED)'), _('REV')),
2273 _('base revision when doing the graft merge (ADVANCED)'), _('REV')),
2273 ('c', 'continue', False, _('resume interrupted graft')),
2274 ('c', 'continue', False, _('resume interrupted graft')),
2274 ('', 'stop', False, _('stop interrupted graft')),
2275 ('', 'stop', False, _('stop interrupted graft')),
2275 ('', 'abort', False, _('abort interrupted graft')),
2276 ('', 'abort', False, _('abort interrupted graft')),
2276 ('e', 'edit', False, _('invoke editor on commit messages')),
2277 ('e', 'edit', False, _('invoke editor on commit messages')),
2277 ('', 'log', None, _('append graft info to log message')),
2278 ('', 'log', None, _('append graft info to log message')),
2278 ('', 'no-commit', None,
2279 ('', 'no-commit', None,
2279 _("don't commit, just apply the changes in working directory")),
2280 _("don't commit, just apply the changes in working directory")),
2280 ('f', 'force', False, _('force graft')),
2281 ('f', 'force', False, _('force graft')),
2281 ('D', 'currentdate', False,
2282 ('D', 'currentdate', False,
2282 _('record the current date as commit date')),
2283 _('record the current date as commit date')),
2283 ('U', 'currentuser', False,
2284 ('U', 'currentuser', False,
2284 _('record the current user as committer'))]
2285 _('record the current user as committer'))]
2285 + commitopts2 + mergetoolopts + dryrunopts,
2286 + commitopts2 + mergetoolopts + dryrunopts,
2286 _('[OPTION]... [-r REV]... REV...'),
2287 _('[OPTION]... [-r REV]... REV...'),
2287 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
2288 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
2288 def graft(ui, repo, *revs, **opts):
2289 def graft(ui, repo, *revs, **opts):
2289 '''copy changes from other branches onto the current branch
2290 '''copy changes from other branches onto the current branch
2290
2291
2291 This command uses Mercurial's merge logic to copy individual
2292 This command uses Mercurial's merge logic to copy individual
2292 changes from other branches without merging branches in the
2293 changes from other branches without merging branches in the
2293 history graph. This is sometimes known as 'backporting' or
2294 history graph. This is sometimes known as 'backporting' or
2294 'cherry-picking'. By default, graft will copy user, date, and
2295 'cherry-picking'. By default, graft will copy user, date, and
2295 description from the source changesets.
2296 description from the source changesets.
2296
2297
2297 Changesets that are ancestors of the current revision, that have
2298 Changesets that are ancestors of the current revision, that have
2298 already been grafted, or that are merges will be skipped.
2299 already been grafted, or that are merges will be skipped.
2299
2300
2300 If --log is specified, log messages will have a comment appended
2301 If --log is specified, log messages will have a comment appended
2301 of the form::
2302 of the form::
2302
2303
2303 (grafted from CHANGESETHASH)
2304 (grafted from CHANGESETHASH)
2304
2305
2305 If --force is specified, revisions will be grafted even if they
2306 If --force is specified, revisions will be grafted even if they
2306 are already ancestors of, or have been grafted to, the destination.
2307 are already ancestors of, or have been grafted to, the destination.
2307 This is useful when the revisions have since been backed out.
2308 This is useful when the revisions have since been backed out.
2308
2309
2309 If a graft merge results in conflicts, the graft process is
2310 If a graft merge results in conflicts, the graft process is
2310 interrupted so that the current merge can be manually resolved.
2311 interrupted so that the current merge can be manually resolved.
2311 Once all conflicts are addressed, the graft process can be
2312 Once all conflicts are addressed, the graft process can be
2312 continued with the -c/--continue option.
2313 continued with the -c/--continue option.
2313
2314
2314 The -c/--continue option reapplies all the earlier options.
2315 The -c/--continue option reapplies all the earlier options.
2315
2316
2316 .. container:: verbose
2317 .. container:: verbose
2317
2318
2318 The --base option exposes more of how graft internally uses merge with a
2319 The --base option exposes more of how graft internally uses merge with a
2319 custom base revision. --base can be used to specify another ancestor than
2320 custom base revision. --base can be used to specify another ancestor than
2320 the first and only parent.
2321 the first and only parent.
2321
2322
2322 The command::
2323 The command::
2323
2324
2324 hg graft -r 345 --base 234
2325 hg graft -r 345 --base 234
2325
2326
2326 is thus pretty much the same as::
2327 is thus pretty much the same as::
2327
2328
2328 hg diff -r 234 -r 345 | hg import
2329 hg diff -r 234 -r 345 | hg import
2329
2330
2330 but using merge to resolve conflicts and track moved files.
2331 but using merge to resolve conflicts and track moved files.
2331
2332
2332 The result of a merge can thus be backported as a single commit by
2333 The result of a merge can thus be backported as a single commit by
2333 specifying one of the merge parents as base, and thus effectively
2334 specifying one of the merge parents as base, and thus effectively
2334 grafting the changes from the other side.
2335 grafting the changes from the other side.
2335
2336
2336 It is also possible to collapse multiple changesets and clean up history
2337 It is also possible to collapse multiple changesets and clean up history
2337 by specifying another ancestor as base, much like rebase --collapse
2338 by specifying another ancestor as base, much like rebase --collapse
2338 --keep.
2339 --keep.
2339
2340
2340 The commit message can be tweaked after the fact using commit --amend .
2341 The commit message can be tweaked after the fact using commit --amend .
2341
2342
2342 For using non-ancestors as the base to backout changes, see the backout
2343 For using non-ancestors as the base to backout changes, see the backout
2343 command and the hidden --parent option.
2344 command and the hidden --parent option.
2344
2345
2345 .. container:: verbose
2346 .. container:: verbose
2346
2347
2347 Examples:
2348 Examples:
2348
2349
2349 - copy a single change to the stable branch and edit its description::
2350 - copy a single change to the stable branch and edit its description::
2350
2351
2351 hg update stable
2352 hg update stable
2352 hg graft --edit 9393
2353 hg graft --edit 9393
2353
2354
2354 - graft a range of changesets with one exception, updating dates::
2355 - graft a range of changesets with one exception, updating dates::
2355
2356
2356 hg graft -D "2085::2093 and not 2091"
2357 hg graft -D "2085::2093 and not 2091"
2357
2358
2358 - continue a graft after resolving conflicts::
2359 - continue a graft after resolving conflicts::
2359
2360
2360 hg graft -c
2361 hg graft -c
2361
2362
2362 - show the source of a grafted changeset::
2363 - show the source of a grafted changeset::
2363
2364
2364 hg log --debug -r .
2365 hg log --debug -r .
2365
2366
2366 - show revisions sorted by date::
2367 - show revisions sorted by date::
2367
2368
2368 hg log -r "sort(all(), date)"
2369 hg log -r "sort(all(), date)"
2369
2370
2370 - backport the result of a merge as a single commit::
2371 - backport the result of a merge as a single commit::
2371
2372
2372 hg graft -r 123 --base 123^
2373 hg graft -r 123 --base 123^
2373
2374
2374 - land a feature branch as one changeset::
2375 - land a feature branch as one changeset::
2375
2376
2376 hg up -cr default
2377 hg up -cr default
2377 hg graft -r featureX --base "ancestor('featureX', 'default')"
2378 hg graft -r featureX --base "ancestor('featureX', 'default')"
2378
2379
2379 See :hg:`help revisions` for more about specifying revisions.
2380 See :hg:`help revisions` for more about specifying revisions.
2380
2381
2381 Returns 0 on successful completion.
2382 Returns 0 on successful completion.
2382 '''
2383 '''
2383 with repo.wlock():
2384 with repo.wlock():
2384 return _dograft(ui, repo, *revs, **opts)
2385 return _dograft(ui, repo, *revs, **opts)
2385
2386
2386 def _dograft(ui, repo, *revs, **opts):
2387 def _dograft(ui, repo, *revs, **opts):
2387 opts = pycompat.byteskwargs(opts)
2388 opts = pycompat.byteskwargs(opts)
2388 if revs and opts.get('rev'):
2389 if revs and opts.get('rev'):
2389 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
2390 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
2390 'revision ordering!\n'))
2391 'revision ordering!\n'))
2391
2392
2392 revs = list(revs)
2393 revs = list(revs)
2393 revs.extend(opts.get('rev'))
2394 revs.extend(opts.get('rev'))
2394 basectx = None
2395 basectx = None
2395 if opts.get('base'):
2396 if opts.get('base'):
2396 basectx = scmutil.revsingle(repo, opts['base'], None)
2397 basectx = scmutil.revsingle(repo, opts['base'], None)
2397 # a dict of data to be stored in state file
2398 # a dict of data to be stored in state file
2398 statedata = {}
2399 statedata = {}
2399 # list of new nodes created by ongoing graft
2400 # list of new nodes created by ongoing graft
2400 statedata['newnodes'] = []
2401 statedata['newnodes'] = []
2401
2402
2402 if opts.get('user') and opts.get('currentuser'):
2403 if opts.get('user') and opts.get('currentuser'):
2403 raise error.Abort(_('--user and --currentuser are mutually exclusive'))
2404 raise error.Abort(_('--user and --currentuser are mutually exclusive'))
2404 if opts.get('date') and opts.get('currentdate'):
2405 if opts.get('date') and opts.get('currentdate'):
2405 raise error.Abort(_('--date and --currentdate are mutually exclusive'))
2406 raise error.Abort(_('--date and --currentdate are mutually exclusive'))
2406 if not opts.get('user') and opts.get('currentuser'):
2407 if not opts.get('user') and opts.get('currentuser'):
2407 opts['user'] = ui.username()
2408 opts['user'] = ui.username()
2408 if not opts.get('date') and opts.get('currentdate'):
2409 if not opts.get('date') and opts.get('currentdate'):
2409 opts['date'] = "%d %d" % dateutil.makedate()
2410 opts['date'] = "%d %d" % dateutil.makedate()
2410
2411
2411 editor = cmdutil.getcommiteditor(editform='graft',
2412 editor = cmdutil.getcommiteditor(editform='graft',
2412 **pycompat.strkwargs(opts))
2413 **pycompat.strkwargs(opts))
2413
2414
2414 cont = False
2415 cont = False
2415 if opts.get('no_commit'):
2416 if opts.get('no_commit'):
2416 if opts.get('edit'):
2417 if opts.get('edit'):
2417 raise error.Abort(_("cannot specify --no-commit and "
2418 raise error.Abort(_("cannot specify --no-commit and "
2418 "--edit together"))
2419 "--edit together"))
2419 if opts.get('currentuser'):
2420 if opts.get('currentuser'):
2420 raise error.Abort(_("cannot specify --no-commit and "
2421 raise error.Abort(_("cannot specify --no-commit and "
2421 "--currentuser together"))
2422 "--currentuser together"))
2422 if opts.get('currentdate'):
2423 if opts.get('currentdate'):
2423 raise error.Abort(_("cannot specify --no-commit and "
2424 raise error.Abort(_("cannot specify --no-commit and "
2424 "--currentdate together"))
2425 "--currentdate together"))
2425 if opts.get('log'):
2426 if opts.get('log'):
2426 raise error.Abort(_("cannot specify --no-commit and "
2427 raise error.Abort(_("cannot specify --no-commit and "
2427 "--log together"))
2428 "--log together"))
2428
2429
2429 graftstate = statemod.cmdstate(repo, 'graftstate')
2430 graftstate = statemod.cmdstate(repo, 'graftstate')
2430
2431
2431 if opts.get('stop'):
2432 if opts.get('stop'):
2432 if opts.get('continue'):
2433 if opts.get('continue'):
2433 raise error.Abort(_("cannot use '--continue' and "
2434 raise error.Abort(_("cannot use '--continue' and "
2434 "'--stop' together"))
2435 "'--stop' together"))
2435 if opts.get('abort'):
2436 if opts.get('abort'):
2436 raise error.Abort(_("cannot use '--abort' and '--stop' together"))
2437 raise error.Abort(_("cannot use '--abort' and '--stop' together"))
2437
2438
2438 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2439 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2439 opts.get('date'), opts.get('currentdate'),
2440 opts.get('date'), opts.get('currentdate'),
2440 opts.get('currentuser'), opts.get('rev'))):
2441 opts.get('currentuser'), opts.get('rev'))):
2441 raise error.Abort(_("cannot specify any other flag with '--stop'"))
2442 raise error.Abort(_("cannot specify any other flag with '--stop'"))
2442 return _stopgraft(ui, repo, graftstate)
2443 return _stopgraft(ui, repo, graftstate)
2443 elif opts.get('abort'):
2444 elif opts.get('abort'):
2444 if opts.get('continue'):
2445 if opts.get('continue'):
2445 raise error.Abort(_("cannot use '--continue' and "
2446 raise error.Abort(_("cannot use '--continue' and "
2446 "'--abort' together"))
2447 "'--abort' together"))
2447 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2448 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2448 opts.get('date'), opts.get('currentdate'),
2449 opts.get('date'), opts.get('currentdate'),
2449 opts.get('currentuser'), opts.get('rev'))):
2450 opts.get('currentuser'), opts.get('rev'))):
2450 raise error.Abort(_("cannot specify any other flag with '--abort'"))
2451 raise error.Abort(_("cannot specify any other flag with '--abort'"))
2451
2452
2452 return _abortgraft(ui, repo, graftstate)
2453 return _abortgraft(ui, repo, graftstate)
2453 elif opts.get('continue'):
2454 elif opts.get('continue'):
2454 cont = True
2455 cont = True
2455 if revs:
2456 if revs:
2456 raise error.Abort(_("can't specify --continue and revisions"))
2457 raise error.Abort(_("can't specify --continue and revisions"))
2457 # read in unfinished revisions
2458 # read in unfinished revisions
2458 if graftstate.exists():
2459 if graftstate.exists():
2459 statedata = _readgraftstate(repo, graftstate)
2460 statedata = _readgraftstate(repo, graftstate)
2460 if statedata.get('date'):
2461 if statedata.get('date'):
2461 opts['date'] = statedata['date']
2462 opts['date'] = statedata['date']
2462 if statedata.get('user'):
2463 if statedata.get('user'):
2463 opts['user'] = statedata['user']
2464 opts['user'] = statedata['user']
2464 if statedata.get('log'):
2465 if statedata.get('log'):
2465 opts['log'] = True
2466 opts['log'] = True
2466 if statedata.get('no_commit'):
2467 if statedata.get('no_commit'):
2467 opts['no_commit'] = statedata.get('no_commit')
2468 opts['no_commit'] = statedata.get('no_commit')
2468 nodes = statedata['nodes']
2469 nodes = statedata['nodes']
2469 revs = [repo[node].rev() for node in nodes]
2470 revs = [repo[node].rev() for node in nodes]
2470 else:
2471 else:
2471 cmdutil.wrongtooltocontinue(repo, _('graft'))
2472 cmdutil.wrongtooltocontinue(repo, _('graft'))
2472 else:
2473 else:
2473 if not revs:
2474 if not revs:
2474 raise error.Abort(_('no revisions specified'))
2475 raise error.Abort(_('no revisions specified'))
2475 cmdutil.checkunfinished(repo)
2476 cmdutil.checkunfinished(repo)
2476 cmdutil.bailifchanged(repo)
2477 cmdutil.bailifchanged(repo)
2477 revs = scmutil.revrange(repo, revs)
2478 revs = scmutil.revrange(repo, revs)
2478
2479
2479 skipped = set()
2480 skipped = set()
2480 if basectx is None:
2481 if basectx is None:
2481 # check for merges
2482 # check for merges
2482 for rev in repo.revs('%ld and merge()', revs):
2483 for rev in repo.revs('%ld and merge()', revs):
2483 ui.warn(_('skipping ungraftable merge revision %d\n') % rev)
2484 ui.warn(_('skipping ungraftable merge revision %d\n') % rev)
2484 skipped.add(rev)
2485 skipped.add(rev)
2485 revs = [r for r in revs if r not in skipped]
2486 revs = [r for r in revs if r not in skipped]
2486 if not revs:
2487 if not revs:
2487 return -1
2488 return -1
2488 if basectx is not None and len(revs) != 1:
2489 if basectx is not None and len(revs) != 1:
2489 raise error.Abort(_('only one revision allowed with --base '))
2490 raise error.Abort(_('only one revision allowed with --base '))
2490
2491
2491 # Don't check in the --continue case, in effect retaining --force across
2492 # Don't check in the --continue case, in effect retaining --force across
2492 # --continues. That's because without --force, any revisions we decided to
2493 # --continues. That's because without --force, any revisions we decided to
2493 # skip would have been filtered out here, so they wouldn't have made their
2494 # skip would have been filtered out here, so they wouldn't have made their
2494 # way to the graftstate. With --force, any revisions we would have otherwise
2495 # way to the graftstate. With --force, any revisions we would have otherwise
2495 # skipped would not have been filtered out, and if they hadn't been applied
2496 # skipped would not have been filtered out, and if they hadn't been applied
2496 # already, they'd have been in the graftstate.
2497 # already, they'd have been in the graftstate.
2497 if not (cont or opts.get('force')) and basectx is None:
2498 if not (cont or opts.get('force')) and basectx is None:
2498 # check for ancestors of dest branch
2499 # check for ancestors of dest branch
2499 crev = repo['.'].rev()
2500 crev = repo['.'].rev()
2500 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2501 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2501 # XXX make this lazy in the future
2502 # XXX make this lazy in the future
2502 # don't mutate while iterating, create a copy
2503 # don't mutate while iterating, create a copy
2503 for rev in list(revs):
2504 for rev in list(revs):
2504 if rev in ancestors:
2505 if rev in ancestors:
2505 ui.warn(_('skipping ancestor revision %d:%s\n') %
2506 ui.warn(_('skipping ancestor revision %d:%s\n') %
2506 (rev, repo[rev]))
2507 (rev, repo[rev]))
2507 # XXX remove on list is slow
2508 # XXX remove on list is slow
2508 revs.remove(rev)
2509 revs.remove(rev)
2509 if not revs:
2510 if not revs:
2510 return -1
2511 return -1
2511
2512
2512 # analyze revs for earlier grafts
2513 # analyze revs for earlier grafts
2513 ids = {}
2514 ids = {}
2514 for ctx in repo.set("%ld", revs):
2515 for ctx in repo.set("%ld", revs):
2515 ids[ctx.hex()] = ctx.rev()
2516 ids[ctx.hex()] = ctx.rev()
2516 n = ctx.extra().get('source')
2517 n = ctx.extra().get('source')
2517 if n:
2518 if n:
2518 ids[n] = ctx.rev()
2519 ids[n] = ctx.rev()
2519
2520
2520 # check ancestors for earlier grafts
2521 # check ancestors for earlier grafts
2521 ui.debug('scanning for duplicate grafts\n')
2522 ui.debug('scanning for duplicate grafts\n')
2522
2523
2523 # The only changesets we can be sure doesn't contain grafts of any
2524 # The only changesets we can be sure doesn't contain grafts of any
2524 # revs, are the ones that are common ancestors of *all* revs:
2525 # revs, are the ones that are common ancestors of *all* revs:
2525 for rev in repo.revs('only(%d,ancestor(%ld))', crev, revs):
2526 for rev in repo.revs('only(%d,ancestor(%ld))', crev, revs):
2526 ctx = repo[rev]
2527 ctx = repo[rev]
2527 n = ctx.extra().get('source')
2528 n = ctx.extra().get('source')
2528 if n in ids:
2529 if n in ids:
2529 try:
2530 try:
2530 r = repo[n].rev()
2531 r = repo[n].rev()
2531 except error.RepoLookupError:
2532 except error.RepoLookupError:
2532 r = None
2533 r = None
2533 if r in revs:
2534 if r in revs:
2534 ui.warn(_('skipping revision %d:%s '
2535 ui.warn(_('skipping revision %d:%s '
2535 '(already grafted to %d:%s)\n')
2536 '(already grafted to %d:%s)\n')
2536 % (r, repo[r], rev, ctx))
2537 % (r, repo[r], rev, ctx))
2537 revs.remove(r)
2538 revs.remove(r)
2538 elif ids[n] in revs:
2539 elif ids[n] in revs:
2539 if r is None:
2540 if r is None:
2540 ui.warn(_('skipping already grafted revision %d:%s '
2541 ui.warn(_('skipping already grafted revision %d:%s '
2541 '(%d:%s also has unknown origin %s)\n')
2542 '(%d:%s also has unknown origin %s)\n')
2542 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
2543 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
2543 else:
2544 else:
2544 ui.warn(_('skipping already grafted revision %d:%s '
2545 ui.warn(_('skipping already grafted revision %d:%s '
2545 '(%d:%s also has origin %d:%s)\n')
2546 '(%d:%s also has origin %d:%s)\n')
2546 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
2547 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
2547 revs.remove(ids[n])
2548 revs.remove(ids[n])
2548 elif ctx.hex() in ids:
2549 elif ctx.hex() in ids:
2549 r = ids[ctx.hex()]
2550 r = ids[ctx.hex()]
2550 if r in revs:
2551 if r in revs:
2551 ui.warn(_('skipping already grafted revision %d:%s '
2552 ui.warn(_('skipping already grafted revision %d:%s '
2552 '(was grafted from %d:%s)\n') %
2553 '(was grafted from %d:%s)\n') %
2553 (r, repo[r], rev, ctx))
2554 (r, repo[r], rev, ctx))
2554 revs.remove(r)
2555 revs.remove(r)
2555 if not revs:
2556 if not revs:
2556 return -1
2557 return -1
2557
2558
2558 if opts.get('no_commit'):
2559 if opts.get('no_commit'):
2559 statedata['no_commit'] = True
2560 statedata['no_commit'] = True
2560 for pos, ctx in enumerate(repo.set("%ld", revs)):
2561 for pos, ctx in enumerate(repo.set("%ld", revs)):
2561 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
2562 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
2562 ctx.description().split('\n', 1)[0])
2563 ctx.description().split('\n', 1)[0])
2563 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2564 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2564 if names:
2565 if names:
2565 desc += ' (%s)' % ' '.join(names)
2566 desc += ' (%s)' % ' '.join(names)
2566 ui.status(_('grafting %s\n') % desc)
2567 ui.status(_('grafting %s\n') % desc)
2567 if opts.get('dry_run'):
2568 if opts.get('dry_run'):
2568 continue
2569 continue
2569
2570
2570 source = ctx.extra().get('source')
2571 source = ctx.extra().get('source')
2571 extra = {}
2572 extra = {}
2572 if source:
2573 if source:
2573 extra['source'] = source
2574 extra['source'] = source
2574 extra['intermediate-source'] = ctx.hex()
2575 extra['intermediate-source'] = ctx.hex()
2575 else:
2576 else:
2576 extra['source'] = ctx.hex()
2577 extra['source'] = ctx.hex()
2577 user = ctx.user()
2578 user = ctx.user()
2578 if opts.get('user'):
2579 if opts.get('user'):
2579 user = opts['user']
2580 user = opts['user']
2580 statedata['user'] = user
2581 statedata['user'] = user
2581 date = ctx.date()
2582 date = ctx.date()
2582 if opts.get('date'):
2583 if opts.get('date'):
2583 date = opts['date']
2584 date = opts['date']
2584 statedata['date'] = date
2585 statedata['date'] = date
2585 message = ctx.description()
2586 message = ctx.description()
2586 if opts.get('log'):
2587 if opts.get('log'):
2587 message += '\n(grafted from %s)' % ctx.hex()
2588 message += '\n(grafted from %s)' % ctx.hex()
2588 statedata['log'] = True
2589 statedata['log'] = True
2589
2590
2590 # we don't merge the first commit when continuing
2591 # we don't merge the first commit when continuing
2591 if not cont:
2592 if not cont:
2592 # perform the graft merge with p1(rev) as 'ancestor'
2593 # perform the graft merge with p1(rev) as 'ancestor'
2593 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
2594 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
2594 base = ctx.p1() if basectx is None else basectx
2595 base = ctx.p1() if basectx is None else basectx
2595 with ui.configoverride(overrides, 'graft'):
2596 with ui.configoverride(overrides, 'graft'):
2596 stats = mergemod.graft(repo, ctx, base, ['local', 'graft'])
2597 stats = mergemod.graft(repo, ctx, base, ['local', 'graft'])
2597 # report any conflicts
2598 # report any conflicts
2598 if stats.unresolvedcount > 0:
2599 if stats.unresolvedcount > 0:
2599 # write out state for --continue
2600 # write out state for --continue
2600 nodes = [repo[rev].hex() for rev in revs[pos:]]
2601 nodes = [repo[rev].hex() for rev in revs[pos:]]
2601 statedata['nodes'] = nodes
2602 statedata['nodes'] = nodes
2602 stateversion = 1
2603 stateversion = 1
2603 graftstate.save(stateversion, statedata)
2604 graftstate.save(stateversion, statedata)
2604 hint = _("use 'hg resolve' and 'hg graft --continue'")
2605 hint = _("use 'hg resolve' and 'hg graft --continue'")
2605 raise error.Abort(
2606 raise error.Abort(
2606 _("unresolved conflicts, can't continue"),
2607 _("unresolved conflicts, can't continue"),
2607 hint=hint)
2608 hint=hint)
2608 else:
2609 else:
2609 cont = False
2610 cont = False
2610
2611
2611 # commit if --no-commit is false
2612 # commit if --no-commit is false
2612 if not opts.get('no_commit'):
2613 if not opts.get('no_commit'):
2613 node = repo.commit(text=message, user=user, date=date, extra=extra,
2614 node = repo.commit(text=message, user=user, date=date, extra=extra,
2614 editor=editor)
2615 editor=editor)
2615 if node is None:
2616 if node is None:
2616 ui.warn(
2617 ui.warn(
2617 _('note: graft of %d:%s created no changes to commit\n') %
2618 _('note: graft of %d:%s created no changes to commit\n') %
2618 (ctx.rev(), ctx))
2619 (ctx.rev(), ctx))
2619 # checking that newnodes exist because old state files won't have it
2620 # checking that newnodes exist because old state files won't have it
2620 elif statedata.get('newnodes') is not None:
2621 elif statedata.get('newnodes') is not None:
2621 statedata['newnodes'].append(node)
2622 statedata['newnodes'].append(node)
2622
2623
2623 # remove state when we complete successfully
2624 # remove state when we complete successfully
2624 if not opts.get('dry_run'):
2625 if not opts.get('dry_run'):
2625 graftstate.delete()
2626 graftstate.delete()
2626
2627
2627 return 0
2628 return 0
2628
2629
2629 def _abortgraft(ui, repo, graftstate):
2630 def _abortgraft(ui, repo, graftstate):
2630 """abort the interrupted graft and rollbacks to the state before interrupted
2631 """abort the interrupted graft and rollbacks to the state before interrupted
2631 graft"""
2632 graft"""
2632 if not graftstate.exists():
2633 if not graftstate.exists():
2633 raise error.Abort(_("no interrupted graft to abort"))
2634 raise error.Abort(_("no interrupted graft to abort"))
2634 statedata = _readgraftstate(repo, graftstate)
2635 statedata = _readgraftstate(repo, graftstate)
2635 newnodes = statedata.get('newnodes')
2636 newnodes = statedata.get('newnodes')
2636 if newnodes is None:
2637 if newnodes is None:
2637 # and old graft state which does not have all the data required to abort
2638 # and old graft state which does not have all the data required to abort
2638 # the graft
2639 # the graft
2639 raise error.Abort(_("cannot abort using an old graftstate"))
2640 raise error.Abort(_("cannot abort using an old graftstate"))
2640
2641
2641 # changeset from which graft operation was started
2642 # changeset from which graft operation was started
2642 if len(newnodes) > 0:
2643 if len(newnodes) > 0:
2643 startctx = repo[newnodes[0]].p1()
2644 startctx = repo[newnodes[0]].p1()
2644 else:
2645 else:
2645 startctx = repo['.']
2646 startctx = repo['.']
2646 # whether to strip or not
2647 # whether to strip or not
2647 cleanup = False
2648 cleanup = False
2648 if newnodes:
2649 if newnodes:
2649 newnodes = [repo[r].rev() for r in newnodes]
2650 newnodes = [repo[r].rev() for r in newnodes]
2650 cleanup = True
2651 cleanup = True
2651 # checking that none of the newnodes turned public or is public
2652 # checking that none of the newnodes turned public or is public
2652 immutable = [c for c in newnodes if not repo[c].mutable()]
2653 immutable = [c for c in newnodes if not repo[c].mutable()]
2653 if immutable:
2654 if immutable:
2654 repo.ui.warn(_("cannot clean up public changesets %s\n")
2655 repo.ui.warn(_("cannot clean up public changesets %s\n")
2655 % ', '.join(bytes(repo[r]) for r in immutable),
2656 % ', '.join(bytes(repo[r]) for r in immutable),
2656 hint=_("see 'hg help phases' for details"))
2657 hint=_("see 'hg help phases' for details"))
2657 cleanup = False
2658 cleanup = False
2658
2659
2659 # checking that no new nodes are created on top of grafted revs
2660 # checking that no new nodes are created on top of grafted revs
2660 desc = set(repo.changelog.descendants(newnodes))
2661 desc = set(repo.changelog.descendants(newnodes))
2661 if desc - set(newnodes):
2662 if desc - set(newnodes):
2662 repo.ui.warn(_("new changesets detected on destination "
2663 repo.ui.warn(_("new changesets detected on destination "
2663 "branch, can't strip\n"))
2664 "branch, can't strip\n"))
2664 cleanup = False
2665 cleanup = False
2665
2666
2666 if cleanup:
2667 if cleanup:
2667 with repo.wlock(), repo.lock():
2668 with repo.wlock(), repo.lock():
2668 hg.updaterepo(repo, startctx.node(), overwrite=True)
2669 hg.updaterepo(repo, startctx.node(), overwrite=True)
2669 # stripping the new nodes created
2670 # stripping the new nodes created
2670 strippoints = [c.node() for c in repo.set("roots(%ld)",
2671 strippoints = [c.node() for c in repo.set("roots(%ld)",
2671 newnodes)]
2672 newnodes)]
2672 repair.strip(repo.ui, repo, strippoints, backup=False)
2673 repair.strip(repo.ui, repo, strippoints, backup=False)
2673
2674
2674 if not cleanup:
2675 if not cleanup:
2675 # we don't update to the startnode if we can't strip
2676 # we don't update to the startnode if we can't strip
2676 startctx = repo['.']
2677 startctx = repo['.']
2677 hg.updaterepo(repo, startctx.node(), overwrite=True)
2678 hg.updaterepo(repo, startctx.node(), overwrite=True)
2678
2679
2679 ui.status(_("graft aborted\n"))
2680 ui.status(_("graft aborted\n"))
2680 ui.status(_("working directory is now at %s\n") % startctx.hex()[:12])
2681 ui.status(_("working directory is now at %s\n") % startctx.hex()[:12])
2681 graftstate.delete()
2682 graftstate.delete()
2682 return 0
2683 return 0
2683
2684
2684 def _readgraftstate(repo, graftstate):
2685 def _readgraftstate(repo, graftstate):
2685 """read the graft state file and return a dict of the data stored in it"""
2686 """read the graft state file and return a dict of the data stored in it"""
2686 try:
2687 try:
2687 return graftstate.read()
2688 return graftstate.read()
2688 except error.CorruptedState:
2689 except error.CorruptedState:
2689 nodes = repo.vfs.read('graftstate').splitlines()
2690 nodes = repo.vfs.read('graftstate').splitlines()
2690 return {'nodes': nodes}
2691 return {'nodes': nodes}
2691
2692
2692 def _stopgraft(ui, repo, graftstate):
2693 def _stopgraft(ui, repo, graftstate):
2693 """stop the interrupted graft"""
2694 """stop the interrupted graft"""
2694 if not graftstate.exists():
2695 if not graftstate.exists():
2695 raise error.Abort(_("no interrupted graft found"))
2696 raise error.Abort(_("no interrupted graft found"))
2696 pctx = repo['.']
2697 pctx = repo['.']
2697 hg.updaterepo(repo, pctx.node(), overwrite=True)
2698 hg.updaterepo(repo, pctx.node(), overwrite=True)
2698 graftstate.delete()
2699 graftstate.delete()
2699 ui.status(_("stopped the interrupted graft\n"))
2700 ui.status(_("stopped the interrupted graft\n"))
2700 ui.status(_("working directory is now at %s\n") % pctx.hex()[:12])
2701 ui.status(_("working directory is now at %s\n") % pctx.hex()[:12])
2701 return 0
2702 return 0
2702
2703
2703 @command('grep',
2704 @command('grep',
2704 [('0', 'print0', None, _('end fields with NUL')),
2705 [('0', 'print0', None, _('end fields with NUL')),
2705 ('', 'all', None, _('print all revisions that match (DEPRECATED) ')),
2706 ('', 'all', None, _('print all revisions that match (DEPRECATED) ')),
2706 ('', 'diff', None, _('print all revisions when the term was introduced '
2707 ('', 'diff', None, _('print all revisions when the term was introduced '
2707 'or removed')),
2708 'or removed')),
2708 ('a', 'text', None, _('treat all files as text')),
2709 ('a', 'text', None, _('treat all files as text')),
2709 ('f', 'follow', None,
2710 ('f', 'follow', None,
2710 _('follow changeset history,'
2711 _('follow changeset history,'
2711 ' or file history across copies and renames')),
2712 ' or file history across copies and renames')),
2712 ('i', 'ignore-case', None, _('ignore case when matching')),
2713 ('i', 'ignore-case', None, _('ignore case when matching')),
2713 ('l', 'files-with-matches', None,
2714 ('l', 'files-with-matches', None,
2714 _('print only filenames and revisions that match')),
2715 _('print only filenames and revisions that match')),
2715 ('n', 'line-number', None, _('print matching line numbers')),
2716 ('n', 'line-number', None, _('print matching line numbers')),
2716 ('r', 'rev', [],
2717 ('r', 'rev', [],
2717 _('only search files changed within revision range'), _('REV')),
2718 _('only search files changed within revision range'), _('REV')),
2718 ('', 'all-files', None,
2719 ('', 'all-files', None,
2719 _('include all files in the changeset while grepping (EXPERIMENTAL)')),
2720 _('include all files in the changeset while grepping (EXPERIMENTAL)')),
2720 ('u', 'user', None, _('list the author (long with -v)')),
2721 ('u', 'user', None, _('list the author (long with -v)')),
2721 ('d', 'date', None, _('list the date (short with -q)')),
2722 ('d', 'date', None, _('list the date (short with -q)')),
2722 ] + formatteropts + walkopts,
2723 ] + formatteropts + walkopts,
2723 _('[OPTION]... PATTERN [FILE]...'),
2724 _('[OPTION]... PATTERN [FILE]...'),
2724 helpcategory=command.CATEGORY_FILE_CONTENTS,
2725 helpcategory=command.CATEGORY_FILE_CONTENTS,
2725 inferrepo=True,
2726 inferrepo=True,
2726 intents={INTENT_READONLY})
2727 intents={INTENT_READONLY})
2727 def grep(ui, repo, pattern, *pats, **opts):
2728 def grep(ui, repo, pattern, *pats, **opts):
2728 """search revision history for a pattern in specified files
2729 """search revision history for a pattern in specified files
2729
2730
2730 Search revision history for a regular expression in the specified
2731 Search revision history for a regular expression in the specified
2731 files or the entire project.
2732 files or the entire project.
2732
2733
2733 By default, grep prints the most recent revision number for each
2734 By default, grep prints the most recent revision number for each
2734 file in which it finds a match. To get it to print every revision
2735 file in which it finds a match. To get it to print every revision
2735 that contains a change in match status ("-" for a match that becomes
2736 that contains a change in match status ("-" for a match that becomes
2736 a non-match, or "+" for a non-match that becomes a match), use the
2737 a non-match, or "+" for a non-match that becomes a match), use the
2737 --diff flag.
2738 --diff flag.
2738
2739
2739 PATTERN can be any Python (roughly Perl-compatible) regular
2740 PATTERN can be any Python (roughly Perl-compatible) regular
2740 expression.
2741 expression.
2741
2742
2742 If no FILEs are specified (and -f/--follow isn't set), all files in
2743 If no FILEs are specified (and -f/--follow isn't set), all files in
2743 the repository are searched, including those that don't exist in the
2744 the repository are searched, including those that don't exist in the
2744 current branch or have been deleted in a prior changeset.
2745 current branch or have been deleted in a prior changeset.
2745
2746
2746 .. container:: verbose
2747 .. container:: verbose
2747
2748
2748 Template:
2749 Template:
2749
2750
2750 The following keywords are supported in addition to the common template
2751 The following keywords are supported in addition to the common template
2751 keywords and functions. See also :hg:`help templates`.
2752 keywords and functions. See also :hg:`help templates`.
2752
2753
2753 :change: String. Character denoting insertion ``+`` or removal ``-``.
2754 :change: String. Character denoting insertion ``+`` or removal ``-``.
2754 Available if ``--diff`` is specified.
2755 Available if ``--diff`` is specified.
2755 :lineno: Integer. Line number of the match.
2756 :lineno: Integer. Line number of the match.
2756 :path: String. Repository-absolute path of the file.
2757 :path: String. Repository-absolute path of the file.
2757 :texts: List of text chunks.
2758 :texts: List of text chunks.
2758
2759
2759 And each entry of ``{texts}`` provides the following sub-keywords.
2760 And each entry of ``{texts}`` provides the following sub-keywords.
2760
2761
2761 :matched: Boolean. True if the chunk matches the specified pattern.
2762 :matched: Boolean. True if the chunk matches the specified pattern.
2762 :text: String. Chunk content.
2763 :text: String. Chunk content.
2763
2764
2764 See :hg:`help templates.operators` for the list expansion syntax.
2765 See :hg:`help templates.operators` for the list expansion syntax.
2765
2766
2766 Returns 0 if a match is found, 1 otherwise.
2767 Returns 0 if a match is found, 1 otherwise.
2767 """
2768 """
2768 opts = pycompat.byteskwargs(opts)
2769 opts = pycompat.byteskwargs(opts)
2769 diff = opts.get('all') or opts.get('diff')
2770 diff = opts.get('all') or opts.get('diff')
2770 all_files = opts.get('all_files')
2771 all_files = opts.get('all_files')
2771 if diff and opts.get('all_files'):
2772 if diff and opts.get('all_files'):
2772 raise error.Abort(_('--diff and --all-files are mutually exclusive'))
2773 raise error.Abort(_('--diff and --all-files are mutually exclusive'))
2773 # TODO: remove "not opts.get('rev')" if --all-files -rMULTIREV gets working
2774 # TODO: remove "not opts.get('rev')" if --all-files -rMULTIREV gets working
2774 if opts.get('all_files') is None and not opts.get('rev') and not diff:
2775 if opts.get('all_files') is None and not opts.get('rev') and not diff:
2775 # experimental config: commands.grep.all-files
2776 # experimental config: commands.grep.all-files
2776 opts['all_files'] = ui.configbool('commands', 'grep.all-files')
2777 opts['all_files'] = ui.configbool('commands', 'grep.all-files')
2777 plaingrep = opts.get('all_files') and not opts.get('rev')
2778 plaingrep = opts.get('all_files') and not opts.get('rev')
2778 if plaingrep:
2779 if plaingrep:
2779 opts['rev'] = ['wdir()']
2780 opts['rev'] = ['wdir()']
2780
2781
2781 reflags = re.M
2782 reflags = re.M
2782 if opts.get('ignore_case'):
2783 if opts.get('ignore_case'):
2783 reflags |= re.I
2784 reflags |= re.I
2784 try:
2785 try:
2785 regexp = util.re.compile(pattern, reflags)
2786 regexp = util.re.compile(pattern, reflags)
2786 except re.error as inst:
2787 except re.error as inst:
2787 ui.warn(_("grep: invalid match pattern: %s\n") % pycompat.bytestr(inst))
2788 ui.warn(_("grep: invalid match pattern: %s\n") % pycompat.bytestr(inst))
2788 return 1
2789 return 1
2789 sep, eol = ':', '\n'
2790 sep, eol = ':', '\n'
2790 if opts.get('print0'):
2791 if opts.get('print0'):
2791 sep = eol = '\0'
2792 sep = eol = '\0'
2792
2793
2793 getfile = util.lrucachefunc(repo.file)
2794 getfile = util.lrucachefunc(repo.file)
2794
2795
2795 def matchlines(body):
2796 def matchlines(body):
2796 begin = 0
2797 begin = 0
2797 linenum = 0
2798 linenum = 0
2798 while begin < len(body):
2799 while begin < len(body):
2799 match = regexp.search(body, begin)
2800 match = regexp.search(body, begin)
2800 if not match:
2801 if not match:
2801 break
2802 break
2802 mstart, mend = match.span()
2803 mstart, mend = match.span()
2803 linenum += body.count('\n', begin, mstart) + 1
2804 linenum += body.count('\n', begin, mstart) + 1
2804 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2805 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2805 begin = body.find('\n', mend) + 1 or len(body) + 1
2806 begin = body.find('\n', mend) + 1 or len(body) + 1
2806 lend = begin - 1
2807 lend = begin - 1
2807 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2808 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2808
2809
2809 class linestate(object):
2810 class linestate(object):
2810 def __init__(self, line, linenum, colstart, colend):
2811 def __init__(self, line, linenum, colstart, colend):
2811 self.line = line
2812 self.line = line
2812 self.linenum = linenum
2813 self.linenum = linenum
2813 self.colstart = colstart
2814 self.colstart = colstart
2814 self.colend = colend
2815 self.colend = colend
2815
2816
2816 def __hash__(self):
2817 def __hash__(self):
2817 return hash((self.linenum, self.line))
2818 return hash((self.linenum, self.line))
2818
2819
2819 def __eq__(self, other):
2820 def __eq__(self, other):
2820 return self.line == other.line
2821 return self.line == other.line
2821
2822
2822 def findpos(self):
2823 def findpos(self):
2823 """Iterate all (start, end) indices of matches"""
2824 """Iterate all (start, end) indices of matches"""
2824 yield self.colstart, self.colend
2825 yield self.colstart, self.colend
2825 p = self.colend
2826 p = self.colend
2826 while p < len(self.line):
2827 while p < len(self.line):
2827 m = regexp.search(self.line, p)
2828 m = regexp.search(self.line, p)
2828 if not m:
2829 if not m:
2829 break
2830 break
2830 yield m.span()
2831 yield m.span()
2831 p = m.end()
2832 p = m.end()
2832
2833
2833 matches = {}
2834 matches = {}
2834 copies = {}
2835 copies = {}
2835 def grepbody(fn, rev, body):
2836 def grepbody(fn, rev, body):
2836 matches[rev].setdefault(fn, [])
2837 matches[rev].setdefault(fn, [])
2837 m = matches[rev][fn]
2838 m = matches[rev][fn]
2838 for lnum, cstart, cend, line in matchlines(body):
2839 for lnum, cstart, cend, line in matchlines(body):
2839 s = linestate(line, lnum, cstart, cend)
2840 s = linestate(line, lnum, cstart, cend)
2840 m.append(s)
2841 m.append(s)
2841
2842
2842 def difflinestates(a, b):
2843 def difflinestates(a, b):
2843 sm = difflib.SequenceMatcher(None, a, b)
2844 sm = difflib.SequenceMatcher(None, a, b)
2844 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2845 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2845 if tag == r'insert':
2846 if tag == r'insert':
2846 for i in pycompat.xrange(blo, bhi):
2847 for i in pycompat.xrange(blo, bhi):
2847 yield ('+', b[i])
2848 yield ('+', b[i])
2848 elif tag == r'delete':
2849 elif tag == r'delete':
2849 for i in pycompat.xrange(alo, ahi):
2850 for i in pycompat.xrange(alo, ahi):
2850 yield ('-', a[i])
2851 yield ('-', a[i])
2851 elif tag == r'replace':
2852 elif tag == r'replace':
2852 for i in pycompat.xrange(alo, ahi):
2853 for i in pycompat.xrange(alo, ahi):
2853 yield ('-', a[i])
2854 yield ('-', a[i])
2854 for i in pycompat.xrange(blo, bhi):
2855 for i in pycompat.xrange(blo, bhi):
2855 yield ('+', b[i])
2856 yield ('+', b[i])
2856
2857
2857 uipathfn = scmutil.getuipathfn(repo)
2858 uipathfn = scmutil.getuipathfn(repo)
2858 def display(fm, fn, ctx, pstates, states):
2859 def display(fm, fn, ctx, pstates, states):
2859 rev = scmutil.intrev(ctx)
2860 rev = scmutil.intrev(ctx)
2860 if fm.isplain():
2861 if fm.isplain():
2861 formatuser = ui.shortuser
2862 formatuser = ui.shortuser
2862 else:
2863 else:
2863 formatuser = pycompat.bytestr
2864 formatuser = pycompat.bytestr
2864 if ui.quiet:
2865 if ui.quiet:
2865 datefmt = '%Y-%m-%d'
2866 datefmt = '%Y-%m-%d'
2866 else:
2867 else:
2867 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2868 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2868 found = False
2869 found = False
2869 @util.cachefunc
2870 @util.cachefunc
2870 def binary():
2871 def binary():
2871 flog = getfile(fn)
2872 flog = getfile(fn)
2872 try:
2873 try:
2873 return stringutil.binary(flog.read(ctx.filenode(fn)))
2874 return stringutil.binary(flog.read(ctx.filenode(fn)))
2874 except error.WdirUnsupported:
2875 except error.WdirUnsupported:
2875 return ctx[fn].isbinary()
2876 return ctx[fn].isbinary()
2876
2877
2877 fieldnamemap = {'linenumber': 'lineno'}
2878 fieldnamemap = {'linenumber': 'lineno'}
2878 if diff:
2879 if diff:
2879 iter = difflinestates(pstates, states)
2880 iter = difflinestates(pstates, states)
2880 else:
2881 else:
2881 iter = [('', l) for l in states]
2882 iter = [('', l) for l in states]
2882 for change, l in iter:
2883 for change, l in iter:
2883 fm.startitem()
2884 fm.startitem()
2884 fm.context(ctx=ctx)
2885 fm.context(ctx=ctx)
2885 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
2886 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
2886 fm.plain(uipathfn(fn), label='grep.filename')
2887 fm.plain(uipathfn(fn), label='grep.filename')
2887
2888
2888 cols = [
2889 cols = [
2889 ('rev', '%d', rev, not plaingrep, ''),
2890 ('rev', '%d', rev, not plaingrep, ''),
2890 ('linenumber', '%d', l.linenum, opts.get('line_number'), ''),
2891 ('linenumber', '%d', l.linenum, opts.get('line_number'), ''),
2891 ]
2892 ]
2892 if diff:
2893 if diff:
2893 cols.append(
2894 cols.append(
2894 ('change', '%s', change, True,
2895 ('change', '%s', change, True,
2895 'grep.inserted ' if change == '+' else 'grep.deleted ')
2896 'grep.inserted ' if change == '+' else 'grep.deleted ')
2896 )
2897 )
2897 cols.extend([
2898 cols.extend([
2898 ('user', '%s', formatuser(ctx.user()), opts.get('user'), ''),
2899 ('user', '%s', formatuser(ctx.user()), opts.get('user'), ''),
2899 ('date', '%s', fm.formatdate(ctx.date(), datefmt),
2900 ('date', '%s', fm.formatdate(ctx.date(), datefmt),
2900 opts.get('date'), ''),
2901 opts.get('date'), ''),
2901 ])
2902 ])
2902 for name, fmt, data, cond, extra_label in cols:
2903 for name, fmt, data, cond, extra_label in cols:
2903 if cond:
2904 if cond:
2904 fm.plain(sep, label='grep.sep')
2905 fm.plain(sep, label='grep.sep')
2905 field = fieldnamemap.get(name, name)
2906 field = fieldnamemap.get(name, name)
2906 label = extra_label + ('grep.%s' % name)
2907 label = extra_label + ('grep.%s' % name)
2907 fm.condwrite(cond, field, fmt, data, label=label)
2908 fm.condwrite(cond, field, fmt, data, label=label)
2908 if not opts.get('files_with_matches'):
2909 if not opts.get('files_with_matches'):
2909 fm.plain(sep, label='grep.sep')
2910 fm.plain(sep, label='grep.sep')
2910 if not opts.get('text') and binary():
2911 if not opts.get('text') and binary():
2911 fm.plain(_(" Binary file matches"))
2912 fm.plain(_(" Binary file matches"))
2912 else:
2913 else:
2913 displaymatches(fm.nested('texts', tmpl='{text}'), l)
2914 displaymatches(fm.nested('texts', tmpl='{text}'), l)
2914 fm.plain(eol)
2915 fm.plain(eol)
2915 found = True
2916 found = True
2916 if opts.get('files_with_matches'):
2917 if opts.get('files_with_matches'):
2917 break
2918 break
2918 return found
2919 return found
2919
2920
2920 def displaymatches(fm, l):
2921 def displaymatches(fm, l):
2921 p = 0
2922 p = 0
2922 for s, e in l.findpos():
2923 for s, e in l.findpos():
2923 if p < s:
2924 if p < s:
2924 fm.startitem()
2925 fm.startitem()
2925 fm.write('text', '%s', l.line[p:s])
2926 fm.write('text', '%s', l.line[p:s])
2926 fm.data(matched=False)
2927 fm.data(matched=False)
2927 fm.startitem()
2928 fm.startitem()
2928 fm.write('text', '%s', l.line[s:e], label='grep.match')
2929 fm.write('text', '%s', l.line[s:e], label='grep.match')
2929 fm.data(matched=True)
2930 fm.data(matched=True)
2930 p = e
2931 p = e
2931 if p < len(l.line):
2932 if p < len(l.line):
2932 fm.startitem()
2933 fm.startitem()
2933 fm.write('text', '%s', l.line[p:])
2934 fm.write('text', '%s', l.line[p:])
2934 fm.data(matched=False)
2935 fm.data(matched=False)
2935 fm.end()
2936 fm.end()
2936
2937
2937 skip = set()
2938 skip = set()
2938 revfiles = {}
2939 revfiles = {}
2939 match = scmutil.match(repo[None], pats, opts)
2940 match = scmutil.match(repo[None], pats, opts)
2940 found = False
2941 found = False
2941 follow = opts.get('follow')
2942 follow = opts.get('follow')
2942
2943
2943 getrenamed = scmutil.getrenamedfn(repo)
2944 getrenamed = scmutil.getrenamedfn(repo)
2944 def prep(ctx, fns):
2945 def prep(ctx, fns):
2945 rev = ctx.rev()
2946 rev = ctx.rev()
2946 pctx = ctx.p1()
2947 pctx = ctx.p1()
2947 parent = pctx.rev()
2948 parent = pctx.rev()
2948 matches.setdefault(rev, {})
2949 matches.setdefault(rev, {})
2949 matches.setdefault(parent, {})
2950 matches.setdefault(parent, {})
2950 files = revfiles.setdefault(rev, [])
2951 files = revfiles.setdefault(rev, [])
2951 for fn in fns:
2952 for fn in fns:
2952 flog = getfile(fn)
2953 flog = getfile(fn)
2953 try:
2954 try:
2954 fnode = ctx.filenode(fn)
2955 fnode = ctx.filenode(fn)
2955 except error.LookupError:
2956 except error.LookupError:
2956 continue
2957 continue
2957
2958
2958 copy = None
2959 copy = None
2959 if follow:
2960 if follow:
2960 copy = getrenamed(fn, rev)
2961 copy = getrenamed(fn, rev)
2961 if copy:
2962 if copy:
2962 copies.setdefault(rev, {})[fn] = copy
2963 copies.setdefault(rev, {})[fn] = copy
2963 if fn in skip:
2964 if fn in skip:
2964 skip.add(copy)
2965 skip.add(copy)
2965 if fn in skip:
2966 if fn in skip:
2966 continue
2967 continue
2967 files.append(fn)
2968 files.append(fn)
2968
2969
2969 if fn not in matches[rev]:
2970 if fn not in matches[rev]:
2970 try:
2971 try:
2971 content = flog.read(fnode)
2972 content = flog.read(fnode)
2972 except error.WdirUnsupported:
2973 except error.WdirUnsupported:
2973 content = ctx[fn].data()
2974 content = ctx[fn].data()
2974 grepbody(fn, rev, content)
2975 grepbody(fn, rev, content)
2975
2976
2976 pfn = copy or fn
2977 pfn = copy or fn
2977 if pfn not in matches[parent]:
2978 if pfn not in matches[parent]:
2978 try:
2979 try:
2979 fnode = pctx.filenode(pfn)
2980 fnode = pctx.filenode(pfn)
2980 grepbody(pfn, parent, flog.read(fnode))
2981 grepbody(pfn, parent, flog.read(fnode))
2981 except error.LookupError:
2982 except error.LookupError:
2982 pass
2983 pass
2983
2984
2984 ui.pager('grep')
2985 ui.pager('grep')
2985 fm = ui.formatter('grep', opts)
2986 fm = ui.formatter('grep', opts)
2986 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
2987 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
2987 rev = ctx.rev()
2988 rev = ctx.rev()
2988 parent = ctx.p1().rev()
2989 parent = ctx.p1().rev()
2989 for fn in sorted(revfiles.get(rev, [])):
2990 for fn in sorted(revfiles.get(rev, [])):
2990 states = matches[rev][fn]
2991 states = matches[rev][fn]
2991 copy = copies.get(rev, {}).get(fn)
2992 copy = copies.get(rev, {}).get(fn)
2992 if fn in skip:
2993 if fn in skip:
2993 if copy:
2994 if copy:
2994 skip.add(copy)
2995 skip.add(copy)
2995 continue
2996 continue
2996 pstates = matches.get(parent, {}).get(copy or fn, [])
2997 pstates = matches.get(parent, {}).get(copy or fn, [])
2997 if pstates or states:
2998 if pstates or states:
2998 r = display(fm, fn, ctx, pstates, states)
2999 r = display(fm, fn, ctx, pstates, states)
2999 found = found or r
3000 found = found or r
3000 if r and not diff and not all_files:
3001 if r and not diff and not all_files:
3001 skip.add(fn)
3002 skip.add(fn)
3002 if copy:
3003 if copy:
3003 skip.add(copy)
3004 skip.add(copy)
3004 del revfiles[rev]
3005 del revfiles[rev]
3005 # We will keep the matches dict for the duration of the window
3006 # We will keep the matches dict for the duration of the window
3006 # clear the matches dict once the window is over
3007 # clear the matches dict once the window is over
3007 if not revfiles:
3008 if not revfiles:
3008 matches.clear()
3009 matches.clear()
3009 fm.end()
3010 fm.end()
3010
3011
3011 return not found
3012 return not found
3012
3013
3013 @command('heads',
3014 @command('heads',
3014 [('r', 'rev', '',
3015 [('r', 'rev', '',
3015 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3016 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3016 ('t', 'topo', False, _('show topological heads only')),
3017 ('t', 'topo', False, _('show topological heads only')),
3017 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3018 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3018 ('c', 'closed', False, _('show normal and closed branch heads')),
3019 ('c', 'closed', False, _('show normal and closed branch heads')),
3019 ] + templateopts,
3020 ] + templateopts,
3020 _('[-ct] [-r STARTREV] [REV]...'),
3021 _('[-ct] [-r STARTREV] [REV]...'),
3021 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3022 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3022 intents={INTENT_READONLY})
3023 intents={INTENT_READONLY})
3023 def heads(ui, repo, *branchrevs, **opts):
3024 def heads(ui, repo, *branchrevs, **opts):
3024 """show branch heads
3025 """show branch heads
3025
3026
3026 With no arguments, show all open branch heads in the repository.
3027 With no arguments, show all open branch heads in the repository.
3027 Branch heads are changesets that have no descendants on the
3028 Branch heads are changesets that have no descendants on the
3028 same branch. They are where development generally takes place and
3029 same branch. They are where development generally takes place and
3029 are the usual targets for update and merge operations.
3030 are the usual targets for update and merge operations.
3030
3031
3031 If one or more REVs are given, only open branch heads on the
3032 If one or more REVs are given, only open branch heads on the
3032 branches associated with the specified changesets are shown. This
3033 branches associated with the specified changesets are shown. This
3033 means that you can use :hg:`heads .` to see the heads on the
3034 means that you can use :hg:`heads .` to see the heads on the
3034 currently checked-out branch.
3035 currently checked-out branch.
3035
3036
3036 If -c/--closed is specified, also show branch heads marked closed
3037 If -c/--closed is specified, also show branch heads marked closed
3037 (see :hg:`commit --close-branch`).
3038 (see :hg:`commit --close-branch`).
3038
3039
3039 If STARTREV is specified, only those heads that are descendants of
3040 If STARTREV is specified, only those heads that are descendants of
3040 STARTREV will be displayed.
3041 STARTREV will be displayed.
3041
3042
3042 If -t/--topo is specified, named branch mechanics will be ignored and only
3043 If -t/--topo is specified, named branch mechanics will be ignored and only
3043 topological heads (changesets with no children) will be shown.
3044 topological heads (changesets with no children) will be shown.
3044
3045
3045 Returns 0 if matching heads are found, 1 if not.
3046 Returns 0 if matching heads are found, 1 if not.
3046 """
3047 """
3047
3048
3048 opts = pycompat.byteskwargs(opts)
3049 opts = pycompat.byteskwargs(opts)
3049 start = None
3050 start = None
3050 rev = opts.get('rev')
3051 rev = opts.get('rev')
3051 if rev:
3052 if rev:
3052 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3053 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3053 start = scmutil.revsingle(repo, rev, None).node()
3054 start = scmutil.revsingle(repo, rev, None).node()
3054
3055
3055 if opts.get('topo'):
3056 if opts.get('topo'):
3056 heads = [repo[h] for h in repo.heads(start)]
3057 heads = [repo[h] for h in repo.heads(start)]
3057 else:
3058 else:
3058 heads = []
3059 heads = []
3059 for branch in repo.branchmap():
3060 for branch in repo.branchmap():
3060 heads += repo.branchheads(branch, start, opts.get('closed'))
3061 heads += repo.branchheads(branch, start, opts.get('closed'))
3061 heads = [repo[h] for h in heads]
3062 heads = [repo[h] for h in heads]
3062
3063
3063 if branchrevs:
3064 if branchrevs:
3064 branches = set(repo[r].branch()
3065 branches = set(repo[r].branch()
3065 for r in scmutil.revrange(repo, branchrevs))
3066 for r in scmutil.revrange(repo, branchrevs))
3066 heads = [h for h in heads if h.branch() in branches]
3067 heads = [h for h in heads if h.branch() in branches]
3067
3068
3068 if opts.get('active') and branchrevs:
3069 if opts.get('active') and branchrevs:
3069 dagheads = repo.heads(start)
3070 dagheads = repo.heads(start)
3070 heads = [h for h in heads if h.node() in dagheads]
3071 heads = [h for h in heads if h.node() in dagheads]
3071
3072
3072 if branchrevs:
3073 if branchrevs:
3073 haveheads = set(h.branch() for h in heads)
3074 haveheads = set(h.branch() for h in heads)
3074 if branches - haveheads:
3075 if branches - haveheads:
3075 headless = ', '.join(b for b in branches - haveheads)
3076 headless = ', '.join(b for b in branches - haveheads)
3076 msg = _('no open branch heads found on branches %s')
3077 msg = _('no open branch heads found on branches %s')
3077 if opts.get('rev'):
3078 if opts.get('rev'):
3078 msg += _(' (started at %s)') % opts['rev']
3079 msg += _(' (started at %s)') % opts['rev']
3079 ui.warn((msg + '\n') % headless)
3080 ui.warn((msg + '\n') % headless)
3080
3081
3081 if not heads:
3082 if not heads:
3082 return 1
3083 return 1
3083
3084
3084 ui.pager('heads')
3085 ui.pager('heads')
3085 heads = sorted(heads, key=lambda x: -x.rev())
3086 heads = sorted(heads, key=lambda x: -x.rev())
3086 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3087 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3087 for ctx in heads:
3088 for ctx in heads:
3088 displayer.show(ctx)
3089 displayer.show(ctx)
3089 displayer.close()
3090 displayer.close()
3090
3091
3091 @command('help',
3092 @command('help',
3092 [('e', 'extension', None, _('show only help for extensions')),
3093 [('e', 'extension', None, _('show only help for extensions')),
3093 ('c', 'command', None, _('show only help for commands')),
3094 ('c', 'command', None, _('show only help for commands')),
3094 ('k', 'keyword', None, _('show topics matching keyword')),
3095 ('k', 'keyword', None, _('show topics matching keyword')),
3095 ('s', 'system', [],
3096 ('s', 'system', [],
3096 _('show help for specific platform(s)'), _('PLATFORM')),
3097 _('show help for specific platform(s)'), _('PLATFORM')),
3097 ],
3098 ],
3098 _('[-eck] [-s PLATFORM] [TOPIC]'),
3099 _('[-eck] [-s PLATFORM] [TOPIC]'),
3099 helpcategory=command.CATEGORY_HELP,
3100 helpcategory=command.CATEGORY_HELP,
3100 norepo=True,
3101 norepo=True,
3101 intents={INTENT_READONLY})
3102 intents={INTENT_READONLY})
3102 def help_(ui, name=None, **opts):
3103 def help_(ui, name=None, **opts):
3103 """show help for a given topic or a help overview
3104 """show help for a given topic or a help overview
3104
3105
3105 With no arguments, print a list of commands with short help messages.
3106 With no arguments, print a list of commands with short help messages.
3106
3107
3107 Given a topic, extension, or command name, print help for that
3108 Given a topic, extension, or command name, print help for that
3108 topic.
3109 topic.
3109
3110
3110 Returns 0 if successful.
3111 Returns 0 if successful.
3111 """
3112 """
3112
3113
3113 keep = opts.get(r'system') or []
3114 keep = opts.get(r'system') or []
3114 if len(keep) == 0:
3115 if len(keep) == 0:
3115 if pycompat.sysplatform.startswith('win'):
3116 if pycompat.sysplatform.startswith('win'):
3116 keep.append('windows')
3117 keep.append('windows')
3117 elif pycompat.sysplatform == 'OpenVMS':
3118 elif pycompat.sysplatform == 'OpenVMS':
3118 keep.append('vms')
3119 keep.append('vms')
3119 elif pycompat.sysplatform == 'plan9':
3120 elif pycompat.sysplatform == 'plan9':
3120 keep.append('plan9')
3121 keep.append('plan9')
3121 else:
3122 else:
3122 keep.append('unix')
3123 keep.append('unix')
3123 keep.append(pycompat.sysplatform.lower())
3124 keep.append(pycompat.sysplatform.lower())
3124 if ui.verbose:
3125 if ui.verbose:
3125 keep.append('verbose')
3126 keep.append('verbose')
3126
3127
3127 commands = sys.modules[__name__]
3128 commands = sys.modules[__name__]
3128 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3129 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3129 ui.pager('help')
3130 ui.pager('help')
3130 ui.write(formatted)
3131 ui.write(formatted)
3131
3132
3132
3133
3133 @command('identify|id',
3134 @command('identify|id',
3134 [('r', 'rev', '',
3135 [('r', 'rev', '',
3135 _('identify the specified revision'), _('REV')),
3136 _('identify the specified revision'), _('REV')),
3136 ('n', 'num', None, _('show local revision number')),
3137 ('n', 'num', None, _('show local revision number')),
3137 ('i', 'id', None, _('show global revision id')),
3138 ('i', 'id', None, _('show global revision id')),
3138 ('b', 'branch', None, _('show branch')),
3139 ('b', 'branch', None, _('show branch')),
3139 ('t', 'tags', None, _('show tags')),
3140 ('t', 'tags', None, _('show tags')),
3140 ('B', 'bookmarks', None, _('show bookmarks')),
3141 ('B', 'bookmarks', None, _('show bookmarks')),
3141 ] + remoteopts + formatteropts,
3142 ] + remoteopts + formatteropts,
3142 _('[-nibtB] [-r REV] [SOURCE]'),
3143 _('[-nibtB] [-r REV] [SOURCE]'),
3143 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3144 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3144 optionalrepo=True,
3145 optionalrepo=True,
3145 intents={INTENT_READONLY})
3146 intents={INTENT_READONLY})
3146 def identify(ui, repo, source=None, rev=None,
3147 def identify(ui, repo, source=None, rev=None,
3147 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3148 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3148 """identify the working directory or specified revision
3149 """identify the working directory or specified revision
3149
3150
3150 Print a summary identifying the repository state at REV using one or
3151 Print a summary identifying the repository state at REV using one or
3151 two parent hash identifiers, followed by a "+" if the working
3152 two parent hash identifiers, followed by a "+" if the working
3152 directory has uncommitted changes, the branch name (if not default),
3153 directory has uncommitted changes, the branch name (if not default),
3153 a list of tags, and a list of bookmarks.
3154 a list of tags, and a list of bookmarks.
3154
3155
3155 When REV is not given, print a summary of the current state of the
3156 When REV is not given, print a summary of the current state of the
3156 repository including the working directory. Specify -r. to get information
3157 repository including the working directory. Specify -r. to get information
3157 of the working directory parent without scanning uncommitted changes.
3158 of the working directory parent without scanning uncommitted changes.
3158
3159
3159 Specifying a path to a repository root or Mercurial bundle will
3160 Specifying a path to a repository root or Mercurial bundle will
3160 cause lookup to operate on that repository/bundle.
3161 cause lookup to operate on that repository/bundle.
3161
3162
3162 .. container:: verbose
3163 .. container:: verbose
3163
3164
3164 Template:
3165 Template:
3165
3166
3166 The following keywords are supported in addition to the common template
3167 The following keywords are supported in addition to the common template
3167 keywords and functions. See also :hg:`help templates`.
3168 keywords and functions. See also :hg:`help templates`.
3168
3169
3169 :dirty: String. Character ``+`` denoting if the working directory has
3170 :dirty: String. Character ``+`` denoting if the working directory has
3170 uncommitted changes.
3171 uncommitted changes.
3171 :id: String. One or two nodes, optionally followed by ``+``.
3172 :id: String. One or two nodes, optionally followed by ``+``.
3172 :parents: List of strings. Parent nodes of the changeset.
3173 :parents: List of strings. Parent nodes of the changeset.
3173
3174
3174 Examples:
3175 Examples:
3175
3176
3176 - generate a build identifier for the working directory::
3177 - generate a build identifier for the working directory::
3177
3178
3178 hg id --id > build-id.dat
3179 hg id --id > build-id.dat
3179
3180
3180 - find the revision corresponding to a tag::
3181 - find the revision corresponding to a tag::
3181
3182
3182 hg id -n -r 1.3
3183 hg id -n -r 1.3
3183
3184
3184 - check the most recent revision of a remote repository::
3185 - check the most recent revision of a remote repository::
3185
3186
3186 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3187 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3187
3188
3188 See :hg:`log` for generating more information about specific revisions,
3189 See :hg:`log` for generating more information about specific revisions,
3189 including full hash identifiers.
3190 including full hash identifiers.
3190
3191
3191 Returns 0 if successful.
3192 Returns 0 if successful.
3192 """
3193 """
3193
3194
3194 opts = pycompat.byteskwargs(opts)
3195 opts = pycompat.byteskwargs(opts)
3195 if not repo and not source:
3196 if not repo and not source:
3196 raise error.Abort(_("there is no Mercurial repository here "
3197 raise error.Abort(_("there is no Mercurial repository here "
3197 "(.hg not found)"))
3198 "(.hg not found)"))
3198
3199
3199 default = not (num or id or branch or tags or bookmarks)
3200 default = not (num or id or branch or tags or bookmarks)
3200 output = []
3201 output = []
3201 revs = []
3202 revs = []
3202
3203
3203 if source:
3204 if source:
3204 source, branches = hg.parseurl(ui.expandpath(source))
3205 source, branches = hg.parseurl(ui.expandpath(source))
3205 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3206 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3206 repo = peer.local()
3207 repo = peer.local()
3207 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3208 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3208
3209
3209 fm = ui.formatter('identify', opts)
3210 fm = ui.formatter('identify', opts)
3210 fm.startitem()
3211 fm.startitem()
3211
3212
3212 if not repo:
3213 if not repo:
3213 if num or branch or tags:
3214 if num or branch or tags:
3214 raise error.Abort(
3215 raise error.Abort(
3215 _("can't query remote revision number, branch, or tags"))
3216 _("can't query remote revision number, branch, or tags"))
3216 if not rev and revs:
3217 if not rev and revs:
3217 rev = revs[0]
3218 rev = revs[0]
3218 if not rev:
3219 if not rev:
3219 rev = "tip"
3220 rev = "tip"
3220
3221
3221 remoterev = peer.lookup(rev)
3222 remoterev = peer.lookup(rev)
3222 hexrev = fm.hexfunc(remoterev)
3223 hexrev = fm.hexfunc(remoterev)
3223 if default or id:
3224 if default or id:
3224 output = [hexrev]
3225 output = [hexrev]
3225 fm.data(id=hexrev)
3226 fm.data(id=hexrev)
3226
3227
3227 @util.cachefunc
3228 @util.cachefunc
3228 def getbms():
3229 def getbms():
3229 bms = []
3230 bms = []
3230
3231
3231 if 'bookmarks' in peer.listkeys('namespaces'):
3232 if 'bookmarks' in peer.listkeys('namespaces'):
3232 hexremoterev = hex(remoterev)
3233 hexremoterev = hex(remoterev)
3233 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3234 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3234 if bmr == hexremoterev]
3235 if bmr == hexremoterev]
3235
3236
3236 return sorted(bms)
3237 return sorted(bms)
3237
3238
3238 if fm.isplain():
3239 if fm.isplain():
3239 if bookmarks:
3240 if bookmarks:
3240 output.extend(getbms())
3241 output.extend(getbms())
3241 elif default and not ui.quiet:
3242 elif default and not ui.quiet:
3242 # multiple bookmarks for a single parent separated by '/'
3243 # multiple bookmarks for a single parent separated by '/'
3243 bm = '/'.join(getbms())
3244 bm = '/'.join(getbms())
3244 if bm:
3245 if bm:
3245 output.append(bm)
3246 output.append(bm)
3246 else:
3247 else:
3247 fm.data(node=hex(remoterev))
3248 fm.data(node=hex(remoterev))
3248 if bookmarks or 'bookmarks' in fm.datahint():
3249 if bookmarks or 'bookmarks' in fm.datahint():
3249 fm.data(bookmarks=fm.formatlist(getbms(), name='bookmark'))
3250 fm.data(bookmarks=fm.formatlist(getbms(), name='bookmark'))
3250 else:
3251 else:
3251 if rev:
3252 if rev:
3252 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3253 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3253 ctx = scmutil.revsingle(repo, rev, None)
3254 ctx = scmutil.revsingle(repo, rev, None)
3254
3255
3255 if ctx.rev() is None:
3256 if ctx.rev() is None:
3256 ctx = repo[None]
3257 ctx = repo[None]
3257 parents = ctx.parents()
3258 parents = ctx.parents()
3258 taglist = []
3259 taglist = []
3259 for p in parents:
3260 for p in parents:
3260 taglist.extend(p.tags())
3261 taglist.extend(p.tags())
3261
3262
3262 dirty = ""
3263 dirty = ""
3263 if ctx.dirty(missing=True, merge=False, branch=False):
3264 if ctx.dirty(missing=True, merge=False, branch=False):
3264 dirty = '+'
3265 dirty = '+'
3265 fm.data(dirty=dirty)
3266 fm.data(dirty=dirty)
3266
3267
3267 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3268 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3268 if default or id:
3269 if default or id:
3269 output = ["%s%s" % ('+'.join(hexoutput), dirty)]
3270 output = ["%s%s" % ('+'.join(hexoutput), dirty)]
3270 fm.data(id="%s%s" % ('+'.join(hexoutput), dirty))
3271 fm.data(id="%s%s" % ('+'.join(hexoutput), dirty))
3271
3272
3272 if num:
3273 if num:
3273 numoutput = ["%d" % p.rev() for p in parents]
3274 numoutput = ["%d" % p.rev() for p in parents]
3274 output.append("%s%s" % ('+'.join(numoutput), dirty))
3275 output.append("%s%s" % ('+'.join(numoutput), dirty))
3275
3276
3276 fm.data(parents=fm.formatlist([fm.hexfunc(p.node())
3277 fm.data(parents=fm.formatlist([fm.hexfunc(p.node())
3277 for p in parents], name='node'))
3278 for p in parents], name='node'))
3278 else:
3279 else:
3279 hexoutput = fm.hexfunc(ctx.node())
3280 hexoutput = fm.hexfunc(ctx.node())
3280 if default or id:
3281 if default or id:
3281 output = [hexoutput]
3282 output = [hexoutput]
3282 fm.data(id=hexoutput)
3283 fm.data(id=hexoutput)
3283
3284
3284 if num:
3285 if num:
3285 output.append(pycompat.bytestr(ctx.rev()))
3286 output.append(pycompat.bytestr(ctx.rev()))
3286 taglist = ctx.tags()
3287 taglist = ctx.tags()
3287
3288
3288 if default and not ui.quiet:
3289 if default and not ui.quiet:
3289 b = ctx.branch()
3290 b = ctx.branch()
3290 if b != 'default':
3291 if b != 'default':
3291 output.append("(%s)" % b)
3292 output.append("(%s)" % b)
3292
3293
3293 # multiple tags for a single parent separated by '/'
3294 # multiple tags for a single parent separated by '/'
3294 t = '/'.join(taglist)
3295 t = '/'.join(taglist)
3295 if t:
3296 if t:
3296 output.append(t)
3297 output.append(t)
3297
3298
3298 # multiple bookmarks for a single parent separated by '/'
3299 # multiple bookmarks for a single parent separated by '/'
3299 bm = '/'.join(ctx.bookmarks())
3300 bm = '/'.join(ctx.bookmarks())
3300 if bm:
3301 if bm:
3301 output.append(bm)
3302 output.append(bm)
3302 else:
3303 else:
3303 if branch:
3304 if branch:
3304 output.append(ctx.branch())
3305 output.append(ctx.branch())
3305
3306
3306 if tags:
3307 if tags:
3307 output.extend(taglist)
3308 output.extend(taglist)
3308
3309
3309 if bookmarks:
3310 if bookmarks:
3310 output.extend(ctx.bookmarks())
3311 output.extend(ctx.bookmarks())
3311
3312
3312 fm.data(node=ctx.hex())
3313 fm.data(node=ctx.hex())
3313 fm.data(branch=ctx.branch())
3314 fm.data(branch=ctx.branch())
3314 fm.data(tags=fm.formatlist(taglist, name='tag', sep=':'))
3315 fm.data(tags=fm.formatlist(taglist, name='tag', sep=':'))
3315 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'))
3316 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'))
3316 fm.context(ctx=ctx)
3317 fm.context(ctx=ctx)
3317
3318
3318 fm.plain("%s\n" % ' '.join(output))
3319 fm.plain("%s\n" % ' '.join(output))
3319 fm.end()
3320 fm.end()
3320
3321
3321 @command('import|patch',
3322 @command('import|patch',
3322 [('p', 'strip', 1,
3323 [('p', 'strip', 1,
3323 _('directory strip option for patch. This has the same '
3324 _('directory strip option for patch. This has the same '
3324 'meaning as the corresponding patch option'), _('NUM')),
3325 'meaning as the corresponding patch option'), _('NUM')),
3325 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3326 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3326 ('e', 'edit', False, _('invoke editor on commit messages')),
3327 ('e', 'edit', False, _('invoke editor on commit messages')),
3327 ('f', 'force', None,
3328 ('f', 'force', None,
3328 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3329 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3329 ('', 'no-commit', None,
3330 ('', 'no-commit', None,
3330 _("don't commit, just update the working directory")),
3331 _("don't commit, just update the working directory")),
3331 ('', 'bypass', None,
3332 ('', 'bypass', None,
3332 _("apply patch without touching the working directory")),
3333 _("apply patch without touching the working directory")),
3333 ('', 'partial', None,
3334 ('', 'partial', None,
3334 _('commit even if some hunks fail')),
3335 _('commit even if some hunks fail')),
3335 ('', 'exact', None,
3336 ('', 'exact', None,
3336 _('abort if patch would apply lossily')),
3337 _('abort if patch would apply lossily')),
3337 ('', 'prefix', '',
3338 ('', 'prefix', '',
3338 _('apply patch to subdirectory'), _('DIR')),
3339 _('apply patch to subdirectory'), _('DIR')),
3339 ('', 'import-branch', None,
3340 ('', 'import-branch', None,
3340 _('use any branch information in patch (implied by --exact)'))] +
3341 _('use any branch information in patch (implied by --exact)'))] +
3341 commitopts + commitopts2 + similarityopts,
3342 commitopts + commitopts2 + similarityopts,
3342 _('[OPTION]... PATCH...'),
3343 _('[OPTION]... PATCH...'),
3343 helpcategory=command.CATEGORY_IMPORT_EXPORT)
3344 helpcategory=command.CATEGORY_IMPORT_EXPORT)
3344 def import_(ui, repo, patch1=None, *patches, **opts):
3345 def import_(ui, repo, patch1=None, *patches, **opts):
3345 """import an ordered set of patches
3346 """import an ordered set of patches
3346
3347
3347 Import a list of patches and commit them individually (unless
3348 Import a list of patches and commit them individually (unless
3348 --no-commit is specified).
3349 --no-commit is specified).
3349
3350
3350 To read a patch from standard input (stdin), use "-" as the patch
3351 To read a patch from standard input (stdin), use "-" as the patch
3351 name. If a URL is specified, the patch will be downloaded from
3352 name. If a URL is specified, the patch will be downloaded from
3352 there.
3353 there.
3353
3354
3354 Import first applies changes to the working directory (unless
3355 Import first applies changes to the working directory (unless
3355 --bypass is specified), import will abort if there are outstanding
3356 --bypass is specified), import will abort if there are outstanding
3356 changes.
3357 changes.
3357
3358
3358 Use --bypass to apply and commit patches directly to the
3359 Use --bypass to apply and commit patches directly to the
3359 repository, without affecting the working directory. Without
3360 repository, without affecting the working directory. Without
3360 --exact, patches will be applied on top of the working directory
3361 --exact, patches will be applied on top of the working directory
3361 parent revision.
3362 parent revision.
3362
3363
3363 You can import a patch straight from a mail message. Even patches
3364 You can import a patch straight from a mail message. Even patches
3364 as attachments work (to use the body part, it must have type
3365 as attachments work (to use the body part, it must have type
3365 text/plain or text/x-patch). From and Subject headers of email
3366 text/plain or text/x-patch). From and Subject headers of email
3366 message are used as default committer and commit message. All
3367 message are used as default committer and commit message. All
3367 text/plain body parts before first diff are added to the commit
3368 text/plain body parts before first diff are added to the commit
3368 message.
3369 message.
3369
3370
3370 If the imported patch was generated by :hg:`export`, user and
3371 If the imported patch was generated by :hg:`export`, user and
3371 description from patch override values from message headers and
3372 description from patch override values from message headers and
3372 body. Values given on command line with -m/--message and -u/--user
3373 body. Values given on command line with -m/--message and -u/--user
3373 override these.
3374 override these.
3374
3375
3375 If --exact is specified, import will set the working directory to
3376 If --exact is specified, import will set the working directory to
3376 the parent of each patch before applying it, and will abort if the
3377 the parent of each patch before applying it, and will abort if the
3377 resulting changeset has a different ID than the one recorded in
3378 resulting changeset has a different ID than the one recorded in
3378 the patch. This will guard against various ways that portable
3379 the patch. This will guard against various ways that portable
3379 patch formats and mail systems might fail to transfer Mercurial
3380 patch formats and mail systems might fail to transfer Mercurial
3380 data or metadata. See :hg:`bundle` for lossless transmission.
3381 data or metadata. See :hg:`bundle` for lossless transmission.
3381
3382
3382 Use --partial to ensure a changeset will be created from the patch
3383 Use --partial to ensure a changeset will be created from the patch
3383 even if some hunks fail to apply. Hunks that fail to apply will be
3384 even if some hunks fail to apply. Hunks that fail to apply will be
3384 written to a <target-file>.rej file. Conflicts can then be resolved
3385 written to a <target-file>.rej file. Conflicts can then be resolved
3385 by hand before :hg:`commit --amend` is run to update the created
3386 by hand before :hg:`commit --amend` is run to update the created
3386 changeset. This flag exists to let people import patches that
3387 changeset. This flag exists to let people import patches that
3387 partially apply without losing the associated metadata (author,
3388 partially apply without losing the associated metadata (author,
3388 date, description, ...).
3389 date, description, ...).
3389
3390
3390 .. note::
3391 .. note::
3391
3392
3392 When no hunks apply cleanly, :hg:`import --partial` will create
3393 When no hunks apply cleanly, :hg:`import --partial` will create
3393 an empty changeset, importing only the patch metadata.
3394 an empty changeset, importing only the patch metadata.
3394
3395
3395 With -s/--similarity, hg will attempt to discover renames and
3396 With -s/--similarity, hg will attempt to discover renames and
3396 copies in the patch in the same way as :hg:`addremove`.
3397 copies in the patch in the same way as :hg:`addremove`.
3397
3398
3398 It is possible to use external patch programs to perform the patch
3399 It is possible to use external patch programs to perform the patch
3399 by setting the ``ui.patch`` configuration option. For the default
3400 by setting the ``ui.patch`` configuration option. For the default
3400 internal tool, the fuzz can also be configured via ``patch.fuzz``.
3401 internal tool, the fuzz can also be configured via ``patch.fuzz``.
3401 See :hg:`help config` for more information about configuration
3402 See :hg:`help config` for more information about configuration
3402 files and how to use these options.
3403 files and how to use these options.
3403
3404
3404 See :hg:`help dates` for a list of formats valid for -d/--date.
3405 See :hg:`help dates` for a list of formats valid for -d/--date.
3405
3406
3406 .. container:: verbose
3407 .. container:: verbose
3407
3408
3408 Examples:
3409 Examples:
3409
3410
3410 - import a traditional patch from a website and detect renames::
3411 - import a traditional patch from a website and detect renames::
3411
3412
3412 hg import -s 80 http://example.com/bugfix.patch
3413 hg import -s 80 http://example.com/bugfix.patch
3413
3414
3414 - import a changeset from an hgweb server::
3415 - import a changeset from an hgweb server::
3415
3416
3416 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
3417 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
3417
3418
3418 - import all the patches in an Unix-style mbox::
3419 - import all the patches in an Unix-style mbox::
3419
3420
3420 hg import incoming-patches.mbox
3421 hg import incoming-patches.mbox
3421
3422
3422 - import patches from stdin::
3423 - import patches from stdin::
3423
3424
3424 hg import -
3425 hg import -
3425
3426
3426 - attempt to exactly restore an exported changeset (not always
3427 - attempt to exactly restore an exported changeset (not always
3427 possible)::
3428 possible)::
3428
3429
3429 hg import --exact proposed-fix.patch
3430 hg import --exact proposed-fix.patch
3430
3431
3431 - use an external tool to apply a patch which is too fuzzy for
3432 - use an external tool to apply a patch which is too fuzzy for
3432 the default internal tool.
3433 the default internal tool.
3433
3434
3434 hg import --config ui.patch="patch --merge" fuzzy.patch
3435 hg import --config ui.patch="patch --merge" fuzzy.patch
3435
3436
3436 - change the default fuzzing from 2 to a less strict 7
3437 - change the default fuzzing from 2 to a less strict 7
3437
3438
3438 hg import --config ui.fuzz=7 fuzz.patch
3439 hg import --config ui.fuzz=7 fuzz.patch
3439
3440
3440 Returns 0 on success, 1 on partial success (see --partial).
3441 Returns 0 on success, 1 on partial success (see --partial).
3441 """
3442 """
3442
3443
3443 opts = pycompat.byteskwargs(opts)
3444 opts = pycompat.byteskwargs(opts)
3444 if not patch1:
3445 if not patch1:
3445 raise error.Abort(_('need at least one patch to import'))
3446 raise error.Abort(_('need at least one patch to import'))
3446
3447
3447 patches = (patch1,) + patches
3448 patches = (patch1,) + patches
3448
3449
3449 date = opts.get('date')
3450 date = opts.get('date')
3450 if date:
3451 if date:
3451 opts['date'] = dateutil.parsedate(date)
3452 opts['date'] = dateutil.parsedate(date)
3452
3453
3453 exact = opts.get('exact')
3454 exact = opts.get('exact')
3454 update = not opts.get('bypass')
3455 update = not opts.get('bypass')
3455 if not update and opts.get('no_commit'):
3456 if not update and opts.get('no_commit'):
3456 raise error.Abort(_('cannot use --no-commit with --bypass'))
3457 raise error.Abort(_('cannot use --no-commit with --bypass'))
3457 try:
3458 try:
3458 sim = float(opts.get('similarity') or 0)
3459 sim = float(opts.get('similarity') or 0)
3459 except ValueError:
3460 except ValueError:
3460 raise error.Abort(_('similarity must be a number'))
3461 raise error.Abort(_('similarity must be a number'))
3461 if sim < 0 or sim > 100:
3462 if sim < 0 or sim > 100:
3462 raise error.Abort(_('similarity must be between 0 and 100'))
3463 raise error.Abort(_('similarity must be between 0 and 100'))
3463 if sim and not update:
3464 if sim and not update:
3464 raise error.Abort(_('cannot use --similarity with --bypass'))
3465 raise error.Abort(_('cannot use --similarity with --bypass'))
3465 if exact:
3466 if exact:
3466 if opts.get('edit'):
3467 if opts.get('edit'):
3467 raise error.Abort(_('cannot use --exact with --edit'))
3468 raise error.Abort(_('cannot use --exact with --edit'))
3468 if opts.get('prefix'):
3469 if opts.get('prefix'):
3469 raise error.Abort(_('cannot use --exact with --prefix'))
3470 raise error.Abort(_('cannot use --exact with --prefix'))
3470
3471
3471 base = opts["base"]
3472 base = opts["base"]
3472 msgs = []
3473 msgs = []
3473 ret = 0
3474 ret = 0
3474
3475
3475 with repo.wlock():
3476 with repo.wlock():
3476 if update:
3477 if update:
3477 cmdutil.checkunfinished(repo)
3478 cmdutil.checkunfinished(repo)
3478 if (exact or not opts.get('force')):
3479 if (exact or not opts.get('force')):
3479 cmdutil.bailifchanged(repo)
3480 cmdutil.bailifchanged(repo)
3480
3481
3481 if not opts.get('no_commit'):
3482 if not opts.get('no_commit'):
3482 lock = repo.lock
3483 lock = repo.lock
3483 tr = lambda: repo.transaction('import')
3484 tr = lambda: repo.transaction('import')
3484 dsguard = util.nullcontextmanager
3485 dsguard = util.nullcontextmanager
3485 else:
3486 else:
3486 lock = util.nullcontextmanager
3487 lock = util.nullcontextmanager
3487 tr = util.nullcontextmanager
3488 tr = util.nullcontextmanager
3488 dsguard = lambda: dirstateguard.dirstateguard(repo, 'import')
3489 dsguard = lambda: dirstateguard.dirstateguard(repo, 'import')
3489 with lock(), tr(), dsguard():
3490 with lock(), tr(), dsguard():
3490 parents = repo[None].parents()
3491 parents = repo[None].parents()
3491 for patchurl in patches:
3492 for patchurl in patches:
3492 if patchurl == '-':
3493 if patchurl == '-':
3493 ui.status(_('applying patch from stdin\n'))
3494 ui.status(_('applying patch from stdin\n'))
3494 patchfile = ui.fin
3495 patchfile = ui.fin
3495 patchurl = 'stdin' # for error message
3496 patchurl = 'stdin' # for error message
3496 else:
3497 else:
3497 patchurl = os.path.join(base, patchurl)
3498 patchurl = os.path.join(base, patchurl)
3498 ui.status(_('applying %s\n') % patchurl)
3499 ui.status(_('applying %s\n') % patchurl)
3499 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
3500 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
3500
3501
3501 haspatch = False
3502 haspatch = False
3502 for hunk in patch.split(patchfile):
3503 for hunk in patch.split(patchfile):
3503 with patch.extract(ui, hunk) as patchdata:
3504 with patch.extract(ui, hunk) as patchdata:
3504 msg, node, rej = cmdutil.tryimportone(ui, repo,
3505 msg, node, rej = cmdutil.tryimportone(ui, repo,
3505 patchdata,
3506 patchdata,
3506 parents, opts,
3507 parents, opts,
3507 msgs, hg.clean)
3508 msgs, hg.clean)
3508 if msg:
3509 if msg:
3509 haspatch = True
3510 haspatch = True
3510 ui.note(msg + '\n')
3511 ui.note(msg + '\n')
3511 if update or exact:
3512 if update or exact:
3512 parents = repo[None].parents()
3513 parents = repo[None].parents()
3513 else:
3514 else:
3514 parents = [repo[node]]
3515 parents = [repo[node]]
3515 if rej:
3516 if rej:
3516 ui.write_err(_("patch applied partially\n"))
3517 ui.write_err(_("patch applied partially\n"))
3517 ui.write_err(_("(fix the .rej files and run "
3518 ui.write_err(_("(fix the .rej files and run "
3518 "`hg commit --amend`)\n"))
3519 "`hg commit --amend`)\n"))
3519 ret = 1
3520 ret = 1
3520 break
3521 break
3521
3522
3522 if not haspatch:
3523 if not haspatch:
3523 raise error.Abort(_('%s: no diffs found') % patchurl)
3524 raise error.Abort(_('%s: no diffs found') % patchurl)
3524
3525
3525 if msgs:
3526 if msgs:
3526 repo.savecommitmessage('\n* * *\n'.join(msgs))
3527 repo.savecommitmessage('\n* * *\n'.join(msgs))
3527 return ret
3528 return ret
3528
3529
3529 @command('incoming|in',
3530 @command('incoming|in',
3530 [('f', 'force', None,
3531 [('f', 'force', None,
3531 _('run even if remote repository is unrelated')),
3532 _('run even if remote repository is unrelated')),
3532 ('n', 'newest-first', None, _('show newest record first')),
3533 ('n', 'newest-first', None, _('show newest record first')),
3533 ('', 'bundle', '',
3534 ('', 'bundle', '',
3534 _('file to store the bundles into'), _('FILE')),
3535 _('file to store the bundles into'), _('FILE')),
3535 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3536 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3536 ('B', 'bookmarks', False, _("compare bookmarks")),
3537 ('B', 'bookmarks', False, _("compare bookmarks")),
3537 ('b', 'branch', [],
3538 ('b', 'branch', [],
3538 _('a specific branch you would like to pull'), _('BRANCH')),
3539 _('a specific branch you would like to pull'), _('BRANCH')),
3539 ] + logopts + remoteopts + subrepoopts,
3540 ] + logopts + remoteopts + subrepoopts,
3540 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
3541 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
3541 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
3542 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
3542 def incoming(ui, repo, source="default", **opts):
3543 def incoming(ui, repo, source="default", **opts):
3543 """show new changesets found in source
3544 """show new changesets found in source
3544
3545
3545 Show new changesets found in the specified path/URL or the default
3546 Show new changesets found in the specified path/URL or the default
3546 pull location. These are the changesets that would have been pulled
3547 pull location. These are the changesets that would have been pulled
3547 by :hg:`pull` at the time you issued this command.
3548 by :hg:`pull` at the time you issued this command.
3548
3549
3549 See pull for valid source format details.
3550 See pull for valid source format details.
3550
3551
3551 .. container:: verbose
3552 .. container:: verbose
3552
3553
3553 With -B/--bookmarks, the result of bookmark comparison between
3554 With -B/--bookmarks, the result of bookmark comparison between
3554 local and remote repositories is displayed. With -v/--verbose,
3555 local and remote repositories is displayed. With -v/--verbose,
3555 status is also displayed for each bookmark like below::
3556 status is also displayed for each bookmark like below::
3556
3557
3557 BM1 01234567890a added
3558 BM1 01234567890a added
3558 BM2 1234567890ab advanced
3559 BM2 1234567890ab advanced
3559 BM3 234567890abc diverged
3560 BM3 234567890abc diverged
3560 BM4 34567890abcd changed
3561 BM4 34567890abcd changed
3561
3562
3562 The action taken locally when pulling depends on the
3563 The action taken locally when pulling depends on the
3563 status of each bookmark:
3564 status of each bookmark:
3564
3565
3565 :``added``: pull will create it
3566 :``added``: pull will create it
3566 :``advanced``: pull will update it
3567 :``advanced``: pull will update it
3567 :``diverged``: pull will create a divergent bookmark
3568 :``diverged``: pull will create a divergent bookmark
3568 :``changed``: result depends on remote changesets
3569 :``changed``: result depends on remote changesets
3569
3570
3570 From the point of view of pulling behavior, bookmark
3571 From the point of view of pulling behavior, bookmark
3571 existing only in the remote repository are treated as ``added``,
3572 existing only in the remote repository are treated as ``added``,
3572 even if it is in fact locally deleted.
3573 even if it is in fact locally deleted.
3573
3574
3574 .. container:: verbose
3575 .. container:: verbose
3575
3576
3576 For remote repository, using --bundle avoids downloading the
3577 For remote repository, using --bundle avoids downloading the
3577 changesets twice if the incoming is followed by a pull.
3578 changesets twice if the incoming is followed by a pull.
3578
3579
3579 Examples:
3580 Examples:
3580
3581
3581 - show incoming changes with patches and full description::
3582 - show incoming changes with patches and full description::
3582
3583
3583 hg incoming -vp
3584 hg incoming -vp
3584
3585
3585 - show incoming changes excluding merges, store a bundle::
3586 - show incoming changes excluding merges, store a bundle::
3586
3587
3587 hg in -vpM --bundle incoming.hg
3588 hg in -vpM --bundle incoming.hg
3588 hg pull incoming.hg
3589 hg pull incoming.hg
3589
3590
3590 - briefly list changes inside a bundle::
3591 - briefly list changes inside a bundle::
3591
3592
3592 hg in changes.hg -T "{desc|firstline}\\n"
3593 hg in changes.hg -T "{desc|firstline}\\n"
3593
3594
3594 Returns 0 if there are incoming changes, 1 otherwise.
3595 Returns 0 if there are incoming changes, 1 otherwise.
3595 """
3596 """
3596 opts = pycompat.byteskwargs(opts)
3597 opts = pycompat.byteskwargs(opts)
3597 if opts.get('graph'):
3598 if opts.get('graph'):
3598 logcmdutil.checkunsupportedgraphflags([], opts)
3599 logcmdutil.checkunsupportedgraphflags([], opts)
3599 def display(other, chlist, displayer):
3600 def display(other, chlist, displayer):
3600 revdag = logcmdutil.graphrevs(other, chlist, opts)
3601 revdag = logcmdutil.graphrevs(other, chlist, opts)
3601 logcmdutil.displaygraph(ui, repo, revdag, displayer,
3602 logcmdutil.displaygraph(ui, repo, revdag, displayer,
3602 graphmod.asciiedges)
3603 graphmod.asciiedges)
3603
3604
3604 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3605 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3605 return 0
3606 return 0
3606
3607
3607 if opts.get('bundle') and opts.get('subrepos'):
3608 if opts.get('bundle') and opts.get('subrepos'):
3608 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3609 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3609
3610
3610 if opts.get('bookmarks'):
3611 if opts.get('bookmarks'):
3611 source, branches = hg.parseurl(ui.expandpath(source),
3612 source, branches = hg.parseurl(ui.expandpath(source),
3612 opts.get('branch'))
3613 opts.get('branch'))
3613 other = hg.peer(repo, opts, source)
3614 other = hg.peer(repo, opts, source)
3614 if 'bookmarks' not in other.listkeys('namespaces'):
3615 if 'bookmarks' not in other.listkeys('namespaces'):
3615 ui.warn(_("remote doesn't support bookmarks\n"))
3616 ui.warn(_("remote doesn't support bookmarks\n"))
3616 return 0
3617 return 0
3617 ui.pager('incoming')
3618 ui.pager('incoming')
3618 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3619 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3619 return bookmarks.incoming(ui, repo, other)
3620 return bookmarks.incoming(ui, repo, other)
3620
3621
3621 repo._subtoppath = ui.expandpath(source)
3622 repo._subtoppath = ui.expandpath(source)
3622 try:
3623 try:
3623 return hg.incoming(ui, repo, source, opts)
3624 return hg.incoming(ui, repo, source, opts)
3624 finally:
3625 finally:
3625 del repo._subtoppath
3626 del repo._subtoppath
3626
3627
3627
3628
3628 @command('init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
3629 @command('init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
3629 helpcategory=command.CATEGORY_REPO_CREATION,
3630 helpcategory=command.CATEGORY_REPO_CREATION,
3630 helpbasic=True, norepo=True)
3631 helpbasic=True, norepo=True)
3631 def init(ui, dest=".", **opts):
3632 def init(ui, dest=".", **opts):
3632 """create a new repository in the given directory
3633 """create a new repository in the given directory
3633
3634
3634 Initialize a new repository in the given directory. If the given
3635 Initialize a new repository in the given directory. If the given
3635 directory does not exist, it will be created.
3636 directory does not exist, it will be created.
3636
3637
3637 If no directory is given, the current directory is used.
3638 If no directory is given, the current directory is used.
3638
3639
3639 It is possible to specify an ``ssh://`` URL as the destination.
3640 It is possible to specify an ``ssh://`` URL as the destination.
3640 See :hg:`help urls` for more information.
3641 See :hg:`help urls` for more information.
3641
3642
3642 Returns 0 on success.
3643 Returns 0 on success.
3643 """
3644 """
3644 opts = pycompat.byteskwargs(opts)
3645 opts = pycompat.byteskwargs(opts)
3645 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3646 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3646
3647
3647 @command('locate',
3648 @command('locate',
3648 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3649 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3649 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3650 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3650 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3651 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3651 ] + walkopts,
3652 ] + walkopts,
3652 _('[OPTION]... [PATTERN]...'),
3653 _('[OPTION]... [PATTERN]...'),
3653 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
3654 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
3654 def locate(ui, repo, *pats, **opts):
3655 def locate(ui, repo, *pats, **opts):
3655 """locate files matching specific patterns (DEPRECATED)
3656 """locate files matching specific patterns (DEPRECATED)
3656
3657
3657 Print files under Mercurial control in the working directory whose
3658 Print files under Mercurial control in the working directory whose
3658 names match the given patterns.
3659 names match the given patterns.
3659
3660
3660 By default, this command searches all directories in the working
3661 By default, this command searches all directories in the working
3661 directory. To search just the current directory and its
3662 directory. To search just the current directory and its
3662 subdirectories, use "--include .".
3663 subdirectories, use "--include .".
3663
3664
3664 If no patterns are given to match, this command prints the names
3665 If no patterns are given to match, this command prints the names
3665 of all files under Mercurial control in the working directory.
3666 of all files under Mercurial control in the working directory.
3666
3667
3667 If you want to feed the output of this command into the "xargs"
3668 If you want to feed the output of this command into the "xargs"
3668 command, use the -0 option to both this command and "xargs". This
3669 command, use the -0 option to both this command and "xargs". This
3669 will avoid the problem of "xargs" treating single filenames that
3670 will avoid the problem of "xargs" treating single filenames that
3670 contain whitespace as multiple filenames.
3671 contain whitespace as multiple filenames.
3671
3672
3672 See :hg:`help files` for a more versatile command.
3673 See :hg:`help files` for a more versatile command.
3673
3674
3674 Returns 0 if a match is found, 1 otherwise.
3675 Returns 0 if a match is found, 1 otherwise.
3675 """
3676 """
3676 opts = pycompat.byteskwargs(opts)
3677 opts = pycompat.byteskwargs(opts)
3677 if opts.get('print0'):
3678 if opts.get('print0'):
3678 end = '\0'
3679 end = '\0'
3679 else:
3680 else:
3680 end = '\n'
3681 end = '\n'
3681 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3682 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3682
3683
3683 ret = 1
3684 ret = 1
3684 m = scmutil.match(ctx, pats, opts, default='relglob',
3685 m = scmutil.match(ctx, pats, opts, default='relglob',
3685 badfn=lambda x, y: False)
3686 badfn=lambda x, y: False)
3686
3687
3687 ui.pager('locate')
3688 ui.pager('locate')
3688 if ctx.rev() is None:
3689 if ctx.rev() is None:
3689 # When run on the working copy, "locate" includes removed files, so
3690 # When run on the working copy, "locate" includes removed files, so
3690 # we get the list of files from the dirstate.
3691 # we get the list of files from the dirstate.
3691 filesgen = sorted(repo.dirstate.matches(m))
3692 filesgen = sorted(repo.dirstate.matches(m))
3692 else:
3693 else:
3693 filesgen = ctx.matches(m)
3694 filesgen = ctx.matches(m)
3694 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
3695 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
3695 for abs in filesgen:
3696 for abs in filesgen:
3696 if opts.get('fullpath'):
3697 if opts.get('fullpath'):
3697 ui.write(repo.wjoin(abs), end)
3698 ui.write(repo.wjoin(abs), end)
3698 else:
3699 else:
3699 ui.write(uipathfn(abs), end)
3700 ui.write(uipathfn(abs), end)
3700 ret = 0
3701 ret = 0
3701
3702
3702 return ret
3703 return ret
3703
3704
3704 @command('log|history',
3705 @command('log|history',
3705 [('f', 'follow', None,
3706 [('f', 'follow', None,
3706 _('follow changeset history, or file history across copies and renames')),
3707 _('follow changeset history, or file history across copies and renames')),
3707 ('', 'follow-first', None,
3708 ('', 'follow-first', None,
3708 _('only follow the first parent of merge changesets (DEPRECATED)')),
3709 _('only follow the first parent of merge changesets (DEPRECATED)')),
3709 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3710 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3710 ('C', 'copies', None, _('show copied files')),
3711 ('C', 'copies', None, _('show copied files')),
3711 ('k', 'keyword', [],
3712 ('k', 'keyword', [],
3712 _('do case-insensitive search for a given text'), _('TEXT')),
3713 _('do case-insensitive search for a given text'), _('TEXT')),
3713 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3714 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3714 ('L', 'line-range', [],
3715 ('L', 'line-range', [],
3715 _('follow line range of specified file (EXPERIMENTAL)'),
3716 _('follow line range of specified file (EXPERIMENTAL)'),
3716 _('FILE,RANGE')),
3717 _('FILE,RANGE')),
3717 ('', 'removed', None, _('include revisions where files were removed')),
3718 ('', 'removed', None, _('include revisions where files were removed')),
3718 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3719 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3719 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3720 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3720 ('', 'only-branch', [],
3721 ('', 'only-branch', [],
3721 _('show only changesets within the given named branch (DEPRECATED)'),
3722 _('show only changesets within the given named branch (DEPRECATED)'),
3722 _('BRANCH')),
3723 _('BRANCH')),
3723 ('b', 'branch', [],
3724 ('b', 'branch', [],
3724 _('show changesets within the given named branch'), _('BRANCH')),
3725 _('show changesets within the given named branch'), _('BRANCH')),
3725 ('P', 'prune', [],
3726 ('P', 'prune', [],
3726 _('do not display revision or any of its ancestors'), _('REV')),
3727 _('do not display revision or any of its ancestors'), _('REV')),
3727 ] + logopts + walkopts,
3728 ] + logopts + walkopts,
3728 _('[OPTION]... [FILE]'),
3729 _('[OPTION]... [FILE]'),
3729 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3730 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3730 helpbasic=True, inferrepo=True,
3731 helpbasic=True, inferrepo=True,
3731 intents={INTENT_READONLY})
3732 intents={INTENT_READONLY})
3732 def log(ui, repo, *pats, **opts):
3733 def log(ui, repo, *pats, **opts):
3733 """show revision history of entire repository or files
3734 """show revision history of entire repository or files
3734
3735
3735 Print the revision history of the specified files or the entire
3736 Print the revision history of the specified files or the entire
3736 project.
3737 project.
3737
3738
3738 If no revision range is specified, the default is ``tip:0`` unless
3739 If no revision range is specified, the default is ``tip:0`` unless
3739 --follow is set, in which case the working directory parent is
3740 --follow is set, in which case the working directory parent is
3740 used as the starting revision.
3741 used as the starting revision.
3741
3742
3742 File history is shown without following rename or copy history of
3743 File history is shown without following rename or copy history of
3743 files. Use -f/--follow with a filename to follow history across
3744 files. Use -f/--follow with a filename to follow history across
3744 renames and copies. --follow without a filename will only show
3745 renames and copies. --follow without a filename will only show
3745 ancestors of the starting revision.
3746 ancestors of the starting revision.
3746
3747
3747 By default this command prints revision number and changeset id,
3748 By default this command prints revision number and changeset id,
3748 tags, non-trivial parents, user, date and time, and a summary for
3749 tags, non-trivial parents, user, date and time, and a summary for
3749 each commit. When the -v/--verbose switch is used, the list of
3750 each commit. When the -v/--verbose switch is used, the list of
3750 changed files and full commit message are shown.
3751 changed files and full commit message are shown.
3751
3752
3752 With --graph the revisions are shown as an ASCII art DAG with the most
3753 With --graph the revisions are shown as an ASCII art DAG with the most
3753 recent changeset at the top.
3754 recent changeset at the top.
3754 'o' is a changeset, '@' is a working directory parent, '_' closes a branch,
3755 'o' is a changeset, '@' is a working directory parent, '_' closes a branch,
3755 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
3756 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
3756 changeset from the lines below is a parent of the 'o' merge on the same
3757 changeset from the lines below is a parent of the 'o' merge on the same
3757 line.
3758 line.
3758 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
3759 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
3759 of a '|' indicates one or more revisions in a path are omitted.
3760 of a '|' indicates one or more revisions in a path are omitted.
3760
3761
3761 .. container:: verbose
3762 .. container:: verbose
3762
3763
3763 Use -L/--line-range FILE,M:N options to follow the history of lines
3764 Use -L/--line-range FILE,M:N options to follow the history of lines
3764 from M to N in FILE. With -p/--patch only diff hunks affecting
3765 from M to N in FILE. With -p/--patch only diff hunks affecting
3765 specified line range will be shown. This option requires --follow;
3766 specified line range will be shown. This option requires --follow;
3766 it can be specified multiple times. Currently, this option is not
3767 it can be specified multiple times. Currently, this option is not
3767 compatible with --graph. This option is experimental.
3768 compatible with --graph. This option is experimental.
3768
3769
3769 .. note::
3770 .. note::
3770
3771
3771 :hg:`log --patch` may generate unexpected diff output for merge
3772 :hg:`log --patch` may generate unexpected diff output for merge
3772 changesets, as it will only compare the merge changeset against
3773 changesets, as it will only compare the merge changeset against
3773 its first parent. Also, only files different from BOTH parents
3774 its first parent. Also, only files different from BOTH parents
3774 will appear in files:.
3775 will appear in files:.
3775
3776
3776 .. note::
3777 .. note::
3777
3778
3778 For performance reasons, :hg:`log FILE` may omit duplicate changes
3779 For performance reasons, :hg:`log FILE` may omit duplicate changes
3779 made on branches and will not show removals or mode changes. To
3780 made on branches and will not show removals or mode changes. To
3780 see all such changes, use the --removed switch.
3781 see all such changes, use the --removed switch.
3781
3782
3782 .. container:: verbose
3783 .. container:: verbose
3783
3784
3784 .. note::
3785 .. note::
3785
3786
3786 The history resulting from -L/--line-range options depends on diff
3787 The history resulting from -L/--line-range options depends on diff
3787 options; for instance if white-spaces are ignored, respective changes
3788 options; for instance if white-spaces are ignored, respective changes
3788 with only white-spaces in specified line range will not be listed.
3789 with only white-spaces in specified line range will not be listed.
3789
3790
3790 .. container:: verbose
3791 .. container:: verbose
3791
3792
3792 Some examples:
3793 Some examples:
3793
3794
3794 - changesets with full descriptions and file lists::
3795 - changesets with full descriptions and file lists::
3795
3796
3796 hg log -v
3797 hg log -v
3797
3798
3798 - changesets ancestral to the working directory::
3799 - changesets ancestral to the working directory::
3799
3800
3800 hg log -f
3801 hg log -f
3801
3802
3802 - last 10 commits on the current branch::
3803 - last 10 commits on the current branch::
3803
3804
3804 hg log -l 10 -b .
3805 hg log -l 10 -b .
3805
3806
3806 - changesets showing all modifications of a file, including removals::
3807 - changesets showing all modifications of a file, including removals::
3807
3808
3808 hg log --removed file.c
3809 hg log --removed file.c
3809
3810
3810 - all changesets that touch a directory, with diffs, excluding merges::
3811 - all changesets that touch a directory, with diffs, excluding merges::
3811
3812
3812 hg log -Mp lib/
3813 hg log -Mp lib/
3813
3814
3814 - all revision numbers that match a keyword::
3815 - all revision numbers that match a keyword::
3815
3816
3816 hg log -k bug --template "{rev}\\n"
3817 hg log -k bug --template "{rev}\\n"
3817
3818
3818 - the full hash identifier of the working directory parent::
3819 - the full hash identifier of the working directory parent::
3819
3820
3820 hg log -r . --template "{node}\\n"
3821 hg log -r . --template "{node}\\n"
3821
3822
3822 - list available log templates::
3823 - list available log templates::
3823
3824
3824 hg log -T list
3825 hg log -T list
3825
3826
3826 - check if a given changeset is included in a tagged release::
3827 - check if a given changeset is included in a tagged release::
3827
3828
3828 hg log -r "a21ccf and ancestor(1.9)"
3829 hg log -r "a21ccf and ancestor(1.9)"
3829
3830
3830 - find all changesets by some user in a date range::
3831 - find all changesets by some user in a date range::
3831
3832
3832 hg log -k alice -d "may 2008 to jul 2008"
3833 hg log -k alice -d "may 2008 to jul 2008"
3833
3834
3834 - summary of all changesets after the last tag::
3835 - summary of all changesets after the last tag::
3835
3836
3836 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3837 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3837
3838
3838 - changesets touching lines 13 to 23 for file.c::
3839 - changesets touching lines 13 to 23 for file.c::
3839
3840
3840 hg log -L file.c,13:23
3841 hg log -L file.c,13:23
3841
3842
3842 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
3843 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
3843 main.c with patch::
3844 main.c with patch::
3844
3845
3845 hg log -L file.c,13:23 -L main.c,2:6 -p
3846 hg log -L file.c,13:23 -L main.c,2:6 -p
3846
3847
3847 See :hg:`help dates` for a list of formats valid for -d/--date.
3848 See :hg:`help dates` for a list of formats valid for -d/--date.
3848
3849
3849 See :hg:`help revisions` for more about specifying and ordering
3850 See :hg:`help revisions` for more about specifying and ordering
3850 revisions.
3851 revisions.
3851
3852
3852 See :hg:`help templates` for more about pre-packaged styles and
3853 See :hg:`help templates` for more about pre-packaged styles and
3853 specifying custom templates. The default template used by the log
3854 specifying custom templates. The default template used by the log
3854 command can be customized via the ``ui.logtemplate`` configuration
3855 command can be customized via the ``ui.logtemplate`` configuration
3855 setting.
3856 setting.
3856
3857
3857 Returns 0 on success.
3858 Returns 0 on success.
3858
3859
3859 """
3860 """
3860 opts = pycompat.byteskwargs(opts)
3861 opts = pycompat.byteskwargs(opts)
3861 linerange = opts.get('line_range')
3862 linerange = opts.get('line_range')
3862
3863
3863 if linerange and not opts.get('follow'):
3864 if linerange and not opts.get('follow'):
3864 raise error.Abort(_('--line-range requires --follow'))
3865 raise error.Abort(_('--line-range requires --follow'))
3865
3866
3866 if linerange and pats:
3867 if linerange and pats:
3867 # TODO: take pats as patterns with no line-range filter
3868 # TODO: take pats as patterns with no line-range filter
3868 raise error.Abort(
3869 raise error.Abort(
3869 _('FILE arguments are not compatible with --line-range option')
3870 _('FILE arguments are not compatible with --line-range option')
3870 )
3871 )
3871
3872
3872 repo = scmutil.unhidehashlikerevs(repo, opts.get('rev'), 'nowarn')
3873 repo = scmutil.unhidehashlikerevs(repo, opts.get('rev'), 'nowarn')
3873 revs, differ = logcmdutil.getrevs(repo, pats, opts)
3874 revs, differ = logcmdutil.getrevs(repo, pats, opts)
3874 if linerange:
3875 if linerange:
3875 # TODO: should follow file history from logcmdutil._initialrevs(),
3876 # TODO: should follow file history from logcmdutil._initialrevs(),
3876 # then filter the result by logcmdutil._makerevset() and --limit
3877 # then filter the result by logcmdutil._makerevset() and --limit
3877 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
3878 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
3878
3879
3879 getrenamed = None
3880 getrenamed = None
3880 if opts.get('copies'):
3881 if opts.get('copies'):
3881 endrev = None
3882 endrev = None
3882 if revs:
3883 if revs:
3883 endrev = revs.max() + 1
3884 endrev = revs.max() + 1
3884 getrenamed = scmutil.getrenamedfn(repo, endrev=endrev)
3885 getrenamed = scmutil.getrenamedfn(repo, endrev=endrev)
3885
3886
3886 ui.pager('log')
3887 ui.pager('log')
3887 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, differ,
3888 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, differ,
3888 buffered=True)
3889 buffered=True)
3889 if opts.get('graph'):
3890 if opts.get('graph'):
3890 displayfn = logcmdutil.displaygraphrevs
3891 displayfn = logcmdutil.displaygraphrevs
3891 else:
3892 else:
3892 displayfn = logcmdutil.displayrevs
3893 displayfn = logcmdutil.displayrevs
3893 displayfn(ui, repo, revs, displayer, getrenamed)
3894 displayfn(ui, repo, revs, displayer, getrenamed)
3894
3895
3895 @command('manifest',
3896 @command('manifest',
3896 [('r', 'rev', '', _('revision to display'), _('REV')),
3897 [('r', 'rev', '', _('revision to display'), _('REV')),
3897 ('', 'all', False, _("list files from all revisions"))]
3898 ('', 'all', False, _("list files from all revisions"))]
3898 + formatteropts,
3899 + formatteropts,
3899 _('[-r REV]'),
3900 _('[-r REV]'),
3900 helpcategory=command.CATEGORY_MAINTENANCE,
3901 helpcategory=command.CATEGORY_MAINTENANCE,
3901 intents={INTENT_READONLY})
3902 intents={INTENT_READONLY})
3902 def manifest(ui, repo, node=None, rev=None, **opts):
3903 def manifest(ui, repo, node=None, rev=None, **opts):
3903 """output the current or given revision of the project manifest
3904 """output the current or given revision of the project manifest
3904
3905
3905 Print a list of version controlled files for the given revision.
3906 Print a list of version controlled files for the given revision.
3906 If no revision is given, the first parent of the working directory
3907 If no revision is given, the first parent of the working directory
3907 is used, or the null revision if no revision is checked out.
3908 is used, or the null revision if no revision is checked out.
3908
3909
3909 With -v, print file permissions, symlink and executable bits.
3910 With -v, print file permissions, symlink and executable bits.
3910 With --debug, print file revision hashes.
3911 With --debug, print file revision hashes.
3911
3912
3912 If option --all is specified, the list of all files from all revisions
3913 If option --all is specified, the list of all files from all revisions
3913 is printed. This includes deleted and renamed files.
3914 is printed. This includes deleted and renamed files.
3914
3915
3915 Returns 0 on success.
3916 Returns 0 on success.
3916 """
3917 """
3917 opts = pycompat.byteskwargs(opts)
3918 opts = pycompat.byteskwargs(opts)
3918 fm = ui.formatter('manifest', opts)
3919 fm = ui.formatter('manifest', opts)
3919
3920
3920 if opts.get('all'):
3921 if opts.get('all'):
3921 if rev or node:
3922 if rev or node:
3922 raise error.Abort(_("can't specify a revision with --all"))
3923 raise error.Abort(_("can't specify a revision with --all"))
3923
3924
3924 res = set()
3925 res = set()
3925 for rev in repo:
3926 for rev in repo:
3926 ctx = repo[rev]
3927 ctx = repo[rev]
3927 res |= set(ctx.files())
3928 res |= set(ctx.files())
3928
3929
3929 ui.pager('manifest')
3930 ui.pager('manifest')
3930 for f in sorted(res):
3931 for f in sorted(res):
3931 fm.startitem()
3932 fm.startitem()
3932 fm.write("path", '%s\n', f)
3933 fm.write("path", '%s\n', f)
3933 fm.end()
3934 fm.end()
3934 return
3935 return
3935
3936
3936 if rev and node:
3937 if rev and node:
3937 raise error.Abort(_("please specify just one revision"))
3938 raise error.Abort(_("please specify just one revision"))
3938
3939
3939 if not node:
3940 if not node:
3940 node = rev
3941 node = rev
3941
3942
3942 char = {'l': '@', 'x': '*', '': '', 't': 'd'}
3943 char = {'l': '@', 'x': '*', '': '', 't': 'd'}
3943 mode = {'l': '644', 'x': '755', '': '644', 't': '755'}
3944 mode = {'l': '644', 'x': '755', '': '644', 't': '755'}
3944 if node:
3945 if node:
3945 repo = scmutil.unhidehashlikerevs(repo, [node], 'nowarn')
3946 repo = scmutil.unhidehashlikerevs(repo, [node], 'nowarn')
3946 ctx = scmutil.revsingle(repo, node)
3947 ctx = scmutil.revsingle(repo, node)
3947 mf = ctx.manifest()
3948 mf = ctx.manifest()
3948 ui.pager('manifest')
3949 ui.pager('manifest')
3949 for f in ctx:
3950 for f in ctx:
3950 fm.startitem()
3951 fm.startitem()
3951 fm.context(ctx=ctx)
3952 fm.context(ctx=ctx)
3952 fl = ctx[f].flags()
3953 fl = ctx[f].flags()
3953 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3954 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3954 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3955 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3955 fm.write('path', '%s\n', f)
3956 fm.write('path', '%s\n', f)
3956 fm.end()
3957 fm.end()
3957
3958
3958 @command('merge',
3959 @command('merge',
3959 [('f', 'force', None,
3960 [('f', 'force', None,
3960 _('force a merge including outstanding changes (DEPRECATED)')),
3961 _('force a merge including outstanding changes (DEPRECATED)')),
3961 ('r', 'rev', '', _('revision to merge'), _('REV')),
3962 ('r', 'rev', '', _('revision to merge'), _('REV')),
3962 ('P', 'preview', None,
3963 ('P', 'preview', None,
3963 _('review revisions to merge (no merge is performed)')),
3964 _('review revisions to merge (no merge is performed)')),
3964 ('', 'abort', None, _('abort the ongoing merge')),
3965 ('', 'abort', None, _('abort the ongoing merge')),
3965 ] + mergetoolopts,
3966 ] + mergetoolopts,
3966 _('[-P] [[-r] REV]'),
3967 _('[-P] [[-r] REV]'),
3967 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, helpbasic=True)
3968 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, helpbasic=True)
3968 def merge(ui, repo, node=None, **opts):
3969 def merge(ui, repo, node=None, **opts):
3969 """merge another revision into working directory
3970 """merge another revision into working directory
3970
3971
3971 The current working directory is updated with all changes made in
3972 The current working directory is updated with all changes made in
3972 the requested revision since the last common predecessor revision.
3973 the requested revision since the last common predecessor revision.
3973
3974
3974 Files that changed between either parent are marked as changed for
3975 Files that changed between either parent are marked as changed for
3975 the next commit and a commit must be performed before any further
3976 the next commit and a commit must be performed before any further
3976 updates to the repository are allowed. The next commit will have
3977 updates to the repository are allowed. The next commit will have
3977 two parents.
3978 two parents.
3978
3979
3979 ``--tool`` can be used to specify the merge tool used for file
3980 ``--tool`` can be used to specify the merge tool used for file
3980 merges. It overrides the HGMERGE environment variable and your
3981 merges. It overrides the HGMERGE environment variable and your
3981 configuration files. See :hg:`help merge-tools` for options.
3982 configuration files. See :hg:`help merge-tools` for options.
3982
3983
3983 If no revision is specified, the working directory's parent is a
3984 If no revision is specified, the working directory's parent is a
3984 head revision, and the current branch contains exactly one other
3985 head revision, and the current branch contains exactly one other
3985 head, the other head is merged with by default. Otherwise, an
3986 head, the other head is merged with by default. Otherwise, an
3986 explicit revision with which to merge with must be provided.
3987 explicit revision with which to merge with must be provided.
3987
3988
3988 See :hg:`help resolve` for information on handling file conflicts.
3989 See :hg:`help resolve` for information on handling file conflicts.
3989
3990
3990 To undo an uncommitted merge, use :hg:`merge --abort` which
3991 To undo an uncommitted merge, use :hg:`merge --abort` which
3991 will check out a clean copy of the original merge parent, losing
3992 will check out a clean copy of the original merge parent, losing
3992 all changes.
3993 all changes.
3993
3994
3994 Returns 0 on success, 1 if there are unresolved files.
3995 Returns 0 on success, 1 if there are unresolved files.
3995 """
3996 """
3996
3997
3997 opts = pycompat.byteskwargs(opts)
3998 opts = pycompat.byteskwargs(opts)
3998 abort = opts.get('abort')
3999 abort = opts.get('abort')
3999 if abort and repo.dirstate.p2() == nullid:
4000 if abort and repo.dirstate.p2() == nullid:
4000 cmdutil.wrongtooltocontinue(repo, _('merge'))
4001 cmdutil.wrongtooltocontinue(repo, _('merge'))
4001 if abort:
4002 if abort:
4002 if node:
4003 if node:
4003 raise error.Abort(_("cannot specify a node with --abort"))
4004 raise error.Abort(_("cannot specify a node with --abort"))
4004 if opts.get('rev'):
4005 if opts.get('rev'):
4005 raise error.Abort(_("cannot specify both --rev and --abort"))
4006 raise error.Abort(_("cannot specify both --rev and --abort"))
4006 if opts.get('preview'):
4007 if opts.get('preview'):
4007 raise error.Abort(_("cannot specify --preview with --abort"))
4008 raise error.Abort(_("cannot specify --preview with --abort"))
4008 if opts.get('rev') and node:
4009 if opts.get('rev') and node:
4009 raise error.Abort(_("please specify just one revision"))
4010 raise error.Abort(_("please specify just one revision"))
4010 if not node:
4011 if not node:
4011 node = opts.get('rev')
4012 node = opts.get('rev')
4012
4013
4013 if node:
4014 if node:
4014 node = scmutil.revsingle(repo, node).node()
4015 node = scmutil.revsingle(repo, node).node()
4015
4016
4016 if not node and not abort:
4017 if not node and not abort:
4017 node = repo[destutil.destmerge(repo)].node()
4018 node = repo[destutil.destmerge(repo)].node()
4018
4019
4019 if opts.get('preview'):
4020 if opts.get('preview'):
4020 # find nodes that are ancestors of p2 but not of p1
4021 # find nodes that are ancestors of p2 but not of p1
4021 p1 = repo.lookup('.')
4022 p1 = repo.lookup('.')
4022 p2 = node
4023 p2 = node
4023 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4024 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4024
4025
4025 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4026 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4026 for node in nodes:
4027 for node in nodes:
4027 displayer.show(repo[node])
4028 displayer.show(repo[node])
4028 displayer.close()
4029 displayer.close()
4029 return 0
4030 return 0
4030
4031
4031 # ui.forcemerge is an internal variable, do not document
4032 # ui.forcemerge is an internal variable, do not document
4032 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4033 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4033 with ui.configoverride(overrides, 'merge'):
4034 with ui.configoverride(overrides, 'merge'):
4034 force = opts.get('force')
4035 force = opts.get('force')
4035 labels = ['working copy', 'merge rev']
4036 labels = ['working copy', 'merge rev']
4036 return hg.merge(repo, node, force=force, mergeforce=force,
4037 return hg.merge(repo, node, force=force, mergeforce=force,
4037 labels=labels, abort=abort)
4038 labels=labels, abort=abort)
4038
4039
4039 @command('outgoing|out',
4040 @command('outgoing|out',
4040 [('f', 'force', None, _('run even when the destination is unrelated')),
4041 [('f', 'force', None, _('run even when the destination is unrelated')),
4041 ('r', 'rev', [],
4042 ('r', 'rev', [],
4042 _('a changeset intended to be included in the destination'), _('REV')),
4043 _('a changeset intended to be included in the destination'), _('REV')),
4043 ('n', 'newest-first', None, _('show newest record first')),
4044 ('n', 'newest-first', None, _('show newest record first')),
4044 ('B', 'bookmarks', False, _('compare bookmarks')),
4045 ('B', 'bookmarks', False, _('compare bookmarks')),
4045 ('b', 'branch', [], _('a specific branch you would like to push'),
4046 ('b', 'branch', [], _('a specific branch you would like to push'),
4046 _('BRANCH')),
4047 _('BRANCH')),
4047 ] + logopts + remoteopts + subrepoopts,
4048 ] + logopts + remoteopts + subrepoopts,
4048 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4049 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4049 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
4050 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
4050 def outgoing(ui, repo, dest=None, **opts):
4051 def outgoing(ui, repo, dest=None, **opts):
4051 """show changesets not found in the destination
4052 """show changesets not found in the destination
4052
4053
4053 Show changesets not found in the specified destination repository
4054 Show changesets not found in the specified destination repository
4054 or the default push location. These are the changesets that would
4055 or the default push location. These are the changesets that would
4055 be pushed if a push was requested.
4056 be pushed if a push was requested.
4056
4057
4057 See pull for details of valid destination formats.
4058 See pull for details of valid destination formats.
4058
4059
4059 .. container:: verbose
4060 .. container:: verbose
4060
4061
4061 With -B/--bookmarks, the result of bookmark comparison between
4062 With -B/--bookmarks, the result of bookmark comparison between
4062 local and remote repositories is displayed. With -v/--verbose,
4063 local and remote repositories is displayed. With -v/--verbose,
4063 status is also displayed for each bookmark like below::
4064 status is also displayed for each bookmark like below::
4064
4065
4065 BM1 01234567890a added
4066 BM1 01234567890a added
4066 BM2 deleted
4067 BM2 deleted
4067 BM3 234567890abc advanced
4068 BM3 234567890abc advanced
4068 BM4 34567890abcd diverged
4069 BM4 34567890abcd diverged
4069 BM5 4567890abcde changed
4070 BM5 4567890abcde changed
4070
4071
4071 The action taken when pushing depends on the
4072 The action taken when pushing depends on the
4072 status of each bookmark:
4073 status of each bookmark:
4073
4074
4074 :``added``: push with ``-B`` will create it
4075 :``added``: push with ``-B`` will create it
4075 :``deleted``: push with ``-B`` will delete it
4076 :``deleted``: push with ``-B`` will delete it
4076 :``advanced``: push will update it
4077 :``advanced``: push will update it
4077 :``diverged``: push with ``-B`` will update it
4078 :``diverged``: push with ``-B`` will update it
4078 :``changed``: push with ``-B`` will update it
4079 :``changed``: push with ``-B`` will update it
4079
4080
4080 From the point of view of pushing behavior, bookmarks
4081 From the point of view of pushing behavior, bookmarks
4081 existing only in the remote repository are treated as
4082 existing only in the remote repository are treated as
4082 ``deleted``, even if it is in fact added remotely.
4083 ``deleted``, even if it is in fact added remotely.
4083
4084
4084 Returns 0 if there are outgoing changes, 1 otherwise.
4085 Returns 0 if there are outgoing changes, 1 otherwise.
4085 """
4086 """
4086 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4087 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4087 # style URLs, so don't overwrite dest.
4088 # style URLs, so don't overwrite dest.
4088 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4089 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4089 if not path:
4090 if not path:
4090 raise error.Abort(_('default repository not configured!'),
4091 raise error.Abort(_('default repository not configured!'),
4091 hint=_("see 'hg help config.paths'"))
4092 hint=_("see 'hg help config.paths'"))
4092
4093
4093 opts = pycompat.byteskwargs(opts)
4094 opts = pycompat.byteskwargs(opts)
4094 if opts.get('graph'):
4095 if opts.get('graph'):
4095 logcmdutil.checkunsupportedgraphflags([], opts)
4096 logcmdutil.checkunsupportedgraphflags([], opts)
4096 o, other = hg._outgoing(ui, repo, dest, opts)
4097 o, other = hg._outgoing(ui, repo, dest, opts)
4097 if not o:
4098 if not o:
4098 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4099 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4099 return
4100 return
4100
4101
4101 revdag = logcmdutil.graphrevs(repo, o, opts)
4102 revdag = logcmdutil.graphrevs(repo, o, opts)
4102 ui.pager('outgoing')
4103 ui.pager('outgoing')
4103 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4104 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4104 logcmdutil.displaygraph(ui, repo, revdag, displayer,
4105 logcmdutil.displaygraph(ui, repo, revdag, displayer,
4105 graphmod.asciiedges)
4106 graphmod.asciiedges)
4106 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4107 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4107 return 0
4108 return 0
4108
4109
4109 if opts.get('bookmarks'):
4110 if opts.get('bookmarks'):
4110 dest = path.pushloc or path.loc
4111 dest = path.pushloc or path.loc
4111 other = hg.peer(repo, opts, dest)
4112 other = hg.peer(repo, opts, dest)
4112 if 'bookmarks' not in other.listkeys('namespaces'):
4113 if 'bookmarks' not in other.listkeys('namespaces'):
4113 ui.warn(_("remote doesn't support bookmarks\n"))
4114 ui.warn(_("remote doesn't support bookmarks\n"))
4114 return 0
4115 return 0
4115 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4116 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4116 ui.pager('outgoing')
4117 ui.pager('outgoing')
4117 return bookmarks.outgoing(ui, repo, other)
4118 return bookmarks.outgoing(ui, repo, other)
4118
4119
4119 repo._subtoppath = path.pushloc or path.loc
4120 repo._subtoppath = path.pushloc or path.loc
4120 try:
4121 try:
4121 return hg.outgoing(ui, repo, dest, opts)
4122 return hg.outgoing(ui, repo, dest, opts)
4122 finally:
4123 finally:
4123 del repo._subtoppath
4124 del repo._subtoppath
4124
4125
4125 @command('parents',
4126 @command('parents',
4126 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4127 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4127 ] + templateopts,
4128 ] + templateopts,
4128 _('[-r REV] [FILE]'),
4129 _('[-r REV] [FILE]'),
4129 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4130 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4130 inferrepo=True)
4131 inferrepo=True)
4131 def parents(ui, repo, file_=None, **opts):
4132 def parents(ui, repo, file_=None, **opts):
4132 """show the parents of the working directory or revision (DEPRECATED)
4133 """show the parents of the working directory or revision (DEPRECATED)
4133
4134
4134 Print the working directory's parent revisions. If a revision is
4135 Print the working directory's parent revisions. If a revision is
4135 given via -r/--rev, the parent of that revision will be printed.
4136 given via -r/--rev, the parent of that revision will be printed.
4136 If a file argument is given, the revision in which the file was
4137 If a file argument is given, the revision in which the file was
4137 last changed (before the working directory revision or the
4138 last changed (before the working directory revision or the
4138 argument to --rev if given) is printed.
4139 argument to --rev if given) is printed.
4139
4140
4140 This command is equivalent to::
4141 This command is equivalent to::
4141
4142
4142 hg log -r "p1()+p2()" or
4143 hg log -r "p1()+p2()" or
4143 hg log -r "p1(REV)+p2(REV)" or
4144 hg log -r "p1(REV)+p2(REV)" or
4144 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
4145 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
4145 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
4146 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
4146
4147
4147 See :hg:`summary` and :hg:`help revsets` for related information.
4148 See :hg:`summary` and :hg:`help revsets` for related information.
4148
4149
4149 Returns 0 on success.
4150 Returns 0 on success.
4150 """
4151 """
4151
4152
4152 opts = pycompat.byteskwargs(opts)
4153 opts = pycompat.byteskwargs(opts)
4153 rev = opts.get('rev')
4154 rev = opts.get('rev')
4154 if rev:
4155 if rev:
4155 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
4156 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
4156 ctx = scmutil.revsingle(repo, rev, None)
4157 ctx = scmutil.revsingle(repo, rev, None)
4157
4158
4158 if file_:
4159 if file_:
4159 m = scmutil.match(ctx, (file_,), opts)
4160 m = scmutil.match(ctx, (file_,), opts)
4160 if m.anypats() or len(m.files()) != 1:
4161 if m.anypats() or len(m.files()) != 1:
4161 raise error.Abort(_('can only specify an explicit filename'))
4162 raise error.Abort(_('can only specify an explicit filename'))
4162 file_ = m.files()[0]
4163 file_ = m.files()[0]
4163 filenodes = []
4164 filenodes = []
4164 for cp in ctx.parents():
4165 for cp in ctx.parents():
4165 if not cp:
4166 if not cp:
4166 continue
4167 continue
4167 try:
4168 try:
4168 filenodes.append(cp.filenode(file_))
4169 filenodes.append(cp.filenode(file_))
4169 except error.LookupError:
4170 except error.LookupError:
4170 pass
4171 pass
4171 if not filenodes:
4172 if not filenodes:
4172 raise error.Abort(_("'%s' not found in manifest!") % file_)
4173 raise error.Abort(_("'%s' not found in manifest!") % file_)
4173 p = []
4174 p = []
4174 for fn in filenodes:
4175 for fn in filenodes:
4175 fctx = repo.filectx(file_, fileid=fn)
4176 fctx = repo.filectx(file_, fileid=fn)
4176 p.append(fctx.node())
4177 p.append(fctx.node())
4177 else:
4178 else:
4178 p = [cp.node() for cp in ctx.parents()]
4179 p = [cp.node() for cp in ctx.parents()]
4179
4180
4180 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4181 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4181 for n in p:
4182 for n in p:
4182 if n != nullid:
4183 if n != nullid:
4183 displayer.show(repo[n])
4184 displayer.show(repo[n])
4184 displayer.close()
4185 displayer.close()
4185
4186
4186 @command('paths', formatteropts, _('[NAME]'),
4187 @command('paths', formatteropts, _('[NAME]'),
4187 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4188 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4188 optionalrepo=True, intents={INTENT_READONLY})
4189 optionalrepo=True, intents={INTENT_READONLY})
4189 def paths(ui, repo, search=None, **opts):
4190 def paths(ui, repo, search=None, **opts):
4190 """show aliases for remote repositories
4191 """show aliases for remote repositories
4191
4192
4192 Show definition of symbolic path name NAME. If no name is given,
4193 Show definition of symbolic path name NAME. If no name is given,
4193 show definition of all available names.
4194 show definition of all available names.
4194
4195
4195 Option -q/--quiet suppresses all output when searching for NAME
4196 Option -q/--quiet suppresses all output when searching for NAME
4196 and shows only the path names when listing all definitions.
4197 and shows only the path names when listing all definitions.
4197
4198
4198 Path names are defined in the [paths] section of your
4199 Path names are defined in the [paths] section of your
4199 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4200 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4200 repository, ``.hg/hgrc`` is used, too.
4201 repository, ``.hg/hgrc`` is used, too.
4201
4202
4202 The path names ``default`` and ``default-push`` have a special
4203 The path names ``default`` and ``default-push`` have a special
4203 meaning. When performing a push or pull operation, they are used
4204 meaning. When performing a push or pull operation, they are used
4204 as fallbacks if no location is specified on the command-line.
4205 as fallbacks if no location is specified on the command-line.
4205 When ``default-push`` is set, it will be used for push and
4206 When ``default-push`` is set, it will be used for push and
4206 ``default`` will be used for pull; otherwise ``default`` is used
4207 ``default`` will be used for pull; otherwise ``default`` is used
4207 as the fallback for both. When cloning a repository, the clone
4208 as the fallback for both. When cloning a repository, the clone
4208 source is written as ``default`` in ``.hg/hgrc``.
4209 source is written as ``default`` in ``.hg/hgrc``.
4209
4210
4210 .. note::
4211 .. note::
4211
4212
4212 ``default`` and ``default-push`` apply to all inbound (e.g.
4213 ``default`` and ``default-push`` apply to all inbound (e.g.
4213 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
4214 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
4214 and :hg:`bundle`) operations.
4215 and :hg:`bundle`) operations.
4215
4216
4216 See :hg:`help urls` for more information.
4217 See :hg:`help urls` for more information.
4217
4218
4218 .. container:: verbose
4219 .. container:: verbose
4219
4220
4220 Template:
4221 Template:
4221
4222
4222 The following keywords are supported. See also :hg:`help templates`.
4223 The following keywords are supported. See also :hg:`help templates`.
4223
4224
4224 :name: String. Symbolic name of the path alias.
4225 :name: String. Symbolic name of the path alias.
4225 :pushurl: String. URL for push operations.
4226 :pushurl: String. URL for push operations.
4226 :url: String. URL or directory path for the other operations.
4227 :url: String. URL or directory path for the other operations.
4227
4228
4228 Returns 0 on success.
4229 Returns 0 on success.
4229 """
4230 """
4230
4231
4231 opts = pycompat.byteskwargs(opts)
4232 opts = pycompat.byteskwargs(opts)
4232 ui.pager('paths')
4233 ui.pager('paths')
4233 if search:
4234 if search:
4234 pathitems = [(name, path) for name, path in ui.paths.iteritems()
4235 pathitems = [(name, path) for name, path in ui.paths.iteritems()
4235 if name == search]
4236 if name == search]
4236 else:
4237 else:
4237 pathitems = sorted(ui.paths.iteritems())
4238 pathitems = sorted(ui.paths.iteritems())
4238
4239
4239 fm = ui.formatter('paths', opts)
4240 fm = ui.formatter('paths', opts)
4240 if fm.isplain():
4241 if fm.isplain():
4241 hidepassword = util.hidepassword
4242 hidepassword = util.hidepassword
4242 else:
4243 else:
4243 hidepassword = bytes
4244 hidepassword = bytes
4244 if ui.quiet:
4245 if ui.quiet:
4245 namefmt = '%s\n'
4246 namefmt = '%s\n'
4246 else:
4247 else:
4247 namefmt = '%s = '
4248 namefmt = '%s = '
4248 showsubopts = not search and not ui.quiet
4249 showsubopts = not search and not ui.quiet
4249
4250
4250 for name, path in pathitems:
4251 for name, path in pathitems:
4251 fm.startitem()
4252 fm.startitem()
4252 fm.condwrite(not search, 'name', namefmt, name)
4253 fm.condwrite(not search, 'name', namefmt, name)
4253 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
4254 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
4254 for subopt, value in sorted(path.suboptions.items()):
4255 for subopt, value in sorted(path.suboptions.items()):
4255 assert subopt not in ('name', 'url')
4256 assert subopt not in ('name', 'url')
4256 if showsubopts:
4257 if showsubopts:
4257 fm.plain('%s:%s = ' % (name, subopt))
4258 fm.plain('%s:%s = ' % (name, subopt))
4258 fm.condwrite(showsubopts, subopt, '%s\n', value)
4259 fm.condwrite(showsubopts, subopt, '%s\n', value)
4259
4260
4260 fm.end()
4261 fm.end()
4261
4262
4262 if search and not pathitems:
4263 if search and not pathitems:
4263 if not ui.quiet:
4264 if not ui.quiet:
4264 ui.warn(_("not found!\n"))
4265 ui.warn(_("not found!\n"))
4265 return 1
4266 return 1
4266 else:
4267 else:
4267 return 0
4268 return 0
4268
4269
4269 @command('phase',
4270 @command('phase',
4270 [('p', 'public', False, _('set changeset phase to public')),
4271 [('p', 'public', False, _('set changeset phase to public')),
4271 ('d', 'draft', False, _('set changeset phase to draft')),
4272 ('d', 'draft', False, _('set changeset phase to draft')),
4272 ('s', 'secret', False, _('set changeset phase to secret')),
4273 ('s', 'secret', False, _('set changeset phase to secret')),
4273 ('f', 'force', False, _('allow to move boundary backward')),
4274 ('f', 'force', False, _('allow to move boundary backward')),
4274 ('r', 'rev', [], _('target revision'), _('REV')),
4275 ('r', 'rev', [], _('target revision'), _('REV')),
4275 ],
4276 ],
4276 _('[-p|-d|-s] [-f] [-r] [REV...]'),
4277 _('[-p|-d|-s] [-f] [-r] [REV...]'),
4277 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
4278 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
4278 def phase(ui, repo, *revs, **opts):
4279 def phase(ui, repo, *revs, **opts):
4279 """set or show the current phase name
4280 """set or show the current phase name
4280
4281
4281 With no argument, show the phase name of the current revision(s).
4282 With no argument, show the phase name of the current revision(s).
4282
4283
4283 With one of -p/--public, -d/--draft or -s/--secret, change the
4284 With one of -p/--public, -d/--draft or -s/--secret, change the
4284 phase value of the specified revisions.
4285 phase value of the specified revisions.
4285
4286
4286 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
4287 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
4287 lower phase to a higher phase. Phases are ordered as follows::
4288 lower phase to a higher phase. Phases are ordered as follows::
4288
4289
4289 public < draft < secret
4290 public < draft < secret
4290
4291
4291 Returns 0 on success, 1 if some phases could not be changed.
4292 Returns 0 on success, 1 if some phases could not be changed.
4292
4293
4293 (For more information about the phases concept, see :hg:`help phases`.)
4294 (For more information about the phases concept, see :hg:`help phases`.)
4294 """
4295 """
4295 opts = pycompat.byteskwargs(opts)
4296 opts = pycompat.byteskwargs(opts)
4296 # search for a unique phase argument
4297 # search for a unique phase argument
4297 targetphase = None
4298 targetphase = None
4298 for idx, name in enumerate(phases.cmdphasenames):
4299 for idx, name in enumerate(phases.cmdphasenames):
4299 if opts[name]:
4300 if opts[name]:
4300 if targetphase is not None:
4301 if targetphase is not None:
4301 raise error.Abort(_('only one phase can be specified'))
4302 raise error.Abort(_('only one phase can be specified'))
4302 targetphase = idx
4303 targetphase = idx
4303
4304
4304 # look for specified revision
4305 # look for specified revision
4305 revs = list(revs)
4306 revs = list(revs)
4306 revs.extend(opts['rev'])
4307 revs.extend(opts['rev'])
4307 if not revs:
4308 if not revs:
4308 # display both parents as the second parent phase can influence
4309 # display both parents as the second parent phase can influence
4309 # the phase of a merge commit
4310 # the phase of a merge commit
4310 revs = [c.rev() for c in repo[None].parents()]
4311 revs = [c.rev() for c in repo[None].parents()]
4311
4312
4312 revs = scmutil.revrange(repo, revs)
4313 revs = scmutil.revrange(repo, revs)
4313
4314
4314 ret = 0
4315 ret = 0
4315 if targetphase is None:
4316 if targetphase is None:
4316 # display
4317 # display
4317 for r in revs:
4318 for r in revs:
4318 ctx = repo[r]
4319 ctx = repo[r]
4319 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4320 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4320 else:
4321 else:
4321 with repo.lock(), repo.transaction("phase") as tr:
4322 with repo.lock(), repo.transaction("phase") as tr:
4322 # set phase
4323 # set phase
4323 if not revs:
4324 if not revs:
4324 raise error.Abort(_('empty revision set'))
4325 raise error.Abort(_('empty revision set'))
4325 nodes = [repo[r].node() for r in revs]
4326 nodes = [repo[r].node() for r in revs]
4326 # moving revision from public to draft may hide them
4327 # moving revision from public to draft may hide them
4327 # We have to check result on an unfiltered repository
4328 # We have to check result on an unfiltered repository
4328 unfi = repo.unfiltered()
4329 unfi = repo.unfiltered()
4329 getphase = unfi._phasecache.phase
4330 getphase = unfi._phasecache.phase
4330 olddata = [getphase(unfi, r) for r in unfi]
4331 olddata = [getphase(unfi, r) for r in unfi]
4331 phases.advanceboundary(repo, tr, targetphase, nodes)
4332 phases.advanceboundary(repo, tr, targetphase, nodes)
4332 if opts['force']:
4333 if opts['force']:
4333 phases.retractboundary(repo, tr, targetphase, nodes)
4334 phases.retractboundary(repo, tr, targetphase, nodes)
4334 getphase = unfi._phasecache.phase
4335 getphase = unfi._phasecache.phase
4335 newdata = [getphase(unfi, r) for r in unfi]
4336 newdata = [getphase(unfi, r) for r in unfi]
4336 changes = sum(newdata[r] != olddata[r] for r in unfi)
4337 changes = sum(newdata[r] != olddata[r] for r in unfi)
4337 cl = unfi.changelog
4338 cl = unfi.changelog
4338 rejected = [n for n in nodes
4339 rejected = [n for n in nodes
4339 if newdata[cl.rev(n)] < targetphase]
4340 if newdata[cl.rev(n)] < targetphase]
4340 if rejected:
4341 if rejected:
4341 ui.warn(_('cannot move %i changesets to a higher '
4342 ui.warn(_('cannot move %i changesets to a higher '
4342 'phase, use --force\n') % len(rejected))
4343 'phase, use --force\n') % len(rejected))
4343 ret = 1
4344 ret = 1
4344 if changes:
4345 if changes:
4345 msg = _('phase changed for %i changesets\n') % changes
4346 msg = _('phase changed for %i changesets\n') % changes
4346 if ret:
4347 if ret:
4347 ui.status(msg)
4348 ui.status(msg)
4348 else:
4349 else:
4349 ui.note(msg)
4350 ui.note(msg)
4350 else:
4351 else:
4351 ui.warn(_('no phases changed\n'))
4352 ui.warn(_('no phases changed\n'))
4352 return ret
4353 return ret
4353
4354
4354 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
4355 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
4355 """Run after a changegroup has been added via pull/unbundle
4356 """Run after a changegroup has been added via pull/unbundle
4356
4357
4357 This takes arguments below:
4358 This takes arguments below:
4358
4359
4359 :modheads: change of heads by pull/unbundle
4360 :modheads: change of heads by pull/unbundle
4360 :optupdate: updating working directory is needed or not
4361 :optupdate: updating working directory is needed or not
4361 :checkout: update destination revision (or None to default destination)
4362 :checkout: update destination revision (or None to default destination)
4362 :brev: a name, which might be a bookmark to be activated after updating
4363 :brev: a name, which might be a bookmark to be activated after updating
4363 """
4364 """
4364 if modheads == 0:
4365 if modheads == 0:
4365 return
4366 return
4366 if optupdate:
4367 if optupdate:
4367 try:
4368 try:
4368 return hg.updatetotally(ui, repo, checkout, brev)
4369 return hg.updatetotally(ui, repo, checkout, brev)
4369 except error.UpdateAbort as inst:
4370 except error.UpdateAbort as inst:
4370 msg = _("not updating: %s") % stringutil.forcebytestr(inst)
4371 msg = _("not updating: %s") % stringutil.forcebytestr(inst)
4371 hint = inst.hint
4372 hint = inst.hint
4372 raise error.UpdateAbort(msg, hint=hint)
4373 raise error.UpdateAbort(msg, hint=hint)
4373 if modheads is not None and modheads > 1:
4374 if modheads is not None and modheads > 1:
4374 currentbranchheads = len(repo.branchheads())
4375 currentbranchheads = len(repo.branchheads())
4375 if currentbranchheads == modheads:
4376 if currentbranchheads == modheads:
4376 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4377 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4377 elif currentbranchheads > 1:
4378 elif currentbranchheads > 1:
4378 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4379 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4379 "merge)\n"))
4380 "merge)\n"))
4380 else:
4381 else:
4381 ui.status(_("(run 'hg heads' to see heads)\n"))
4382 ui.status(_("(run 'hg heads' to see heads)\n"))
4382 elif not ui.configbool('commands', 'update.requiredest'):
4383 elif not ui.configbool('commands', 'update.requiredest'):
4383 ui.status(_("(run 'hg update' to get a working copy)\n"))
4384 ui.status(_("(run 'hg update' to get a working copy)\n"))
4384
4385
4385 @command('pull',
4386 @command('pull',
4386 [('u', 'update', None,
4387 [('u', 'update', None,
4387 _('update to new branch head if new descendants were pulled')),
4388 _('update to new branch head if new descendants were pulled')),
4388 ('f', 'force', None, _('run even when remote repository is unrelated')),
4389 ('f', 'force', None, _('run even when remote repository is unrelated')),
4389 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4390 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4390 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4391 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4391 ('b', 'branch', [], _('a specific branch you would like to pull'),
4392 ('b', 'branch', [], _('a specific branch you would like to pull'),
4392 _('BRANCH')),
4393 _('BRANCH')),
4393 ] + remoteopts,
4394 ] + remoteopts,
4394 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
4395 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
4395 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4396 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4396 helpbasic=True)
4397 helpbasic=True)
4397 def pull(ui, repo, source="default", **opts):
4398 def pull(ui, repo, source="default", **opts):
4398 """pull changes from the specified source
4399 """pull changes from the specified source
4399
4400
4400 Pull changes from a remote repository to a local one.
4401 Pull changes from a remote repository to a local one.
4401
4402
4402 This finds all changes from the repository at the specified path
4403 This finds all changes from the repository at the specified path
4403 or URL and adds them to a local repository (the current one unless
4404 or URL and adds them to a local repository (the current one unless
4404 -R is specified). By default, this does not update the copy of the
4405 -R is specified). By default, this does not update the copy of the
4405 project in the working directory.
4406 project in the working directory.
4406
4407
4407 When cloning from servers that support it, Mercurial may fetch
4408 When cloning from servers that support it, Mercurial may fetch
4408 pre-generated data. When this is done, hooks operating on incoming
4409 pre-generated data. When this is done, hooks operating on incoming
4409 changesets and changegroups may fire more than once, once for each
4410 changesets and changegroups may fire more than once, once for each
4410 pre-generated bundle and as well as for any additional remaining
4411 pre-generated bundle and as well as for any additional remaining
4411 data. See :hg:`help -e clonebundles` for more.
4412 data. See :hg:`help -e clonebundles` for more.
4412
4413
4413 Use :hg:`incoming` if you want to see what would have been added
4414 Use :hg:`incoming` if you want to see what would have been added
4414 by a pull at the time you issued this command. If you then decide
4415 by a pull at the time you issued this command. If you then decide
4415 to add those changes to the repository, you should use :hg:`pull
4416 to add those changes to the repository, you should use :hg:`pull
4416 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4417 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4417
4418
4418 If SOURCE is omitted, the 'default' path will be used.
4419 If SOURCE is omitted, the 'default' path will be used.
4419 See :hg:`help urls` for more information.
4420 See :hg:`help urls` for more information.
4420
4421
4421 Specifying bookmark as ``.`` is equivalent to specifying the active
4422 Specifying bookmark as ``.`` is equivalent to specifying the active
4422 bookmark's name.
4423 bookmark's name.
4423
4424
4424 Returns 0 on success, 1 if an update had unresolved files.
4425 Returns 0 on success, 1 if an update had unresolved files.
4425 """
4426 """
4426
4427
4427 opts = pycompat.byteskwargs(opts)
4428 opts = pycompat.byteskwargs(opts)
4428 if ui.configbool('commands', 'update.requiredest') and opts.get('update'):
4429 if ui.configbool('commands', 'update.requiredest') and opts.get('update'):
4429 msg = _('update destination required by configuration')
4430 msg = _('update destination required by configuration')
4430 hint = _('use hg pull followed by hg update DEST')
4431 hint = _('use hg pull followed by hg update DEST')
4431 raise error.Abort(msg, hint=hint)
4432 raise error.Abort(msg, hint=hint)
4432
4433
4433 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4434 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4434 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4435 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4435 other = hg.peer(repo, opts, source)
4436 other = hg.peer(repo, opts, source)
4436 try:
4437 try:
4437 revs, checkout = hg.addbranchrevs(repo, other, branches,
4438 revs, checkout = hg.addbranchrevs(repo, other, branches,
4438 opts.get('rev'))
4439 opts.get('rev'))
4439
4440
4440 pullopargs = {}
4441 pullopargs = {}
4441
4442
4442 nodes = None
4443 nodes = None
4443 if opts.get('bookmark') or revs:
4444 if opts.get('bookmark') or revs:
4444 # The list of bookmark used here is the same used to actually update
4445 # The list of bookmark used here is the same used to actually update
4445 # the bookmark names, to avoid the race from issue 4689 and we do
4446 # the bookmark names, to avoid the race from issue 4689 and we do
4446 # all lookup and bookmark queries in one go so they see the same
4447 # all lookup and bookmark queries in one go so they see the same
4447 # version of the server state (issue 4700).
4448 # version of the server state (issue 4700).
4448 nodes = []
4449 nodes = []
4449 fnodes = []
4450 fnodes = []
4450 revs = revs or []
4451 revs = revs or []
4451 if revs and not other.capable('lookup'):
4452 if revs and not other.capable('lookup'):
4452 err = _("other repository doesn't support revision lookup, "
4453 err = _("other repository doesn't support revision lookup, "
4453 "so a rev cannot be specified.")
4454 "so a rev cannot be specified.")
4454 raise error.Abort(err)
4455 raise error.Abort(err)
4455 with other.commandexecutor() as e:
4456 with other.commandexecutor() as e:
4456 fremotebookmarks = e.callcommand('listkeys', {
4457 fremotebookmarks = e.callcommand('listkeys', {
4457 'namespace': 'bookmarks'
4458 'namespace': 'bookmarks'
4458 })
4459 })
4459 for r in revs:
4460 for r in revs:
4460 fnodes.append(e.callcommand('lookup', {'key': r}))
4461 fnodes.append(e.callcommand('lookup', {'key': r}))
4461 remotebookmarks = fremotebookmarks.result()
4462 remotebookmarks = fremotebookmarks.result()
4462 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
4463 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
4463 pullopargs['remotebookmarks'] = remotebookmarks
4464 pullopargs['remotebookmarks'] = remotebookmarks
4464 for b in opts.get('bookmark', []):
4465 for b in opts.get('bookmark', []):
4465 b = repo._bookmarks.expandname(b)
4466 b = repo._bookmarks.expandname(b)
4466 if b not in remotebookmarks:
4467 if b not in remotebookmarks:
4467 raise error.Abort(_('remote bookmark %s not found!') % b)
4468 raise error.Abort(_('remote bookmark %s not found!') % b)
4468 nodes.append(remotebookmarks[b])
4469 nodes.append(remotebookmarks[b])
4469 for i, rev in enumerate(revs):
4470 for i, rev in enumerate(revs):
4470 node = fnodes[i].result()
4471 node = fnodes[i].result()
4471 nodes.append(node)
4472 nodes.append(node)
4472 if rev == checkout:
4473 if rev == checkout:
4473 checkout = node
4474 checkout = node
4474
4475
4475 wlock = util.nullcontextmanager()
4476 wlock = util.nullcontextmanager()
4476 if opts.get('update'):
4477 if opts.get('update'):
4477 wlock = repo.wlock()
4478 wlock = repo.wlock()
4478 with wlock:
4479 with wlock:
4479 pullopargs.update(opts.get('opargs', {}))
4480 pullopargs.update(opts.get('opargs', {}))
4480 modheads = exchange.pull(repo, other, heads=nodes,
4481 modheads = exchange.pull(repo, other, heads=nodes,
4481 force=opts.get('force'),
4482 force=opts.get('force'),
4482 bookmarks=opts.get('bookmark', ()),
4483 bookmarks=opts.get('bookmark', ()),
4483 opargs=pullopargs).cgresult
4484 opargs=pullopargs).cgresult
4484
4485
4485 # brev is a name, which might be a bookmark to be activated at
4486 # brev is a name, which might be a bookmark to be activated at
4486 # the end of the update. In other words, it is an explicit
4487 # the end of the update. In other words, it is an explicit
4487 # destination of the update
4488 # destination of the update
4488 brev = None
4489 brev = None
4489
4490
4490 if checkout:
4491 if checkout:
4491 checkout = repo.unfiltered().changelog.rev(checkout)
4492 checkout = repo.unfiltered().changelog.rev(checkout)
4492
4493
4493 # order below depends on implementation of
4494 # order below depends on implementation of
4494 # hg.addbranchrevs(). opts['bookmark'] is ignored,
4495 # hg.addbranchrevs(). opts['bookmark'] is ignored,
4495 # because 'checkout' is determined without it.
4496 # because 'checkout' is determined without it.
4496 if opts.get('rev'):
4497 if opts.get('rev'):
4497 brev = opts['rev'][0]
4498 brev = opts['rev'][0]
4498 elif opts.get('branch'):
4499 elif opts.get('branch'):
4499 brev = opts['branch'][0]
4500 brev = opts['branch'][0]
4500 else:
4501 else:
4501 brev = branches[0]
4502 brev = branches[0]
4502 repo._subtoppath = source
4503 repo._subtoppath = source
4503 try:
4504 try:
4504 ret = postincoming(ui, repo, modheads, opts.get('update'),
4505 ret = postincoming(ui, repo, modheads, opts.get('update'),
4505 checkout, brev)
4506 checkout, brev)
4506 except error.FilteredRepoLookupError as exc:
4507 except error.FilteredRepoLookupError as exc:
4507 msg = _('cannot update to target: %s') % exc.args[0]
4508 msg = _('cannot update to target: %s') % exc.args[0]
4508 exc.args = (msg,) + exc.args[1:]
4509 exc.args = (msg,) + exc.args[1:]
4509 raise
4510 raise
4510 finally:
4511 finally:
4511 del repo._subtoppath
4512 del repo._subtoppath
4512
4513
4513 finally:
4514 finally:
4514 other.close()
4515 other.close()
4515 return ret
4516 return ret
4516
4517
4517 @command('push',
4518 @command('push',
4518 [('f', 'force', None, _('force push')),
4519 [('f', 'force', None, _('force push')),
4519 ('r', 'rev', [],
4520 ('r', 'rev', [],
4520 _('a changeset intended to be included in the destination'),
4521 _('a changeset intended to be included in the destination'),
4521 _('REV')),
4522 _('REV')),
4522 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4523 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4523 ('b', 'branch', [],
4524 ('b', 'branch', [],
4524 _('a specific branch you would like to push'), _('BRANCH')),
4525 _('a specific branch you would like to push'), _('BRANCH')),
4525 ('', 'new-branch', False, _('allow pushing a new branch')),
4526 ('', 'new-branch', False, _('allow pushing a new branch')),
4526 ('', 'pushvars', [], _('variables that can be sent to server (ADVANCED)')),
4527 ('', 'pushvars', [], _('variables that can be sent to server (ADVANCED)')),
4527 ('', 'publish', False, _('push the changeset as public (EXPERIMENTAL)')),
4528 ('', 'publish', False, _('push the changeset as public (EXPERIMENTAL)')),
4528 ] + remoteopts,
4529 ] + remoteopts,
4529 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
4530 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
4530 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4531 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4531 helpbasic=True)
4532 helpbasic=True)
4532 def push(ui, repo, dest=None, **opts):
4533 def push(ui, repo, dest=None, **opts):
4533 """push changes to the specified destination
4534 """push changes to the specified destination
4534
4535
4535 Push changesets from the local repository to the specified
4536 Push changesets from the local repository to the specified
4536 destination.
4537 destination.
4537
4538
4538 This operation is symmetrical to pull: it is identical to a pull
4539 This operation is symmetrical to pull: it is identical to a pull
4539 in the destination repository from the current one.
4540 in the destination repository from the current one.
4540
4541
4541 By default, push will not allow creation of new heads at the
4542 By default, push will not allow creation of new heads at the
4542 destination, since multiple heads would make it unclear which head
4543 destination, since multiple heads would make it unclear which head
4543 to use. In this situation, it is recommended to pull and merge
4544 to use. In this situation, it is recommended to pull and merge
4544 before pushing.
4545 before pushing.
4545
4546
4546 Use --new-branch if you want to allow push to create a new named
4547 Use --new-branch if you want to allow push to create a new named
4547 branch that is not present at the destination. This allows you to
4548 branch that is not present at the destination. This allows you to
4548 only create a new branch without forcing other changes.
4549 only create a new branch without forcing other changes.
4549
4550
4550 .. note::
4551 .. note::
4551
4552
4552 Extra care should be taken with the -f/--force option,
4553 Extra care should be taken with the -f/--force option,
4553 which will push all new heads on all branches, an action which will
4554 which will push all new heads on all branches, an action which will
4554 almost always cause confusion for collaborators.
4555 almost always cause confusion for collaborators.
4555
4556
4556 If -r/--rev is used, the specified revision and all its ancestors
4557 If -r/--rev is used, the specified revision and all its ancestors
4557 will be pushed to the remote repository.
4558 will be pushed to the remote repository.
4558
4559
4559 If -B/--bookmark is used, the specified bookmarked revision, its
4560 If -B/--bookmark is used, the specified bookmarked revision, its
4560 ancestors, and the bookmark will be pushed to the remote
4561 ancestors, and the bookmark will be pushed to the remote
4561 repository. Specifying ``.`` is equivalent to specifying the active
4562 repository. Specifying ``.`` is equivalent to specifying the active
4562 bookmark's name.
4563 bookmark's name.
4563
4564
4564 Please see :hg:`help urls` for important details about ``ssh://``
4565 Please see :hg:`help urls` for important details about ``ssh://``
4565 URLs. If DESTINATION is omitted, a default path will be used.
4566 URLs. If DESTINATION is omitted, a default path will be used.
4566
4567
4567 .. container:: verbose
4568 .. container:: verbose
4568
4569
4569 The --pushvars option sends strings to the server that become
4570 The --pushvars option sends strings to the server that become
4570 environment variables prepended with ``HG_USERVAR_``. For example,
4571 environment variables prepended with ``HG_USERVAR_``. For example,
4571 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
4572 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
4572 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
4573 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
4573
4574
4574 pushvars can provide for user-overridable hooks as well as set debug
4575 pushvars can provide for user-overridable hooks as well as set debug
4575 levels. One example is having a hook that blocks commits containing
4576 levels. One example is having a hook that blocks commits containing
4576 conflict markers, but enables the user to override the hook if the file
4577 conflict markers, but enables the user to override the hook if the file
4577 is using conflict markers for testing purposes or the file format has
4578 is using conflict markers for testing purposes or the file format has
4578 strings that look like conflict markers.
4579 strings that look like conflict markers.
4579
4580
4580 By default, servers will ignore `--pushvars`. To enable it add the
4581 By default, servers will ignore `--pushvars`. To enable it add the
4581 following to your configuration file::
4582 following to your configuration file::
4582
4583
4583 [push]
4584 [push]
4584 pushvars.server = true
4585 pushvars.server = true
4585
4586
4586 Returns 0 if push was successful, 1 if nothing to push.
4587 Returns 0 if push was successful, 1 if nothing to push.
4587 """
4588 """
4588
4589
4589 opts = pycompat.byteskwargs(opts)
4590 opts = pycompat.byteskwargs(opts)
4590 if opts.get('bookmark'):
4591 if opts.get('bookmark'):
4591 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4592 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4592 for b in opts['bookmark']:
4593 for b in opts['bookmark']:
4593 # translate -B options to -r so changesets get pushed
4594 # translate -B options to -r so changesets get pushed
4594 b = repo._bookmarks.expandname(b)
4595 b = repo._bookmarks.expandname(b)
4595 if b in repo._bookmarks:
4596 if b in repo._bookmarks:
4596 opts.setdefault('rev', []).append(b)
4597 opts.setdefault('rev', []).append(b)
4597 else:
4598 else:
4598 # if we try to push a deleted bookmark, translate it to null
4599 # if we try to push a deleted bookmark, translate it to null
4599 # this lets simultaneous -r, -b options continue working
4600 # this lets simultaneous -r, -b options continue working
4600 opts.setdefault('rev', []).append("null")
4601 opts.setdefault('rev', []).append("null")
4601
4602
4602 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4603 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4603 if not path:
4604 if not path:
4604 raise error.Abort(_('default repository not configured!'),
4605 raise error.Abort(_('default repository not configured!'),
4605 hint=_("see 'hg help config.paths'"))
4606 hint=_("see 'hg help config.paths'"))
4606 dest = path.pushloc or path.loc
4607 dest = path.pushloc or path.loc
4607 branches = (path.branch, opts.get('branch') or [])
4608 branches = (path.branch, opts.get('branch') or [])
4608 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4609 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4609 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4610 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4610 other = hg.peer(repo, opts, dest)
4611 other = hg.peer(repo, opts, dest)
4611
4612
4612 if revs:
4613 if revs:
4613 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
4614 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
4614 if not revs:
4615 if not revs:
4615 raise error.Abort(_("specified revisions evaluate to an empty set"),
4616 raise error.Abort(_("specified revisions evaluate to an empty set"),
4616 hint=_("use different revision arguments"))
4617 hint=_("use different revision arguments"))
4617 elif path.pushrev:
4618 elif path.pushrev:
4618 # It doesn't make any sense to specify ancestor revisions. So limit
4619 # It doesn't make any sense to specify ancestor revisions. So limit
4619 # to DAG heads to make discovery simpler.
4620 # to DAG heads to make discovery simpler.
4620 expr = revsetlang.formatspec('heads(%r)', path.pushrev)
4621 expr = revsetlang.formatspec('heads(%r)', path.pushrev)
4621 revs = scmutil.revrange(repo, [expr])
4622 revs = scmutil.revrange(repo, [expr])
4622 revs = [repo[rev].node() for rev in revs]
4623 revs = [repo[rev].node() for rev in revs]
4623 if not revs:
4624 if not revs:
4624 raise error.Abort(_('default push revset for path evaluates to an '
4625 raise error.Abort(_('default push revset for path evaluates to an '
4625 'empty set'))
4626 'empty set'))
4626
4627
4627 repo._subtoppath = dest
4628 repo._subtoppath = dest
4628 try:
4629 try:
4629 # push subrepos depth-first for coherent ordering
4630 # push subrepos depth-first for coherent ordering
4630 c = repo['.']
4631 c = repo['.']
4631 subs = c.substate # only repos that are committed
4632 subs = c.substate # only repos that are committed
4632 for s in sorted(subs):
4633 for s in sorted(subs):
4633 result = c.sub(s).push(opts)
4634 result = c.sub(s).push(opts)
4634 if result == 0:
4635 if result == 0:
4635 return not result
4636 return not result
4636 finally:
4637 finally:
4637 del repo._subtoppath
4638 del repo._subtoppath
4638
4639
4639 opargs = dict(opts.get('opargs', {})) # copy opargs since we may mutate it
4640 opargs = dict(opts.get('opargs', {})) # copy opargs since we may mutate it
4640 opargs.setdefault('pushvars', []).extend(opts.get('pushvars', []))
4641 opargs.setdefault('pushvars', []).extend(opts.get('pushvars', []))
4641
4642
4642 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
4643 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
4643 newbranch=opts.get('new_branch'),
4644 newbranch=opts.get('new_branch'),
4644 bookmarks=opts.get('bookmark', ()),
4645 bookmarks=opts.get('bookmark', ()),
4645 publish=opts.get('publish'),
4646 publish=opts.get('publish'),
4646 opargs=opargs)
4647 opargs=opargs)
4647
4648
4648 result = not pushop.cgresult
4649 result = not pushop.cgresult
4649
4650
4650 if pushop.bkresult is not None:
4651 if pushop.bkresult is not None:
4651 if pushop.bkresult == 2:
4652 if pushop.bkresult == 2:
4652 result = 2
4653 result = 2
4653 elif not result and pushop.bkresult:
4654 elif not result and pushop.bkresult:
4654 result = 2
4655 result = 2
4655
4656
4656 return result
4657 return result
4657
4658
4658 @command('recover',
4659 @command('recover',
4659 [('','verify', True, "run `hg verify` after succesful recover"),
4660 [('','verify', True, "run `hg verify` after succesful recover"),
4660 ],
4661 ],
4661 helpcategory=command.CATEGORY_MAINTENANCE)
4662 helpcategory=command.CATEGORY_MAINTENANCE)
4662 def recover(ui, repo, **opts):
4663 def recover(ui, repo, **opts):
4663 """roll back an interrupted transaction
4664 """roll back an interrupted transaction
4664
4665
4665 Recover from an interrupted commit or pull.
4666 Recover from an interrupted commit or pull.
4666
4667
4667 This command tries to fix the repository status after an
4668 This command tries to fix the repository status after an
4668 interrupted operation. It should only be necessary when Mercurial
4669 interrupted operation. It should only be necessary when Mercurial
4669 suggests it.
4670 suggests it.
4670
4671
4671 Returns 0 if successful, 1 if nothing to recover or verify fails.
4672 Returns 0 if successful, 1 if nothing to recover or verify fails.
4672 """
4673 """
4673 ret = repo.recover()
4674 ret = repo.recover()
4674 if ret:
4675 if ret:
4675 if opts['verify']:
4676 if opts['verify']:
4676 return hg.verify(repo)
4677 return hg.verify(repo)
4677 else:
4678 else:
4678 msg = _("(verify step skipped, run `hg verify` to check your "
4679 msg = _("(verify step skipped, run `hg verify` to check your "
4679 "repository content)\n")
4680 "repository content)\n")
4680 ui.warn(msg)
4681 ui.warn(msg)
4681 return 0
4682 return 0
4682 return 1
4683 return 1
4683
4684
4684 @command('remove|rm',
4685 @command('remove|rm',
4685 [('A', 'after', None, _('record delete for missing files')),
4686 [('A', 'after', None, _('record delete for missing files')),
4686 ('f', 'force', None,
4687 ('f', 'force', None,
4687 _('forget added files, delete modified files')),
4688 _('forget added files, delete modified files')),
4688 ] + subrepoopts + walkopts + dryrunopts,
4689 ] + subrepoopts + walkopts + dryrunopts,
4689 _('[OPTION]... FILE...'),
4690 _('[OPTION]... FILE...'),
4690 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4691 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4691 helpbasic=True, inferrepo=True)
4692 helpbasic=True, inferrepo=True)
4692 def remove(ui, repo, *pats, **opts):
4693 def remove(ui, repo, *pats, **opts):
4693 """remove the specified files on the next commit
4694 """remove the specified files on the next commit
4694
4695
4695 Schedule the indicated files for removal from the current branch.
4696 Schedule the indicated files for removal from the current branch.
4696
4697
4697 This command schedules the files to be removed at the next commit.
4698 This command schedules the files to be removed at the next commit.
4698 To undo a remove before that, see :hg:`revert`. To undo added
4699 To undo a remove before that, see :hg:`revert`. To undo added
4699 files, see :hg:`forget`.
4700 files, see :hg:`forget`.
4700
4701
4701 .. container:: verbose
4702 .. container:: verbose
4702
4703
4703 -A/--after can be used to remove only files that have already
4704 -A/--after can be used to remove only files that have already
4704 been deleted, -f/--force can be used to force deletion, and -Af
4705 been deleted, -f/--force can be used to force deletion, and -Af
4705 can be used to remove files from the next revision without
4706 can be used to remove files from the next revision without
4706 deleting them from the working directory.
4707 deleting them from the working directory.
4707
4708
4708 The following table details the behavior of remove for different
4709 The following table details the behavior of remove for different
4709 file states (columns) and option combinations (rows). The file
4710 file states (columns) and option combinations (rows). The file
4710 states are Added [A], Clean [C], Modified [M] and Missing [!]
4711 states are Added [A], Clean [C], Modified [M] and Missing [!]
4711 (as reported by :hg:`status`). The actions are Warn, Remove
4712 (as reported by :hg:`status`). The actions are Warn, Remove
4712 (from branch) and Delete (from disk):
4713 (from branch) and Delete (from disk):
4713
4714
4714 ========= == == == ==
4715 ========= == == == ==
4715 opt/state A C M !
4716 opt/state A C M !
4716 ========= == == == ==
4717 ========= == == == ==
4717 none W RD W R
4718 none W RD W R
4718 -f R RD RD R
4719 -f R RD RD R
4719 -A W W W R
4720 -A W W W R
4720 -Af R R R R
4721 -Af R R R R
4721 ========= == == == ==
4722 ========= == == == ==
4722
4723
4723 .. note::
4724 .. note::
4724
4725
4725 :hg:`remove` never deletes files in Added [A] state from the
4726 :hg:`remove` never deletes files in Added [A] state from the
4726 working directory, not even if ``--force`` is specified.
4727 working directory, not even if ``--force`` is specified.
4727
4728
4728 Returns 0 on success, 1 if any warnings encountered.
4729 Returns 0 on success, 1 if any warnings encountered.
4729 """
4730 """
4730
4731
4731 opts = pycompat.byteskwargs(opts)
4732 opts = pycompat.byteskwargs(opts)
4732 after, force = opts.get('after'), opts.get('force')
4733 after, force = opts.get('after'), opts.get('force')
4733 dryrun = opts.get('dry_run')
4734 dryrun = opts.get('dry_run')
4734 if not pats and not after:
4735 if not pats and not after:
4735 raise error.Abort(_('no files specified'))
4736 raise error.Abort(_('no files specified'))
4736
4737
4737 m = scmutil.match(repo[None], pats, opts)
4738 m = scmutil.match(repo[None], pats, opts)
4738 subrepos = opts.get('subrepos')
4739 subrepos = opts.get('subrepos')
4739 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
4740 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
4740 return cmdutil.remove(ui, repo, m, "", uipathfn, after, force, subrepos,
4741 return cmdutil.remove(ui, repo, m, "", uipathfn, after, force, subrepos,
4741 dryrun=dryrun)
4742 dryrun=dryrun)
4742
4743
4743 @command('rename|move|mv',
4744 @command('rename|move|mv',
4744 [('A', 'after', None, _('record a rename that has already occurred')),
4745 [('A', 'after', None, _('record a rename that has already occurred')),
4745 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4746 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4746 ] + walkopts + dryrunopts,
4747 ] + walkopts + dryrunopts,
4747 _('[OPTION]... SOURCE... DEST'),
4748 _('[OPTION]... SOURCE... DEST'),
4748 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
4749 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
4749 def rename(ui, repo, *pats, **opts):
4750 def rename(ui, repo, *pats, **opts):
4750 """rename files; equivalent of copy + remove
4751 """rename files; equivalent of copy + remove
4751
4752
4752 Mark dest as copies of sources; mark sources for deletion. If dest
4753 Mark dest as copies of sources; mark sources for deletion. If dest
4753 is a directory, copies are put in that directory. If dest is a
4754 is a directory, copies are put in that directory. If dest is a
4754 file, there can only be one source.
4755 file, there can only be one source.
4755
4756
4756 By default, this command copies the contents of files as they
4757 By default, this command copies the contents of files as they
4757 exist in the working directory. If invoked with -A/--after, the
4758 exist in the working directory. If invoked with -A/--after, the
4758 operation is recorded, but no copying is performed.
4759 operation is recorded, but no copying is performed.
4759
4760
4760 This command takes effect at the next commit. To undo a rename
4761 This command takes effect at the next commit. To undo a rename
4761 before that, see :hg:`revert`.
4762 before that, see :hg:`revert`.
4762
4763
4763 Returns 0 on success, 1 if errors are encountered.
4764 Returns 0 on success, 1 if errors are encountered.
4764 """
4765 """
4765 opts = pycompat.byteskwargs(opts)
4766 opts = pycompat.byteskwargs(opts)
4766 with repo.wlock(False):
4767 with repo.wlock(False):
4767 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4768 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4768
4769
4769 @command('resolve',
4770 @command('resolve',
4770 [('a', 'all', None, _('select all unresolved files')),
4771 [('a', 'all', None, _('select all unresolved files')),
4771 ('l', 'list', None, _('list state of files needing merge')),
4772 ('l', 'list', None, _('list state of files needing merge')),
4772 ('m', 'mark', None, _('mark files as resolved')),
4773 ('m', 'mark', None, _('mark files as resolved')),
4773 ('u', 'unmark', None, _('mark files as unresolved')),
4774 ('u', 'unmark', None, _('mark files as unresolved')),
4774 ('n', 'no-status', None, _('hide status prefix')),
4775 ('n', 'no-status', None, _('hide status prefix')),
4775 ('', 're-merge', None, _('re-merge files'))]
4776 ('', 're-merge', None, _('re-merge files'))]
4776 + mergetoolopts + walkopts + formatteropts,
4777 + mergetoolopts + walkopts + formatteropts,
4777 _('[OPTION]... [FILE]...'),
4778 _('[OPTION]... [FILE]...'),
4778 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4779 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4779 inferrepo=True)
4780 inferrepo=True)
4780 def resolve(ui, repo, *pats, **opts):
4781 def resolve(ui, repo, *pats, **opts):
4781 """redo merges or set/view the merge status of files
4782 """redo merges or set/view the merge status of files
4782
4783
4783 Merges with unresolved conflicts are often the result of
4784 Merges with unresolved conflicts are often the result of
4784 non-interactive merging using the ``internal:merge`` configuration
4785 non-interactive merging using the ``internal:merge`` configuration
4785 setting, or a command-line merge tool like ``diff3``. The resolve
4786 setting, or a command-line merge tool like ``diff3``. The resolve
4786 command is used to manage the files involved in a merge, after
4787 command is used to manage the files involved in a merge, after
4787 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4788 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4788 working directory must have two parents). See :hg:`help
4789 working directory must have two parents). See :hg:`help
4789 merge-tools` for information on configuring merge tools.
4790 merge-tools` for information on configuring merge tools.
4790
4791
4791 The resolve command can be used in the following ways:
4792 The resolve command can be used in the following ways:
4792
4793
4793 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
4794 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
4794 the specified files, discarding any previous merge attempts. Re-merging
4795 the specified files, discarding any previous merge attempts. Re-merging
4795 is not performed for files already marked as resolved. Use ``--all/-a``
4796 is not performed for files already marked as resolved. Use ``--all/-a``
4796 to select all unresolved files. ``--tool`` can be used to specify
4797 to select all unresolved files. ``--tool`` can be used to specify
4797 the merge tool used for the given files. It overrides the HGMERGE
4798 the merge tool used for the given files. It overrides the HGMERGE
4798 environment variable and your configuration files. Previous file
4799 environment variable and your configuration files. Previous file
4799 contents are saved with a ``.orig`` suffix.
4800 contents are saved with a ``.orig`` suffix.
4800
4801
4801 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4802 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4802 (e.g. after having manually fixed-up the files). The default is
4803 (e.g. after having manually fixed-up the files). The default is
4803 to mark all unresolved files.
4804 to mark all unresolved files.
4804
4805
4805 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4806 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4806 default is to mark all resolved files.
4807 default is to mark all resolved files.
4807
4808
4808 - :hg:`resolve -l`: list files which had or still have conflicts.
4809 - :hg:`resolve -l`: list files which had or still have conflicts.
4809 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4810 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4810 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
4811 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
4811 the list. See :hg:`help filesets` for details.
4812 the list. See :hg:`help filesets` for details.
4812
4813
4813 .. note::
4814 .. note::
4814
4815
4815 Mercurial will not let you commit files with unresolved merge
4816 Mercurial will not let you commit files with unresolved merge
4816 conflicts. You must use :hg:`resolve -m ...` before you can
4817 conflicts. You must use :hg:`resolve -m ...` before you can
4817 commit after a conflicting merge.
4818 commit after a conflicting merge.
4818
4819
4819 .. container:: verbose
4820 .. container:: verbose
4820
4821
4821 Template:
4822 Template:
4822
4823
4823 The following keywords are supported in addition to the common template
4824 The following keywords are supported in addition to the common template
4824 keywords and functions. See also :hg:`help templates`.
4825 keywords and functions. See also :hg:`help templates`.
4825
4826
4826 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
4827 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
4827 :path: String. Repository-absolute path of the file.
4828 :path: String. Repository-absolute path of the file.
4828
4829
4829 Returns 0 on success, 1 if any files fail a resolve attempt.
4830 Returns 0 on success, 1 if any files fail a resolve attempt.
4830 """
4831 """
4831
4832
4832 opts = pycompat.byteskwargs(opts)
4833 opts = pycompat.byteskwargs(opts)
4833 confirm = ui.configbool('commands', 'resolve.confirm')
4834 confirm = ui.configbool('commands', 'resolve.confirm')
4834 flaglist = 'all mark unmark list no_status re_merge'.split()
4835 flaglist = 'all mark unmark list no_status re_merge'.split()
4835 all, mark, unmark, show, nostatus, remerge = [
4836 all, mark, unmark, show, nostatus, remerge = [
4836 opts.get(o) for o in flaglist]
4837 opts.get(o) for o in flaglist]
4837
4838
4838 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
4839 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
4839 if actioncount > 1:
4840 if actioncount > 1:
4840 raise error.Abort(_("too many actions specified"))
4841 raise error.Abort(_("too many actions specified"))
4841 elif (actioncount == 0
4842 elif (actioncount == 0
4842 and ui.configbool('commands', 'resolve.explicit-re-merge')):
4843 and ui.configbool('commands', 'resolve.explicit-re-merge')):
4843 hint = _('use --mark, --unmark, --list or --re-merge')
4844 hint = _('use --mark, --unmark, --list or --re-merge')
4844 raise error.Abort(_('no action specified'), hint=hint)
4845 raise error.Abort(_('no action specified'), hint=hint)
4845 if pats and all:
4846 if pats and all:
4846 raise error.Abort(_("can't specify --all and patterns"))
4847 raise error.Abort(_("can't specify --all and patterns"))
4847 if not (all or pats or show or mark or unmark):
4848 if not (all or pats or show or mark or unmark):
4848 raise error.Abort(_('no files or directories specified'),
4849 raise error.Abort(_('no files or directories specified'),
4849 hint=('use --all to re-merge all unresolved files'))
4850 hint=('use --all to re-merge all unresolved files'))
4850
4851
4851 if confirm:
4852 if confirm:
4852 if all:
4853 if all:
4853 if ui.promptchoice(_(b're-merge all unresolved files (yn)?'
4854 if ui.promptchoice(_(b're-merge all unresolved files (yn)?'
4854 b'$$ &Yes $$ &No')):
4855 b'$$ &Yes $$ &No')):
4855 raise error.Abort(_('user quit'))
4856 raise error.Abort(_('user quit'))
4856 if mark and not pats:
4857 if mark and not pats:
4857 if ui.promptchoice(_(b'mark all unresolved files as resolved (yn)?'
4858 if ui.promptchoice(_(b'mark all unresolved files as resolved (yn)?'
4858 b'$$ &Yes $$ &No')):
4859 b'$$ &Yes $$ &No')):
4859 raise error.Abort(_('user quit'))
4860 raise error.Abort(_('user quit'))
4860 if unmark and not pats:
4861 if unmark and not pats:
4861 if ui.promptchoice(_(b'mark all resolved files as unresolved (yn)?'
4862 if ui.promptchoice(_(b'mark all resolved files as unresolved (yn)?'
4862 b'$$ &Yes $$ &No')):
4863 b'$$ &Yes $$ &No')):
4863 raise error.Abort(_('user quit'))
4864 raise error.Abort(_('user quit'))
4864
4865
4865 uipathfn = scmutil.getuipathfn(repo)
4866 uipathfn = scmutil.getuipathfn(repo)
4866
4867
4867 if show:
4868 if show:
4868 ui.pager('resolve')
4869 ui.pager('resolve')
4869 fm = ui.formatter('resolve', opts)
4870 fm = ui.formatter('resolve', opts)
4870 ms = mergemod.mergestate.read(repo)
4871 ms = mergemod.mergestate.read(repo)
4871 wctx = repo[None]
4872 wctx = repo[None]
4872 m = scmutil.match(wctx, pats, opts)
4873 m = scmutil.match(wctx, pats, opts)
4873
4874
4874 # Labels and keys based on merge state. Unresolved path conflicts show
4875 # Labels and keys based on merge state. Unresolved path conflicts show
4875 # as 'P'. Resolved path conflicts show as 'R', the same as normal
4876 # as 'P'. Resolved path conflicts show as 'R', the same as normal
4876 # resolved conflicts.
4877 # resolved conflicts.
4877 mergestateinfo = {
4878 mergestateinfo = {
4878 mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'),
4879 mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'),
4879 mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'),
4880 mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'),
4880 mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'),
4881 mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'),
4881 mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'),
4882 mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'),
4882 mergemod.MERGE_RECORD_DRIVER_RESOLVED: ('resolve.driverresolved',
4883 mergemod.MERGE_RECORD_DRIVER_RESOLVED: ('resolve.driverresolved',
4883 'D'),
4884 'D'),
4884 }
4885 }
4885
4886
4886 for f in ms:
4887 for f in ms:
4887 if not m(f):
4888 if not m(f):
4888 continue
4889 continue
4889
4890
4890 label, key = mergestateinfo[ms[f]]
4891 label, key = mergestateinfo[ms[f]]
4891 fm.startitem()
4892 fm.startitem()
4892 fm.context(ctx=wctx)
4893 fm.context(ctx=wctx)
4893 fm.condwrite(not nostatus, 'mergestatus', '%s ', key, label=label)
4894 fm.condwrite(not nostatus, 'mergestatus', '%s ', key, label=label)
4894 fm.data(path=f)
4895 fm.data(path=f)
4895 fm.plain('%s\n' % uipathfn(f), label=label)
4896 fm.plain('%s\n' % uipathfn(f), label=label)
4896 fm.end()
4897 fm.end()
4897 return 0
4898 return 0
4898
4899
4899 with repo.wlock():
4900 with repo.wlock():
4900 ms = mergemod.mergestate.read(repo)
4901 ms = mergemod.mergestate.read(repo)
4901
4902
4902 if not (ms.active() or repo.dirstate.p2() != nullid):
4903 if not (ms.active() or repo.dirstate.p2() != nullid):
4903 raise error.Abort(
4904 raise error.Abort(
4904 _('resolve command not applicable when not merging'))
4905 _('resolve command not applicable when not merging'))
4905
4906
4906 wctx = repo[None]
4907 wctx = repo[None]
4907
4908
4908 if (ms.mergedriver
4909 if (ms.mergedriver
4909 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED):
4910 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED):
4910 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4911 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4911 ms.commit()
4912 ms.commit()
4912 # allow mark and unmark to go through
4913 # allow mark and unmark to go through
4913 if not mark and not unmark and not proceed:
4914 if not mark and not unmark and not proceed:
4914 return 1
4915 return 1
4915
4916
4916 m = scmutil.match(wctx, pats, opts)
4917 m = scmutil.match(wctx, pats, opts)
4917 ret = 0
4918 ret = 0
4918 didwork = False
4919 didwork = False
4919 runconclude = False
4920 runconclude = False
4920
4921
4921 tocomplete = []
4922 tocomplete = []
4922 hasconflictmarkers = []
4923 hasconflictmarkers = []
4923 if mark:
4924 if mark:
4924 markcheck = ui.config('commands', 'resolve.mark-check')
4925 markcheck = ui.config('commands', 'resolve.mark-check')
4925 if markcheck not in ['warn', 'abort']:
4926 if markcheck not in ['warn', 'abort']:
4926 # Treat all invalid / unrecognized values as 'none'.
4927 # Treat all invalid / unrecognized values as 'none'.
4927 markcheck = False
4928 markcheck = False
4928 for f in ms:
4929 for f in ms:
4929 if not m(f):
4930 if not m(f):
4930 continue
4931 continue
4931
4932
4932 didwork = True
4933 didwork = True
4933
4934
4934 # don't let driver-resolved files be marked, and run the conclude
4935 # don't let driver-resolved files be marked, and run the conclude
4935 # step if asked to resolve
4936 # step if asked to resolve
4936 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
4937 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
4937 exact = m.exact(f)
4938 exact = m.exact(f)
4938 if mark:
4939 if mark:
4939 if exact:
4940 if exact:
4940 ui.warn(_('not marking %s as it is driver-resolved\n')
4941 ui.warn(_('not marking %s as it is driver-resolved\n')
4941 % uipathfn(f))
4942 % uipathfn(f))
4942 elif unmark:
4943 elif unmark:
4943 if exact:
4944 if exact:
4944 ui.warn(_('not unmarking %s as it is driver-resolved\n')
4945 ui.warn(_('not unmarking %s as it is driver-resolved\n')
4945 % uipathfn(f))
4946 % uipathfn(f))
4946 else:
4947 else:
4947 runconclude = True
4948 runconclude = True
4948 continue
4949 continue
4949
4950
4950 # path conflicts must be resolved manually
4951 # path conflicts must be resolved manually
4951 if ms[f] in (mergemod.MERGE_RECORD_UNRESOLVED_PATH,
4952 if ms[f] in (mergemod.MERGE_RECORD_UNRESOLVED_PATH,
4952 mergemod.MERGE_RECORD_RESOLVED_PATH):
4953 mergemod.MERGE_RECORD_RESOLVED_PATH):
4953 if mark:
4954 if mark:
4954 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
4955 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
4955 elif unmark:
4956 elif unmark:
4956 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
4957 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
4957 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
4958 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
4958 ui.warn(_('%s: path conflict must be resolved manually\n')
4959 ui.warn(_('%s: path conflict must be resolved manually\n')
4959 % uipathfn(f))
4960 % uipathfn(f))
4960 continue
4961 continue
4961
4962
4962 if mark:
4963 if mark:
4963 if markcheck:
4964 if markcheck:
4964 fdata = repo.wvfs.tryread(f)
4965 fdata = repo.wvfs.tryread(f)
4965 if (filemerge.hasconflictmarkers(fdata) and
4966 if (filemerge.hasconflictmarkers(fdata) and
4966 ms[f] != mergemod.MERGE_RECORD_RESOLVED):
4967 ms[f] != mergemod.MERGE_RECORD_RESOLVED):
4967 hasconflictmarkers.append(f)
4968 hasconflictmarkers.append(f)
4968 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
4969 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
4969 elif unmark:
4970 elif unmark:
4970 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
4971 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
4971 else:
4972 else:
4972 # backup pre-resolve (merge uses .orig for its own purposes)
4973 # backup pre-resolve (merge uses .orig for its own purposes)
4973 a = repo.wjoin(f)
4974 a = repo.wjoin(f)
4974 try:
4975 try:
4975 util.copyfile(a, a + ".resolve")
4976 util.copyfile(a, a + ".resolve")
4976 except (IOError, OSError) as inst:
4977 except (IOError, OSError) as inst:
4977 if inst.errno != errno.ENOENT:
4978 if inst.errno != errno.ENOENT:
4978 raise
4979 raise
4979
4980
4980 try:
4981 try:
4981 # preresolve file
4982 # preresolve file
4982 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4983 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4983 with ui.configoverride(overrides, 'resolve'):
4984 with ui.configoverride(overrides, 'resolve'):
4984 complete, r = ms.preresolve(f, wctx)
4985 complete, r = ms.preresolve(f, wctx)
4985 if not complete:
4986 if not complete:
4986 tocomplete.append(f)
4987 tocomplete.append(f)
4987 elif r:
4988 elif r:
4988 ret = 1
4989 ret = 1
4989 finally:
4990 finally:
4990 ms.commit()
4991 ms.commit()
4991
4992
4992 # replace filemerge's .orig file with our resolve file, but only
4993 # replace filemerge's .orig file with our resolve file, but only
4993 # for merges that are complete
4994 # for merges that are complete
4994 if complete:
4995 if complete:
4995 try:
4996 try:
4996 util.rename(a + ".resolve",
4997 util.rename(a + ".resolve",
4997 scmutil.backuppath(ui, repo, f))
4998 scmutil.backuppath(ui, repo, f))
4998 except OSError as inst:
4999 except OSError as inst:
4999 if inst.errno != errno.ENOENT:
5000 if inst.errno != errno.ENOENT:
5000 raise
5001 raise
5001
5002
5002 if hasconflictmarkers:
5003 if hasconflictmarkers:
5003 ui.warn(_('warning: the following files still have conflict '
5004 ui.warn(_('warning: the following files still have conflict '
5004 'markers:\n') + ''.join(' ' + uipathfn(f) + '\n'
5005 'markers:\n') + ''.join(' ' + uipathfn(f) + '\n'
5005 for f in hasconflictmarkers))
5006 for f in hasconflictmarkers))
5006 if markcheck == 'abort' and not all and not pats:
5007 if markcheck == 'abort' and not all and not pats:
5007 raise error.Abort(_('conflict markers detected'),
5008 raise error.Abort(_('conflict markers detected'),
5008 hint=_('use --all to mark anyway'))
5009 hint=_('use --all to mark anyway'))
5009
5010
5010 for f in tocomplete:
5011 for f in tocomplete:
5011 try:
5012 try:
5012 # resolve file
5013 # resolve file
5013 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
5014 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
5014 with ui.configoverride(overrides, 'resolve'):
5015 with ui.configoverride(overrides, 'resolve'):
5015 r = ms.resolve(f, wctx)
5016 r = ms.resolve(f, wctx)
5016 if r:
5017 if r:
5017 ret = 1
5018 ret = 1
5018 finally:
5019 finally:
5019 ms.commit()
5020 ms.commit()
5020
5021
5021 # replace filemerge's .orig file with our resolve file
5022 # replace filemerge's .orig file with our resolve file
5022 a = repo.wjoin(f)
5023 a = repo.wjoin(f)
5023 try:
5024 try:
5024 util.rename(a + ".resolve", scmutil.backuppath(ui, repo, f))
5025 util.rename(a + ".resolve", scmutil.backuppath(ui, repo, f))
5025 except OSError as inst:
5026 except OSError as inst:
5026 if inst.errno != errno.ENOENT:
5027 if inst.errno != errno.ENOENT:
5027 raise
5028 raise
5028
5029
5029 ms.commit()
5030 ms.commit()
5030 ms.recordactions()
5031 ms.recordactions()
5031
5032
5032 if not didwork and pats:
5033 if not didwork and pats:
5033 hint = None
5034 hint = None
5034 if not any([p for p in pats if p.find(':') >= 0]):
5035 if not any([p for p in pats if p.find(':') >= 0]):
5035 pats = ['path:%s' % p for p in pats]
5036 pats = ['path:%s' % p for p in pats]
5036 m = scmutil.match(wctx, pats, opts)
5037 m = scmutil.match(wctx, pats, opts)
5037 for f in ms:
5038 for f in ms:
5038 if not m(f):
5039 if not m(f):
5039 continue
5040 continue
5040 def flag(o):
5041 def flag(o):
5041 if o == 're_merge':
5042 if o == 're_merge':
5042 return '--re-merge '
5043 return '--re-merge '
5043 return '-%s ' % o[0:1]
5044 return '-%s ' % o[0:1]
5044 flags = ''.join([flag(o) for o in flaglist if opts.get(o)])
5045 flags = ''.join([flag(o) for o in flaglist if opts.get(o)])
5045 hint = _("(try: hg resolve %s%s)\n") % (
5046 hint = _("(try: hg resolve %s%s)\n") % (
5046 flags,
5047 flags,
5047 ' '.join(pats))
5048 ' '.join(pats))
5048 break
5049 break
5049 ui.warn(_("arguments do not match paths that need resolving\n"))
5050 ui.warn(_("arguments do not match paths that need resolving\n"))
5050 if hint:
5051 if hint:
5051 ui.warn(hint)
5052 ui.warn(hint)
5052 elif ms.mergedriver and ms.mdstate() != 's':
5053 elif ms.mergedriver and ms.mdstate() != 's':
5053 # run conclude step when either a driver-resolved file is requested
5054 # run conclude step when either a driver-resolved file is requested
5054 # or there are no driver-resolved files
5055 # or there are no driver-resolved files
5055 # we can't use 'ret' to determine whether any files are unresolved
5056 # we can't use 'ret' to determine whether any files are unresolved
5056 # because we might not have tried to resolve some
5057 # because we might not have tried to resolve some
5057 if ((runconclude or not list(ms.driverresolved()))
5058 if ((runconclude or not list(ms.driverresolved()))
5058 and not list(ms.unresolved())):
5059 and not list(ms.unresolved())):
5059 proceed = mergemod.driverconclude(repo, ms, wctx)
5060 proceed = mergemod.driverconclude(repo, ms, wctx)
5060 ms.commit()
5061 ms.commit()
5061 if not proceed:
5062 if not proceed:
5062 return 1
5063 return 1
5063
5064
5064 # Nudge users into finishing an unfinished operation
5065 # Nudge users into finishing an unfinished operation
5065 unresolvedf = list(ms.unresolved())
5066 unresolvedf = list(ms.unresolved())
5066 driverresolvedf = list(ms.driverresolved())
5067 driverresolvedf = list(ms.driverresolved())
5067 if not unresolvedf and not driverresolvedf:
5068 if not unresolvedf and not driverresolvedf:
5068 ui.status(_('(no more unresolved files)\n'))
5069 ui.status(_('(no more unresolved files)\n'))
5069 cmdutil.checkafterresolved(repo)
5070 cmdutil.checkafterresolved(repo)
5070 elif not unresolvedf:
5071 elif not unresolvedf:
5071 ui.status(_('(no more unresolved files -- '
5072 ui.status(_('(no more unresolved files -- '
5072 'run "hg resolve --all" to conclude)\n'))
5073 'run "hg resolve --all" to conclude)\n'))
5073
5074
5074 return ret
5075 return ret
5075
5076
5076 @command('revert',
5077 @command('revert',
5077 [('a', 'all', None, _('revert all changes when no arguments given')),
5078 [('a', 'all', None, _('revert all changes when no arguments given')),
5078 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5079 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5079 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5080 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5080 ('C', 'no-backup', None, _('do not save backup copies of files')),
5081 ('C', 'no-backup', None, _('do not save backup copies of files')),
5081 ('i', 'interactive', None, _('interactively select the changes')),
5082 ('i', 'interactive', None, _('interactively select the changes')),
5082 ] + walkopts + dryrunopts,
5083 ] + walkopts + dryrunopts,
5083 _('[OPTION]... [-r REV] [NAME]...'),
5084 _('[OPTION]... [-r REV] [NAME]...'),
5084 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5085 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5085 def revert(ui, repo, *pats, **opts):
5086 def revert(ui, repo, *pats, **opts):
5086 """restore files to their checkout state
5087 """restore files to their checkout state
5087
5088
5088 .. note::
5089 .. note::
5089
5090
5090 To check out earlier revisions, you should use :hg:`update REV`.
5091 To check out earlier revisions, you should use :hg:`update REV`.
5091 To cancel an uncommitted merge (and lose your changes),
5092 To cancel an uncommitted merge (and lose your changes),
5092 use :hg:`merge --abort`.
5093 use :hg:`merge --abort`.
5093
5094
5094 With no revision specified, revert the specified files or directories
5095 With no revision specified, revert the specified files or directories
5095 to the contents they had in the parent of the working directory.
5096 to the contents they had in the parent of the working directory.
5096 This restores the contents of files to an unmodified
5097 This restores the contents of files to an unmodified
5097 state and unschedules adds, removes, copies, and renames. If the
5098 state and unschedules adds, removes, copies, and renames. If the
5098 working directory has two parents, you must explicitly specify a
5099 working directory has two parents, you must explicitly specify a
5099 revision.
5100 revision.
5100
5101
5101 Using the -r/--rev or -d/--date options, revert the given files or
5102 Using the -r/--rev or -d/--date options, revert the given files or
5102 directories to their states as of a specific revision. Because
5103 directories to their states as of a specific revision. Because
5103 revert does not change the working directory parents, this will
5104 revert does not change the working directory parents, this will
5104 cause these files to appear modified. This can be helpful to "back
5105 cause these files to appear modified. This can be helpful to "back
5105 out" some or all of an earlier change. See :hg:`backout` for a
5106 out" some or all of an earlier change. See :hg:`backout` for a
5106 related method.
5107 related method.
5107
5108
5108 Modified files are saved with a .orig suffix before reverting.
5109 Modified files are saved with a .orig suffix before reverting.
5109 To disable these backups, use --no-backup. It is possible to store
5110 To disable these backups, use --no-backup. It is possible to store
5110 the backup files in a custom directory relative to the root of the
5111 the backup files in a custom directory relative to the root of the
5111 repository by setting the ``ui.origbackuppath`` configuration
5112 repository by setting the ``ui.origbackuppath`` configuration
5112 option.
5113 option.
5113
5114
5114 See :hg:`help dates` for a list of formats valid for -d/--date.
5115 See :hg:`help dates` for a list of formats valid for -d/--date.
5115
5116
5116 See :hg:`help backout` for a way to reverse the effect of an
5117 See :hg:`help backout` for a way to reverse the effect of an
5117 earlier changeset.
5118 earlier changeset.
5118
5119
5119 Returns 0 on success.
5120 Returns 0 on success.
5120 """
5121 """
5121
5122
5122 opts = pycompat.byteskwargs(opts)
5123 opts = pycompat.byteskwargs(opts)
5123 if opts.get("date"):
5124 if opts.get("date"):
5124 if opts.get("rev"):
5125 if opts.get("rev"):
5125 raise error.Abort(_("you can't specify a revision and a date"))
5126 raise error.Abort(_("you can't specify a revision and a date"))
5126 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5127 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5127
5128
5128 parent, p2 = repo.dirstate.parents()
5129 parent, p2 = repo.dirstate.parents()
5129 if not opts.get('rev') and p2 != nullid:
5130 if not opts.get('rev') and p2 != nullid:
5130 # revert after merge is a trap for new users (issue2915)
5131 # revert after merge is a trap for new users (issue2915)
5131 raise error.Abort(_('uncommitted merge with no revision specified'),
5132 raise error.Abort(_('uncommitted merge with no revision specified'),
5132 hint=_("use 'hg update' or see 'hg help revert'"))
5133 hint=_("use 'hg update' or see 'hg help revert'"))
5133
5134
5134 rev = opts.get('rev')
5135 rev = opts.get('rev')
5135 if rev:
5136 if rev:
5136 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
5137 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
5137 ctx = scmutil.revsingle(repo, rev)
5138 ctx = scmutil.revsingle(repo, rev)
5138
5139
5139 if (not (pats or opts.get('include') or opts.get('exclude') or
5140 if (not (pats or opts.get('include') or opts.get('exclude') or
5140 opts.get('all') or opts.get('interactive'))):
5141 opts.get('all') or opts.get('interactive'))):
5141 msg = _("no files or directories specified")
5142 msg = _("no files or directories specified")
5142 if p2 != nullid:
5143 if p2 != nullid:
5143 hint = _("uncommitted merge, use --all to discard all changes,"
5144 hint = _("uncommitted merge, use --all to discard all changes,"
5144 " or 'hg update -C .' to abort the merge")
5145 " or 'hg update -C .' to abort the merge")
5145 raise error.Abort(msg, hint=hint)
5146 raise error.Abort(msg, hint=hint)
5146 dirty = any(repo.status())
5147 dirty = any(repo.status())
5147 node = ctx.node()
5148 node = ctx.node()
5148 if node != parent:
5149 if node != parent:
5149 if dirty:
5150 if dirty:
5150 hint = _("uncommitted changes, use --all to discard all"
5151 hint = _("uncommitted changes, use --all to discard all"
5151 " changes, or 'hg update %d' to update") % ctx.rev()
5152 " changes, or 'hg update %d' to update") % ctx.rev()
5152 else:
5153 else:
5153 hint = _("use --all to revert all files,"
5154 hint = _("use --all to revert all files,"
5154 " or 'hg update %d' to update") % ctx.rev()
5155 " or 'hg update %d' to update") % ctx.rev()
5155 elif dirty:
5156 elif dirty:
5156 hint = _("uncommitted changes, use --all to discard all changes")
5157 hint = _("uncommitted changes, use --all to discard all changes")
5157 else:
5158 else:
5158 hint = _("use --all to revert all files")
5159 hint = _("use --all to revert all files")
5159 raise error.Abort(msg, hint=hint)
5160 raise error.Abort(msg, hint=hint)
5160
5161
5161 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats,
5162 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats,
5162 **pycompat.strkwargs(opts))
5163 **pycompat.strkwargs(opts))
5163
5164
5164 @command(
5165 @command(
5165 'rollback',
5166 'rollback',
5166 dryrunopts + [('f', 'force', False, _('ignore safety measures'))],
5167 dryrunopts + [('f', 'force', False, _('ignore safety measures'))],
5167 helpcategory=command.CATEGORY_MAINTENANCE)
5168 helpcategory=command.CATEGORY_MAINTENANCE)
5168 def rollback(ui, repo, **opts):
5169 def rollback(ui, repo, **opts):
5169 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5170 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5170
5171
5171 Please use :hg:`commit --amend` instead of rollback to correct
5172 Please use :hg:`commit --amend` instead of rollback to correct
5172 mistakes in the last commit.
5173 mistakes in the last commit.
5173
5174
5174 This command should be used with care. There is only one level of
5175 This command should be used with care. There is only one level of
5175 rollback, and there is no way to undo a rollback. It will also
5176 rollback, and there is no way to undo a rollback. It will also
5176 restore the dirstate at the time of the last transaction, losing
5177 restore the dirstate at the time of the last transaction, losing
5177 any dirstate changes since that time. This command does not alter
5178 any dirstate changes since that time. This command does not alter
5178 the working directory.
5179 the working directory.
5179
5180
5180 Transactions are used to encapsulate the effects of all commands
5181 Transactions are used to encapsulate the effects of all commands
5181 that create new changesets or propagate existing changesets into a
5182 that create new changesets or propagate existing changesets into a
5182 repository.
5183 repository.
5183
5184
5184 .. container:: verbose
5185 .. container:: verbose
5185
5186
5186 For example, the following commands are transactional, and their
5187 For example, the following commands are transactional, and their
5187 effects can be rolled back:
5188 effects can be rolled back:
5188
5189
5189 - commit
5190 - commit
5190 - import
5191 - import
5191 - pull
5192 - pull
5192 - push (with this repository as the destination)
5193 - push (with this repository as the destination)
5193 - unbundle
5194 - unbundle
5194
5195
5195 To avoid permanent data loss, rollback will refuse to rollback a
5196 To avoid permanent data loss, rollback will refuse to rollback a
5196 commit transaction if it isn't checked out. Use --force to
5197 commit transaction if it isn't checked out. Use --force to
5197 override this protection.
5198 override this protection.
5198
5199
5199 The rollback command can be entirely disabled by setting the
5200 The rollback command can be entirely disabled by setting the
5200 ``ui.rollback`` configuration setting to false. If you're here
5201 ``ui.rollback`` configuration setting to false. If you're here
5201 because you want to use rollback and it's disabled, you can
5202 because you want to use rollback and it's disabled, you can
5202 re-enable the command by setting ``ui.rollback`` to true.
5203 re-enable the command by setting ``ui.rollback`` to true.
5203
5204
5204 This command is not intended for use on public repositories. Once
5205 This command is not intended for use on public repositories. Once
5205 changes are visible for pull by other users, rolling a transaction
5206 changes are visible for pull by other users, rolling a transaction
5206 back locally is ineffective (someone else may already have pulled
5207 back locally is ineffective (someone else may already have pulled
5207 the changes). Furthermore, a race is possible with readers of the
5208 the changes). Furthermore, a race is possible with readers of the
5208 repository; for example an in-progress pull from the repository
5209 repository; for example an in-progress pull from the repository
5209 may fail if a rollback is performed.
5210 may fail if a rollback is performed.
5210
5211
5211 Returns 0 on success, 1 if no rollback data is available.
5212 Returns 0 on success, 1 if no rollback data is available.
5212 """
5213 """
5213 if not ui.configbool('ui', 'rollback'):
5214 if not ui.configbool('ui', 'rollback'):
5214 raise error.Abort(_('rollback is disabled because it is unsafe'),
5215 raise error.Abort(_('rollback is disabled because it is unsafe'),
5215 hint=('see `hg help -v rollback` for information'))
5216 hint=('see `hg help -v rollback` for information'))
5216 return repo.rollback(dryrun=opts.get(r'dry_run'),
5217 return repo.rollback(dryrun=opts.get(r'dry_run'),
5217 force=opts.get(r'force'))
5218 force=opts.get(r'force'))
5218
5219
5219 @command(
5220 @command(
5220 'root', [], intents={INTENT_READONLY},
5221 'root', [], intents={INTENT_READONLY},
5221 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5222 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5222 def root(ui, repo):
5223 def root(ui, repo):
5223 """print the root (top) of the current working directory
5224 """print the root (top) of the current working directory
5224
5225
5225 Print the root directory of the current repository.
5226 Print the root directory of the current repository.
5226
5227
5227 Returns 0 on success.
5228 Returns 0 on success.
5228 """
5229 """
5229 ui.write(repo.root + "\n")
5230 ui.write(repo.root + "\n")
5230
5231
5231 @command('serve',
5232 @command('serve',
5232 [('A', 'accesslog', '', _('name of access log file to write to'),
5233 [('A', 'accesslog', '', _('name of access log file to write to'),
5233 _('FILE')),
5234 _('FILE')),
5234 ('d', 'daemon', None, _('run server in background')),
5235 ('d', 'daemon', None, _('run server in background')),
5235 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
5236 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
5236 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5237 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5237 # use string type, then we can check if something was passed
5238 # use string type, then we can check if something was passed
5238 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5239 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5239 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5240 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5240 _('ADDR')),
5241 _('ADDR')),
5241 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5242 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5242 _('PREFIX')),
5243 _('PREFIX')),
5243 ('n', 'name', '',
5244 ('n', 'name', '',
5244 _('name to show in web pages (default: working directory)'), _('NAME')),
5245 _('name to show in web pages (default: working directory)'), _('NAME')),
5245 ('', 'web-conf', '',
5246 ('', 'web-conf', '',
5246 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
5247 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
5247 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5248 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5248 _('FILE')),
5249 _('FILE')),
5249 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5250 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5250 ('', 'stdio', None, _('for remote clients (ADVANCED)')),
5251 ('', 'stdio', None, _('for remote clients (ADVANCED)')),
5251 ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')),
5252 ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')),
5252 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5253 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5253 ('', 'style', '', _('template style to use'), _('STYLE')),
5254 ('', 'style', '', _('template style to use'), _('STYLE')),
5254 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5255 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5255 ('', 'certificate', '', _('SSL certificate file'), _('FILE')),
5256 ('', 'certificate', '', _('SSL certificate file'), _('FILE')),
5256 ('', 'print-url', None, _('start and print only the URL'))]
5257 ('', 'print-url', None, _('start and print only the URL'))]
5257 + subrepoopts,
5258 + subrepoopts,
5258 _('[OPTION]...'),
5259 _('[OPTION]...'),
5259 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5260 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5260 helpbasic=True, optionalrepo=True)
5261 helpbasic=True, optionalrepo=True)
5261 def serve(ui, repo, **opts):
5262 def serve(ui, repo, **opts):
5262 """start stand-alone webserver
5263 """start stand-alone webserver
5263
5264
5264 Start a local HTTP repository browser and pull server. You can use
5265 Start a local HTTP repository browser and pull server. You can use
5265 this for ad-hoc sharing and browsing of repositories. It is
5266 this for ad-hoc sharing and browsing of repositories. It is
5266 recommended to use a real web server to serve a repository for
5267 recommended to use a real web server to serve a repository for
5267 longer periods of time.
5268 longer periods of time.
5268
5269
5269 Please note that the server does not implement access control.
5270 Please note that the server does not implement access control.
5270 This means that, by default, anybody can read from the server and
5271 This means that, by default, anybody can read from the server and
5271 nobody can write to it by default. Set the ``web.allow-push``
5272 nobody can write to it by default. Set the ``web.allow-push``
5272 option to ``*`` to allow everybody to push to the server. You
5273 option to ``*`` to allow everybody to push to the server. You
5273 should use a real web server if you need to authenticate users.
5274 should use a real web server if you need to authenticate users.
5274
5275
5275 By default, the server logs accesses to stdout and errors to
5276 By default, the server logs accesses to stdout and errors to
5276 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5277 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5277 files.
5278 files.
5278
5279
5279 To have the server choose a free port number to listen on, specify
5280 To have the server choose a free port number to listen on, specify
5280 a port number of 0; in this case, the server will print the port
5281 a port number of 0; in this case, the server will print the port
5281 number it uses.
5282 number it uses.
5282
5283
5283 Returns 0 on success.
5284 Returns 0 on success.
5284 """
5285 """
5285
5286
5286 opts = pycompat.byteskwargs(opts)
5287 opts = pycompat.byteskwargs(opts)
5287 if opts["stdio"] and opts["cmdserver"]:
5288 if opts["stdio"] and opts["cmdserver"]:
5288 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5289 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5289 if opts["print_url"] and ui.verbose:
5290 if opts["print_url"] and ui.verbose:
5290 raise error.Abort(_("cannot use --print-url with --verbose"))
5291 raise error.Abort(_("cannot use --print-url with --verbose"))
5291
5292
5292 if opts["stdio"]:
5293 if opts["stdio"]:
5293 if repo is None:
5294 if repo is None:
5294 raise error.RepoError(_("there is no Mercurial repository here"
5295 raise error.RepoError(_("there is no Mercurial repository here"
5295 " (.hg not found)"))
5296 " (.hg not found)"))
5296 s = wireprotoserver.sshserver(ui, repo)
5297 s = wireprotoserver.sshserver(ui, repo)
5297 s.serve_forever()
5298 s.serve_forever()
5298
5299
5299 service = server.createservice(ui, repo, opts)
5300 service = server.createservice(ui, repo, opts)
5300 return server.runservice(opts, initfn=service.init, runfn=service.run)
5301 return server.runservice(opts, initfn=service.init, runfn=service.run)
5301
5302
5302 _NOTTERSE = 'nothing'
5303 _NOTTERSE = 'nothing'
5303
5304
5304 @command('status|st',
5305 @command('status|st',
5305 [('A', 'all', None, _('show status of all files')),
5306 [('A', 'all', None, _('show status of all files')),
5306 ('m', 'modified', None, _('show only modified files')),
5307 ('m', 'modified', None, _('show only modified files')),
5307 ('a', 'added', None, _('show only added files')),
5308 ('a', 'added', None, _('show only added files')),
5308 ('r', 'removed', None, _('show only removed files')),
5309 ('r', 'removed', None, _('show only removed files')),
5309 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5310 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5310 ('c', 'clean', None, _('show only files without changes')),
5311 ('c', 'clean', None, _('show only files without changes')),
5311 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5312 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5312 ('i', 'ignored', None, _('show only ignored files')),
5313 ('i', 'ignored', None, _('show only ignored files')),
5313 ('n', 'no-status', None, _('hide status prefix')),
5314 ('n', 'no-status', None, _('hide status prefix')),
5314 ('t', 'terse', _NOTTERSE, _('show the terse output (EXPERIMENTAL)')),
5315 ('t', 'terse', _NOTTERSE, _('show the terse output (EXPERIMENTAL)')),
5315 ('C', 'copies', None, _('show source of copied files')),
5316 ('C', 'copies', None, _('show source of copied files')),
5316 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5317 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5317 ('', 'rev', [], _('show difference from revision'), _('REV')),
5318 ('', 'rev', [], _('show difference from revision'), _('REV')),
5318 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5319 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5319 ] + walkopts + subrepoopts + formatteropts,
5320 ] + walkopts + subrepoopts + formatteropts,
5320 _('[OPTION]... [FILE]...'),
5321 _('[OPTION]... [FILE]...'),
5321 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5322 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5322 helpbasic=True, inferrepo=True,
5323 helpbasic=True, inferrepo=True,
5323 intents={INTENT_READONLY})
5324 intents={INTENT_READONLY})
5324 def status(ui, repo, *pats, **opts):
5325 def status(ui, repo, *pats, **opts):
5325 """show changed files in the working directory
5326 """show changed files in the working directory
5326
5327
5327 Show status of files in the repository. If names are given, only
5328 Show status of files in the repository. If names are given, only
5328 files that match are shown. Files that are clean or ignored or
5329 files that match are shown. Files that are clean or ignored or
5329 the source of a copy/move operation, are not listed unless
5330 the source of a copy/move operation, are not listed unless
5330 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5331 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5331 Unless options described with "show only ..." are given, the
5332 Unless options described with "show only ..." are given, the
5332 options -mardu are used.
5333 options -mardu are used.
5333
5334
5334 Option -q/--quiet hides untracked (unknown and ignored) files
5335 Option -q/--quiet hides untracked (unknown and ignored) files
5335 unless explicitly requested with -u/--unknown or -i/--ignored.
5336 unless explicitly requested with -u/--unknown or -i/--ignored.
5336
5337
5337 .. note::
5338 .. note::
5338
5339
5339 :hg:`status` may appear to disagree with diff if permissions have
5340 :hg:`status` may appear to disagree with diff if permissions have
5340 changed or a merge has occurred. The standard diff format does
5341 changed or a merge has occurred. The standard diff format does
5341 not report permission changes and diff only reports changes
5342 not report permission changes and diff only reports changes
5342 relative to one merge parent.
5343 relative to one merge parent.
5343
5344
5344 If one revision is given, it is used as the base revision.
5345 If one revision is given, it is used as the base revision.
5345 If two revisions are given, the differences between them are
5346 If two revisions are given, the differences between them are
5346 shown. The --change option can also be used as a shortcut to list
5347 shown. The --change option can also be used as a shortcut to list
5347 the changed files of a revision from its first parent.
5348 the changed files of a revision from its first parent.
5348
5349
5349 The codes used to show the status of files are::
5350 The codes used to show the status of files are::
5350
5351
5351 M = modified
5352 M = modified
5352 A = added
5353 A = added
5353 R = removed
5354 R = removed
5354 C = clean
5355 C = clean
5355 ! = missing (deleted by non-hg command, but still tracked)
5356 ! = missing (deleted by non-hg command, but still tracked)
5356 ? = not tracked
5357 ? = not tracked
5357 I = ignored
5358 I = ignored
5358 = origin of the previous file (with --copies)
5359 = origin of the previous file (with --copies)
5359
5360
5360 .. container:: verbose
5361 .. container:: verbose
5361
5362
5362 The -t/--terse option abbreviates the output by showing only the directory
5363 The -t/--terse option abbreviates the output by showing only the directory
5363 name if all the files in it share the same status. The option takes an
5364 name if all the files in it share the same status. The option takes an
5364 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
5365 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
5365 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
5366 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
5366 for 'ignored' and 'c' for clean.
5367 for 'ignored' and 'c' for clean.
5367
5368
5368 It abbreviates only those statuses which are passed. Note that clean and
5369 It abbreviates only those statuses which are passed. Note that clean and
5369 ignored files are not displayed with '--terse ic' unless the -c/--clean
5370 ignored files are not displayed with '--terse ic' unless the -c/--clean
5370 and -i/--ignored options are also used.
5371 and -i/--ignored options are also used.
5371
5372
5372 The -v/--verbose option shows information when the repository is in an
5373 The -v/--verbose option shows information when the repository is in an
5373 unfinished merge, shelve, rebase state etc. You can have this behavior
5374 unfinished merge, shelve, rebase state etc. You can have this behavior
5374 turned on by default by enabling the ``commands.status.verbose`` option.
5375 turned on by default by enabling the ``commands.status.verbose`` option.
5375
5376
5376 You can skip displaying some of these states by setting
5377 You can skip displaying some of these states by setting
5377 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
5378 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
5378 'histedit', 'merge', 'rebase', or 'unshelve'.
5379 'histedit', 'merge', 'rebase', or 'unshelve'.
5379
5380
5380 Template:
5381 Template:
5381
5382
5382 The following keywords are supported in addition to the common template
5383 The following keywords are supported in addition to the common template
5383 keywords and functions. See also :hg:`help templates`.
5384 keywords and functions. See also :hg:`help templates`.
5384
5385
5385 :path: String. Repository-absolute path of the file.
5386 :path: String. Repository-absolute path of the file.
5386 :source: String. Repository-absolute path of the file originated from.
5387 :source: String. Repository-absolute path of the file originated from.
5387 Available if ``--copies`` is specified.
5388 Available if ``--copies`` is specified.
5388 :status: String. Character denoting file's status.
5389 :status: String. Character denoting file's status.
5389
5390
5390 Examples:
5391 Examples:
5391
5392
5392 - show changes in the working directory relative to a
5393 - show changes in the working directory relative to a
5393 changeset::
5394 changeset::
5394
5395
5395 hg status --rev 9353
5396 hg status --rev 9353
5396
5397
5397 - show changes in the working directory relative to the
5398 - show changes in the working directory relative to the
5398 current directory (see :hg:`help patterns` for more information)::
5399 current directory (see :hg:`help patterns` for more information)::
5399
5400
5400 hg status re:
5401 hg status re:
5401
5402
5402 - show all changes including copies in an existing changeset::
5403 - show all changes including copies in an existing changeset::
5403
5404
5404 hg status --copies --change 9353
5405 hg status --copies --change 9353
5405
5406
5406 - get a NUL separated list of added files, suitable for xargs::
5407 - get a NUL separated list of added files, suitable for xargs::
5407
5408
5408 hg status -an0
5409 hg status -an0
5409
5410
5410 - show more information about the repository status, abbreviating
5411 - show more information about the repository status, abbreviating
5411 added, removed, modified, deleted, and untracked paths::
5412 added, removed, modified, deleted, and untracked paths::
5412
5413
5413 hg status -v -t mardu
5414 hg status -v -t mardu
5414
5415
5415 Returns 0 on success.
5416 Returns 0 on success.
5416
5417
5417 """
5418 """
5418
5419
5419 opts = pycompat.byteskwargs(opts)
5420 opts = pycompat.byteskwargs(opts)
5420 revs = opts.get('rev')
5421 revs = opts.get('rev')
5421 change = opts.get('change')
5422 change = opts.get('change')
5422 terse = opts.get('terse')
5423 terse = opts.get('terse')
5423 if terse is _NOTTERSE:
5424 if terse is _NOTTERSE:
5424 if revs:
5425 if revs:
5425 terse = ''
5426 terse = ''
5426 else:
5427 else:
5427 terse = ui.config('commands', 'status.terse')
5428 terse = ui.config('commands', 'status.terse')
5428
5429
5429 if revs and change:
5430 if revs and change:
5430 msg = _('cannot specify --rev and --change at the same time')
5431 msg = _('cannot specify --rev and --change at the same time')
5431 raise error.Abort(msg)
5432 raise error.Abort(msg)
5432 elif revs and terse:
5433 elif revs and terse:
5433 msg = _('cannot use --terse with --rev')
5434 msg = _('cannot use --terse with --rev')
5434 raise error.Abort(msg)
5435 raise error.Abort(msg)
5435 elif change:
5436 elif change:
5436 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
5437 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
5437 ctx2 = scmutil.revsingle(repo, change, None)
5438 ctx2 = scmutil.revsingle(repo, change, None)
5438 ctx1 = ctx2.p1()
5439 ctx1 = ctx2.p1()
5439 else:
5440 else:
5440 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
5441 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
5441 ctx1, ctx2 = scmutil.revpair(repo, revs)
5442 ctx1, ctx2 = scmutil.revpair(repo, revs)
5442
5443
5443 forcerelativevalue = None
5444 forcerelativevalue = None
5444 if ui.hasconfig('commands', 'status.relative'):
5445 if ui.hasconfig('commands', 'status.relative'):
5445 forcerelativevalue = ui.configbool('commands', 'status.relative')
5446 forcerelativevalue = ui.configbool('commands', 'status.relative')
5446 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats),
5447 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats),
5447 forcerelativevalue=forcerelativevalue)
5448 forcerelativevalue=forcerelativevalue)
5448
5449
5449 if opts.get('print0'):
5450 if opts.get('print0'):
5450 end = '\0'
5451 end = '\0'
5451 else:
5452 else:
5452 end = '\n'
5453 end = '\n'
5453 copy = {}
5454 copy = {}
5454 states = 'modified added removed deleted unknown ignored clean'.split()
5455 states = 'modified added removed deleted unknown ignored clean'.split()
5455 show = [k for k in states if opts.get(k)]
5456 show = [k for k in states if opts.get(k)]
5456 if opts.get('all'):
5457 if opts.get('all'):
5457 show += ui.quiet and (states[:4] + ['clean']) or states
5458 show += ui.quiet and (states[:4] + ['clean']) or states
5458
5459
5459 if not show:
5460 if not show:
5460 if ui.quiet:
5461 if ui.quiet:
5461 show = states[:4]
5462 show = states[:4]
5462 else:
5463 else:
5463 show = states[:5]
5464 show = states[:5]
5464
5465
5465 m = scmutil.match(ctx2, pats, opts)
5466 m = scmutil.match(ctx2, pats, opts)
5466 if terse:
5467 if terse:
5467 # we need to compute clean and unknown to terse
5468 # we need to compute clean and unknown to terse
5468 stat = repo.status(ctx1.node(), ctx2.node(), m,
5469 stat = repo.status(ctx1.node(), ctx2.node(), m,
5469 'ignored' in show or 'i' in terse,
5470 'ignored' in show or 'i' in terse,
5470 clean=True, unknown=True,
5471 clean=True, unknown=True,
5471 listsubrepos=opts.get('subrepos'))
5472 listsubrepos=opts.get('subrepos'))
5472
5473
5473 stat = cmdutil.tersedir(stat, terse)
5474 stat = cmdutil.tersedir(stat, terse)
5474 else:
5475 else:
5475 stat = repo.status(ctx1.node(), ctx2.node(), m,
5476 stat = repo.status(ctx1.node(), ctx2.node(), m,
5476 'ignored' in show, 'clean' in show,
5477 'ignored' in show, 'clean' in show,
5477 'unknown' in show, opts.get('subrepos'))
5478 'unknown' in show, opts.get('subrepos'))
5478
5479
5479 changestates = zip(states, pycompat.iterbytestr('MAR!?IC'), stat)
5480 changestates = zip(states, pycompat.iterbytestr('MAR!?IC'), stat)
5480
5481
5481 if (opts.get('all') or opts.get('copies')
5482 if (opts.get('all') or opts.get('copies')
5482 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5483 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5483 copy = copies.pathcopies(ctx1, ctx2, m)
5484 copy = copies.pathcopies(ctx1, ctx2, m)
5484
5485
5485 ui.pager('status')
5486 ui.pager('status')
5486 fm = ui.formatter('status', opts)
5487 fm = ui.formatter('status', opts)
5487 fmt = '%s' + end
5488 fmt = '%s' + end
5488 showchar = not opts.get('no_status')
5489 showchar = not opts.get('no_status')
5489
5490
5490 for state, char, files in changestates:
5491 for state, char, files in changestates:
5491 if state in show:
5492 if state in show:
5492 label = 'status.' + state
5493 label = 'status.' + state
5493 for f in files:
5494 for f in files:
5494 fm.startitem()
5495 fm.startitem()
5495 fm.context(ctx=ctx2)
5496 fm.context(ctx=ctx2)
5496 fm.data(path=f)
5497 fm.data(path=f)
5497 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5498 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5498 fm.plain(fmt % uipathfn(f), label=label)
5499 fm.plain(fmt % uipathfn(f), label=label)
5499 if f in copy:
5500 if f in copy:
5500 fm.data(source=copy[f])
5501 fm.data(source=copy[f])
5501 fm.plain((' %s' + end) % uipathfn(copy[f]),
5502 fm.plain((' %s' + end) % uipathfn(copy[f]),
5502 label='status.copied')
5503 label='status.copied')
5503
5504
5504 if ((ui.verbose or ui.configbool('commands', 'status.verbose'))
5505 if ((ui.verbose or ui.configbool('commands', 'status.verbose'))
5505 and not ui.plain()):
5506 and not ui.plain()):
5506 cmdutil.morestatus(repo, fm)
5507 cmdutil.morestatus(repo, fm)
5507 fm.end()
5508 fm.end()
5508
5509
5509 @command('summary|sum',
5510 @command('summary|sum',
5510 [('', 'remote', None, _('check for push and pull'))],
5511 [('', 'remote', None, _('check for push and pull'))],
5511 '[--remote]',
5512 '[--remote]',
5512 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5513 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5513 helpbasic=True,
5514 helpbasic=True,
5514 intents={INTENT_READONLY})
5515 intents={INTENT_READONLY})
5515 def summary(ui, repo, **opts):
5516 def summary(ui, repo, **opts):
5516 """summarize working directory state
5517 """summarize working directory state
5517
5518
5518 This generates a brief summary of the working directory state,
5519 This generates a brief summary of the working directory state,
5519 including parents, branch, commit status, phase and available updates.
5520 including parents, branch, commit status, phase and available updates.
5520
5521
5521 With the --remote option, this will check the default paths for
5522 With the --remote option, this will check the default paths for
5522 incoming and outgoing changes. This can be time-consuming.
5523 incoming and outgoing changes. This can be time-consuming.
5523
5524
5524 Returns 0 on success.
5525 Returns 0 on success.
5525 """
5526 """
5526
5527
5527 opts = pycompat.byteskwargs(opts)
5528 opts = pycompat.byteskwargs(opts)
5528 ui.pager('summary')
5529 ui.pager('summary')
5529 ctx = repo[None]
5530 ctx = repo[None]
5530 parents = ctx.parents()
5531 parents = ctx.parents()
5531 pnode = parents[0].node()
5532 pnode = parents[0].node()
5532 marks = []
5533 marks = []
5533
5534
5534 try:
5535 try:
5535 ms = mergemod.mergestate.read(repo)
5536 ms = mergemod.mergestate.read(repo)
5536 except error.UnsupportedMergeRecords as e:
5537 except error.UnsupportedMergeRecords as e:
5537 s = ' '.join(e.recordtypes)
5538 s = ' '.join(e.recordtypes)
5538 ui.warn(
5539 ui.warn(
5539 _('warning: merge state has unsupported record types: %s\n') % s)
5540 _('warning: merge state has unsupported record types: %s\n') % s)
5540 unresolved = []
5541 unresolved = []
5541 else:
5542 else:
5542 unresolved = list(ms.unresolved())
5543 unresolved = list(ms.unresolved())
5543
5544
5544 for p in parents:
5545 for p in parents:
5545 # label with log.changeset (instead of log.parent) since this
5546 # label with log.changeset (instead of log.parent) since this
5546 # shows a working directory parent *changeset*:
5547 # shows a working directory parent *changeset*:
5547 # i18n: column positioning for "hg summary"
5548 # i18n: column positioning for "hg summary"
5548 ui.write(_('parent: %d:%s ') % (p.rev(), p),
5549 ui.write(_('parent: %d:%s ') % (p.rev(), p),
5549 label=logcmdutil.changesetlabels(p))
5550 label=logcmdutil.changesetlabels(p))
5550 ui.write(' '.join(p.tags()), label='log.tag')
5551 ui.write(' '.join(p.tags()), label='log.tag')
5551 if p.bookmarks():
5552 if p.bookmarks():
5552 marks.extend(p.bookmarks())
5553 marks.extend(p.bookmarks())
5553 if p.rev() == -1:
5554 if p.rev() == -1:
5554 if not len(repo):
5555 if not len(repo):
5555 ui.write(_(' (empty repository)'))
5556 ui.write(_(' (empty repository)'))
5556 else:
5557 else:
5557 ui.write(_(' (no revision checked out)'))
5558 ui.write(_(' (no revision checked out)'))
5558 if p.obsolete():
5559 if p.obsolete():
5559 ui.write(_(' (obsolete)'))
5560 ui.write(_(' (obsolete)'))
5560 if p.isunstable():
5561 if p.isunstable():
5561 instabilities = (ui.label(instability, 'trouble.%s' % instability)
5562 instabilities = (ui.label(instability, 'trouble.%s' % instability)
5562 for instability in p.instabilities())
5563 for instability in p.instabilities())
5563 ui.write(' ('
5564 ui.write(' ('
5564 + ', '.join(instabilities)
5565 + ', '.join(instabilities)
5565 + ')')
5566 + ')')
5566 ui.write('\n')
5567 ui.write('\n')
5567 if p.description():
5568 if p.description():
5568 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5569 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5569 label='log.summary')
5570 label='log.summary')
5570
5571
5571 branch = ctx.branch()
5572 branch = ctx.branch()
5572 bheads = repo.branchheads(branch)
5573 bheads = repo.branchheads(branch)
5573 # i18n: column positioning for "hg summary"
5574 # i18n: column positioning for "hg summary"
5574 m = _('branch: %s\n') % branch
5575 m = _('branch: %s\n') % branch
5575 if branch != 'default':
5576 if branch != 'default':
5576 ui.write(m, label='log.branch')
5577 ui.write(m, label='log.branch')
5577 else:
5578 else:
5578 ui.status(m, label='log.branch')
5579 ui.status(m, label='log.branch')
5579
5580
5580 if marks:
5581 if marks:
5581 active = repo._activebookmark
5582 active = repo._activebookmark
5582 # i18n: column positioning for "hg summary"
5583 # i18n: column positioning for "hg summary"
5583 ui.write(_('bookmarks:'), label='log.bookmark')
5584 ui.write(_('bookmarks:'), label='log.bookmark')
5584 if active is not None:
5585 if active is not None:
5585 if active in marks:
5586 if active in marks:
5586 ui.write(' *' + active, label=bookmarks.activebookmarklabel)
5587 ui.write(' *' + active, label=bookmarks.activebookmarklabel)
5587 marks.remove(active)
5588 marks.remove(active)
5588 else:
5589 else:
5589 ui.write(' [%s]' % active, label=bookmarks.activebookmarklabel)
5590 ui.write(' [%s]' % active, label=bookmarks.activebookmarklabel)
5590 for m in marks:
5591 for m in marks:
5591 ui.write(' ' + m, label='log.bookmark')
5592 ui.write(' ' + m, label='log.bookmark')
5592 ui.write('\n', label='log.bookmark')
5593 ui.write('\n', label='log.bookmark')
5593
5594
5594 status = repo.status(unknown=True)
5595 status = repo.status(unknown=True)
5595
5596
5596 c = repo.dirstate.copies()
5597 c = repo.dirstate.copies()
5597 copied, renamed = [], []
5598 copied, renamed = [], []
5598 for d, s in c.iteritems():
5599 for d, s in c.iteritems():
5599 if s in status.removed:
5600 if s in status.removed:
5600 status.removed.remove(s)
5601 status.removed.remove(s)
5601 renamed.append(d)
5602 renamed.append(d)
5602 else:
5603 else:
5603 copied.append(d)
5604 copied.append(d)
5604 if d in status.added:
5605 if d in status.added:
5605 status.added.remove(d)
5606 status.added.remove(d)
5606
5607
5607 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5608 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5608
5609
5609 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
5610 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
5610 (ui.label(_('%d added'), 'status.added'), status.added),
5611 (ui.label(_('%d added'), 'status.added'), status.added),
5611 (ui.label(_('%d removed'), 'status.removed'), status.removed),
5612 (ui.label(_('%d removed'), 'status.removed'), status.removed),
5612 (ui.label(_('%d renamed'), 'status.copied'), renamed),
5613 (ui.label(_('%d renamed'), 'status.copied'), renamed),
5613 (ui.label(_('%d copied'), 'status.copied'), copied),
5614 (ui.label(_('%d copied'), 'status.copied'), copied),
5614 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
5615 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
5615 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
5616 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
5616 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
5617 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
5617 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
5618 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
5618 t = []
5619 t = []
5619 for l, s in labels:
5620 for l, s in labels:
5620 if s:
5621 if s:
5621 t.append(l % len(s))
5622 t.append(l % len(s))
5622
5623
5623 t = ', '.join(t)
5624 t = ', '.join(t)
5624 cleanworkdir = False
5625 cleanworkdir = False
5625
5626
5626 if repo.vfs.exists('graftstate'):
5627 if repo.vfs.exists('graftstate'):
5627 t += _(' (graft in progress)')
5628 t += _(' (graft in progress)')
5628 if repo.vfs.exists('updatestate'):
5629 if repo.vfs.exists('updatestate'):
5629 t += _(' (interrupted update)')
5630 t += _(' (interrupted update)')
5630 elif len(parents) > 1:
5631 elif len(parents) > 1:
5631 t += _(' (merge)')
5632 t += _(' (merge)')
5632 elif branch != parents[0].branch():
5633 elif branch != parents[0].branch():
5633 t += _(' (new branch)')
5634 t += _(' (new branch)')
5634 elif (parents[0].closesbranch() and
5635 elif (parents[0].closesbranch() and
5635 pnode in repo.branchheads(branch, closed=True)):
5636 pnode in repo.branchheads(branch, closed=True)):
5636 t += _(' (head closed)')
5637 t += _(' (head closed)')
5637 elif not (status.modified or status.added or status.removed or renamed or
5638 elif not (status.modified or status.added or status.removed or renamed or
5638 copied or subs):
5639 copied or subs):
5639 t += _(' (clean)')
5640 t += _(' (clean)')
5640 cleanworkdir = True
5641 cleanworkdir = True
5641 elif pnode not in bheads:
5642 elif pnode not in bheads:
5642 t += _(' (new branch head)')
5643 t += _(' (new branch head)')
5643
5644
5644 if parents:
5645 if parents:
5645 pendingphase = max(p.phase() for p in parents)
5646 pendingphase = max(p.phase() for p in parents)
5646 else:
5647 else:
5647 pendingphase = phases.public
5648 pendingphase = phases.public
5648
5649
5649 if pendingphase > phases.newcommitphase(ui):
5650 if pendingphase > phases.newcommitphase(ui):
5650 t += ' (%s)' % phases.phasenames[pendingphase]
5651 t += ' (%s)' % phases.phasenames[pendingphase]
5651
5652
5652 if cleanworkdir:
5653 if cleanworkdir:
5653 # i18n: column positioning for "hg summary"
5654 # i18n: column positioning for "hg summary"
5654 ui.status(_('commit: %s\n') % t.strip())
5655 ui.status(_('commit: %s\n') % t.strip())
5655 else:
5656 else:
5656 # i18n: column positioning for "hg summary"
5657 # i18n: column positioning for "hg summary"
5657 ui.write(_('commit: %s\n') % t.strip())
5658 ui.write(_('commit: %s\n') % t.strip())
5658
5659
5659 # all ancestors of branch heads - all ancestors of parent = new csets
5660 # all ancestors of branch heads - all ancestors of parent = new csets
5660 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
5661 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
5661 bheads))
5662 bheads))
5662
5663
5663 if new == 0:
5664 if new == 0:
5664 # i18n: column positioning for "hg summary"
5665 # i18n: column positioning for "hg summary"
5665 ui.status(_('update: (current)\n'))
5666 ui.status(_('update: (current)\n'))
5666 elif pnode not in bheads:
5667 elif pnode not in bheads:
5667 # i18n: column positioning for "hg summary"
5668 # i18n: column positioning for "hg summary"
5668 ui.write(_('update: %d new changesets (update)\n') % new)
5669 ui.write(_('update: %d new changesets (update)\n') % new)
5669 else:
5670 else:
5670 # i18n: column positioning for "hg summary"
5671 # i18n: column positioning for "hg summary"
5671 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5672 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5672 (new, len(bheads)))
5673 (new, len(bheads)))
5673
5674
5674 t = []
5675 t = []
5675 draft = len(repo.revs('draft()'))
5676 draft = len(repo.revs('draft()'))
5676 if draft:
5677 if draft:
5677 t.append(_('%d draft') % draft)
5678 t.append(_('%d draft') % draft)
5678 secret = len(repo.revs('secret()'))
5679 secret = len(repo.revs('secret()'))
5679 if secret:
5680 if secret:
5680 t.append(_('%d secret') % secret)
5681 t.append(_('%d secret') % secret)
5681
5682
5682 if draft or secret:
5683 if draft or secret:
5683 ui.status(_('phases: %s\n') % ', '.join(t))
5684 ui.status(_('phases: %s\n') % ', '.join(t))
5684
5685
5685 if obsolete.isenabled(repo, obsolete.createmarkersopt):
5686 if obsolete.isenabled(repo, obsolete.createmarkersopt):
5686 for trouble in ("orphan", "contentdivergent", "phasedivergent"):
5687 for trouble in ("orphan", "contentdivergent", "phasedivergent"):
5687 numtrouble = len(repo.revs(trouble + "()"))
5688 numtrouble = len(repo.revs(trouble + "()"))
5688 # We write all the possibilities to ease translation
5689 # We write all the possibilities to ease translation
5689 troublemsg = {
5690 troublemsg = {
5690 "orphan": _("orphan: %d changesets"),
5691 "orphan": _("orphan: %d changesets"),
5691 "contentdivergent": _("content-divergent: %d changesets"),
5692 "contentdivergent": _("content-divergent: %d changesets"),
5692 "phasedivergent": _("phase-divergent: %d changesets"),
5693 "phasedivergent": _("phase-divergent: %d changesets"),
5693 }
5694 }
5694 if numtrouble > 0:
5695 if numtrouble > 0:
5695 ui.status(troublemsg[trouble] % numtrouble + "\n")
5696 ui.status(troublemsg[trouble] % numtrouble + "\n")
5696
5697
5697 cmdutil.summaryhooks(ui, repo)
5698 cmdutil.summaryhooks(ui, repo)
5698
5699
5699 if opts.get('remote'):
5700 if opts.get('remote'):
5700 needsincoming, needsoutgoing = True, True
5701 needsincoming, needsoutgoing = True, True
5701 else:
5702 else:
5702 needsincoming, needsoutgoing = False, False
5703 needsincoming, needsoutgoing = False, False
5703 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5704 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5704 if i:
5705 if i:
5705 needsincoming = True
5706 needsincoming = True
5706 if o:
5707 if o:
5707 needsoutgoing = True
5708 needsoutgoing = True
5708 if not needsincoming and not needsoutgoing:
5709 if not needsincoming and not needsoutgoing:
5709 return
5710 return
5710
5711
5711 def getincoming():
5712 def getincoming():
5712 source, branches = hg.parseurl(ui.expandpath('default'))
5713 source, branches = hg.parseurl(ui.expandpath('default'))
5713 sbranch = branches[0]
5714 sbranch = branches[0]
5714 try:
5715 try:
5715 other = hg.peer(repo, {}, source)
5716 other = hg.peer(repo, {}, source)
5716 except error.RepoError:
5717 except error.RepoError:
5717 if opts.get('remote'):
5718 if opts.get('remote'):
5718 raise
5719 raise
5719 return source, sbranch, None, None, None
5720 return source, sbranch, None, None, None
5720 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5721 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5721 if revs:
5722 if revs:
5722 revs = [other.lookup(rev) for rev in revs]
5723 revs = [other.lookup(rev) for rev in revs]
5723 ui.debug('comparing with %s\n' % util.hidepassword(source))
5724 ui.debug('comparing with %s\n' % util.hidepassword(source))
5724 repo.ui.pushbuffer()
5725 repo.ui.pushbuffer()
5725 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5726 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5726 repo.ui.popbuffer()
5727 repo.ui.popbuffer()
5727 return source, sbranch, other, commoninc, commoninc[1]
5728 return source, sbranch, other, commoninc, commoninc[1]
5728
5729
5729 if needsincoming:
5730 if needsincoming:
5730 source, sbranch, sother, commoninc, incoming = getincoming()
5731 source, sbranch, sother, commoninc, incoming = getincoming()
5731 else:
5732 else:
5732 source = sbranch = sother = commoninc = incoming = None
5733 source = sbranch = sother = commoninc = incoming = None
5733
5734
5734 def getoutgoing():
5735 def getoutgoing():
5735 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5736 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5736 dbranch = branches[0]
5737 dbranch = branches[0]
5737 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5738 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5738 if source != dest:
5739 if source != dest:
5739 try:
5740 try:
5740 dother = hg.peer(repo, {}, dest)
5741 dother = hg.peer(repo, {}, dest)
5741 except error.RepoError:
5742 except error.RepoError:
5742 if opts.get('remote'):
5743 if opts.get('remote'):
5743 raise
5744 raise
5744 return dest, dbranch, None, None
5745 return dest, dbranch, None, None
5745 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5746 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5746 elif sother is None:
5747 elif sother is None:
5747 # there is no explicit destination peer, but source one is invalid
5748 # there is no explicit destination peer, but source one is invalid
5748 return dest, dbranch, None, None
5749 return dest, dbranch, None, None
5749 else:
5750 else:
5750 dother = sother
5751 dother = sother
5751 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5752 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5752 common = None
5753 common = None
5753 else:
5754 else:
5754 common = commoninc
5755 common = commoninc
5755 if revs:
5756 if revs:
5756 revs = [repo.lookup(rev) for rev in revs]
5757 revs = [repo.lookup(rev) for rev in revs]
5757 repo.ui.pushbuffer()
5758 repo.ui.pushbuffer()
5758 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5759 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5759 commoninc=common)
5760 commoninc=common)
5760 repo.ui.popbuffer()
5761 repo.ui.popbuffer()
5761 return dest, dbranch, dother, outgoing
5762 return dest, dbranch, dother, outgoing
5762
5763
5763 if needsoutgoing:
5764 if needsoutgoing:
5764 dest, dbranch, dother, outgoing = getoutgoing()
5765 dest, dbranch, dother, outgoing = getoutgoing()
5765 else:
5766 else:
5766 dest = dbranch = dother = outgoing = None
5767 dest = dbranch = dother = outgoing = None
5767
5768
5768 if opts.get('remote'):
5769 if opts.get('remote'):
5769 t = []
5770 t = []
5770 if incoming:
5771 if incoming:
5771 t.append(_('1 or more incoming'))
5772 t.append(_('1 or more incoming'))
5772 o = outgoing.missing
5773 o = outgoing.missing
5773 if o:
5774 if o:
5774 t.append(_('%d outgoing') % len(o))
5775 t.append(_('%d outgoing') % len(o))
5775 other = dother or sother
5776 other = dother or sother
5776 if 'bookmarks' in other.listkeys('namespaces'):
5777 if 'bookmarks' in other.listkeys('namespaces'):
5777 counts = bookmarks.summary(repo, other)
5778 counts = bookmarks.summary(repo, other)
5778 if counts[0] > 0:
5779 if counts[0] > 0:
5779 t.append(_('%d incoming bookmarks') % counts[0])
5780 t.append(_('%d incoming bookmarks') % counts[0])
5780 if counts[1] > 0:
5781 if counts[1] > 0:
5781 t.append(_('%d outgoing bookmarks') % counts[1])
5782 t.append(_('%d outgoing bookmarks') % counts[1])
5782
5783
5783 if t:
5784 if t:
5784 # i18n: column positioning for "hg summary"
5785 # i18n: column positioning for "hg summary"
5785 ui.write(_('remote: %s\n') % (', '.join(t)))
5786 ui.write(_('remote: %s\n') % (', '.join(t)))
5786 else:
5787 else:
5787 # i18n: column positioning for "hg summary"
5788 # i18n: column positioning for "hg summary"
5788 ui.status(_('remote: (synced)\n'))
5789 ui.status(_('remote: (synced)\n'))
5789
5790
5790 cmdutil.summaryremotehooks(ui, repo, opts,
5791 cmdutil.summaryremotehooks(ui, repo, opts,
5791 ((source, sbranch, sother, commoninc),
5792 ((source, sbranch, sother, commoninc),
5792 (dest, dbranch, dother, outgoing)))
5793 (dest, dbranch, dother, outgoing)))
5793
5794
5794 @command('tag',
5795 @command('tag',
5795 [('f', 'force', None, _('force tag')),
5796 [('f', 'force', None, _('force tag')),
5796 ('l', 'local', None, _('make the tag local')),
5797 ('l', 'local', None, _('make the tag local')),
5797 ('r', 'rev', '', _('revision to tag'), _('REV')),
5798 ('r', 'rev', '', _('revision to tag'), _('REV')),
5798 ('', 'remove', None, _('remove a tag')),
5799 ('', 'remove', None, _('remove a tag')),
5799 # -l/--local is already there, commitopts cannot be used
5800 # -l/--local is already there, commitopts cannot be used
5800 ('e', 'edit', None, _('invoke editor on commit messages')),
5801 ('e', 'edit', None, _('invoke editor on commit messages')),
5801 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
5802 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
5802 ] + commitopts2,
5803 ] + commitopts2,
5803 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
5804 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
5804 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
5805 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
5805 def tag(ui, repo, name1, *names, **opts):
5806 def tag(ui, repo, name1, *names, **opts):
5806 """add one or more tags for the current or given revision
5807 """add one or more tags for the current or given revision
5807
5808
5808 Name a particular revision using <name>.
5809 Name a particular revision using <name>.
5809
5810
5810 Tags are used to name particular revisions of the repository and are
5811 Tags are used to name particular revisions of the repository and are
5811 very useful to compare different revisions, to go back to significant
5812 very useful to compare different revisions, to go back to significant
5812 earlier versions or to mark branch points as releases, etc. Changing
5813 earlier versions or to mark branch points as releases, etc. Changing
5813 an existing tag is normally disallowed; use -f/--force to override.
5814 an existing tag is normally disallowed; use -f/--force to override.
5814
5815
5815 If no revision is given, the parent of the working directory is
5816 If no revision is given, the parent of the working directory is
5816 used.
5817 used.
5817
5818
5818 To facilitate version control, distribution, and merging of tags,
5819 To facilitate version control, distribution, and merging of tags,
5819 they are stored as a file named ".hgtags" which is managed similarly
5820 they are stored as a file named ".hgtags" which is managed similarly
5820 to other project files and can be hand-edited if necessary. This
5821 to other project files and can be hand-edited if necessary. This
5821 also means that tagging creates a new commit. The file
5822 also means that tagging creates a new commit. The file
5822 ".hg/localtags" is used for local tags (not shared among
5823 ".hg/localtags" is used for local tags (not shared among
5823 repositories).
5824 repositories).
5824
5825
5825 Tag commits are usually made at the head of a branch. If the parent
5826 Tag commits are usually made at the head of a branch. If the parent
5826 of the working directory is not a branch head, :hg:`tag` aborts; use
5827 of the working directory is not a branch head, :hg:`tag` aborts; use
5827 -f/--force to force the tag commit to be based on a non-head
5828 -f/--force to force the tag commit to be based on a non-head
5828 changeset.
5829 changeset.
5829
5830
5830 See :hg:`help dates` for a list of formats valid for -d/--date.
5831 See :hg:`help dates` for a list of formats valid for -d/--date.
5831
5832
5832 Since tag names have priority over branch names during revision
5833 Since tag names have priority over branch names during revision
5833 lookup, using an existing branch name as a tag name is discouraged.
5834 lookup, using an existing branch name as a tag name is discouraged.
5834
5835
5835 Returns 0 on success.
5836 Returns 0 on success.
5836 """
5837 """
5837 opts = pycompat.byteskwargs(opts)
5838 opts = pycompat.byteskwargs(opts)
5838 with repo.wlock(), repo.lock():
5839 with repo.wlock(), repo.lock():
5839 rev_ = "."
5840 rev_ = "."
5840 names = [t.strip() for t in (name1,) + names]
5841 names = [t.strip() for t in (name1,) + names]
5841 if len(names) != len(set(names)):
5842 if len(names) != len(set(names)):
5842 raise error.Abort(_('tag names must be unique'))
5843 raise error.Abort(_('tag names must be unique'))
5843 for n in names:
5844 for n in names:
5844 scmutil.checknewlabel(repo, n, 'tag')
5845 scmutil.checknewlabel(repo, n, 'tag')
5845 if not n:
5846 if not n:
5846 raise error.Abort(_('tag names cannot consist entirely of '
5847 raise error.Abort(_('tag names cannot consist entirely of '
5847 'whitespace'))
5848 'whitespace'))
5848 if opts.get('rev') and opts.get('remove'):
5849 if opts.get('rev') and opts.get('remove'):
5849 raise error.Abort(_("--rev and --remove are incompatible"))
5850 raise error.Abort(_("--rev and --remove are incompatible"))
5850 if opts.get('rev'):
5851 if opts.get('rev'):
5851 rev_ = opts['rev']
5852 rev_ = opts['rev']
5852 message = opts.get('message')
5853 message = opts.get('message')
5853 if opts.get('remove'):
5854 if opts.get('remove'):
5854 if opts.get('local'):
5855 if opts.get('local'):
5855 expectedtype = 'local'
5856 expectedtype = 'local'
5856 else:
5857 else:
5857 expectedtype = 'global'
5858 expectedtype = 'global'
5858
5859
5859 for n in names:
5860 for n in names:
5860 if repo.tagtype(n) == 'global':
5861 if repo.tagtype(n) == 'global':
5861 alltags = tagsmod.findglobaltags(ui, repo)
5862 alltags = tagsmod.findglobaltags(ui, repo)
5862 if alltags[n][0] == nullid:
5863 if alltags[n][0] == nullid:
5863 raise error.Abort(_("tag '%s' is already removed") % n)
5864 raise error.Abort(_("tag '%s' is already removed") % n)
5864 if not repo.tagtype(n):
5865 if not repo.tagtype(n):
5865 raise error.Abort(_("tag '%s' does not exist") % n)
5866 raise error.Abort(_("tag '%s' does not exist") % n)
5866 if repo.tagtype(n) != expectedtype:
5867 if repo.tagtype(n) != expectedtype:
5867 if expectedtype == 'global':
5868 if expectedtype == 'global':
5868 raise error.Abort(_("tag '%s' is not a global tag") % n)
5869 raise error.Abort(_("tag '%s' is not a global tag") % n)
5869 else:
5870 else:
5870 raise error.Abort(_("tag '%s' is not a local tag") % n)
5871 raise error.Abort(_("tag '%s' is not a local tag") % n)
5871 rev_ = 'null'
5872 rev_ = 'null'
5872 if not message:
5873 if not message:
5873 # we don't translate commit messages
5874 # we don't translate commit messages
5874 message = 'Removed tag %s' % ', '.join(names)
5875 message = 'Removed tag %s' % ', '.join(names)
5875 elif not opts.get('force'):
5876 elif not opts.get('force'):
5876 for n in names:
5877 for n in names:
5877 if n in repo.tags():
5878 if n in repo.tags():
5878 raise error.Abort(_("tag '%s' already exists "
5879 raise error.Abort(_("tag '%s' already exists "
5879 "(use -f to force)") % n)
5880 "(use -f to force)") % n)
5880 if not opts.get('local'):
5881 if not opts.get('local'):
5881 p1, p2 = repo.dirstate.parents()
5882 p1, p2 = repo.dirstate.parents()
5882 if p2 != nullid:
5883 if p2 != nullid:
5883 raise error.Abort(_('uncommitted merge'))
5884 raise error.Abort(_('uncommitted merge'))
5884 bheads = repo.branchheads()
5885 bheads = repo.branchheads()
5885 if not opts.get('force') and bheads and p1 not in bheads:
5886 if not opts.get('force') and bheads and p1 not in bheads:
5886 raise error.Abort(_('working directory is not at a branch head '
5887 raise error.Abort(_('working directory is not at a branch head '
5887 '(use -f to force)'))
5888 '(use -f to force)'))
5888 node = scmutil.revsingle(repo, rev_).node()
5889 node = scmutil.revsingle(repo, rev_).node()
5889
5890
5890 if not message:
5891 if not message:
5891 # we don't translate commit messages
5892 # we don't translate commit messages
5892 message = ('Added tag %s for changeset %s' %
5893 message = ('Added tag %s for changeset %s' %
5893 (', '.join(names), short(node)))
5894 (', '.join(names), short(node)))
5894
5895
5895 date = opts.get('date')
5896 date = opts.get('date')
5896 if date:
5897 if date:
5897 date = dateutil.parsedate(date)
5898 date = dateutil.parsedate(date)
5898
5899
5899 if opts.get('remove'):
5900 if opts.get('remove'):
5900 editform = 'tag.remove'
5901 editform = 'tag.remove'
5901 else:
5902 else:
5902 editform = 'tag.add'
5903 editform = 'tag.add'
5903 editor = cmdutil.getcommiteditor(editform=editform,
5904 editor = cmdutil.getcommiteditor(editform=editform,
5904 **pycompat.strkwargs(opts))
5905 **pycompat.strkwargs(opts))
5905
5906
5906 # don't allow tagging the null rev
5907 # don't allow tagging the null rev
5907 if (not opts.get('remove') and
5908 if (not opts.get('remove') and
5908 scmutil.revsingle(repo, rev_).rev() == nullrev):
5909 scmutil.revsingle(repo, rev_).rev() == nullrev):
5909 raise error.Abort(_("cannot tag null revision"))
5910 raise error.Abort(_("cannot tag null revision"))
5910
5911
5911 tagsmod.tag(repo, names, node, message, opts.get('local'),
5912 tagsmod.tag(repo, names, node, message, opts.get('local'),
5912 opts.get('user'), date, editor=editor)
5913 opts.get('user'), date, editor=editor)
5913
5914
5914 @command(
5915 @command(
5915 'tags', formatteropts, '',
5916 'tags', formatteropts, '',
5916 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5917 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5917 intents={INTENT_READONLY})
5918 intents={INTENT_READONLY})
5918 def tags(ui, repo, **opts):
5919 def tags(ui, repo, **opts):
5919 """list repository tags
5920 """list repository tags
5920
5921
5921 This lists both regular and local tags. When the -v/--verbose
5922 This lists both regular and local tags. When the -v/--verbose
5922 switch is used, a third column "local" is printed for local tags.
5923 switch is used, a third column "local" is printed for local tags.
5923 When the -q/--quiet switch is used, only the tag name is printed.
5924 When the -q/--quiet switch is used, only the tag name is printed.
5924
5925
5925 .. container:: verbose
5926 .. container:: verbose
5926
5927
5927 Template:
5928 Template:
5928
5929
5929 The following keywords are supported in addition to the common template
5930 The following keywords are supported in addition to the common template
5930 keywords and functions such as ``{tag}``. See also
5931 keywords and functions such as ``{tag}``. See also
5931 :hg:`help templates`.
5932 :hg:`help templates`.
5932
5933
5933 :type: String. ``local`` for local tags.
5934 :type: String. ``local`` for local tags.
5934
5935
5935 Returns 0 on success.
5936 Returns 0 on success.
5936 """
5937 """
5937
5938
5938 opts = pycompat.byteskwargs(opts)
5939 opts = pycompat.byteskwargs(opts)
5939 ui.pager('tags')
5940 ui.pager('tags')
5940 fm = ui.formatter('tags', opts)
5941 fm = ui.formatter('tags', opts)
5941 hexfunc = fm.hexfunc
5942 hexfunc = fm.hexfunc
5942
5943
5943 for t, n in reversed(repo.tagslist()):
5944 for t, n in reversed(repo.tagslist()):
5944 hn = hexfunc(n)
5945 hn = hexfunc(n)
5945 label = 'tags.normal'
5946 label = 'tags.normal'
5946 tagtype = ''
5947 tagtype = ''
5947 if repo.tagtype(t) == 'local':
5948 if repo.tagtype(t) == 'local':
5948 label = 'tags.local'
5949 label = 'tags.local'
5949 tagtype = 'local'
5950 tagtype = 'local'
5950
5951
5951 fm.startitem()
5952 fm.startitem()
5952 fm.context(repo=repo)
5953 fm.context(repo=repo)
5953 fm.write('tag', '%s', t, label=label)
5954 fm.write('tag', '%s', t, label=label)
5954 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5955 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5955 fm.condwrite(not ui.quiet, 'rev node', fmt,
5956 fm.condwrite(not ui.quiet, 'rev node', fmt,
5956 repo.changelog.rev(n), hn, label=label)
5957 repo.changelog.rev(n), hn, label=label)
5957 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5958 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5958 tagtype, label=label)
5959 tagtype, label=label)
5959 fm.plain('\n')
5960 fm.plain('\n')
5960 fm.end()
5961 fm.end()
5961
5962
5962 @command('tip',
5963 @command('tip',
5963 [('p', 'patch', None, _('show patch')),
5964 [('p', 'patch', None, _('show patch')),
5964 ('g', 'git', None, _('use git extended diff format')),
5965 ('g', 'git', None, _('use git extended diff format')),
5965 ] + templateopts,
5966 ] + templateopts,
5966 _('[-p] [-g]'),
5967 _('[-p] [-g]'),
5967 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
5968 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
5968 def tip(ui, repo, **opts):
5969 def tip(ui, repo, **opts):
5969 """show the tip revision (DEPRECATED)
5970 """show the tip revision (DEPRECATED)
5970
5971
5971 The tip revision (usually just called the tip) is the changeset
5972 The tip revision (usually just called the tip) is the changeset
5972 most recently added to the repository (and therefore the most
5973 most recently added to the repository (and therefore the most
5973 recently changed head).
5974 recently changed head).
5974
5975
5975 If you have just made a commit, that commit will be the tip. If
5976 If you have just made a commit, that commit will be the tip. If
5976 you have just pulled changes from another repository, the tip of
5977 you have just pulled changes from another repository, the tip of
5977 that repository becomes the current tip. The "tip" tag is special
5978 that repository becomes the current tip. The "tip" tag is special
5978 and cannot be renamed or assigned to a different changeset.
5979 and cannot be renamed or assigned to a different changeset.
5979
5980
5980 This command is deprecated, please use :hg:`heads` instead.
5981 This command is deprecated, please use :hg:`heads` instead.
5981
5982
5982 Returns 0 on success.
5983 Returns 0 on success.
5983 """
5984 """
5984 opts = pycompat.byteskwargs(opts)
5985 opts = pycompat.byteskwargs(opts)
5985 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5986 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5986 displayer.show(repo['tip'])
5987 displayer.show(repo['tip'])
5987 displayer.close()
5988 displayer.close()
5988
5989
5989 @command('unbundle',
5990 @command('unbundle',
5990 [('u', 'update', None,
5991 [('u', 'update', None,
5991 _('update to new branch head if changesets were unbundled'))],
5992 _('update to new branch head if changesets were unbundled'))],
5992 _('[-u] FILE...'),
5993 _('[-u] FILE...'),
5993 helpcategory=command.CATEGORY_IMPORT_EXPORT)
5994 helpcategory=command.CATEGORY_IMPORT_EXPORT)
5994 def unbundle(ui, repo, fname1, *fnames, **opts):
5995 def unbundle(ui, repo, fname1, *fnames, **opts):
5995 """apply one or more bundle files
5996 """apply one or more bundle files
5996
5997
5997 Apply one or more bundle files generated by :hg:`bundle`.
5998 Apply one or more bundle files generated by :hg:`bundle`.
5998
5999
5999 Returns 0 on success, 1 if an update has unresolved files.
6000 Returns 0 on success, 1 if an update has unresolved files.
6000 """
6001 """
6001 fnames = (fname1,) + fnames
6002 fnames = (fname1,) + fnames
6002
6003
6003 with repo.lock():
6004 with repo.lock():
6004 for fname in fnames:
6005 for fname in fnames:
6005 f = hg.openpath(ui, fname)
6006 f = hg.openpath(ui, fname)
6006 gen = exchange.readbundle(ui, f, fname)
6007 gen = exchange.readbundle(ui, f, fname)
6007 if isinstance(gen, streamclone.streamcloneapplier):
6008 if isinstance(gen, streamclone.streamcloneapplier):
6008 raise error.Abort(
6009 raise error.Abort(
6009 _('packed bundles cannot be applied with '
6010 _('packed bundles cannot be applied with '
6010 '"hg unbundle"'),
6011 '"hg unbundle"'),
6011 hint=_('use "hg debugapplystreamclonebundle"'))
6012 hint=_('use "hg debugapplystreamclonebundle"'))
6012 url = 'bundle:' + fname
6013 url = 'bundle:' + fname
6013 try:
6014 try:
6014 txnname = 'unbundle'
6015 txnname = 'unbundle'
6015 if not isinstance(gen, bundle2.unbundle20):
6016 if not isinstance(gen, bundle2.unbundle20):
6016 txnname = 'unbundle\n%s' % util.hidepassword(url)
6017 txnname = 'unbundle\n%s' % util.hidepassword(url)
6017 with repo.transaction(txnname) as tr:
6018 with repo.transaction(txnname) as tr:
6018 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6019 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6019 url=url)
6020 url=url)
6020 except error.BundleUnknownFeatureError as exc:
6021 except error.BundleUnknownFeatureError as exc:
6021 raise error.Abort(
6022 raise error.Abort(
6022 _('%s: unknown bundle feature, %s') % (fname, exc),
6023 _('%s: unknown bundle feature, %s') % (fname, exc),
6023 hint=_("see https://mercurial-scm.org/"
6024 hint=_("see https://mercurial-scm.org/"
6024 "wiki/BundleFeature for more "
6025 "wiki/BundleFeature for more "
6025 "information"))
6026 "information"))
6026 modheads = bundle2.combinechangegroupresults(op)
6027 modheads = bundle2.combinechangegroupresults(op)
6027
6028
6028 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
6029 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
6029
6030
6030 @command('update|up|checkout|co',
6031 @command('update|up|checkout|co',
6031 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6032 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6032 ('c', 'check', None, _('require clean working directory')),
6033 ('c', 'check', None, _('require clean working directory')),
6033 ('m', 'merge', None, _('merge uncommitted changes')),
6034 ('m', 'merge', None, _('merge uncommitted changes')),
6034 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6035 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6035 ('r', 'rev', '', _('revision'), _('REV'))
6036 ('r', 'rev', '', _('revision'), _('REV'))
6036 ] + mergetoolopts,
6037 ] + mergetoolopts,
6037 _('[-C|-c|-m] [-d DATE] [[-r] REV]'),
6038 _('[-C|-c|-m] [-d DATE] [[-r] REV]'),
6038 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6039 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6039 helpbasic=True)
6040 helpbasic=True)
6040 def update(ui, repo, node=None, **opts):
6041 def update(ui, repo, node=None, **opts):
6041 """update working directory (or switch revisions)
6042 """update working directory (or switch revisions)
6042
6043
6043 Update the repository's working directory to the specified
6044 Update the repository's working directory to the specified
6044 changeset. If no changeset is specified, update to the tip of the
6045 changeset. If no changeset is specified, update to the tip of the
6045 current named branch and move the active bookmark (see :hg:`help
6046 current named branch and move the active bookmark (see :hg:`help
6046 bookmarks`).
6047 bookmarks`).
6047
6048
6048 Update sets the working directory's parent revision to the specified
6049 Update sets the working directory's parent revision to the specified
6049 changeset (see :hg:`help parents`).
6050 changeset (see :hg:`help parents`).
6050
6051
6051 If the changeset is not a descendant or ancestor of the working
6052 If the changeset is not a descendant or ancestor of the working
6052 directory's parent and there are uncommitted changes, the update is
6053 directory's parent and there are uncommitted changes, the update is
6053 aborted. With the -c/--check option, the working directory is checked
6054 aborted. With the -c/--check option, the working directory is checked
6054 for uncommitted changes; if none are found, the working directory is
6055 for uncommitted changes; if none are found, the working directory is
6055 updated to the specified changeset.
6056 updated to the specified changeset.
6056
6057
6057 .. container:: verbose
6058 .. container:: verbose
6058
6059
6059 The -C/--clean, -c/--check, and -m/--merge options control what
6060 The -C/--clean, -c/--check, and -m/--merge options control what
6060 happens if the working directory contains uncommitted changes.
6061 happens if the working directory contains uncommitted changes.
6061 At most of one of them can be specified.
6062 At most of one of them can be specified.
6062
6063
6063 1. If no option is specified, and if
6064 1. If no option is specified, and if
6064 the requested changeset is an ancestor or descendant of
6065 the requested changeset is an ancestor or descendant of
6065 the working directory's parent, the uncommitted changes
6066 the working directory's parent, the uncommitted changes
6066 are merged into the requested changeset and the merged
6067 are merged into the requested changeset and the merged
6067 result is left uncommitted. If the requested changeset is
6068 result is left uncommitted. If the requested changeset is
6068 not an ancestor or descendant (that is, it is on another
6069 not an ancestor or descendant (that is, it is on another
6069 branch), the update is aborted and the uncommitted changes
6070 branch), the update is aborted and the uncommitted changes
6070 are preserved.
6071 are preserved.
6071
6072
6072 2. With the -m/--merge option, the update is allowed even if the
6073 2. With the -m/--merge option, the update is allowed even if the
6073 requested changeset is not an ancestor or descendant of
6074 requested changeset is not an ancestor or descendant of
6074 the working directory's parent.
6075 the working directory's parent.
6075
6076
6076 3. With the -c/--check option, the update is aborted and the
6077 3. With the -c/--check option, the update is aborted and the
6077 uncommitted changes are preserved.
6078 uncommitted changes are preserved.
6078
6079
6079 4. With the -C/--clean option, uncommitted changes are discarded and
6080 4. With the -C/--clean option, uncommitted changes are discarded and
6080 the working directory is updated to the requested changeset.
6081 the working directory is updated to the requested changeset.
6081
6082
6082 To cancel an uncommitted merge (and lose your changes), use
6083 To cancel an uncommitted merge (and lose your changes), use
6083 :hg:`merge --abort`.
6084 :hg:`merge --abort`.
6084
6085
6085 Use null as the changeset to remove the working directory (like
6086 Use null as the changeset to remove the working directory (like
6086 :hg:`clone -U`).
6087 :hg:`clone -U`).
6087
6088
6088 If you want to revert just one file to an older revision, use
6089 If you want to revert just one file to an older revision, use
6089 :hg:`revert [-r REV] NAME`.
6090 :hg:`revert [-r REV] NAME`.
6090
6091
6091 See :hg:`help dates` for a list of formats valid for -d/--date.
6092 See :hg:`help dates` for a list of formats valid for -d/--date.
6092
6093
6093 Returns 0 on success, 1 if there are unresolved files.
6094 Returns 0 on success, 1 if there are unresolved files.
6094 """
6095 """
6095 rev = opts.get(r'rev')
6096 rev = opts.get(r'rev')
6096 date = opts.get(r'date')
6097 date = opts.get(r'date')
6097 clean = opts.get(r'clean')
6098 clean = opts.get(r'clean')
6098 check = opts.get(r'check')
6099 check = opts.get(r'check')
6099 merge = opts.get(r'merge')
6100 merge = opts.get(r'merge')
6100 if rev and node:
6101 if rev and node:
6101 raise error.Abort(_("please specify just one revision"))
6102 raise error.Abort(_("please specify just one revision"))
6102
6103
6103 if ui.configbool('commands', 'update.requiredest'):
6104 if ui.configbool('commands', 'update.requiredest'):
6104 if not node and not rev and not date:
6105 if not node and not rev and not date:
6105 raise error.Abort(_('you must specify a destination'),
6106 raise error.Abort(_('you must specify a destination'),
6106 hint=_('for example: hg update ".::"'))
6107 hint=_('for example: hg update ".::"'))
6107
6108
6108 if rev is None or rev == '':
6109 if rev is None or rev == '':
6109 rev = node
6110 rev = node
6110
6111
6111 if date and rev is not None:
6112 if date and rev is not None:
6112 raise error.Abort(_("you can't specify a revision and a date"))
6113 raise error.Abort(_("you can't specify a revision and a date"))
6113
6114
6114 if len([x for x in (clean, check, merge) if x]) > 1:
6115 if len([x for x in (clean, check, merge) if x]) > 1:
6115 raise error.Abort(_("can only specify one of -C/--clean, -c/--check, "
6116 raise error.Abort(_("can only specify one of -C/--clean, -c/--check, "
6116 "or -m/--merge"))
6117 "or -m/--merge"))
6117
6118
6118 updatecheck = None
6119 updatecheck = None
6119 if check:
6120 if check:
6120 updatecheck = 'abort'
6121 updatecheck = 'abort'
6121 elif merge:
6122 elif merge:
6122 updatecheck = 'none'
6123 updatecheck = 'none'
6123
6124
6124 with repo.wlock():
6125 with repo.wlock():
6125 cmdutil.clearunfinished(repo)
6126 cmdutil.clearunfinished(repo)
6126
6127
6127 if date:
6128 if date:
6128 rev = cmdutil.finddate(ui, repo, date)
6129 rev = cmdutil.finddate(ui, repo, date)
6129
6130
6130 # if we defined a bookmark, we have to remember the original name
6131 # if we defined a bookmark, we have to remember the original name
6131 brev = rev
6132 brev = rev
6132 if rev:
6133 if rev:
6133 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
6134 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
6134 ctx = scmutil.revsingle(repo, rev, default=None)
6135 ctx = scmutil.revsingle(repo, rev, default=None)
6135 rev = ctx.rev()
6136 rev = ctx.rev()
6136 hidden = ctx.hidden()
6137 hidden = ctx.hidden()
6137 overrides = {('ui', 'forcemerge'): opts.get(r'tool', '')}
6138 overrides = {('ui', 'forcemerge'): opts.get(r'tool', '')}
6138 with ui.configoverride(overrides, 'update'):
6139 with ui.configoverride(overrides, 'update'):
6139 ret = hg.updatetotally(ui, repo, rev, brev, clean=clean,
6140 ret = hg.updatetotally(ui, repo, rev, brev, clean=clean,
6140 updatecheck=updatecheck)
6141 updatecheck=updatecheck)
6141 if hidden:
6142 if hidden:
6142 ctxstr = ctx.hex()[:12]
6143 ctxstr = ctx.hex()[:12]
6143 ui.warn(_("updated to hidden changeset %s\n") % ctxstr)
6144 ui.warn(_("updated to hidden changeset %s\n") % ctxstr)
6144
6145
6145 if ctx.obsolete():
6146 if ctx.obsolete():
6146 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
6147 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
6147 ui.warn("(%s)\n" % obsfatemsg)
6148 ui.warn("(%s)\n" % obsfatemsg)
6148 return ret
6149 return ret
6149
6150
6150 @command('verify', [], helpcategory=command.CATEGORY_MAINTENANCE)
6151 @command('verify',
6151 def verify(ui, repo):
6152 [('', 'full', False, 'perform more checks (EXPERIMENTAL)')],
6153 helpcategory=command.CATEGORY_MAINTENANCE)
6154 def verify(ui, repo, **opts):
6152 """verify the integrity of the repository
6155 """verify the integrity of the repository
6153
6156
6154 Verify the integrity of the current repository.
6157 Verify the integrity of the current repository.
6155
6158
6156 This will perform an extensive check of the repository's
6159 This will perform an extensive check of the repository's
6157 integrity, validating the hashes and checksums of each entry in
6160 integrity, validating the hashes and checksums of each entry in
6158 the changelog, manifest, and tracked files, as well as the
6161 the changelog, manifest, and tracked files, as well as the
6159 integrity of their crosslinks and indices.
6162 integrity of their crosslinks and indices.
6160
6163
6161 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6164 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6162 for more information about recovery from corruption of the
6165 for more information about recovery from corruption of the
6163 repository.
6166 repository.
6164
6167
6165 Returns 0 on success, 1 if errors are encountered.
6168 Returns 0 on success, 1 if errors are encountered.
6166 """
6169 """
6167 return hg.verify(repo)
6170 level = None
6171 if opts['full']:
6172 level = verifymod.VERIFY_FULL
6173 return hg.verify(repo, level)
6168
6174
6169 @command(
6175 @command(
6170 'version', [] + formatteropts, helpcategory=command.CATEGORY_HELP,
6176 'version', [] + formatteropts, helpcategory=command.CATEGORY_HELP,
6171 norepo=True, intents={INTENT_READONLY})
6177 norepo=True, intents={INTENT_READONLY})
6172 def version_(ui, **opts):
6178 def version_(ui, **opts):
6173 """output version and copyright information
6179 """output version and copyright information
6174
6180
6175 .. container:: verbose
6181 .. container:: verbose
6176
6182
6177 Template:
6183 Template:
6178
6184
6179 The following keywords are supported. See also :hg:`help templates`.
6185 The following keywords are supported. See also :hg:`help templates`.
6180
6186
6181 :extensions: List of extensions.
6187 :extensions: List of extensions.
6182 :ver: String. Version number.
6188 :ver: String. Version number.
6183
6189
6184 And each entry of ``{extensions}`` provides the following sub-keywords
6190 And each entry of ``{extensions}`` provides the following sub-keywords
6185 in addition to ``{ver}``.
6191 in addition to ``{ver}``.
6186
6192
6187 :bundled: Boolean. True if included in the release.
6193 :bundled: Boolean. True if included in the release.
6188 :name: String. Extension name.
6194 :name: String. Extension name.
6189 """
6195 """
6190 opts = pycompat.byteskwargs(opts)
6196 opts = pycompat.byteskwargs(opts)
6191 if ui.verbose:
6197 if ui.verbose:
6192 ui.pager('version')
6198 ui.pager('version')
6193 fm = ui.formatter("version", opts)
6199 fm = ui.formatter("version", opts)
6194 fm.startitem()
6200 fm.startitem()
6195 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
6201 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
6196 util.version())
6202 util.version())
6197 license = _(
6203 license = _(
6198 "(see https://mercurial-scm.org for more information)\n"
6204 "(see https://mercurial-scm.org for more information)\n"
6199 "\nCopyright (C) 2005-2019 Matt Mackall and others\n"
6205 "\nCopyright (C) 2005-2019 Matt Mackall and others\n"
6200 "This is free software; see the source for copying conditions. "
6206 "This is free software; see the source for copying conditions. "
6201 "There is NO\nwarranty; "
6207 "There is NO\nwarranty; "
6202 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6208 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6203 )
6209 )
6204 if not ui.quiet:
6210 if not ui.quiet:
6205 fm.plain(license)
6211 fm.plain(license)
6206
6212
6207 if ui.verbose:
6213 if ui.verbose:
6208 fm.plain(_("\nEnabled extensions:\n\n"))
6214 fm.plain(_("\nEnabled extensions:\n\n"))
6209 # format names and versions into columns
6215 # format names and versions into columns
6210 names = []
6216 names = []
6211 vers = []
6217 vers = []
6212 isinternals = []
6218 isinternals = []
6213 for name, module in extensions.extensions():
6219 for name, module in extensions.extensions():
6214 names.append(name)
6220 names.append(name)
6215 vers.append(extensions.moduleversion(module) or None)
6221 vers.append(extensions.moduleversion(module) or None)
6216 isinternals.append(extensions.ismoduleinternal(module))
6222 isinternals.append(extensions.ismoduleinternal(module))
6217 fn = fm.nested("extensions", tmpl='{name}\n')
6223 fn = fm.nested("extensions", tmpl='{name}\n')
6218 if names:
6224 if names:
6219 namefmt = " %%-%ds " % max(len(n) for n in names)
6225 namefmt = " %%-%ds " % max(len(n) for n in names)
6220 places = [_("external"), _("internal")]
6226 places = [_("external"), _("internal")]
6221 for n, v, p in zip(names, vers, isinternals):
6227 for n, v, p in zip(names, vers, isinternals):
6222 fn.startitem()
6228 fn.startitem()
6223 fn.condwrite(ui.verbose, "name", namefmt, n)
6229 fn.condwrite(ui.verbose, "name", namefmt, n)
6224 if ui.verbose:
6230 if ui.verbose:
6225 fn.plain("%s " % places[p])
6231 fn.plain("%s " % places[p])
6226 fn.data(bundled=p)
6232 fn.data(bundled=p)
6227 fn.condwrite(ui.verbose and v, "ver", "%s", v)
6233 fn.condwrite(ui.verbose and v, "ver", "%s", v)
6228 if ui.verbose:
6234 if ui.verbose:
6229 fn.plain("\n")
6235 fn.plain("\n")
6230 fn.end()
6236 fn.end()
6231 fm.end()
6237 fm.end()
6232
6238
6233 def loadcmdtable(ui, name, cmdtable):
6239 def loadcmdtable(ui, name, cmdtable):
6234 """Load command functions from specified cmdtable
6240 """Load command functions from specified cmdtable
6235 """
6241 """
6236 cmdtable = cmdtable.copy()
6242 cmdtable = cmdtable.copy()
6237 for cmd in list(cmdtable):
6243 for cmd in list(cmdtable):
6238 if not cmd.startswith('^'):
6244 if not cmd.startswith('^'):
6239 continue
6245 continue
6240 ui.deprecwarn("old-style command registration '%s' in extension '%s'"
6246 ui.deprecwarn("old-style command registration '%s' in extension '%s'"
6241 % (cmd, name), '4.8')
6247 % (cmd, name), '4.8')
6242 entry = cmdtable.pop(cmd)
6248 entry = cmdtable.pop(cmd)
6243 entry[0].helpbasic = True
6249 entry[0].helpbasic = True
6244 cmdtable[cmd[1:]] = entry
6250 cmdtable[cmd[1:]] = entry
6245
6251
6246 overrides = [cmd for cmd in cmdtable if cmd in table]
6252 overrides = [cmd for cmd in cmdtable if cmd in table]
6247 if overrides:
6253 if overrides:
6248 ui.warn(_("extension '%s' overrides commands: %s\n")
6254 ui.warn(_("extension '%s' overrides commands: %s\n")
6249 % (name, " ".join(overrides)))
6255 % (name, " ".join(overrides)))
6250 table.update(cmdtable)
6256 table.update(cmdtable)
@@ -1,541 +1,542 b''
1 # verify.py - repository integrity checking for Mercurial
1 # verify.py - repository integrity checking for Mercurial
2 #
2 #
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 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 os
10 import os
11
11
12 from .i18n import _
12 from .i18n import _
13 from .node import (
13 from .node import (
14 nullid,
14 nullid,
15 short,
15 short,
16 )
16 )
17
17
18 from . import (
18 from . import (
19 error,
19 error,
20 pycompat,
20 pycompat,
21 revlog,
21 revlog,
22 util,
22 util,
23 )
23 )
24
24
25 VERIFY_DEFAULT = 0
25 VERIFY_DEFAULT = 0
26 VERIFY_FULL = 1
26
27
27 def verify(repo, level=None):
28 def verify(repo, level=None):
28 with repo.lock():
29 with repo.lock():
29 v = verifier(repo, level)
30 v = verifier(repo, level)
30 return v.verify()
31 return v.verify()
31
32
32 def _normpath(f):
33 def _normpath(f):
33 # under hg < 2.4, convert didn't sanitize paths properly, so a
34 # under hg < 2.4, convert didn't sanitize paths properly, so a
34 # converted repo may contain repeated slashes
35 # converted repo may contain repeated slashes
35 while '//' in f:
36 while '//' in f:
36 f = f.replace('//', '/')
37 f = f.replace('//', '/')
37 return f
38 return f
38
39
39 class verifier(object):
40 class verifier(object):
40 def __init__(self, repo, level=None):
41 def __init__(self, repo, level=None):
41 self.repo = repo.unfiltered()
42 self.repo = repo.unfiltered()
42 self.ui = repo.ui
43 self.ui = repo.ui
43 self.match = repo.narrowmatch()
44 self.match = repo.narrowmatch()
44 if level is None:
45 if level is None:
45 level = VERIFY_DEFAULT
46 level = VERIFY_DEFAULT
46 self._level = level
47 self._level = level
47 self.badrevs = set()
48 self.badrevs = set()
48 self.errors = 0
49 self.errors = 0
49 self.warnings = 0
50 self.warnings = 0
50 self.havecl = len(repo.changelog) > 0
51 self.havecl = len(repo.changelog) > 0
51 self.havemf = len(repo.manifestlog.getstorage(b'')) > 0
52 self.havemf = len(repo.manifestlog.getstorage(b'')) > 0
52 self.revlogv1 = repo.changelog.version != revlog.REVLOGV0
53 self.revlogv1 = repo.changelog.version != revlog.REVLOGV0
53 self.lrugetctx = util.lrucachefunc(repo.__getitem__)
54 self.lrugetctx = util.lrucachefunc(repo.__getitem__)
54 self.refersmf = False
55 self.refersmf = False
55 self.fncachewarned = False
56 self.fncachewarned = False
56 # developer config: verify.skipflags
57 # developer config: verify.skipflags
57 self.skipflags = repo.ui.configint('verify', 'skipflags')
58 self.skipflags = repo.ui.configint('verify', 'skipflags')
58 self.warnorphanstorefiles = True
59 self.warnorphanstorefiles = True
59
60
60 def _warn(self, msg):
61 def _warn(self, msg):
61 """record a "warning" level issue"""
62 """record a "warning" level issue"""
62 self.ui.warn(msg + "\n")
63 self.ui.warn(msg + "\n")
63 self.warnings += 1
64 self.warnings += 1
64
65
65 def _err(self, linkrev, msg, filename=None):
66 def _err(self, linkrev, msg, filename=None):
66 """record a "error" level issue"""
67 """record a "error" level issue"""
67 if linkrev is not None:
68 if linkrev is not None:
68 self.badrevs.add(linkrev)
69 self.badrevs.add(linkrev)
69 linkrev = "%d" % linkrev
70 linkrev = "%d" % linkrev
70 else:
71 else:
71 linkrev = '?'
72 linkrev = '?'
72 msg = "%s: %s" % (linkrev, msg)
73 msg = "%s: %s" % (linkrev, msg)
73 if filename:
74 if filename:
74 msg = "%s@%s" % (filename, msg)
75 msg = "%s@%s" % (filename, msg)
75 self.ui.warn(" " + msg + "\n")
76 self.ui.warn(" " + msg + "\n")
76 self.errors += 1
77 self.errors += 1
77
78
78 def _exc(self, linkrev, msg, inst, filename=None):
79 def _exc(self, linkrev, msg, inst, filename=None):
79 """record exception raised during the verify process"""
80 """record exception raised during the verify process"""
80 fmsg = pycompat.bytestr(inst)
81 fmsg = pycompat.bytestr(inst)
81 if not fmsg:
82 if not fmsg:
82 fmsg = pycompat.byterepr(inst)
83 fmsg = pycompat.byterepr(inst)
83 self._err(linkrev, "%s: %s" % (msg, fmsg), filename)
84 self._err(linkrev, "%s: %s" % (msg, fmsg), filename)
84
85
85 def _checkrevlog(self, obj, name, linkrev):
86 def _checkrevlog(self, obj, name, linkrev):
86 """verify high level property of a revlog
87 """verify high level property of a revlog
87
88
88 - revlog is present,
89 - revlog is present,
89 - revlog is non-empty,
90 - revlog is non-empty,
90 - sizes (index and data) are correct,
91 - sizes (index and data) are correct,
91 - revlog's format version is correct.
92 - revlog's format version is correct.
92 """
93 """
93 if not len(obj) and (self.havecl or self.havemf):
94 if not len(obj) and (self.havecl or self.havemf):
94 self._err(linkrev, _("empty or missing %s") % name)
95 self._err(linkrev, _("empty or missing %s") % name)
95 return
96 return
96
97
97 d = obj.checksize()
98 d = obj.checksize()
98 if d[0]:
99 if d[0]:
99 self.err(None, _("data length off by %d bytes") % d[0], name)
100 self.err(None, _("data length off by %d bytes") % d[0], name)
100 if d[1]:
101 if d[1]:
101 self.err(None, _("index contains %d extra bytes") % d[1], name)
102 self.err(None, _("index contains %d extra bytes") % d[1], name)
102
103
103 if obj.version != revlog.REVLOGV0:
104 if obj.version != revlog.REVLOGV0:
104 if not self.revlogv1:
105 if not self.revlogv1:
105 self._warn(_("warning: `%s' uses revlog format 1") % name)
106 self._warn(_("warning: `%s' uses revlog format 1") % name)
106 elif self.revlogv1:
107 elif self.revlogv1:
107 self._warn(_("warning: `%s' uses revlog format 0") % name)
108 self._warn(_("warning: `%s' uses revlog format 0") % name)
108
109
109 def _checkentry(self, obj, i, node, seen, linkrevs, f):
110 def _checkentry(self, obj, i, node, seen, linkrevs, f):
110 """verify a single revlog entry
111 """verify a single revlog entry
111
112
112 arguments are:
113 arguments are:
113 - obj: the source revlog
114 - obj: the source revlog
114 - i: the revision number
115 - i: the revision number
115 - node: the revision node id
116 - node: the revision node id
116 - seen: nodes previously seen for this revlog
117 - seen: nodes previously seen for this revlog
117 - linkrevs: [changelog-revisions] introducing "node"
118 - linkrevs: [changelog-revisions] introducing "node"
118 - f: string label ("changelog", "manifest", or filename)
119 - f: string label ("changelog", "manifest", or filename)
119
120
120 Performs the following checks:
121 Performs the following checks:
121 - linkrev points to an existing changelog revision,
122 - linkrev points to an existing changelog revision,
122 - linkrev points to a changelog revision that introduces this revision,
123 - linkrev points to a changelog revision that introduces this revision,
123 - linkrev points to the lowest of these changesets,
124 - linkrev points to the lowest of these changesets,
124 - both parents exist in the revlog,
125 - both parents exist in the revlog,
125 - the revision is not duplicated.
126 - the revision is not duplicated.
126
127
127 Return the linkrev of the revision (or None for changelog's revisions).
128 Return the linkrev of the revision (or None for changelog's revisions).
128 """
129 """
129 lr = obj.linkrev(obj.rev(node))
130 lr = obj.linkrev(obj.rev(node))
130 if lr < 0 or (self.havecl and lr not in linkrevs):
131 if lr < 0 or (self.havecl and lr not in linkrevs):
131 if lr < 0 or lr >= len(self.repo.changelog):
132 if lr < 0 or lr >= len(self.repo.changelog):
132 msg = _("rev %d points to nonexistent changeset %d")
133 msg = _("rev %d points to nonexistent changeset %d")
133 else:
134 else:
134 msg = _("rev %d points to unexpected changeset %d")
135 msg = _("rev %d points to unexpected changeset %d")
135 self._err(None, msg % (i, lr), f)
136 self._err(None, msg % (i, lr), f)
136 if linkrevs:
137 if linkrevs:
137 if f and len(linkrevs) > 1:
138 if f and len(linkrevs) > 1:
138 try:
139 try:
139 # attempt to filter down to real linkrevs
140 # attempt to filter down to real linkrevs
140 linkrevs = [l for l in linkrevs
141 linkrevs = [l for l in linkrevs
141 if self.lrugetctx(l)[f].filenode() == node]
142 if self.lrugetctx(l)[f].filenode() == node]
142 except Exception:
143 except Exception:
143 pass
144 pass
144 self._warn(_(" (expected %s)") % " ".join
145 self._warn(_(" (expected %s)") % " ".join
145 (map(pycompat.bytestr, linkrevs)))
146 (map(pycompat.bytestr, linkrevs)))
146 lr = None # can't be trusted
147 lr = None # can't be trusted
147
148
148 try:
149 try:
149 p1, p2 = obj.parents(node)
150 p1, p2 = obj.parents(node)
150 if p1 not in seen and p1 != nullid:
151 if p1 not in seen and p1 != nullid:
151 self._err(lr, _("unknown parent 1 %s of %s") %
152 self._err(lr, _("unknown parent 1 %s of %s") %
152 (short(p1), short(node)), f)
153 (short(p1), short(node)), f)
153 if p2 not in seen and p2 != nullid:
154 if p2 not in seen and p2 != nullid:
154 self._err(lr, _("unknown parent 2 %s of %s") %
155 self._err(lr, _("unknown parent 2 %s of %s") %
155 (short(p2), short(node)), f)
156 (short(p2), short(node)), f)
156 except Exception as inst:
157 except Exception as inst:
157 self._exc(lr, _("checking parents of %s") % short(node), inst, f)
158 self._exc(lr, _("checking parents of %s") % short(node), inst, f)
158
159
159 if node in seen:
160 if node in seen:
160 self._err(lr, _("duplicate revision %d (%d)") % (i, seen[node]), f)
161 self._err(lr, _("duplicate revision %d (%d)") % (i, seen[node]), f)
161 seen[node] = i
162 seen[node] = i
162 return lr
163 return lr
163
164
164 def verify(self):
165 def verify(self):
165 """verify the content of the Mercurial repository
166 """verify the content of the Mercurial repository
166
167
167 This method run all verifications, displaying issues as they are found.
168 This method run all verifications, displaying issues as they are found.
168
169
169 return 1 if any error have been encountered, 0 otherwise."""
170 return 1 if any error have been encountered, 0 otherwise."""
170 # initial validation and generic report
171 # initial validation and generic report
171 repo = self.repo
172 repo = self.repo
172 ui = repo.ui
173 ui = repo.ui
173 if not repo.url().startswith('file:'):
174 if not repo.url().startswith('file:'):
174 raise error.Abort(_("cannot verify bundle or remote repos"))
175 raise error.Abort(_("cannot verify bundle or remote repos"))
175
176
176 if os.path.exists(repo.sjoin("journal")):
177 if os.path.exists(repo.sjoin("journal")):
177 ui.warn(_("abandoned transaction found - run hg recover\n"))
178 ui.warn(_("abandoned transaction found - run hg recover\n"))
178
179
179 if ui.verbose or not self.revlogv1:
180 if ui.verbose or not self.revlogv1:
180 ui.status(_("repository uses revlog format %d\n") %
181 ui.status(_("repository uses revlog format %d\n") %
181 (self.revlogv1 and 1 or 0))
182 (self.revlogv1 and 1 or 0))
182
183
183 # data verification
184 # data verification
184 mflinkrevs, filelinkrevs = self._verifychangelog()
185 mflinkrevs, filelinkrevs = self._verifychangelog()
185 filenodes = self._verifymanifest(mflinkrevs)
186 filenodes = self._verifymanifest(mflinkrevs)
186 del mflinkrevs
187 del mflinkrevs
187 self._crosscheckfiles(filelinkrevs, filenodes)
188 self._crosscheckfiles(filelinkrevs, filenodes)
188 totalfiles, filerevisions = self._verifyfiles(filenodes, filelinkrevs)
189 totalfiles, filerevisions = self._verifyfiles(filenodes, filelinkrevs)
189
190
190 # final report
191 # final report
191 ui.status(_("checked %d changesets with %d changes to %d files\n") %
192 ui.status(_("checked %d changesets with %d changes to %d files\n") %
192 (len(repo.changelog), filerevisions, totalfiles))
193 (len(repo.changelog), filerevisions, totalfiles))
193 if self.warnings:
194 if self.warnings:
194 ui.warn(_("%d warnings encountered!\n") % self.warnings)
195 ui.warn(_("%d warnings encountered!\n") % self.warnings)
195 if self.fncachewarned:
196 if self.fncachewarned:
196 ui.warn(_('hint: run "hg debugrebuildfncache" to recover from '
197 ui.warn(_('hint: run "hg debugrebuildfncache" to recover from '
197 'corrupt fncache\n'))
198 'corrupt fncache\n'))
198 if self.errors:
199 if self.errors:
199 ui.warn(_("%d integrity errors encountered!\n") % self.errors)
200 ui.warn(_("%d integrity errors encountered!\n") % self.errors)
200 if self.badrevs:
201 if self.badrevs:
201 ui.warn(_("(first damaged changeset appears to be %d)\n")
202 ui.warn(_("(first damaged changeset appears to be %d)\n")
202 % min(self.badrevs))
203 % min(self.badrevs))
203 return 1
204 return 1
204 return 0
205 return 0
205
206
206 def _verifychangelog(self):
207 def _verifychangelog(self):
207 """verify the changelog of a repository
208 """verify the changelog of a repository
208
209
209 The following checks are performed:
210 The following checks are performed:
210 - all of `_checkrevlog` checks,
211 - all of `_checkrevlog` checks,
211 - all of `_checkentry` checks (for each revisions),
212 - all of `_checkentry` checks (for each revisions),
212 - each revision can be read.
213 - each revision can be read.
213
214
214 The function returns some of the data observed in the changesets as a
215 The function returns some of the data observed in the changesets as a
215 (mflinkrevs, filelinkrevs) tuples:
216 (mflinkrevs, filelinkrevs) tuples:
216 - mflinkrevs: is a { manifest-node -> [changelog-rev] } mapping
217 - mflinkrevs: is a { manifest-node -> [changelog-rev] } mapping
217 - filelinkrevs: is a { file-path -> [changelog-rev] } mapping
218 - filelinkrevs: is a { file-path -> [changelog-rev] } mapping
218
219
219 If a matcher was specified, filelinkrevs will only contains matched
220 If a matcher was specified, filelinkrevs will only contains matched
220 files.
221 files.
221 """
222 """
222 ui = self.ui
223 ui = self.ui
223 repo = self.repo
224 repo = self.repo
224 match = self.match
225 match = self.match
225 cl = repo.changelog
226 cl = repo.changelog
226
227
227 ui.status(_("checking changesets\n"))
228 ui.status(_("checking changesets\n"))
228 mflinkrevs = {}
229 mflinkrevs = {}
229 filelinkrevs = {}
230 filelinkrevs = {}
230 seen = {}
231 seen = {}
231 self._checkrevlog(cl, "changelog", 0)
232 self._checkrevlog(cl, "changelog", 0)
232 progress = ui.makeprogress(_('checking'), unit=_('changesets'),
233 progress = ui.makeprogress(_('checking'), unit=_('changesets'),
233 total=len(repo))
234 total=len(repo))
234 for i in repo:
235 for i in repo:
235 progress.update(i)
236 progress.update(i)
236 n = cl.node(i)
237 n = cl.node(i)
237 self._checkentry(cl, i, n, seen, [i], "changelog")
238 self._checkentry(cl, i, n, seen, [i], "changelog")
238
239
239 try:
240 try:
240 changes = cl.read(n)
241 changes = cl.read(n)
241 if changes[0] != nullid:
242 if changes[0] != nullid:
242 mflinkrevs.setdefault(changes[0], []).append(i)
243 mflinkrevs.setdefault(changes[0], []).append(i)
243 self.refersmf = True
244 self.refersmf = True
244 for f in changes[3]:
245 for f in changes[3]:
245 if match(f):
246 if match(f):
246 filelinkrevs.setdefault(_normpath(f), []).append(i)
247 filelinkrevs.setdefault(_normpath(f), []).append(i)
247 except Exception as inst:
248 except Exception as inst:
248 self.refersmf = True
249 self.refersmf = True
249 self._exc(i, _("unpacking changeset %s") % short(n), inst)
250 self._exc(i, _("unpacking changeset %s") % short(n), inst)
250 progress.complete()
251 progress.complete()
251 return mflinkrevs, filelinkrevs
252 return mflinkrevs, filelinkrevs
252
253
253 def _verifymanifest(self, mflinkrevs, dir="", storefiles=None,
254 def _verifymanifest(self, mflinkrevs, dir="", storefiles=None,
254 subdirprogress=None):
255 subdirprogress=None):
255 """verify the manifestlog content
256 """verify the manifestlog content
256
257
257 Inputs:
258 Inputs:
258 - mflinkrevs: a {manifest-node -> [changelog-revisions]} mapping
259 - mflinkrevs: a {manifest-node -> [changelog-revisions]} mapping
259 - dir: a subdirectory to check (for tree manifest repo)
260 - dir: a subdirectory to check (for tree manifest repo)
260 - storefiles: set of currently "orphan" files.
261 - storefiles: set of currently "orphan" files.
261 - subdirprogress: a progress object
262 - subdirprogress: a progress object
262
263
263 This function checks:
264 This function checks:
264 * all of `_checkrevlog` checks (for all manifest related revlogs)
265 * all of `_checkrevlog` checks (for all manifest related revlogs)
265 * all of `_checkentry` checks (for all manifest related revisions)
266 * all of `_checkentry` checks (for all manifest related revisions)
266 * nodes for subdirectory exists in the sub-directory manifest
267 * nodes for subdirectory exists in the sub-directory manifest
267 * each manifest entries have a file path
268 * each manifest entries have a file path
268 * each manifest node refered in mflinkrevs exist in the manifest log
269 * each manifest node refered in mflinkrevs exist in the manifest log
269
270
270 If tree manifest is in use and a matchers is specified, only the
271 If tree manifest is in use and a matchers is specified, only the
271 sub-directories matching it will be verified.
272 sub-directories matching it will be verified.
272
273
273 return a two level mapping:
274 return a two level mapping:
274 {"path" -> { filenode -> changelog-revision}}
275 {"path" -> { filenode -> changelog-revision}}
275
276
276 This mapping primarily contains entries for every files in the
277 This mapping primarily contains entries for every files in the
277 repository. In addition, when tree-manifest is used, it also contains
278 repository. In addition, when tree-manifest is used, it also contains
278 sub-directory entries.
279 sub-directory entries.
279
280
280 If a matcher is provided, only matching paths will be included.
281 If a matcher is provided, only matching paths will be included.
281 """
282 """
282 repo = self.repo
283 repo = self.repo
283 ui = self.ui
284 ui = self.ui
284 match = self.match
285 match = self.match
285 mfl = self.repo.manifestlog
286 mfl = self.repo.manifestlog
286 mf = mfl.getstorage(dir)
287 mf = mfl.getstorage(dir)
287
288
288 if not dir:
289 if not dir:
289 self.ui.status(_("checking manifests\n"))
290 self.ui.status(_("checking manifests\n"))
290
291
291 filenodes = {}
292 filenodes = {}
292 subdirnodes = {}
293 subdirnodes = {}
293 seen = {}
294 seen = {}
294 label = "manifest"
295 label = "manifest"
295 if dir:
296 if dir:
296 label = dir
297 label = dir
297 revlogfiles = mf.files()
298 revlogfiles = mf.files()
298 storefiles.difference_update(revlogfiles)
299 storefiles.difference_update(revlogfiles)
299 if subdirprogress: # should be true since we're in a subdirectory
300 if subdirprogress: # should be true since we're in a subdirectory
300 subdirprogress.increment()
301 subdirprogress.increment()
301 if self.refersmf:
302 if self.refersmf:
302 # Do not check manifest if there are only changelog entries with
303 # Do not check manifest if there are only changelog entries with
303 # null manifests.
304 # null manifests.
304 self._checkrevlog(mf, label, 0)
305 self._checkrevlog(mf, label, 0)
305 progress = ui.makeprogress(_('checking'), unit=_('manifests'),
306 progress = ui.makeprogress(_('checking'), unit=_('manifests'),
306 total=len(mf))
307 total=len(mf))
307 for i in mf:
308 for i in mf:
308 if not dir:
309 if not dir:
309 progress.update(i)
310 progress.update(i)
310 n = mf.node(i)
311 n = mf.node(i)
311 lr = self._checkentry(mf, i, n, seen, mflinkrevs.get(n, []), label)
312 lr = self._checkentry(mf, i, n, seen, mflinkrevs.get(n, []), label)
312 if n in mflinkrevs:
313 if n in mflinkrevs:
313 del mflinkrevs[n]
314 del mflinkrevs[n]
314 elif dir:
315 elif dir:
315 self._err(lr, _("%s not in parent-directory manifest") %
316 self._err(lr, _("%s not in parent-directory manifest") %
316 short(n), label)
317 short(n), label)
317 else:
318 else:
318 self._err(lr, _("%s not in changesets") % short(n), label)
319 self._err(lr, _("%s not in changesets") % short(n), label)
319
320
320 try:
321 try:
321 mfdelta = mfl.get(dir, n).readdelta(shallow=True)
322 mfdelta = mfl.get(dir, n).readdelta(shallow=True)
322 for f, fn, fl in mfdelta.iterentries():
323 for f, fn, fl in mfdelta.iterentries():
323 if not f:
324 if not f:
324 self._err(lr, _("entry without name in manifest"))
325 self._err(lr, _("entry without name in manifest"))
325 elif f == "/dev/null": # ignore this in very old repos
326 elif f == "/dev/null": # ignore this in very old repos
326 continue
327 continue
327 fullpath = dir + _normpath(f)
328 fullpath = dir + _normpath(f)
328 if fl == 't':
329 if fl == 't':
329 if not match.visitdir(fullpath):
330 if not match.visitdir(fullpath):
330 continue
331 continue
331 subdirnodes.setdefault(fullpath + '/', {}).setdefault(
332 subdirnodes.setdefault(fullpath + '/', {}).setdefault(
332 fn, []).append(lr)
333 fn, []).append(lr)
333 else:
334 else:
334 if not match(fullpath):
335 if not match(fullpath):
335 continue
336 continue
336 filenodes.setdefault(fullpath, {}).setdefault(fn, lr)
337 filenodes.setdefault(fullpath, {}).setdefault(fn, lr)
337 except Exception as inst:
338 except Exception as inst:
338 self._exc(lr, _("reading delta %s") % short(n), inst, label)
339 self._exc(lr, _("reading delta %s") % short(n), inst, label)
339 if not dir:
340 if not dir:
340 progress.complete()
341 progress.complete()
341
342
342 if self.havemf:
343 if self.havemf:
343 # since we delete entry in `mflinkrevs` during iteration, any
344 # since we delete entry in `mflinkrevs` during iteration, any
344 # remaining entries are "missing". We need to issue errors for them.
345 # remaining entries are "missing". We need to issue errors for them.
345 changesetpairs = [(c, m) for m in mflinkrevs for c in mflinkrevs[m]]
346 changesetpairs = [(c, m) for m in mflinkrevs for c in mflinkrevs[m]]
346 for c, m in sorted(changesetpairs):
347 for c, m in sorted(changesetpairs):
347 if dir:
348 if dir:
348 self._err(c, _("parent-directory manifest refers to unknown"
349 self._err(c, _("parent-directory manifest refers to unknown"
349 " revision %s") % short(m), label)
350 " revision %s") % short(m), label)
350 else:
351 else:
351 self._err(c, _("changeset refers to unknown revision %s") %
352 self._err(c, _("changeset refers to unknown revision %s") %
352 short(m), label)
353 short(m), label)
353
354
354 if not dir and subdirnodes:
355 if not dir and subdirnodes:
355 self.ui.status(_("checking directory manifests\n"))
356 self.ui.status(_("checking directory manifests\n"))
356 storefiles = set()
357 storefiles = set()
357 subdirs = set()
358 subdirs = set()
358 revlogv1 = self.revlogv1
359 revlogv1 = self.revlogv1
359 for f, f2, size in repo.store.datafiles():
360 for f, f2, size in repo.store.datafiles():
360 if not f:
361 if not f:
361 self._err(None, _("cannot decode filename '%s'") % f2)
362 self._err(None, _("cannot decode filename '%s'") % f2)
362 elif (size > 0 or not revlogv1) and f.startswith('meta/'):
363 elif (size > 0 or not revlogv1) and f.startswith('meta/'):
363 storefiles.add(_normpath(f))
364 storefiles.add(_normpath(f))
364 subdirs.add(os.path.dirname(f))
365 subdirs.add(os.path.dirname(f))
365 subdirprogress = ui.makeprogress(_('checking'), unit=_('manifests'),
366 subdirprogress = ui.makeprogress(_('checking'), unit=_('manifests'),
366 total=len(subdirs))
367 total=len(subdirs))
367
368
368 for subdir, linkrevs in subdirnodes.iteritems():
369 for subdir, linkrevs in subdirnodes.iteritems():
369 subdirfilenodes = self._verifymanifest(linkrevs, subdir, storefiles,
370 subdirfilenodes = self._verifymanifest(linkrevs, subdir, storefiles,
370 subdirprogress)
371 subdirprogress)
371 for f, onefilenodes in subdirfilenodes.iteritems():
372 for f, onefilenodes in subdirfilenodes.iteritems():
372 filenodes.setdefault(f, {}).update(onefilenodes)
373 filenodes.setdefault(f, {}).update(onefilenodes)
373
374
374 if not dir and subdirnodes:
375 if not dir and subdirnodes:
375 subdirprogress.complete()
376 subdirprogress.complete()
376 if self.warnorphanstorefiles:
377 if self.warnorphanstorefiles:
377 for f in sorted(storefiles):
378 for f in sorted(storefiles):
378 self._warn(_("warning: orphan data file '%s'") % f)
379 self._warn(_("warning: orphan data file '%s'") % f)
379
380
380 return filenodes
381 return filenodes
381
382
382 def _crosscheckfiles(self, filelinkrevs, filenodes):
383 def _crosscheckfiles(self, filelinkrevs, filenodes):
383 repo = self.repo
384 repo = self.repo
384 ui = self.ui
385 ui = self.ui
385 ui.status(_("crosschecking files in changesets and manifests\n"))
386 ui.status(_("crosschecking files in changesets and manifests\n"))
386
387
387 total = len(filelinkrevs) + len(filenodes)
388 total = len(filelinkrevs) + len(filenodes)
388 progress = ui.makeprogress(_('crosschecking'), unit=_('files'),
389 progress = ui.makeprogress(_('crosschecking'), unit=_('files'),
389 total=total)
390 total=total)
390 if self.havemf:
391 if self.havemf:
391 for f in sorted(filelinkrevs):
392 for f in sorted(filelinkrevs):
392 progress.increment()
393 progress.increment()
393 if f not in filenodes:
394 if f not in filenodes:
394 lr = filelinkrevs[f][0]
395 lr = filelinkrevs[f][0]
395 self._err(lr, _("in changeset but not in manifest"), f)
396 self._err(lr, _("in changeset but not in manifest"), f)
396
397
397 if self.havecl:
398 if self.havecl:
398 for f in sorted(filenodes):
399 for f in sorted(filenodes):
399 progress.increment()
400 progress.increment()
400 if f not in filelinkrevs:
401 if f not in filelinkrevs:
401 try:
402 try:
402 fl = repo.file(f)
403 fl = repo.file(f)
403 lr = min([fl.linkrev(fl.rev(n)) for n in filenodes[f]])
404 lr = min([fl.linkrev(fl.rev(n)) for n in filenodes[f]])
404 except Exception:
405 except Exception:
405 lr = None
406 lr = None
406 self._err(lr, _("in manifest but not in changeset"), f)
407 self._err(lr, _("in manifest but not in changeset"), f)
407
408
408 progress.complete()
409 progress.complete()
409
410
410 def _verifyfiles(self, filenodes, filelinkrevs):
411 def _verifyfiles(self, filenodes, filelinkrevs):
411 repo = self.repo
412 repo = self.repo
412 ui = self.ui
413 ui = self.ui
413 lrugetctx = self.lrugetctx
414 lrugetctx = self.lrugetctx
414 revlogv1 = self.revlogv1
415 revlogv1 = self.revlogv1
415 havemf = self.havemf
416 havemf = self.havemf
416 ui.status(_("checking files\n"))
417 ui.status(_("checking files\n"))
417
418
418 storefiles = set()
419 storefiles = set()
419 for f, f2, size in repo.store.datafiles():
420 for f, f2, size in repo.store.datafiles():
420 if not f:
421 if not f:
421 self._err(None, _("cannot decode filename '%s'") % f2)
422 self._err(None, _("cannot decode filename '%s'") % f2)
422 elif (size > 0 or not revlogv1) and f.startswith('data/'):
423 elif (size > 0 or not revlogv1) and f.startswith('data/'):
423 storefiles.add(_normpath(f))
424 storefiles.add(_normpath(f))
424
425
425 state = {
426 state = {
426 # TODO this assumes revlog storage for changelog.
427 # TODO this assumes revlog storage for changelog.
427 'expectedversion': self.repo.changelog.version & 0xFFFF,
428 'expectedversion': self.repo.changelog.version & 0xFFFF,
428 'skipflags': self.skipflags,
429 'skipflags': self.skipflags,
429 # experimental config: censor.policy
430 # experimental config: censor.policy
430 'erroroncensored': ui.config('censor', 'policy') == 'abort',
431 'erroroncensored': ui.config('censor', 'policy') == 'abort',
431 }
432 }
432
433
433 files = sorted(set(filenodes) | set(filelinkrevs))
434 files = sorted(set(filenodes) | set(filelinkrevs))
434 revisions = 0
435 revisions = 0
435 progress = ui.makeprogress(_('checking'), unit=_('files'),
436 progress = ui.makeprogress(_('checking'), unit=_('files'),
436 total=len(files))
437 total=len(files))
437 for i, f in enumerate(files):
438 for i, f in enumerate(files):
438 progress.update(i, item=f)
439 progress.update(i, item=f)
439 try:
440 try:
440 linkrevs = filelinkrevs[f]
441 linkrevs = filelinkrevs[f]
441 except KeyError:
442 except KeyError:
442 # in manifest but not in changelog
443 # in manifest but not in changelog
443 linkrevs = []
444 linkrevs = []
444
445
445 if linkrevs:
446 if linkrevs:
446 lr = linkrevs[0]
447 lr = linkrevs[0]
447 else:
448 else:
448 lr = None
449 lr = None
449
450
450 try:
451 try:
451 fl = repo.file(f)
452 fl = repo.file(f)
452 except error.StorageError as e:
453 except error.StorageError as e:
453 self._err(lr, _("broken revlog! (%s)") % e, f)
454 self._err(lr, _("broken revlog! (%s)") % e, f)
454 continue
455 continue
455
456
456 for ff in fl.files():
457 for ff in fl.files():
457 try:
458 try:
458 storefiles.remove(ff)
459 storefiles.remove(ff)
459 except KeyError:
460 except KeyError:
460 if self.warnorphanstorefiles:
461 if self.warnorphanstorefiles:
461 self._warn(_(" warning: revlog '%s' not in fncache!") %
462 self._warn(_(" warning: revlog '%s' not in fncache!") %
462 ff)
463 ff)
463 self.fncachewarned = True
464 self.fncachewarned = True
464
465
465 if not len(fl) and (self.havecl or self.havemf):
466 if not len(fl) and (self.havecl or self.havemf):
466 self._err(lr, _("empty or missing %s") % f)
467 self._err(lr, _("empty or missing %s") % f)
467 else:
468 else:
468 # Guard against implementations not setting this.
469 # Guard against implementations not setting this.
469 state['skipread'] = set()
470 state['skipread'] = set()
470 for problem in fl.verifyintegrity(state):
471 for problem in fl.verifyintegrity(state):
471 if problem.node is not None:
472 if problem.node is not None:
472 linkrev = fl.linkrev(fl.rev(problem.node))
473 linkrev = fl.linkrev(fl.rev(problem.node))
473 else:
474 else:
474 linkrev = None
475 linkrev = None
475
476
476 if problem.warning:
477 if problem.warning:
477 self._warn(problem.warning)
478 self._warn(problem.warning)
478 elif problem.error:
479 elif problem.error:
479 self._err(linkrev if linkrev is not None else lr,
480 self._err(linkrev if linkrev is not None else lr,
480 problem.error, f)
481 problem.error, f)
481 else:
482 else:
482 raise error.ProgrammingError(
483 raise error.ProgrammingError(
483 'problem instance does not set warning or error '
484 'problem instance does not set warning or error '
484 'attribute: %s' % problem.msg)
485 'attribute: %s' % problem.msg)
485
486
486 seen = {}
487 seen = {}
487 for i in fl:
488 for i in fl:
488 revisions += 1
489 revisions += 1
489 n = fl.node(i)
490 n = fl.node(i)
490 lr = self._checkentry(fl, i, n, seen, linkrevs, f)
491 lr = self._checkentry(fl, i, n, seen, linkrevs, f)
491 if f in filenodes:
492 if f in filenodes:
492 if havemf and n not in filenodes[f]:
493 if havemf and n not in filenodes[f]:
493 self._err(lr, _("%s not in manifests") % (short(n)), f)
494 self._err(lr, _("%s not in manifests") % (short(n)), f)
494 else:
495 else:
495 del filenodes[f][n]
496 del filenodes[f][n]
496
497
497 if n in state['skipread']:
498 if n in state['skipread']:
498 continue
499 continue
499
500
500 # check renames
501 # check renames
501 try:
502 try:
502 # This requires resolving fulltext (at least on revlogs). We
503 # This requires resolving fulltext (at least on revlogs). We
503 # may want ``verifyintegrity()`` to pass a set of nodes with
504 # may want ``verifyintegrity()`` to pass a set of nodes with
504 # rename metadata as an optimization.
505 # rename metadata as an optimization.
505 rp = fl.renamed(n)
506 rp = fl.renamed(n)
506 if rp:
507 if rp:
507 if lr is not None and ui.verbose:
508 if lr is not None and ui.verbose:
508 ctx = lrugetctx(lr)
509 ctx = lrugetctx(lr)
509 if not any(rp[0] in pctx for pctx in ctx.parents()):
510 if not any(rp[0] in pctx for pctx in ctx.parents()):
510 self._warn(_("warning: copy source of '%s' not"
511 self._warn(_("warning: copy source of '%s' not"
511 " in parents of %s") % (f, ctx))
512 " in parents of %s") % (f, ctx))
512 fl2 = repo.file(rp[0])
513 fl2 = repo.file(rp[0])
513 if not len(fl2):
514 if not len(fl2):
514 self._err(lr,
515 self._err(lr,
515 _("empty or missing copy source revlog "
516 _("empty or missing copy source revlog "
516 "%s:%s") % (rp[0],
517 "%s:%s") % (rp[0],
517 short(rp[1])),
518 short(rp[1])),
518 f)
519 f)
519 elif rp[1] == nullid:
520 elif rp[1] == nullid:
520 ui.note(_("warning: %s@%s: copy source"
521 ui.note(_("warning: %s@%s: copy source"
521 " revision is nullid %s:%s\n")
522 " revision is nullid %s:%s\n")
522 % (f, lr, rp[0], short(rp[1])))
523 % (f, lr, rp[0], short(rp[1])))
523 else:
524 else:
524 fl2.rev(rp[1])
525 fl2.rev(rp[1])
525 except Exception as inst:
526 except Exception as inst:
526 self._exc(lr, _("checking rename of %s") % short(n),
527 self._exc(lr, _("checking rename of %s") % short(n),
527 inst, f)
528 inst, f)
528
529
529 # cross-check
530 # cross-check
530 if f in filenodes:
531 if f in filenodes:
531 fns = [(v, k) for k, v in filenodes[f].iteritems()]
532 fns = [(v, k) for k, v in filenodes[f].iteritems()]
532 for lr, node in sorted(fns):
533 for lr, node in sorted(fns):
533 self._err(lr, _("manifest refers to unknown revision %s") %
534 self._err(lr, _("manifest refers to unknown revision %s") %
534 short(node), f)
535 short(node), f)
535 progress.complete()
536 progress.complete()
536
537
537 if self.warnorphanstorefiles:
538 if self.warnorphanstorefiles:
538 for f in sorted(storefiles):
539 for f in sorted(storefiles):
539 self._warn(_("warning: orphan data file '%s'") % f)
540 self._warn(_("warning: orphan data file '%s'") % f)
540
541
541 return len(files), revisions
542 return len(files), revisions
@@ -1,414 +1,414 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 add
3 add
4 addremove
4 addremove
5 annotate
5 annotate
6 archive
6 archive
7 backout
7 backout
8 bisect
8 bisect
9 bookmarks
9 bookmarks
10 branch
10 branch
11 branches
11 branches
12 bundle
12 bundle
13 cat
13 cat
14 clone
14 clone
15 commit
15 commit
16 config
16 config
17 copy
17 copy
18 diff
18 diff
19 export
19 export
20 files
20 files
21 forget
21 forget
22 graft
22 graft
23 grep
23 grep
24 heads
24 heads
25 help
25 help
26 identify
26 identify
27 import
27 import
28 incoming
28 incoming
29 init
29 init
30 locate
30 locate
31 log
31 log
32 manifest
32 manifest
33 merge
33 merge
34 outgoing
34 outgoing
35 parents
35 parents
36 paths
36 paths
37 phase
37 phase
38 pull
38 pull
39 push
39 push
40 recover
40 recover
41 remove
41 remove
42 rename
42 rename
43 resolve
43 resolve
44 revert
44 revert
45 rollback
45 rollback
46 root
46 root
47 serve
47 serve
48 status
48 status
49 summary
49 summary
50 tag
50 tag
51 tags
51 tags
52 tip
52 tip
53 unbundle
53 unbundle
54 update
54 update
55 verify
55 verify
56 version
56 version
57
57
58 Show all commands that start with "a"
58 Show all commands that start with "a"
59 $ hg debugcomplete a
59 $ hg debugcomplete a
60 add
60 add
61 addremove
61 addremove
62 annotate
62 annotate
63 archive
63 archive
64
64
65 Do not show debug commands if there are other candidates
65 Do not show debug commands if there are other candidates
66 $ hg debugcomplete d
66 $ hg debugcomplete d
67 diff
67 diff
68
68
69 Show debug commands if there are no other candidates
69 Show debug commands if there are no other candidates
70 $ hg debugcomplete debug
70 $ hg debugcomplete debug
71 debugancestor
71 debugancestor
72 debugapplystreamclonebundle
72 debugapplystreamclonebundle
73 debugbuilddag
73 debugbuilddag
74 debugbundle
74 debugbundle
75 debugcapabilities
75 debugcapabilities
76 debugcheckstate
76 debugcheckstate
77 debugcolor
77 debugcolor
78 debugcommands
78 debugcommands
79 debugcomplete
79 debugcomplete
80 debugconfig
80 debugconfig
81 debugcreatestreamclonebundle
81 debugcreatestreamclonebundle
82 debugdag
82 debugdag
83 debugdata
83 debugdata
84 debugdate
84 debugdate
85 debugdeltachain
85 debugdeltachain
86 debugdirstate
86 debugdirstate
87 debugdiscovery
87 debugdiscovery
88 debugdownload
88 debugdownload
89 debugextensions
89 debugextensions
90 debugfileset
90 debugfileset
91 debugformat
91 debugformat
92 debugfsinfo
92 debugfsinfo
93 debuggetbundle
93 debuggetbundle
94 debugignore
94 debugignore
95 debugindex
95 debugindex
96 debugindexdot
96 debugindexdot
97 debugindexstats
97 debugindexstats
98 debuginstall
98 debuginstall
99 debugknown
99 debugknown
100 debuglabelcomplete
100 debuglabelcomplete
101 debuglocks
101 debuglocks
102 debugmanifestfulltextcache
102 debugmanifestfulltextcache
103 debugmergestate
103 debugmergestate
104 debugnamecomplete
104 debugnamecomplete
105 debugobsolete
105 debugobsolete
106 debugp1copies
106 debugp1copies
107 debugp2copies
107 debugp2copies
108 debugpathcomplete
108 debugpathcomplete
109 debugpathcopies
109 debugpathcopies
110 debugpeer
110 debugpeer
111 debugpickmergetool
111 debugpickmergetool
112 debugpushkey
112 debugpushkey
113 debugpvec
113 debugpvec
114 debugrebuilddirstate
114 debugrebuilddirstate
115 debugrebuildfncache
115 debugrebuildfncache
116 debugrename
116 debugrename
117 debugrevlog
117 debugrevlog
118 debugrevlogindex
118 debugrevlogindex
119 debugrevspec
119 debugrevspec
120 debugserve
120 debugserve
121 debugsetparents
121 debugsetparents
122 debugssl
122 debugssl
123 debugsub
123 debugsub
124 debugsuccessorssets
124 debugsuccessorssets
125 debugtemplate
125 debugtemplate
126 debuguigetpass
126 debuguigetpass
127 debuguiprompt
127 debuguiprompt
128 debugupdatecaches
128 debugupdatecaches
129 debugupgraderepo
129 debugupgraderepo
130 debugwalk
130 debugwalk
131 debugwhyunstable
131 debugwhyunstable
132 debugwireargs
132 debugwireargs
133 debugwireproto
133 debugwireproto
134
134
135 Do not show the alias of a debug command if there are other candidates
135 Do not show the alias of a debug command if there are other candidates
136 (this should hide rawcommit)
136 (this should hide rawcommit)
137 $ hg debugcomplete r
137 $ hg debugcomplete r
138 recover
138 recover
139 remove
139 remove
140 rename
140 rename
141 resolve
141 resolve
142 revert
142 revert
143 rollback
143 rollback
144 root
144 root
145 Show the alias of a debug command if there are no other candidates
145 Show the alias of a debug command if there are no other candidates
146 $ hg debugcomplete rawc
146 $ hg debugcomplete rawc
147
147
148
148
149 Show the global options
149 Show the global options
150 $ hg debugcomplete --options | sort
150 $ hg debugcomplete --options | sort
151 --color
151 --color
152 --config
152 --config
153 --cwd
153 --cwd
154 --debug
154 --debug
155 --debugger
155 --debugger
156 --encoding
156 --encoding
157 --encodingmode
157 --encodingmode
158 --help
158 --help
159 --hidden
159 --hidden
160 --noninteractive
160 --noninteractive
161 --pager
161 --pager
162 --profile
162 --profile
163 --quiet
163 --quiet
164 --repository
164 --repository
165 --time
165 --time
166 --traceback
166 --traceback
167 --verbose
167 --verbose
168 --version
168 --version
169 -R
169 -R
170 -h
170 -h
171 -q
171 -q
172 -v
172 -v
173 -y
173 -y
174
174
175 Show the options for the "serve" command
175 Show the options for the "serve" command
176 $ hg debugcomplete --options serve | sort
176 $ hg debugcomplete --options serve | sort
177 --accesslog
177 --accesslog
178 --address
178 --address
179 --certificate
179 --certificate
180 --cmdserver
180 --cmdserver
181 --color
181 --color
182 --config
182 --config
183 --cwd
183 --cwd
184 --daemon
184 --daemon
185 --daemon-postexec
185 --daemon-postexec
186 --debug
186 --debug
187 --debugger
187 --debugger
188 --encoding
188 --encoding
189 --encodingmode
189 --encodingmode
190 --errorlog
190 --errorlog
191 --help
191 --help
192 --hidden
192 --hidden
193 --ipv6
193 --ipv6
194 --name
194 --name
195 --noninteractive
195 --noninteractive
196 --pager
196 --pager
197 --pid-file
197 --pid-file
198 --port
198 --port
199 --prefix
199 --prefix
200 --print-url
200 --print-url
201 --profile
201 --profile
202 --quiet
202 --quiet
203 --repository
203 --repository
204 --stdio
204 --stdio
205 --style
205 --style
206 --subrepos
206 --subrepos
207 --templates
207 --templates
208 --time
208 --time
209 --traceback
209 --traceback
210 --verbose
210 --verbose
211 --version
211 --version
212 --web-conf
212 --web-conf
213 -6
213 -6
214 -A
214 -A
215 -E
215 -E
216 -R
216 -R
217 -S
217 -S
218 -a
218 -a
219 -d
219 -d
220 -h
220 -h
221 -n
221 -n
222 -p
222 -p
223 -q
223 -q
224 -t
224 -t
225 -v
225 -v
226 -y
226 -y
227
227
228 Show an error if we use --options with an ambiguous abbreviation
228 Show an error if we use --options with an ambiguous abbreviation
229 $ hg debugcomplete --options s
229 $ hg debugcomplete --options s
230 hg: command 's' is ambiguous:
230 hg: command 's' is ambiguous:
231 serve showconfig status summary
231 serve showconfig status summary
232 [255]
232 [255]
233
233
234 Show all commands + options
234 Show all commands + options
235 $ hg debugcommands
235 $ hg debugcommands
236 add: include, exclude, subrepos, dry-run
236 add: include, exclude, subrepos, dry-run
237 addremove: similarity, subrepos, include, exclude, dry-run
237 addremove: similarity, subrepos, include, exclude, dry-run
238 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
238 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
239 archive: no-decode, prefix, rev, type, subrepos, include, exclude
239 archive: no-decode, prefix, rev, type, subrepos, include, exclude
240 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
240 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
241 bisect: reset, good, bad, skip, extend, command, noupdate
241 bisect: reset, good, bad, skip, extend, command, noupdate
242 bookmarks: force, rev, delete, rename, inactive, list, template
242 bookmarks: force, rev, delete, rename, inactive, list, template
243 branch: force, clean, rev
243 branch: force, clean, rev
244 branches: active, closed, rev, template
244 branches: active, closed, rev, template
245 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
245 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
246 cat: output, rev, decode, include, exclude, template
246 cat: output, rev, decode, include, exclude, template
247 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
247 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
248 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
248 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
249 config: untrusted, edit, local, global, template
249 config: untrusted, edit, local, global, template
250 copy: after, force, include, exclude, dry-run
250 copy: after, force, include, exclude, dry-run
251 debugancestor:
251 debugancestor:
252 debugapplystreamclonebundle:
252 debugapplystreamclonebundle:
253 debugbuilddag: mergeable-file, overwritten-file, new-file
253 debugbuilddag: mergeable-file, overwritten-file, new-file
254 debugbundle: all, part-type, spec
254 debugbundle: all, part-type, spec
255 debugcapabilities:
255 debugcapabilities:
256 debugcheckstate:
256 debugcheckstate:
257 debugcolor: style
257 debugcolor: style
258 debugcommands:
258 debugcommands:
259 debugcomplete: options
259 debugcomplete: options
260 debugcreatestreamclonebundle:
260 debugcreatestreamclonebundle:
261 debugdag: tags, branches, dots, spaces
261 debugdag: tags, branches, dots, spaces
262 debugdata: changelog, manifest, dir
262 debugdata: changelog, manifest, dir
263 debugdate: extended
263 debugdate: extended
264 debugdeltachain: changelog, manifest, dir, template
264 debugdeltachain: changelog, manifest, dir, template
265 debugdirstate: nodates, dates, datesort
265 debugdirstate: nodates, dates, datesort
266 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
266 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
267 debugdownload: output
267 debugdownload: output
268 debugextensions: template
268 debugextensions: template
269 debugfileset: rev, all-files, show-matcher, show-stage
269 debugfileset: rev, all-files, show-matcher, show-stage
270 debugformat: template
270 debugformat: template
271 debugfsinfo:
271 debugfsinfo:
272 debuggetbundle: head, common, type
272 debuggetbundle: head, common, type
273 debugignore:
273 debugignore:
274 debugindex: changelog, manifest, dir, template
274 debugindex: changelog, manifest, dir, template
275 debugindexdot: changelog, manifest, dir
275 debugindexdot: changelog, manifest, dir
276 debugindexstats:
276 debugindexstats:
277 debuginstall: template
277 debuginstall: template
278 debugknown:
278 debugknown:
279 debuglabelcomplete:
279 debuglabelcomplete:
280 debuglocks: force-lock, force-wlock, set-lock, set-wlock
280 debuglocks: force-lock, force-wlock, set-lock, set-wlock
281 debugmanifestfulltextcache: clear, add
281 debugmanifestfulltextcache: clear, add
282 debugmergestate:
282 debugmergestate:
283 debugnamecomplete:
283 debugnamecomplete:
284 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
284 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
285 debugp1copies: rev
285 debugp1copies: rev
286 debugp2copies: rev
286 debugp2copies: rev
287 debugpathcomplete: full, normal, added, removed
287 debugpathcomplete: full, normal, added, removed
288 debugpathcopies: include, exclude
288 debugpathcopies: include, exclude
289 debugpeer:
289 debugpeer:
290 debugpickmergetool: rev, changedelete, include, exclude, tool
290 debugpickmergetool: rev, changedelete, include, exclude, tool
291 debugpushkey:
291 debugpushkey:
292 debugpvec:
292 debugpvec:
293 debugrebuilddirstate: rev, minimal
293 debugrebuilddirstate: rev, minimal
294 debugrebuildfncache:
294 debugrebuildfncache:
295 debugrename: rev
295 debugrename: rev
296 debugrevlog: changelog, manifest, dir, dump
296 debugrevlog: changelog, manifest, dir, dump
297 debugrevlogindex: changelog, manifest, dir, format
297 debugrevlogindex: changelog, manifest, dir, format
298 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
298 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
299 debugserve: sshstdio, logiofd, logiofile
299 debugserve: sshstdio, logiofd, logiofile
300 debugsetparents:
300 debugsetparents:
301 debugssl:
301 debugssl:
302 debugsub: rev
302 debugsub: rev
303 debugsuccessorssets: closest
303 debugsuccessorssets: closest
304 debugtemplate: rev, define
304 debugtemplate: rev, define
305 debuguigetpass: prompt
305 debuguigetpass: prompt
306 debuguiprompt: prompt
306 debuguiprompt: prompt
307 debugupdatecaches:
307 debugupdatecaches:
308 debugupgraderepo: optimize, run, backup
308 debugupgraderepo: optimize, run, backup
309 debugwalk: include, exclude
309 debugwalk: include, exclude
310 debugwhyunstable:
310 debugwhyunstable:
311 debugwireargs: three, four, five, ssh, remotecmd, insecure
311 debugwireargs: three, four, five, ssh, remotecmd, insecure
312 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
312 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
313 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
313 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
314 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
314 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
315 files: rev, print0, include, exclude, template, subrepos
315 files: rev, print0, include, exclude, template, subrepos
316 forget: interactive, include, exclude, dry-run
316 forget: interactive, include, exclude, dry-run
317 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
317 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
318 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
318 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
319 heads: rev, topo, active, closed, style, template
319 heads: rev, topo, active, closed, style, template
320 help: extension, command, keyword, system
320 help: extension, command, keyword, system
321 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
321 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
322 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
322 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
323 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
323 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
324 init: ssh, remotecmd, insecure
324 init: ssh, remotecmd, insecure
325 locate: rev, print0, fullpath, include, exclude
325 locate: rev, print0, fullpath, include, exclude
326 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
326 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
327 manifest: rev, all, template
327 manifest: rev, all, template
328 merge: force, rev, preview, abort, tool
328 merge: force, rev, preview, abort, tool
329 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
329 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
330 parents: rev, style, template
330 parents: rev, style, template
331 paths: template
331 paths: template
332 phase: public, draft, secret, force, rev
332 phase: public, draft, secret, force, rev
333 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
333 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
334 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
334 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
335 recover: verify
335 recover: verify
336 remove: after, force, subrepos, include, exclude, dry-run
336 remove: after, force, subrepos, include, exclude, dry-run
337 rename: after, force, include, exclude, dry-run
337 rename: after, force, include, exclude, dry-run
338 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
338 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
339 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
339 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
340 rollback: dry-run, force
340 rollback: dry-run, force
341 root:
341 root:
342 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
342 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
343 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
343 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
344 summary: remote
344 summary: remote
345 tag: force, local, rev, remove, edit, message, date, user
345 tag: force, local, rev, remove, edit, message, date, user
346 tags: template
346 tags: template
347 tip: patch, git, style, template
347 tip: patch, git, style, template
348 unbundle: update
348 unbundle: update
349 update: clean, check, merge, date, rev, tool
349 update: clean, check, merge, date, rev, tool
350 verify:
350 verify: full
351 version: template
351 version: template
352
352
353 $ hg init a
353 $ hg init a
354 $ cd a
354 $ cd a
355 $ echo fee > fee
355 $ echo fee > fee
356 $ hg ci -q -Amfee
356 $ hg ci -q -Amfee
357 $ hg tag fee
357 $ hg tag fee
358 $ mkdir fie
358 $ mkdir fie
359 $ echo dead > fie/dead
359 $ echo dead > fie/dead
360 $ echo live > fie/live
360 $ echo live > fie/live
361 $ hg bookmark fo
361 $ hg bookmark fo
362 $ hg branch -q fie
362 $ hg branch -q fie
363 $ hg ci -q -Amfie
363 $ hg ci -q -Amfie
364 $ echo fo > fo
364 $ echo fo > fo
365 $ hg branch -qf default
365 $ hg branch -qf default
366 $ hg ci -q -Amfo
366 $ hg ci -q -Amfo
367 $ echo Fum > Fum
367 $ echo Fum > Fum
368 $ hg ci -q -AmFum
368 $ hg ci -q -AmFum
369 $ hg bookmark Fum
369 $ hg bookmark Fum
370
370
371 Test debugpathcomplete
371 Test debugpathcomplete
372
372
373 $ hg debugpathcomplete f
373 $ hg debugpathcomplete f
374 fee
374 fee
375 fie
375 fie
376 fo
376 fo
377 $ hg debugpathcomplete -f f
377 $ hg debugpathcomplete -f f
378 fee
378 fee
379 fie/dead
379 fie/dead
380 fie/live
380 fie/live
381 fo
381 fo
382
382
383 $ hg rm Fum
383 $ hg rm Fum
384 $ hg debugpathcomplete -r F
384 $ hg debugpathcomplete -r F
385 Fum
385 Fum
386
386
387 Test debugnamecomplete
387 Test debugnamecomplete
388
388
389 $ hg debugnamecomplete
389 $ hg debugnamecomplete
390 Fum
390 Fum
391 default
391 default
392 fee
392 fee
393 fie
393 fie
394 fo
394 fo
395 tip
395 tip
396 $ hg debugnamecomplete f
396 $ hg debugnamecomplete f
397 fee
397 fee
398 fie
398 fie
399 fo
399 fo
400
400
401 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
401 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
402 used for completions in some shells.
402 used for completions in some shells.
403
403
404 $ hg debuglabelcomplete
404 $ hg debuglabelcomplete
405 Fum
405 Fum
406 default
406 default
407 fee
407 fee
408 fie
408 fie
409 fo
409 fo
410 tip
410 tip
411 $ hg debuglabelcomplete f
411 $ hg debuglabelcomplete f
412 fee
412 fee
413 fie
413 fie
414 fo
414 fo
@@ -1,3833 +1,3835 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 status show changed files in the working directory
115 status show changed files in the working directory
116 summary summarize working directory state
116 summary summarize working directory state
117 update update working directory (or switch revisions)
117 update update working directory (or switch revisions)
118
118
119 Change import/export:
119 Change import/export:
120
120
121 archive create an unversioned archive of a repository revision
121 archive create an unversioned archive of a repository revision
122 bundle create a bundle file
122 bundle create a bundle file
123 export dump the header and diffs for one or more changesets
123 export dump the header and diffs for one or more changesets
124 import import an ordered set of patches
124 import import an ordered set of patches
125 unbundle apply one or more bundle files
125 unbundle apply one or more bundle files
126
126
127 Repository maintenance:
127 Repository maintenance:
128
128
129 manifest output the current or given revision of the project manifest
129 manifest output the current or given revision of the project manifest
130 recover roll back an interrupted transaction
130 recover roll back an interrupted transaction
131 verify verify the integrity of the repository
131 verify verify the integrity of the repository
132
132
133 Help:
133 Help:
134
134
135 config show combined config settings from all hgrc files
135 config show combined config settings from all hgrc files
136 help show help for a given topic or a help overview
136 help show help for a given topic or a help overview
137 version output version and copyright information
137 version output version and copyright information
138
138
139 additional help topics:
139 additional help topics:
140
140
141 Mercurial identifiers:
141 Mercurial identifiers:
142
142
143 filesets Specifying File Sets
143 filesets Specifying File Sets
144 hgignore Syntax for Mercurial Ignore Files
144 hgignore Syntax for Mercurial Ignore Files
145 patterns File Name Patterns
145 patterns File Name Patterns
146 revisions Specifying Revisions
146 revisions Specifying Revisions
147 urls URL Paths
147 urls URL Paths
148
148
149 Mercurial output:
149 Mercurial output:
150
150
151 color Colorizing Outputs
151 color Colorizing Outputs
152 dates Date Formats
152 dates Date Formats
153 diffs Diff Formats
153 diffs Diff Formats
154 templating Template Usage
154 templating Template Usage
155
155
156 Mercurial configuration:
156 Mercurial configuration:
157
157
158 config Configuration Files
158 config Configuration Files
159 environment Environment Variables
159 environment Environment Variables
160 extensions Using Additional Features
160 extensions Using Additional Features
161 flags Command-line flags
161 flags Command-line flags
162 hgweb Configuring hgweb
162 hgweb Configuring hgweb
163 merge-tools Merge Tools
163 merge-tools Merge Tools
164 pager Pager Support
164 pager Pager Support
165
165
166 Concepts:
166 Concepts:
167
167
168 bundlespec Bundle File Formats
168 bundlespec Bundle File Formats
169 glossary Glossary
169 glossary Glossary
170 phases Working with Phases
170 phases Working with Phases
171 subrepos Subrepositories
171 subrepos Subrepositories
172
172
173 Miscellaneous:
173 Miscellaneous:
174
174
175 deprecated Deprecated Features
175 deprecated Deprecated Features
176 internals Technical implementation topics
176 internals Technical implementation topics
177 scripting Using Mercurial from scripts and automation
177 scripting Using Mercurial from scripts and automation
178
178
179 (use 'hg help -v' to show built-in aliases and global options)
179 (use 'hg help -v' to show built-in aliases and global options)
180
180
181 $ hg -q help
181 $ hg -q help
182 Repository creation:
182 Repository creation:
183
183
184 clone make a copy of an existing repository
184 clone make a copy of an existing repository
185 init create a new repository in the given directory
185 init create a new repository in the given directory
186
186
187 Remote repository management:
187 Remote repository management:
188
188
189 incoming show new changesets found in source
189 incoming show new changesets found in source
190 outgoing show changesets not found in the destination
190 outgoing show changesets not found in the destination
191 paths show aliases for remote repositories
191 paths show aliases for remote repositories
192 pull pull changes from the specified source
192 pull pull changes from the specified source
193 push push changes to the specified destination
193 push push changes to the specified destination
194 serve start stand-alone webserver
194 serve start stand-alone webserver
195
195
196 Change creation:
196 Change creation:
197
197
198 commit commit the specified files or all outstanding changes
198 commit commit the specified files or all outstanding changes
199
199
200 Change manipulation:
200 Change manipulation:
201
201
202 backout reverse effect of earlier changeset
202 backout reverse effect of earlier changeset
203 graft copy changes from other branches onto the current branch
203 graft copy changes from other branches onto the current branch
204 merge merge another revision into working directory
204 merge merge another revision into working directory
205
205
206 Change organization:
206 Change organization:
207
207
208 bookmarks create a new bookmark or list existing bookmarks
208 bookmarks create a new bookmark or list existing bookmarks
209 branch set or show the current branch name
209 branch set or show the current branch name
210 branches list repository named branches
210 branches list repository named branches
211 phase set or show the current phase name
211 phase set or show the current phase name
212 tag add one or more tags for the current or given revision
212 tag add one or more tags for the current or given revision
213 tags list repository tags
213 tags list repository tags
214
214
215 File content management:
215 File content management:
216
216
217 annotate show changeset information by line for each file
217 annotate show changeset information by line for each file
218 cat output the current or given revision of files
218 cat output the current or given revision of files
219 copy mark files as copied for the next commit
219 copy mark files as copied for the next commit
220 diff diff repository (or selected files)
220 diff diff repository (or selected files)
221 grep search revision history for a pattern in specified files
221 grep search revision history for a pattern in specified files
222
222
223 Change navigation:
223 Change navigation:
224
224
225 bisect subdivision search of changesets
225 bisect subdivision search of changesets
226 heads show branch heads
226 heads show branch heads
227 identify identify the working directory or specified revision
227 identify identify the working directory or specified revision
228 log show revision history of entire repository or files
228 log show revision history of entire repository or files
229
229
230 Working directory management:
230 Working directory management:
231
231
232 add add the specified files on the next commit
232 add add the specified files on the next commit
233 addremove add all new files, delete all missing files
233 addremove add all new files, delete all missing files
234 files list tracked files
234 files list tracked files
235 forget forget the specified files on the next commit
235 forget forget the specified files on the next commit
236 remove remove the specified files on the next commit
236 remove remove the specified files on the next commit
237 rename rename files; equivalent of copy + remove
237 rename rename files; equivalent of copy + remove
238 resolve redo merges or set/view the merge status of files
238 resolve redo merges or set/view the merge status of files
239 revert restore files to their checkout state
239 revert restore files to their checkout state
240 root print the root (top) of the current working directory
240 root print the root (top) of the current working directory
241 status show changed files in the working directory
241 status show changed files in the working directory
242 summary summarize working directory state
242 summary summarize working directory state
243 update update working directory (or switch revisions)
243 update update working directory (or switch revisions)
244
244
245 Change import/export:
245 Change import/export:
246
246
247 archive create an unversioned archive of a repository revision
247 archive create an unversioned archive of a repository revision
248 bundle create a bundle file
248 bundle create a bundle file
249 export dump the header and diffs for one or more changesets
249 export dump the header and diffs for one or more changesets
250 import import an ordered set of patches
250 import import an ordered set of patches
251 unbundle apply one or more bundle files
251 unbundle apply one or more bundle files
252
252
253 Repository maintenance:
253 Repository maintenance:
254
254
255 manifest output the current or given revision of the project manifest
255 manifest output the current or given revision of the project manifest
256 recover roll back an interrupted transaction
256 recover roll back an interrupted transaction
257 verify verify the integrity of the repository
257 verify verify the integrity of the repository
258
258
259 Help:
259 Help:
260
260
261 config show combined config settings from all hgrc files
261 config show combined config settings from all hgrc files
262 help show help for a given topic or a help overview
262 help show help for a given topic or a help overview
263 version output version and copyright information
263 version output version and copyright information
264
264
265 additional help topics:
265 additional help topics:
266
266
267 Mercurial identifiers:
267 Mercurial identifiers:
268
268
269 filesets Specifying File Sets
269 filesets Specifying File Sets
270 hgignore Syntax for Mercurial Ignore Files
270 hgignore Syntax for Mercurial Ignore Files
271 patterns File Name Patterns
271 patterns File Name Patterns
272 revisions Specifying Revisions
272 revisions Specifying Revisions
273 urls URL Paths
273 urls URL Paths
274
274
275 Mercurial output:
275 Mercurial output:
276
276
277 color Colorizing Outputs
277 color Colorizing Outputs
278 dates Date Formats
278 dates Date Formats
279 diffs Diff Formats
279 diffs Diff Formats
280 templating Template Usage
280 templating Template Usage
281
281
282 Mercurial configuration:
282 Mercurial configuration:
283
283
284 config Configuration Files
284 config Configuration Files
285 environment Environment Variables
285 environment Environment Variables
286 extensions Using Additional Features
286 extensions Using Additional Features
287 flags Command-line flags
287 flags Command-line flags
288 hgweb Configuring hgweb
288 hgweb Configuring hgweb
289 merge-tools Merge Tools
289 merge-tools Merge Tools
290 pager Pager Support
290 pager Pager Support
291
291
292 Concepts:
292 Concepts:
293
293
294 bundlespec Bundle File Formats
294 bundlespec Bundle File Formats
295 glossary Glossary
295 glossary Glossary
296 phases Working with Phases
296 phases Working with Phases
297 subrepos Subrepositories
297 subrepos Subrepositories
298
298
299 Miscellaneous:
299 Miscellaneous:
300
300
301 deprecated Deprecated Features
301 deprecated Deprecated Features
302 internals Technical implementation topics
302 internals Technical implementation topics
303 scripting Using Mercurial from scripts and automation
303 scripting Using Mercurial from scripts and automation
304
304
305 Test extension help:
305 Test extension help:
306 $ hg help extensions --config extensions.rebase= --config extensions.children=
306 $ hg help extensions --config extensions.rebase= --config extensions.children=
307 Using Additional Features
307 Using Additional Features
308 """""""""""""""""""""""""
308 """""""""""""""""""""""""
309
309
310 Mercurial has the ability to add new features through the use of
310 Mercurial has the ability to add new features through the use of
311 extensions. Extensions may add new commands, add options to existing
311 extensions. Extensions may add new commands, add options to existing
312 commands, change the default behavior of commands, or implement hooks.
312 commands, change the default behavior of commands, or implement hooks.
313
313
314 To enable the "foo" extension, either shipped with Mercurial or in the
314 To enable the "foo" extension, either shipped with Mercurial or in the
315 Python search path, create an entry for it in your configuration file,
315 Python search path, create an entry for it in your configuration file,
316 like this:
316 like this:
317
317
318 [extensions]
318 [extensions]
319 foo =
319 foo =
320
320
321 You may also specify the full path to an extension:
321 You may also specify the full path to an extension:
322
322
323 [extensions]
323 [extensions]
324 myfeature = ~/.hgext/myfeature.py
324 myfeature = ~/.hgext/myfeature.py
325
325
326 See 'hg help config' for more information on configuration files.
326 See 'hg help config' for more information on configuration files.
327
327
328 Extensions are not loaded by default for a variety of reasons: they can
328 Extensions are not loaded by default for a variety of reasons: they can
329 increase startup overhead; they may be meant for advanced usage only; they
329 increase startup overhead; they may be meant for advanced usage only; they
330 may provide potentially dangerous abilities (such as letting you destroy
330 may provide potentially dangerous abilities (such as letting you destroy
331 or modify history); they might not be ready for prime time; or they may
331 or modify history); they might not be ready for prime time; or they may
332 alter some usual behaviors of stock Mercurial. It is thus up to the user
332 alter some usual behaviors of stock Mercurial. It is thus up to the user
333 to activate extensions as needed.
333 to activate extensions as needed.
334
334
335 To explicitly disable an extension enabled in a configuration file of
335 To explicitly disable an extension enabled in a configuration file of
336 broader scope, prepend its path with !:
336 broader scope, prepend its path with !:
337
337
338 [extensions]
338 [extensions]
339 # disabling extension bar residing in /path/to/extension/bar.py
339 # disabling extension bar residing in /path/to/extension/bar.py
340 bar = !/path/to/extension/bar.py
340 bar = !/path/to/extension/bar.py
341 # ditto, but no path was supplied for extension baz
341 # ditto, but no path was supplied for extension baz
342 baz = !
342 baz = !
343
343
344 enabled extensions:
344 enabled extensions:
345
345
346 children command to display child changesets (DEPRECATED)
346 children command to display child changesets (DEPRECATED)
347 rebase command to move sets of revisions to a different ancestor
347 rebase command to move sets of revisions to a different ancestor
348
348
349 disabled extensions:
349 disabled extensions:
350
350
351 acl hooks for controlling repository access
351 acl hooks for controlling repository access
352 blackbox log repository events to a blackbox for debugging
352 blackbox log repository events to a blackbox for debugging
353 bugzilla hooks for integrating with the Bugzilla bug tracker
353 bugzilla hooks for integrating with the Bugzilla bug tracker
354 censor erase file content at a given revision
354 censor erase file content at a given revision
355 churn command to display statistics about repository history
355 churn command to display statistics about repository history
356 clonebundles advertise pre-generated bundles to seed clones
356 clonebundles advertise pre-generated bundles to seed clones
357 closehead close arbitrary heads without checking them out first
357 closehead close arbitrary heads without checking them out first
358 convert import revisions from foreign VCS repositories into
358 convert import revisions from foreign VCS repositories into
359 Mercurial
359 Mercurial
360 eol automatically manage newlines in repository files
360 eol automatically manage newlines in repository files
361 extdiff command to allow external programs to compare revisions
361 extdiff command to allow external programs to compare revisions
362 factotum http authentication with factotum
362 factotum http authentication with factotum
363 githelp try mapping git commands to Mercurial commands
363 githelp try mapping git commands to Mercurial commands
364 gpg commands to sign and verify changesets
364 gpg commands to sign and verify changesets
365 hgk browse the repository in a graphical way
365 hgk browse the repository in a graphical way
366 highlight syntax highlighting for hgweb (requires Pygments)
366 highlight syntax highlighting for hgweb (requires Pygments)
367 histedit interactive history editing
367 histedit interactive history editing
368 keyword expand keywords in tracked files
368 keyword expand keywords in tracked files
369 largefiles track large binary files
369 largefiles track large binary files
370 mq manage a stack of patches
370 mq manage a stack of patches
371 notify hooks for sending email push notifications
371 notify hooks for sending email push notifications
372 patchbomb command to send changesets as (a series of) patch emails
372 patchbomb command to send changesets as (a series of) patch emails
373 purge command to delete untracked files from the working
373 purge command to delete untracked files from the working
374 directory
374 directory
375 relink recreates hardlinks between repository clones
375 relink recreates hardlinks between repository clones
376 schemes extend schemes with shortcuts to repository swarms
376 schemes extend schemes with shortcuts to repository swarms
377 share share a common history between several working directories
377 share share a common history between several working directories
378 shelve save and restore changes to the working directory
378 shelve save and restore changes to the working directory
379 strip strip changesets and their descendants from history
379 strip strip changesets and their descendants from history
380 transplant command to transplant changesets from another branch
380 transplant command to transplant changesets from another branch
381 win32mbcs allow the use of MBCS paths with problematic encodings
381 win32mbcs allow the use of MBCS paths with problematic encodings
382 zeroconf discover and advertise repositories on the local network
382 zeroconf discover and advertise repositories on the local network
383
383
384 #endif
384 #endif
385
385
386 Verify that deprecated extensions are included if --verbose:
386 Verify that deprecated extensions are included if --verbose:
387
387
388 $ hg -v help extensions | grep children
388 $ hg -v help extensions | grep children
389 children command to display child changesets (DEPRECATED)
389 children command to display child changesets (DEPRECATED)
390
390
391 Verify that extension keywords appear in help templates
391 Verify that extension keywords appear in help templates
392
392
393 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
393 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
394
394
395 Test short command list with verbose option
395 Test short command list with verbose option
396
396
397 $ hg -v help shortlist
397 $ hg -v help shortlist
398 Mercurial Distributed SCM
398 Mercurial Distributed SCM
399
399
400 basic commands:
400 basic commands:
401
401
402 add add the specified files on the next commit
402 add add the specified files on the next commit
403 annotate, blame
403 annotate, blame
404 show changeset information by line for each file
404 show changeset information by line for each file
405 clone make a copy of an existing repository
405 clone make a copy of an existing repository
406 commit, ci commit the specified files or all outstanding changes
406 commit, ci commit the specified files or all outstanding changes
407 diff diff repository (or selected files)
407 diff diff repository (or selected files)
408 export dump the header and diffs for one or more changesets
408 export dump the header and diffs for one or more changesets
409 forget forget the specified files on the next commit
409 forget forget the specified files on the next commit
410 init create a new repository in the given directory
410 init create a new repository in the given directory
411 log, history show revision history of entire repository or files
411 log, history show revision history of entire repository or files
412 merge merge another revision into working directory
412 merge merge another revision into working directory
413 pull pull changes from the specified source
413 pull pull changes from the specified source
414 push push changes to the specified destination
414 push push changes to the specified destination
415 remove, rm remove the specified files on the next commit
415 remove, rm remove the specified files on the next commit
416 serve start stand-alone webserver
416 serve start stand-alone webserver
417 status, st show changed files in the working directory
417 status, st show changed files in the working directory
418 summary, sum summarize working directory state
418 summary, sum summarize working directory state
419 update, up, checkout, co
419 update, up, checkout, co
420 update working directory (or switch revisions)
420 update working directory (or switch revisions)
421
421
422 global options ([+] can be repeated):
422 global options ([+] can be repeated):
423
423
424 -R --repository REPO repository root directory or name of overlay bundle
424 -R --repository REPO repository root directory or name of overlay bundle
425 file
425 file
426 --cwd DIR change working directory
426 --cwd DIR change working directory
427 -y --noninteractive do not prompt, automatically pick the first choice for
427 -y --noninteractive do not prompt, automatically pick the first choice for
428 all prompts
428 all prompts
429 -q --quiet suppress output
429 -q --quiet suppress output
430 -v --verbose enable additional output
430 -v --verbose enable additional output
431 --color TYPE when to colorize (boolean, always, auto, never, or
431 --color TYPE when to colorize (boolean, always, auto, never, or
432 debug)
432 debug)
433 --config CONFIG [+] set/override config option (use 'section.name=value')
433 --config CONFIG [+] set/override config option (use 'section.name=value')
434 --debug enable debugging output
434 --debug enable debugging output
435 --debugger start debugger
435 --debugger start debugger
436 --encoding ENCODE set the charset encoding (default: ascii)
436 --encoding ENCODE set the charset encoding (default: ascii)
437 --encodingmode MODE set the charset encoding mode (default: strict)
437 --encodingmode MODE set the charset encoding mode (default: strict)
438 --traceback always print a traceback on exception
438 --traceback always print a traceback on exception
439 --time time how long the command takes
439 --time time how long the command takes
440 --profile print command execution profile
440 --profile print command execution profile
441 --version output version information and exit
441 --version output version information and exit
442 -h --help display help and exit
442 -h --help display help and exit
443 --hidden consider hidden changesets
443 --hidden consider hidden changesets
444 --pager TYPE when to paginate (boolean, always, auto, or never)
444 --pager TYPE when to paginate (boolean, always, auto, or never)
445 (default: auto)
445 (default: auto)
446
446
447 (use 'hg help' for the full list of commands)
447 (use 'hg help' for the full list of commands)
448
448
449 $ hg add -h
449 $ hg add -h
450 hg add [OPTION]... [FILE]...
450 hg add [OPTION]... [FILE]...
451
451
452 add the specified files on the next commit
452 add the specified files on the next commit
453
453
454 Schedule files to be version controlled and added to the repository.
454 Schedule files to be version controlled and added to the repository.
455
455
456 The files will be added to the repository at the next commit. To undo an
456 The files will be added to the repository at the next commit. To undo an
457 add before that, see 'hg forget'.
457 add before that, see 'hg forget'.
458
458
459 If no names are given, add all files to the repository (except files
459 If no names are given, add all files to the repository (except files
460 matching ".hgignore").
460 matching ".hgignore").
461
461
462 Returns 0 if all files are successfully added.
462 Returns 0 if all files are successfully added.
463
463
464 options ([+] can be repeated):
464 options ([+] can be repeated):
465
465
466 -I --include PATTERN [+] include names matching the given patterns
466 -I --include PATTERN [+] include names matching the given patterns
467 -X --exclude PATTERN [+] exclude names matching the given patterns
467 -X --exclude PATTERN [+] exclude names matching the given patterns
468 -S --subrepos recurse into subrepositories
468 -S --subrepos recurse into subrepositories
469 -n --dry-run do not perform actions, just print output
469 -n --dry-run do not perform actions, just print output
470
470
471 (some details hidden, use --verbose to show complete help)
471 (some details hidden, use --verbose to show complete help)
472
472
473 Verbose help for add
473 Verbose help for add
474
474
475 $ hg add -hv
475 $ hg add -hv
476 hg add [OPTION]... [FILE]...
476 hg add [OPTION]... [FILE]...
477
477
478 add the specified files on the next commit
478 add the specified files on the next commit
479
479
480 Schedule files to be version controlled and added to the repository.
480 Schedule files to be version controlled and added to the repository.
481
481
482 The files will be added to the repository at the next commit. To undo an
482 The files will be added to the repository at the next commit. To undo an
483 add before that, see 'hg forget'.
483 add before that, see 'hg forget'.
484
484
485 If no names are given, add all files to the repository (except files
485 If no names are given, add all files to the repository (except files
486 matching ".hgignore").
486 matching ".hgignore").
487
487
488 Examples:
488 Examples:
489
489
490 - New (unknown) files are added automatically by 'hg add':
490 - New (unknown) files are added automatically by 'hg add':
491
491
492 $ ls
492 $ ls
493 foo.c
493 foo.c
494 $ hg status
494 $ hg status
495 ? foo.c
495 ? foo.c
496 $ hg add
496 $ hg add
497 adding foo.c
497 adding foo.c
498 $ hg status
498 $ hg status
499 A foo.c
499 A foo.c
500
500
501 - Specific files to be added can be specified:
501 - Specific files to be added can be specified:
502
502
503 $ ls
503 $ ls
504 bar.c foo.c
504 bar.c foo.c
505 $ hg status
505 $ hg status
506 ? bar.c
506 ? bar.c
507 ? foo.c
507 ? foo.c
508 $ hg add bar.c
508 $ hg add bar.c
509 $ hg status
509 $ hg status
510 A bar.c
510 A bar.c
511 ? foo.c
511 ? foo.c
512
512
513 Returns 0 if all files are successfully added.
513 Returns 0 if all files are successfully added.
514
514
515 options ([+] can be repeated):
515 options ([+] can be repeated):
516
516
517 -I --include PATTERN [+] include names matching the given patterns
517 -I --include PATTERN [+] include names matching the given patterns
518 -X --exclude PATTERN [+] exclude names matching the given patterns
518 -X --exclude PATTERN [+] exclude names matching the given patterns
519 -S --subrepos recurse into subrepositories
519 -S --subrepos recurse into subrepositories
520 -n --dry-run do not perform actions, just print output
520 -n --dry-run do not perform actions, just print output
521
521
522 global options ([+] can be repeated):
522 global options ([+] can be repeated):
523
523
524 -R --repository REPO repository root directory or name of overlay bundle
524 -R --repository REPO repository root directory or name of overlay bundle
525 file
525 file
526 --cwd DIR change working directory
526 --cwd DIR change working directory
527 -y --noninteractive do not prompt, automatically pick the first choice for
527 -y --noninteractive do not prompt, automatically pick the first choice for
528 all prompts
528 all prompts
529 -q --quiet suppress output
529 -q --quiet suppress output
530 -v --verbose enable additional output
530 -v --verbose enable additional output
531 --color TYPE when to colorize (boolean, always, auto, never, or
531 --color TYPE when to colorize (boolean, always, auto, never, or
532 debug)
532 debug)
533 --config CONFIG [+] set/override config option (use 'section.name=value')
533 --config CONFIG [+] set/override config option (use 'section.name=value')
534 --debug enable debugging output
534 --debug enable debugging output
535 --debugger start debugger
535 --debugger start debugger
536 --encoding ENCODE set the charset encoding (default: ascii)
536 --encoding ENCODE set the charset encoding (default: ascii)
537 --encodingmode MODE set the charset encoding mode (default: strict)
537 --encodingmode MODE set the charset encoding mode (default: strict)
538 --traceback always print a traceback on exception
538 --traceback always print a traceback on exception
539 --time time how long the command takes
539 --time time how long the command takes
540 --profile print command execution profile
540 --profile print command execution profile
541 --version output version information and exit
541 --version output version information and exit
542 -h --help display help and exit
542 -h --help display help and exit
543 --hidden consider hidden changesets
543 --hidden consider hidden changesets
544 --pager TYPE when to paginate (boolean, always, auto, or never)
544 --pager TYPE when to paginate (boolean, always, auto, or never)
545 (default: auto)
545 (default: auto)
546
546
547 Test the textwidth config option
547 Test the textwidth config option
548
548
549 $ hg root -h --config ui.textwidth=50
549 $ hg root -h --config ui.textwidth=50
550 hg root
550 hg root
551
551
552 print the root (top) of the current working
552 print the root (top) of the current working
553 directory
553 directory
554
554
555 Print the root directory of the current
555 Print the root directory of the current
556 repository.
556 repository.
557
557
558 Returns 0 on success.
558 Returns 0 on success.
559
559
560 (some details hidden, use --verbose to show
560 (some details hidden, use --verbose to show
561 complete help)
561 complete help)
562
562
563 Test help option with version option
563 Test help option with version option
564
564
565 $ hg add -h --version
565 $ hg add -h --version
566 Mercurial Distributed SCM (version *) (glob)
566 Mercurial Distributed SCM (version *) (glob)
567 (see https://mercurial-scm.org for more information)
567 (see https://mercurial-scm.org for more information)
568
568
569 Copyright (C) 2005-* Matt Mackall and others (glob)
569 Copyright (C) 2005-* Matt Mackall and others (glob)
570 This is free software; see the source for copying conditions. There is NO
570 This is free software; see the source for copying conditions. There is NO
571 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
571 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
572
572
573 $ hg add --skjdfks
573 $ hg add --skjdfks
574 hg add: option --skjdfks not recognized
574 hg add: option --skjdfks not recognized
575 hg add [OPTION]... [FILE]...
575 hg add [OPTION]... [FILE]...
576
576
577 add the specified files on the next commit
577 add the specified files on the next commit
578
578
579 options ([+] can be repeated):
579 options ([+] can be repeated):
580
580
581 -I --include PATTERN [+] include names matching the given patterns
581 -I --include PATTERN [+] include names matching the given patterns
582 -X --exclude PATTERN [+] exclude names matching the given patterns
582 -X --exclude PATTERN [+] exclude names matching the given patterns
583 -S --subrepos recurse into subrepositories
583 -S --subrepos recurse into subrepositories
584 -n --dry-run do not perform actions, just print output
584 -n --dry-run do not perform actions, just print output
585
585
586 (use 'hg add -h' to show more help)
586 (use 'hg add -h' to show more help)
587 [255]
587 [255]
588
588
589 Test ambiguous command help
589 Test ambiguous command help
590
590
591 $ hg help ad
591 $ hg help ad
592 list of commands:
592 list of commands:
593
593
594 add add the specified files on the next commit
594 add add the specified files on the next commit
595 addremove add all new files, delete all missing files
595 addremove add all new files, delete all missing files
596
596
597 (use 'hg help -v ad' to show built-in aliases and global options)
597 (use 'hg help -v ad' to show built-in aliases and global options)
598
598
599 Test command without options
599 Test command without options
600
600
601 $ hg help verify
601 $ hg help verify
602 hg verify
602 hg verify
603
603
604 verify the integrity of the repository
604 verify the integrity of the repository
605
605
606 Verify the integrity of the current repository.
606 Verify the integrity of the current repository.
607
607
608 This will perform an extensive check of the repository's integrity,
608 This will perform an extensive check of the repository's integrity,
609 validating the hashes and checksums of each entry in the changelog,
609 validating the hashes and checksums of each entry in the changelog,
610 manifest, and tracked files, as well as the integrity of their crosslinks
610 manifest, and tracked files, as well as the integrity of their crosslinks
611 and indices.
611 and indices.
612
612
613 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
613 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
614 information about recovery from corruption of the repository.
614 information about recovery from corruption of the repository.
615
615
616 Returns 0 on success, 1 if errors are encountered.
616 Returns 0 on success, 1 if errors are encountered.
617
617
618 options:
619
618 (some details hidden, use --verbose to show complete help)
620 (some details hidden, use --verbose to show complete help)
619
621
620 $ hg help diff
622 $ hg help diff
621 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
623 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
622
624
623 diff repository (or selected files)
625 diff repository (or selected files)
624
626
625 Show differences between revisions for the specified files.
627 Show differences between revisions for the specified files.
626
628
627 Differences between files are shown using the unified diff format.
629 Differences between files are shown using the unified diff format.
628
630
629 Note:
631 Note:
630 'hg diff' may generate unexpected results for merges, as it will
632 'hg diff' may generate unexpected results for merges, as it will
631 default to comparing against the working directory's first parent
633 default to comparing against the working directory's first parent
632 changeset if no revisions are specified.
634 changeset if no revisions are specified.
633
635
634 When two revision arguments are given, then changes are shown between
636 When two revision arguments are given, then changes are shown between
635 those revisions. If only one revision is specified then that revision is
637 those revisions. If only one revision is specified then that revision is
636 compared to the working directory, and, when no revisions are specified,
638 compared to the working directory, and, when no revisions are specified,
637 the working directory files are compared to its first parent.
639 the working directory files are compared to its first parent.
638
640
639 Alternatively you can specify -c/--change with a revision to see the
641 Alternatively you can specify -c/--change with a revision to see the
640 changes in that changeset relative to its first parent.
642 changes in that changeset relative to its first parent.
641
643
642 Without the -a/--text option, diff will avoid generating diffs of files it
644 Without the -a/--text option, diff will avoid generating diffs of files it
643 detects as binary. With -a, diff will generate a diff anyway, probably
645 detects as binary. With -a, diff will generate a diff anyway, probably
644 with undesirable results.
646 with undesirable results.
645
647
646 Use the -g/--git option to generate diffs in the git extended diff format.
648 Use the -g/--git option to generate diffs in the git extended diff format.
647 For more information, read 'hg help diffs'.
649 For more information, read 'hg help diffs'.
648
650
649 Returns 0 on success.
651 Returns 0 on success.
650
652
651 options ([+] can be repeated):
653 options ([+] can be repeated):
652
654
653 -r --rev REV [+] revision
655 -r --rev REV [+] revision
654 -c --change REV change made by revision
656 -c --change REV change made by revision
655 -a --text treat all files as text
657 -a --text treat all files as text
656 -g --git use git extended diff format
658 -g --git use git extended diff format
657 --binary generate binary diffs in git mode (default)
659 --binary generate binary diffs in git mode (default)
658 --nodates omit dates from diff headers
660 --nodates omit dates from diff headers
659 --noprefix omit a/ and b/ prefixes from filenames
661 --noprefix omit a/ and b/ prefixes from filenames
660 -p --show-function show which function each change is in
662 -p --show-function show which function each change is in
661 --reverse produce a diff that undoes the changes
663 --reverse produce a diff that undoes the changes
662 -w --ignore-all-space ignore white space when comparing lines
664 -w --ignore-all-space ignore white space when comparing lines
663 -b --ignore-space-change ignore changes in the amount of white space
665 -b --ignore-space-change ignore changes in the amount of white space
664 -B --ignore-blank-lines ignore changes whose lines are all blank
666 -B --ignore-blank-lines ignore changes whose lines are all blank
665 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
667 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
666 -U --unified NUM number of lines of context to show
668 -U --unified NUM number of lines of context to show
667 --stat output diffstat-style summary of changes
669 --stat output diffstat-style summary of changes
668 --root DIR produce diffs relative to subdirectory
670 --root DIR produce diffs relative to subdirectory
669 -I --include PATTERN [+] include names matching the given patterns
671 -I --include PATTERN [+] include names matching the given patterns
670 -X --exclude PATTERN [+] exclude names matching the given patterns
672 -X --exclude PATTERN [+] exclude names matching the given patterns
671 -S --subrepos recurse into subrepositories
673 -S --subrepos recurse into subrepositories
672
674
673 (some details hidden, use --verbose to show complete help)
675 (some details hidden, use --verbose to show complete help)
674
676
675 $ hg help status
677 $ hg help status
676 hg status [OPTION]... [FILE]...
678 hg status [OPTION]... [FILE]...
677
679
678 aliases: st
680 aliases: st
679
681
680 show changed files in the working directory
682 show changed files in the working directory
681
683
682 Show status of files in the repository. If names are given, only files
684 Show status of files in the repository. If names are given, only files
683 that match are shown. Files that are clean or ignored or the source of a
685 that match are shown. Files that are clean or ignored or the source of a
684 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
686 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
685 -C/--copies or -A/--all are given. Unless options described with "show
687 -C/--copies or -A/--all are given. Unless options described with "show
686 only ..." are given, the options -mardu are used.
688 only ..." are given, the options -mardu are used.
687
689
688 Option -q/--quiet hides untracked (unknown and ignored) files unless
690 Option -q/--quiet hides untracked (unknown and ignored) files unless
689 explicitly requested with -u/--unknown or -i/--ignored.
691 explicitly requested with -u/--unknown or -i/--ignored.
690
692
691 Note:
693 Note:
692 'hg status' may appear to disagree with diff if permissions have
694 'hg status' may appear to disagree with diff if permissions have
693 changed or a merge has occurred. The standard diff format does not
695 changed or a merge has occurred. The standard diff format does not
694 report permission changes and diff only reports changes relative to one
696 report permission changes and diff only reports changes relative to one
695 merge parent.
697 merge parent.
696
698
697 If one revision is given, it is used as the base revision. If two
699 If one revision is given, it is used as the base revision. If two
698 revisions are given, the differences between them are shown. The --change
700 revisions are given, the differences between them are shown. The --change
699 option can also be used as a shortcut to list the changed files of a
701 option can also be used as a shortcut to list the changed files of a
700 revision from its first parent.
702 revision from its first parent.
701
703
702 The codes used to show the status of files are:
704 The codes used to show the status of files are:
703
705
704 M = modified
706 M = modified
705 A = added
707 A = added
706 R = removed
708 R = removed
707 C = clean
709 C = clean
708 ! = missing (deleted by non-hg command, but still tracked)
710 ! = missing (deleted by non-hg command, but still tracked)
709 ? = not tracked
711 ? = not tracked
710 I = ignored
712 I = ignored
711 = origin of the previous file (with --copies)
713 = origin of the previous file (with --copies)
712
714
713 Returns 0 on success.
715 Returns 0 on success.
714
716
715 options ([+] can be repeated):
717 options ([+] can be repeated):
716
718
717 -A --all show status of all files
719 -A --all show status of all files
718 -m --modified show only modified files
720 -m --modified show only modified files
719 -a --added show only added files
721 -a --added show only added files
720 -r --removed show only removed files
722 -r --removed show only removed files
721 -d --deleted show only deleted (but tracked) files
723 -d --deleted show only deleted (but tracked) files
722 -c --clean show only files without changes
724 -c --clean show only files without changes
723 -u --unknown show only unknown (not tracked) files
725 -u --unknown show only unknown (not tracked) files
724 -i --ignored show only ignored files
726 -i --ignored show only ignored files
725 -n --no-status hide status prefix
727 -n --no-status hide status prefix
726 -C --copies show source of copied files
728 -C --copies show source of copied files
727 -0 --print0 end filenames with NUL, for use with xargs
729 -0 --print0 end filenames with NUL, for use with xargs
728 --rev REV [+] show difference from revision
730 --rev REV [+] show difference from revision
729 --change REV list the changed files of a revision
731 --change REV list the changed files of a revision
730 -I --include PATTERN [+] include names matching the given patterns
732 -I --include PATTERN [+] include names matching the given patterns
731 -X --exclude PATTERN [+] exclude names matching the given patterns
733 -X --exclude PATTERN [+] exclude names matching the given patterns
732 -S --subrepos recurse into subrepositories
734 -S --subrepos recurse into subrepositories
733 -T --template TEMPLATE display with template
735 -T --template TEMPLATE display with template
734
736
735 (some details hidden, use --verbose to show complete help)
737 (some details hidden, use --verbose to show complete help)
736
738
737 $ hg -q help status
739 $ hg -q help status
738 hg status [OPTION]... [FILE]...
740 hg status [OPTION]... [FILE]...
739
741
740 show changed files in the working directory
742 show changed files in the working directory
741
743
742 $ hg help foo
744 $ hg help foo
743 abort: no such help topic: foo
745 abort: no such help topic: foo
744 (try 'hg help --keyword foo')
746 (try 'hg help --keyword foo')
745 [255]
747 [255]
746
748
747 $ hg skjdfks
749 $ hg skjdfks
748 hg: unknown command 'skjdfks'
750 hg: unknown command 'skjdfks'
749 (use 'hg help' for a list of commands)
751 (use 'hg help' for a list of commands)
750 [255]
752 [255]
751
753
752 Typoed command gives suggestion
754 Typoed command gives suggestion
753 $ hg puls
755 $ hg puls
754 hg: unknown command 'puls'
756 hg: unknown command 'puls'
755 (did you mean one of pull, push?)
757 (did you mean one of pull, push?)
756 [255]
758 [255]
757
759
758 Not enabled extension gets suggested
760 Not enabled extension gets suggested
759
761
760 $ hg rebase
762 $ hg rebase
761 hg: unknown command 'rebase'
763 hg: unknown command 'rebase'
762 'rebase' is provided by the following extension:
764 'rebase' is provided by the following extension:
763
765
764 rebase command to move sets of revisions to a different ancestor
766 rebase command to move sets of revisions to a different ancestor
765
767
766 (use 'hg help extensions' for information on enabling extensions)
768 (use 'hg help extensions' for information on enabling extensions)
767 [255]
769 [255]
768
770
769 Disabled extension gets suggested
771 Disabled extension gets suggested
770 $ hg --config extensions.rebase=! rebase
772 $ hg --config extensions.rebase=! rebase
771 hg: unknown command 'rebase'
773 hg: unknown command 'rebase'
772 'rebase' is provided by the following extension:
774 'rebase' is provided by the following extension:
773
775
774 rebase command to move sets of revisions to a different ancestor
776 rebase command to move sets of revisions to a different ancestor
775
777
776 (use 'hg help extensions' for information on enabling extensions)
778 (use 'hg help extensions' for information on enabling extensions)
777 [255]
779 [255]
778
780
779 Make sure that we don't run afoul of the help system thinking that
781 Make sure that we don't run afoul of the help system thinking that
780 this is a section and erroring out weirdly.
782 this is a section and erroring out weirdly.
781
783
782 $ hg .log
784 $ hg .log
783 hg: unknown command '.log'
785 hg: unknown command '.log'
784 (did you mean log?)
786 (did you mean log?)
785 [255]
787 [255]
786
788
787 $ hg log.
789 $ hg log.
788 hg: unknown command 'log.'
790 hg: unknown command 'log.'
789 (did you mean log?)
791 (did you mean log?)
790 [255]
792 [255]
791 $ hg pu.lh
793 $ hg pu.lh
792 hg: unknown command 'pu.lh'
794 hg: unknown command 'pu.lh'
793 (did you mean one of pull, push?)
795 (did you mean one of pull, push?)
794 [255]
796 [255]
795
797
796 $ cat > helpext.py <<EOF
798 $ cat > helpext.py <<EOF
797 > import os
799 > import os
798 > from mercurial import commands, fancyopts, registrar
800 > from mercurial import commands, fancyopts, registrar
799 >
801 >
800 > def func(arg):
802 > def func(arg):
801 > return '%sfoo' % arg
803 > return '%sfoo' % arg
802 > class customopt(fancyopts.customopt):
804 > class customopt(fancyopts.customopt):
803 > def newstate(self, oldstate, newparam, abort):
805 > def newstate(self, oldstate, newparam, abort):
804 > return '%sbar' % oldstate
806 > return '%sbar' % oldstate
805 > cmdtable = {}
807 > cmdtable = {}
806 > command = registrar.command(cmdtable)
808 > command = registrar.command(cmdtable)
807 >
809 >
808 > @command(b'nohelp',
810 > @command(b'nohelp',
809 > [(b'', b'longdesc', 3, b'x'*67),
811 > [(b'', b'longdesc', 3, b'x'*67),
810 > (b'n', b'', None, b'normal desc'),
812 > (b'n', b'', None, b'normal desc'),
811 > (b'', b'newline', b'', b'line1\nline2'),
813 > (b'', b'newline', b'', b'line1\nline2'),
812 > (b'', b'default-off', False, b'enable X'),
814 > (b'', b'default-off', False, b'enable X'),
813 > (b'', b'default-on', True, b'enable Y'),
815 > (b'', b'default-on', True, b'enable Y'),
814 > (b'', b'callableopt', func, b'adds foo'),
816 > (b'', b'callableopt', func, b'adds foo'),
815 > (b'', b'customopt', customopt(''), b'adds bar'),
817 > (b'', b'customopt', customopt(''), b'adds bar'),
816 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
818 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
817 > b'hg nohelp',
819 > b'hg nohelp',
818 > norepo=True)
820 > norepo=True)
819 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
821 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
820 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
822 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
821 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
823 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
822 > def nohelp(ui, *args, **kwargs):
824 > def nohelp(ui, *args, **kwargs):
823 > pass
825 > pass
824 >
826 >
825 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
827 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
826 > def hashelp(ui, *args, **kwargs):
828 > def hashelp(ui, *args, **kwargs):
827 > """Extension command's help"""
829 > """Extension command's help"""
828 >
830 >
829 > def uisetup(ui):
831 > def uisetup(ui):
830 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
832 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
831 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
833 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
832 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
834 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
833 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
835 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
834 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
836 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
835 >
837 >
836 > EOF
838 > EOF
837 $ echo '[extensions]' >> $HGRCPATH
839 $ echo '[extensions]' >> $HGRCPATH
838 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
840 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
839
841
840 Test for aliases
842 Test for aliases
841
843
842 $ hg help | grep hgalias
844 $ hg help | grep hgalias
843 hgalias My doc
845 hgalias My doc
844
846
845 $ hg help hgalias
847 $ hg help hgalias
846 hg hgalias [--remote]
848 hg hgalias [--remote]
847
849
848 alias for: hg summary
850 alias for: hg summary
849
851
850 My doc
852 My doc
851
853
852 defined by: helpext
854 defined by: helpext
853
855
854 options:
856 options:
855
857
856 --remote check for push and pull
858 --remote check for push and pull
857
859
858 (some details hidden, use --verbose to show complete help)
860 (some details hidden, use --verbose to show complete help)
859 $ hg help hgaliasnodoc
861 $ hg help hgaliasnodoc
860 hg hgaliasnodoc [--remote]
862 hg hgaliasnodoc [--remote]
861
863
862 alias for: hg summary
864 alias for: hg summary
863
865
864 summarize working directory state
866 summarize working directory state
865
867
866 This generates a brief summary of the working directory state, including
868 This generates a brief summary of the working directory state, including
867 parents, branch, commit status, phase and available updates.
869 parents, branch, commit status, phase and available updates.
868
870
869 With the --remote option, this will check the default paths for incoming
871 With the --remote option, this will check the default paths for incoming
870 and outgoing changes. This can be time-consuming.
872 and outgoing changes. This can be time-consuming.
871
873
872 Returns 0 on success.
874 Returns 0 on success.
873
875
874 defined by: helpext
876 defined by: helpext
875
877
876 options:
878 options:
877
879
878 --remote check for push and pull
880 --remote check for push and pull
879
881
880 (some details hidden, use --verbose to show complete help)
882 (some details hidden, use --verbose to show complete help)
881
883
882 $ hg help shellalias
884 $ hg help shellalias
883 hg shellalias
885 hg shellalias
884
886
885 shell alias for: echo hi
887 shell alias for: echo hi
886
888
887 (no help text available)
889 (no help text available)
888
890
889 defined by: helpext
891 defined by: helpext
890
892
891 (some details hidden, use --verbose to show complete help)
893 (some details hidden, use --verbose to show complete help)
892
894
893 Test command with no help text
895 Test command with no help text
894
896
895 $ hg help nohelp
897 $ hg help nohelp
896 hg nohelp
898 hg nohelp
897
899
898 (no help text available)
900 (no help text available)
899
901
900 options:
902 options:
901
903
902 --longdesc VALUE
904 --longdesc VALUE
903 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
905 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
904 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
906 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
905 -n -- normal desc
907 -n -- normal desc
906 --newline VALUE line1 line2
908 --newline VALUE line1 line2
907 --default-off enable X
909 --default-off enable X
908 --[no-]default-on enable Y (default: on)
910 --[no-]default-on enable Y (default: on)
909 --callableopt VALUE adds foo
911 --callableopt VALUE adds foo
910 --customopt VALUE adds bar
912 --customopt VALUE adds bar
911 --customopt-withdefault VALUE adds bar (default: foo)
913 --customopt-withdefault VALUE adds bar (default: foo)
912
914
913 (some details hidden, use --verbose to show complete help)
915 (some details hidden, use --verbose to show complete help)
914
916
915 Test that default list of commands includes extension commands that have help,
917 Test that default list of commands includes extension commands that have help,
916 but not those that don't, except in verbose mode, when a keyword is passed, or
918 but not those that don't, except in verbose mode, when a keyword is passed, or
917 when help about the extension is requested.
919 when help about the extension is requested.
918
920
919 #if no-extraextensions
921 #if no-extraextensions
920
922
921 $ hg help | grep hashelp
923 $ hg help | grep hashelp
922 hashelp Extension command's help
924 hashelp Extension command's help
923 $ hg help | grep nohelp
925 $ hg help | grep nohelp
924 [1]
926 [1]
925 $ hg help -v | grep nohelp
927 $ hg help -v | grep nohelp
926 nohelp (no help text available)
928 nohelp (no help text available)
927
929
928 $ hg help -k nohelp
930 $ hg help -k nohelp
929 Commands:
931 Commands:
930
932
931 nohelp hg nohelp
933 nohelp hg nohelp
932
934
933 Extension Commands:
935 Extension Commands:
934
936
935 nohelp (no help text available)
937 nohelp (no help text available)
936
938
937 $ hg help helpext
939 $ hg help helpext
938 helpext extension - no help text available
940 helpext extension - no help text available
939
941
940 list of commands:
942 list of commands:
941
943
942 hashelp Extension command's help
944 hashelp Extension command's help
943 nohelp (no help text available)
945 nohelp (no help text available)
944
946
945 (use 'hg help -v helpext' to show built-in aliases and global options)
947 (use 'hg help -v helpext' to show built-in aliases and global options)
946
948
947 #endif
949 #endif
948
950
949 Test list of internal help commands
951 Test list of internal help commands
950
952
951 $ hg help debug
953 $ hg help debug
952 debug commands (internal and unsupported):
954 debug commands (internal and unsupported):
953
955
954 debugancestor
956 debugancestor
955 find the ancestor revision of two revisions in a given index
957 find the ancestor revision of two revisions in a given index
956 debugapplystreamclonebundle
958 debugapplystreamclonebundle
957 apply a stream clone bundle file
959 apply a stream clone bundle file
958 debugbuilddag
960 debugbuilddag
959 builds a repo with a given DAG from scratch in the current
961 builds a repo with a given DAG from scratch in the current
960 empty repo
962 empty repo
961 debugbundle lists the contents of a bundle
963 debugbundle lists the contents of a bundle
962 debugcapabilities
964 debugcapabilities
963 lists the capabilities of a remote peer
965 lists the capabilities of a remote peer
964 debugcheckstate
966 debugcheckstate
965 validate the correctness of the current dirstate
967 validate the correctness of the current dirstate
966 debugcolor show available color, effects or style
968 debugcolor show available color, effects or style
967 debugcommands
969 debugcommands
968 list all available commands and options
970 list all available commands and options
969 debugcomplete
971 debugcomplete
970 returns the completion list associated with the given command
972 returns the completion list associated with the given command
971 debugcreatestreamclonebundle
973 debugcreatestreamclonebundle
972 create a stream clone bundle file
974 create a stream clone bundle file
973 debugdag format the changelog or an index DAG as a concise textual
975 debugdag format the changelog or an index DAG as a concise textual
974 description
976 description
975 debugdata dump the contents of a data file revision
977 debugdata dump the contents of a data file revision
976 debugdate parse and display a date
978 debugdate parse and display a date
977 debugdeltachain
979 debugdeltachain
978 dump information about delta chains in a revlog
980 dump information about delta chains in a revlog
979 debugdirstate
981 debugdirstate
980 show the contents of the current dirstate
982 show the contents of the current dirstate
981 debugdiscovery
983 debugdiscovery
982 runs the changeset discovery protocol in isolation
984 runs the changeset discovery protocol in isolation
983 debugdownload
985 debugdownload
984 download a resource using Mercurial logic and config
986 download a resource using Mercurial logic and config
985 debugextensions
987 debugextensions
986 show information about active extensions
988 show information about active extensions
987 debugfileset parse and apply a fileset specification
989 debugfileset parse and apply a fileset specification
988 debugformat display format information about the current repository
990 debugformat display format information about the current repository
989 debugfsinfo show information detected about current filesystem
991 debugfsinfo show information detected about current filesystem
990 debuggetbundle
992 debuggetbundle
991 retrieves a bundle from a repo
993 retrieves a bundle from a repo
992 debugignore display the combined ignore pattern and information about
994 debugignore display the combined ignore pattern and information about
993 ignored files
995 ignored files
994 debugindex dump index data for a storage primitive
996 debugindex dump index data for a storage primitive
995 debugindexdot
997 debugindexdot
996 dump an index DAG as a graphviz dot file
998 dump an index DAG as a graphviz dot file
997 debugindexstats
999 debugindexstats
998 show stats related to the changelog index
1000 show stats related to the changelog index
999 debuginstall test Mercurial installation
1001 debuginstall test Mercurial installation
1000 debugknown test whether node ids are known to a repo
1002 debugknown test whether node ids are known to a repo
1001 debuglocks show or modify state of locks
1003 debuglocks show or modify state of locks
1002 debugmanifestfulltextcache
1004 debugmanifestfulltextcache
1003 show, clear or amend the contents of the manifest fulltext
1005 show, clear or amend the contents of the manifest fulltext
1004 cache
1006 cache
1005 debugmergestate
1007 debugmergestate
1006 print merge state
1008 print merge state
1007 debugnamecomplete
1009 debugnamecomplete
1008 complete "names" - tags, open branch names, bookmark names
1010 complete "names" - tags, open branch names, bookmark names
1009 debugobsolete
1011 debugobsolete
1010 create arbitrary obsolete marker
1012 create arbitrary obsolete marker
1011 debugoptADV (no help text available)
1013 debugoptADV (no help text available)
1012 debugoptDEP (no help text available)
1014 debugoptDEP (no help text available)
1013 debugoptEXP (no help text available)
1015 debugoptEXP (no help text available)
1014 debugp1copies
1016 debugp1copies
1015 dump copy information compared to p1
1017 dump copy information compared to p1
1016 debugp2copies
1018 debugp2copies
1017 dump copy information compared to p2
1019 dump copy information compared to p2
1018 debugpathcomplete
1020 debugpathcomplete
1019 complete part or all of a tracked path
1021 complete part or all of a tracked path
1020 debugpathcopies
1022 debugpathcopies
1021 show copies between two revisions
1023 show copies between two revisions
1022 debugpeer establish a connection to a peer repository
1024 debugpeer establish a connection to a peer repository
1023 debugpickmergetool
1025 debugpickmergetool
1024 examine which merge tool is chosen for specified file
1026 examine which merge tool is chosen for specified file
1025 debugpushkey access the pushkey key/value protocol
1027 debugpushkey access the pushkey key/value protocol
1026 debugpvec (no help text available)
1028 debugpvec (no help text available)
1027 debugrebuilddirstate
1029 debugrebuilddirstate
1028 rebuild the dirstate as it would look like for the given
1030 rebuild the dirstate as it would look like for the given
1029 revision
1031 revision
1030 debugrebuildfncache
1032 debugrebuildfncache
1031 rebuild the fncache file
1033 rebuild the fncache file
1032 debugrename dump rename information
1034 debugrename dump rename information
1033 debugrevlog show data and statistics about a revlog
1035 debugrevlog show data and statistics about a revlog
1034 debugrevlogindex
1036 debugrevlogindex
1035 dump the contents of a revlog index
1037 dump the contents of a revlog index
1036 debugrevspec parse and apply a revision specification
1038 debugrevspec parse and apply a revision specification
1037 debugserve run a server with advanced settings
1039 debugserve run a server with advanced settings
1038 debugsetparents
1040 debugsetparents
1039 manually set the parents of the current working directory
1041 manually set the parents of the current working directory
1040 debugssl test a secure connection to a server
1042 debugssl test a secure connection to a server
1041 debugsub (no help text available)
1043 debugsub (no help text available)
1042 debugsuccessorssets
1044 debugsuccessorssets
1043 show set of successors for revision
1045 show set of successors for revision
1044 debugtemplate
1046 debugtemplate
1045 parse and apply a template
1047 parse and apply a template
1046 debuguigetpass
1048 debuguigetpass
1047 show prompt to type password
1049 show prompt to type password
1048 debuguiprompt
1050 debuguiprompt
1049 show plain prompt
1051 show plain prompt
1050 debugupdatecaches
1052 debugupdatecaches
1051 warm all known caches in the repository
1053 warm all known caches in the repository
1052 debugupgraderepo
1054 debugupgraderepo
1053 upgrade a repository to use different features
1055 upgrade a repository to use different features
1054 debugwalk show how files match on given patterns
1056 debugwalk show how files match on given patterns
1055 debugwhyunstable
1057 debugwhyunstable
1056 explain instabilities of a changeset
1058 explain instabilities of a changeset
1057 debugwireargs
1059 debugwireargs
1058 (no help text available)
1060 (no help text available)
1059 debugwireproto
1061 debugwireproto
1060 send wire protocol commands to a server
1062 send wire protocol commands to a server
1061
1063
1062 (use 'hg help -v debug' to show built-in aliases and global options)
1064 (use 'hg help -v debug' to show built-in aliases and global options)
1063
1065
1064 internals topic renders index of available sub-topics
1066 internals topic renders index of available sub-topics
1065
1067
1066 $ hg help internals
1068 $ hg help internals
1067 Technical implementation topics
1069 Technical implementation topics
1068 """""""""""""""""""""""""""""""
1070 """""""""""""""""""""""""""""""
1069
1071
1070 To access a subtopic, use "hg help internals.{subtopic-name}"
1072 To access a subtopic, use "hg help internals.{subtopic-name}"
1071
1073
1072 bundle2 Bundle2
1074 bundle2 Bundle2
1073 bundles Bundles
1075 bundles Bundles
1074 cbor CBOR
1076 cbor CBOR
1075 censor Censor
1077 censor Censor
1076 changegroups Changegroups
1078 changegroups Changegroups
1077 config Config Registrar
1079 config Config Registrar
1078 extensions Extension API
1080 extensions Extension API
1079 requirements Repository Requirements
1081 requirements Repository Requirements
1080 revlogs Revision Logs
1082 revlogs Revision Logs
1081 wireprotocol Wire Protocol
1083 wireprotocol Wire Protocol
1082 wireprotocolrpc
1084 wireprotocolrpc
1083 Wire Protocol RPC
1085 Wire Protocol RPC
1084 wireprotocolv2
1086 wireprotocolv2
1085 Wire Protocol Version 2
1087 Wire Protocol Version 2
1086
1088
1087 sub-topics can be accessed
1089 sub-topics can be accessed
1088
1090
1089 $ hg help internals.changegroups
1091 $ hg help internals.changegroups
1090 Changegroups
1092 Changegroups
1091 """"""""""""
1093 """"""""""""
1092
1094
1093 Changegroups are representations of repository revlog data, specifically
1095 Changegroups are representations of repository revlog data, specifically
1094 the changelog data, root/flat manifest data, treemanifest data, and
1096 the changelog data, root/flat manifest data, treemanifest data, and
1095 filelogs.
1097 filelogs.
1096
1098
1097 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1099 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1098 level, versions "1" and "2" are almost exactly the same, with the only
1100 level, versions "1" and "2" are almost exactly the same, with the only
1099 difference being an additional item in the *delta header*. Version "3"
1101 difference being an additional item in the *delta header*. Version "3"
1100 adds support for storage flags in the *delta header* and optionally
1102 adds support for storage flags in the *delta header* and optionally
1101 exchanging treemanifests (enabled by setting an option on the
1103 exchanging treemanifests (enabled by setting an option on the
1102 "changegroup" part in the bundle2).
1104 "changegroup" part in the bundle2).
1103
1105
1104 Changegroups when not exchanging treemanifests consist of 3 logical
1106 Changegroups when not exchanging treemanifests consist of 3 logical
1105 segments:
1107 segments:
1106
1108
1107 +---------------------------------+
1109 +---------------------------------+
1108 | | | |
1110 | | | |
1109 | changeset | manifest | filelogs |
1111 | changeset | manifest | filelogs |
1110 | | | |
1112 | | | |
1111 | | | |
1113 | | | |
1112 +---------------------------------+
1114 +---------------------------------+
1113
1115
1114 When exchanging treemanifests, there are 4 logical segments:
1116 When exchanging treemanifests, there are 4 logical segments:
1115
1117
1116 +-------------------------------------------------+
1118 +-------------------------------------------------+
1117 | | | | |
1119 | | | | |
1118 | changeset | root | treemanifests | filelogs |
1120 | changeset | root | treemanifests | filelogs |
1119 | | manifest | | |
1121 | | manifest | | |
1120 | | | | |
1122 | | | | |
1121 +-------------------------------------------------+
1123 +-------------------------------------------------+
1122
1124
1123 The principle building block of each segment is a *chunk*. A *chunk* is a
1125 The principle building block of each segment is a *chunk*. A *chunk* is a
1124 framed piece of data:
1126 framed piece of data:
1125
1127
1126 +---------------------------------------+
1128 +---------------------------------------+
1127 | | |
1129 | | |
1128 | length | data |
1130 | length | data |
1129 | (4 bytes) | (<length - 4> bytes) |
1131 | (4 bytes) | (<length - 4> bytes) |
1130 | | |
1132 | | |
1131 +---------------------------------------+
1133 +---------------------------------------+
1132
1134
1133 All integers are big-endian signed integers. Each chunk starts with a
1135 All integers are big-endian signed integers. Each chunk starts with a
1134 32-bit integer indicating the length of the entire chunk (including the
1136 32-bit integer indicating the length of the entire chunk (including the
1135 length field itself).
1137 length field itself).
1136
1138
1137 There is a special case chunk that has a value of 0 for the length
1139 There is a special case chunk that has a value of 0 for the length
1138 ("0x00000000"). We call this an *empty chunk*.
1140 ("0x00000000"). We call this an *empty chunk*.
1139
1141
1140 Delta Groups
1142 Delta Groups
1141 ============
1143 ============
1142
1144
1143 A *delta group* expresses the content of a revlog as a series of deltas,
1145 A *delta group* expresses the content of a revlog as a series of deltas,
1144 or patches against previous revisions.
1146 or patches against previous revisions.
1145
1147
1146 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1148 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1147 to signal the end of the delta group:
1149 to signal the end of the delta group:
1148
1150
1149 +------------------------------------------------------------------------+
1151 +------------------------------------------------------------------------+
1150 | | | | | |
1152 | | | | | |
1151 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1153 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1152 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1154 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1153 | | | | | |
1155 | | | | | |
1154 +------------------------------------------------------------------------+
1156 +------------------------------------------------------------------------+
1155
1157
1156 Each *chunk*'s data consists of the following:
1158 Each *chunk*'s data consists of the following:
1157
1159
1158 +---------------------------------------+
1160 +---------------------------------------+
1159 | | |
1161 | | |
1160 | delta header | delta data |
1162 | delta header | delta data |
1161 | (various by version) | (various) |
1163 | (various by version) | (various) |
1162 | | |
1164 | | |
1163 +---------------------------------------+
1165 +---------------------------------------+
1164
1166
1165 The *delta data* is a series of *delta*s that describe a diff from an
1167 The *delta data* is a series of *delta*s that describe a diff from an
1166 existing entry (either that the recipient already has, or previously
1168 existing entry (either that the recipient already has, or previously
1167 specified in the bundle/changegroup).
1169 specified in the bundle/changegroup).
1168
1170
1169 The *delta header* is different between versions "1", "2", and "3" of the
1171 The *delta header* is different between versions "1", "2", and "3" of the
1170 changegroup format.
1172 changegroup format.
1171
1173
1172 Version 1 (headerlen=80):
1174 Version 1 (headerlen=80):
1173
1175
1174 +------------------------------------------------------+
1176 +------------------------------------------------------+
1175 | | | | |
1177 | | | | |
1176 | node | p1 node | p2 node | link node |
1178 | node | p1 node | p2 node | link node |
1177 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1179 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1178 | | | | |
1180 | | | | |
1179 +------------------------------------------------------+
1181 +------------------------------------------------------+
1180
1182
1181 Version 2 (headerlen=100):
1183 Version 2 (headerlen=100):
1182
1184
1183 +------------------------------------------------------------------+
1185 +------------------------------------------------------------------+
1184 | | | | | |
1186 | | | | | |
1185 | node | p1 node | p2 node | base node | link node |
1187 | node | p1 node | p2 node | base node | link node |
1186 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1188 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1187 | | | | | |
1189 | | | | | |
1188 +------------------------------------------------------------------+
1190 +------------------------------------------------------------------+
1189
1191
1190 Version 3 (headerlen=102):
1192 Version 3 (headerlen=102):
1191
1193
1192 +------------------------------------------------------------------------------+
1194 +------------------------------------------------------------------------------+
1193 | | | | | | |
1195 | | | | | | |
1194 | node | p1 node | p2 node | base node | link node | flags |
1196 | node | p1 node | p2 node | base node | link node | flags |
1195 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1197 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1196 | | | | | | |
1198 | | | | | | |
1197 +------------------------------------------------------------------------------+
1199 +------------------------------------------------------------------------------+
1198
1200
1199 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1201 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1200 contain a series of *delta*s, densely packed (no separators). These deltas
1202 contain a series of *delta*s, densely packed (no separators). These deltas
1201 describe a diff from an existing entry (either that the recipient already
1203 describe a diff from an existing entry (either that the recipient already
1202 has, or previously specified in the bundle/changegroup). The format is
1204 has, or previously specified in the bundle/changegroup). The format is
1203 described more fully in "hg help internals.bdiff", but briefly:
1205 described more fully in "hg help internals.bdiff", but briefly:
1204
1206
1205 +---------------------------------------------------------------+
1207 +---------------------------------------------------------------+
1206 | | | | |
1208 | | | | |
1207 | start offset | end offset | new length | content |
1209 | start offset | end offset | new length | content |
1208 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1210 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1209 | | | | |
1211 | | | | |
1210 +---------------------------------------------------------------+
1212 +---------------------------------------------------------------+
1211
1213
1212 Please note that the length field in the delta data does *not* include
1214 Please note that the length field in the delta data does *not* include
1213 itself.
1215 itself.
1214
1216
1215 In version 1, the delta is always applied against the previous node from
1217 In version 1, the delta is always applied against the previous node from
1216 the changegroup or the first parent if this is the first entry in the
1218 the changegroup or the first parent if this is the first entry in the
1217 changegroup.
1219 changegroup.
1218
1220
1219 In version 2 and up, the delta base node is encoded in the entry in the
1221 In version 2 and up, the delta base node is encoded in the entry in the
1220 changegroup. This allows the delta to be expressed against any parent,
1222 changegroup. This allows the delta to be expressed against any parent,
1221 which can result in smaller deltas and more efficient encoding of data.
1223 which can result in smaller deltas and more efficient encoding of data.
1222
1224
1223 The *flags* field holds bitwise flags affecting the processing of revision
1225 The *flags* field holds bitwise flags affecting the processing of revision
1224 data. The following flags are defined:
1226 data. The following flags are defined:
1225
1227
1226 32768
1228 32768
1227 Censored revision. The revision's fulltext has been replaced by censor
1229 Censored revision. The revision's fulltext has been replaced by censor
1228 metadata. May only occur on file revisions.
1230 metadata. May only occur on file revisions.
1229
1231
1230 16384
1232 16384
1231 Ellipsis revision. Revision hash does not match data (likely due to
1233 Ellipsis revision. Revision hash does not match data (likely due to
1232 rewritten parents).
1234 rewritten parents).
1233
1235
1234 8192
1236 8192
1235 Externally stored. The revision fulltext contains "key:value" "\n"
1237 Externally stored. The revision fulltext contains "key:value" "\n"
1236 delimited metadata defining an object stored elsewhere. Used by the LFS
1238 delimited metadata defining an object stored elsewhere. Used by the LFS
1237 extension.
1239 extension.
1238
1240
1239 For historical reasons, the integer values are identical to revlog version
1241 For historical reasons, the integer values are identical to revlog version
1240 1 per-revision storage flags and correspond to bits being set in this
1242 1 per-revision storage flags and correspond to bits being set in this
1241 2-byte field. Bits were allocated starting from the most-significant bit,
1243 2-byte field. Bits were allocated starting from the most-significant bit,
1242 hence the reverse ordering and allocation of these flags.
1244 hence the reverse ordering and allocation of these flags.
1243
1245
1244 Changeset Segment
1246 Changeset Segment
1245 =================
1247 =================
1246
1248
1247 The *changeset segment* consists of a single *delta group* holding
1249 The *changeset segment* consists of a single *delta group* holding
1248 changelog data. The *empty chunk* at the end of the *delta group* denotes
1250 changelog data. The *empty chunk* at the end of the *delta group* denotes
1249 the boundary to the *manifest segment*.
1251 the boundary to the *manifest segment*.
1250
1252
1251 Manifest Segment
1253 Manifest Segment
1252 ================
1254 ================
1253
1255
1254 The *manifest segment* consists of a single *delta group* holding manifest
1256 The *manifest segment* consists of a single *delta group* holding manifest
1255 data. If treemanifests are in use, it contains only the manifest for the
1257 data. If treemanifests are in use, it contains only the manifest for the
1256 root directory of the repository. Otherwise, it contains the entire
1258 root directory of the repository. Otherwise, it contains the entire
1257 manifest data. The *empty chunk* at the end of the *delta group* denotes
1259 manifest data. The *empty chunk* at the end of the *delta group* denotes
1258 the boundary to the next segment (either the *treemanifests segment* or
1260 the boundary to the next segment (either the *treemanifests segment* or
1259 the *filelogs segment*, depending on version and the request options).
1261 the *filelogs segment*, depending on version and the request options).
1260
1262
1261 Treemanifests Segment
1263 Treemanifests Segment
1262 ---------------------
1264 ---------------------
1263
1265
1264 The *treemanifests segment* only exists in changegroup version "3", and
1266 The *treemanifests segment* only exists in changegroup version "3", and
1265 only if the 'treemanifest' param is part of the bundle2 changegroup part
1267 only if the 'treemanifest' param is part of the bundle2 changegroup part
1266 (it is not possible to use changegroup version 3 outside of bundle2).
1268 (it is not possible to use changegroup version 3 outside of bundle2).
1267 Aside from the filenames in the *treemanifests segment* containing a
1269 Aside from the filenames in the *treemanifests segment* containing a
1268 trailing "/" character, it behaves identically to the *filelogs segment*
1270 trailing "/" character, it behaves identically to the *filelogs segment*
1269 (see below). The final sub-segment is followed by an *empty chunk*
1271 (see below). The final sub-segment is followed by an *empty chunk*
1270 (logically, a sub-segment with filename size 0). This denotes the boundary
1272 (logically, a sub-segment with filename size 0). This denotes the boundary
1271 to the *filelogs segment*.
1273 to the *filelogs segment*.
1272
1274
1273 Filelogs Segment
1275 Filelogs Segment
1274 ================
1276 ================
1275
1277
1276 The *filelogs segment* consists of multiple sub-segments, each
1278 The *filelogs segment* consists of multiple sub-segments, each
1277 corresponding to an individual file whose data is being described:
1279 corresponding to an individual file whose data is being described:
1278
1280
1279 +--------------------------------------------------+
1281 +--------------------------------------------------+
1280 | | | | | |
1282 | | | | | |
1281 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1283 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1282 | | | | | (4 bytes) |
1284 | | | | | (4 bytes) |
1283 | | | | | |
1285 | | | | | |
1284 +--------------------------------------------------+
1286 +--------------------------------------------------+
1285
1287
1286 The final filelog sub-segment is followed by an *empty chunk* (logically,
1288 The final filelog sub-segment is followed by an *empty chunk* (logically,
1287 a sub-segment with filename size 0). This denotes the end of the segment
1289 a sub-segment with filename size 0). This denotes the end of the segment
1288 and of the overall changegroup.
1290 and of the overall changegroup.
1289
1291
1290 Each filelog sub-segment consists of the following:
1292 Each filelog sub-segment consists of the following:
1291
1293
1292 +------------------------------------------------------+
1294 +------------------------------------------------------+
1293 | | | |
1295 | | | |
1294 | filename length | filename | delta group |
1296 | filename length | filename | delta group |
1295 | (4 bytes) | (<length - 4> bytes) | (various) |
1297 | (4 bytes) | (<length - 4> bytes) | (various) |
1296 | | | |
1298 | | | |
1297 +------------------------------------------------------+
1299 +------------------------------------------------------+
1298
1300
1299 That is, a *chunk* consisting of the filename (not terminated or padded)
1301 That is, a *chunk* consisting of the filename (not terminated or padded)
1300 followed by N chunks constituting the *delta group* for this file. The
1302 followed by N chunks constituting the *delta group* for this file. The
1301 *empty chunk* at the end of each *delta group* denotes the boundary to the
1303 *empty chunk* at the end of each *delta group* denotes the boundary to the
1302 next filelog sub-segment.
1304 next filelog sub-segment.
1303
1305
1304 test advanced, deprecated and experimental options are hidden in command help
1306 test advanced, deprecated and experimental options are hidden in command help
1305 $ hg help debugoptADV
1307 $ hg help debugoptADV
1306 hg debugoptADV
1308 hg debugoptADV
1307
1309
1308 (no help text available)
1310 (no help text available)
1309
1311
1310 options:
1312 options:
1311
1313
1312 (some details hidden, use --verbose to show complete help)
1314 (some details hidden, use --verbose to show complete help)
1313 $ hg help debugoptDEP
1315 $ hg help debugoptDEP
1314 hg debugoptDEP
1316 hg debugoptDEP
1315
1317
1316 (no help text available)
1318 (no help text available)
1317
1319
1318 options:
1320 options:
1319
1321
1320 (some details hidden, use --verbose to show complete help)
1322 (some details hidden, use --verbose to show complete help)
1321
1323
1322 $ hg help debugoptEXP
1324 $ hg help debugoptEXP
1323 hg debugoptEXP
1325 hg debugoptEXP
1324
1326
1325 (no help text available)
1327 (no help text available)
1326
1328
1327 options:
1329 options:
1328
1330
1329 (some details hidden, use --verbose to show complete help)
1331 (some details hidden, use --verbose to show complete help)
1330
1332
1331 test advanced, deprecated and experimental options are shown with -v
1333 test advanced, deprecated and experimental options are shown with -v
1332 $ hg help -v debugoptADV | grep aopt
1334 $ hg help -v debugoptADV | grep aopt
1333 --aopt option is (ADVANCED)
1335 --aopt option is (ADVANCED)
1334 $ hg help -v debugoptDEP | grep dopt
1336 $ hg help -v debugoptDEP | grep dopt
1335 --dopt option is (DEPRECATED)
1337 --dopt option is (DEPRECATED)
1336 $ hg help -v debugoptEXP | grep eopt
1338 $ hg help -v debugoptEXP | grep eopt
1337 --eopt option is (EXPERIMENTAL)
1339 --eopt option is (EXPERIMENTAL)
1338
1340
1339 #if gettext
1341 #if gettext
1340 test deprecated option is hidden with translation with untranslated description
1342 test deprecated option is hidden with translation with untranslated description
1341 (use many globy for not failing on changed transaction)
1343 (use many globy for not failing on changed transaction)
1342 $ LANGUAGE=sv hg help debugoptDEP
1344 $ LANGUAGE=sv hg help debugoptDEP
1343 hg debugoptDEP
1345 hg debugoptDEP
1344
1346
1345 (*) (glob)
1347 (*) (glob)
1346
1348
1347 options:
1349 options:
1348
1350
1349 (some details hidden, use --verbose to show complete help)
1351 (some details hidden, use --verbose to show complete help)
1350 #endif
1352 #endif
1351
1353
1352 Test commands that collide with topics (issue4240)
1354 Test commands that collide with topics (issue4240)
1353
1355
1354 $ hg config -hq
1356 $ hg config -hq
1355 hg config [-u] [NAME]...
1357 hg config [-u] [NAME]...
1356
1358
1357 show combined config settings from all hgrc files
1359 show combined config settings from all hgrc files
1358 $ hg showconfig -hq
1360 $ hg showconfig -hq
1359 hg config [-u] [NAME]...
1361 hg config [-u] [NAME]...
1360
1362
1361 show combined config settings from all hgrc files
1363 show combined config settings from all hgrc files
1362
1364
1363 Test a help topic
1365 Test a help topic
1364
1366
1365 $ hg help dates
1367 $ hg help dates
1366 Date Formats
1368 Date Formats
1367 """"""""""""
1369 """"""""""""
1368
1370
1369 Some commands allow the user to specify a date, e.g.:
1371 Some commands allow the user to specify a date, e.g.:
1370
1372
1371 - backout, commit, import, tag: Specify the commit date.
1373 - backout, commit, import, tag: Specify the commit date.
1372 - log, revert, update: Select revision(s) by date.
1374 - log, revert, update: Select revision(s) by date.
1373
1375
1374 Many date formats are valid. Here are some examples:
1376 Many date formats are valid. Here are some examples:
1375
1377
1376 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1378 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1377 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1379 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1378 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1380 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1379 - "Dec 6" (midnight)
1381 - "Dec 6" (midnight)
1380 - "13:18" (today assumed)
1382 - "13:18" (today assumed)
1381 - "3:39" (3:39AM assumed)
1383 - "3:39" (3:39AM assumed)
1382 - "3:39pm" (15:39)
1384 - "3:39pm" (15:39)
1383 - "2006-12-06 13:18:29" (ISO 8601 format)
1385 - "2006-12-06 13:18:29" (ISO 8601 format)
1384 - "2006-12-6 13:18"
1386 - "2006-12-6 13:18"
1385 - "2006-12-6"
1387 - "2006-12-6"
1386 - "12-6"
1388 - "12-6"
1387 - "12/6"
1389 - "12/6"
1388 - "12/6/6" (Dec 6 2006)
1390 - "12/6/6" (Dec 6 2006)
1389 - "today" (midnight)
1391 - "today" (midnight)
1390 - "yesterday" (midnight)
1392 - "yesterday" (midnight)
1391 - "now" - right now
1393 - "now" - right now
1392
1394
1393 Lastly, there is Mercurial's internal format:
1395 Lastly, there is Mercurial's internal format:
1394
1396
1395 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1397 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1396
1398
1397 This is the internal representation format for dates. The first number is
1399 This is the internal representation format for dates. The first number is
1398 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1400 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1399 is the offset of the local timezone, in seconds west of UTC (negative if
1401 is the offset of the local timezone, in seconds west of UTC (negative if
1400 the timezone is east of UTC).
1402 the timezone is east of UTC).
1401
1403
1402 The log command also accepts date ranges:
1404 The log command also accepts date ranges:
1403
1405
1404 - "<DATE" - at or before a given date/time
1406 - "<DATE" - at or before a given date/time
1405 - ">DATE" - on or after a given date/time
1407 - ">DATE" - on or after a given date/time
1406 - "DATE to DATE" - a date range, inclusive
1408 - "DATE to DATE" - a date range, inclusive
1407 - "-DAYS" - within a given number of days of today
1409 - "-DAYS" - within a given number of days of today
1408
1410
1409 Test repeated config section name
1411 Test repeated config section name
1410
1412
1411 $ hg help config.host
1413 $ hg help config.host
1412 "http_proxy.host"
1414 "http_proxy.host"
1413 Host name and (optional) port of the proxy server, for example
1415 Host name and (optional) port of the proxy server, for example
1414 "myproxy:8000".
1416 "myproxy:8000".
1415
1417
1416 "smtp.host"
1418 "smtp.host"
1417 Host name of mail server, e.g. "mail.example.com".
1419 Host name of mail server, e.g. "mail.example.com".
1418
1420
1419
1421
1420 Test section name with dot
1422 Test section name with dot
1421
1423
1422 $ hg help config.ui.username
1424 $ hg help config.ui.username
1423 "ui.username"
1425 "ui.username"
1424 The committer of a changeset created when running "commit". Typically
1426 The committer of a changeset created when running "commit". Typically
1425 a person's name and email address, e.g. "Fred Widget
1427 a person's name and email address, e.g. "Fred Widget
1426 <fred@example.com>". Environment variables in the username are
1428 <fred@example.com>". Environment variables in the username are
1427 expanded.
1429 expanded.
1428
1430
1429 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1431 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1430 empty, e.g. if the system admin set "username =" in the system hgrc,
1432 empty, e.g. if the system admin set "username =" in the system hgrc,
1431 it has to be specified manually or in a different hgrc file)
1433 it has to be specified manually or in a different hgrc file)
1432
1434
1433
1435
1434 $ hg help config.annotate.git
1436 $ hg help config.annotate.git
1435 abort: help section not found: config.annotate.git
1437 abort: help section not found: config.annotate.git
1436 [255]
1438 [255]
1437
1439
1438 $ hg help config.update.check
1440 $ hg help config.update.check
1439 "commands.update.check"
1441 "commands.update.check"
1440 Determines what level of checking 'hg update' will perform before
1442 Determines what level of checking 'hg update' will perform before
1441 moving to a destination revision. Valid values are "abort", "none",
1443 moving to a destination revision. Valid values are "abort", "none",
1442 "linear", and "noconflict". "abort" always fails if the working
1444 "linear", and "noconflict". "abort" always fails if the working
1443 directory has uncommitted changes. "none" performs no checking, and
1445 directory has uncommitted changes. "none" performs no checking, and
1444 may result in a merge with uncommitted changes. "linear" allows any
1446 may result in a merge with uncommitted changes. "linear" allows any
1445 update as long as it follows a straight line in the revision history,
1447 update as long as it follows a straight line in the revision history,
1446 and may trigger a merge with uncommitted changes. "noconflict" will
1448 and may trigger a merge with uncommitted changes. "noconflict" will
1447 allow any update which would not trigger a merge with uncommitted
1449 allow any update which would not trigger a merge with uncommitted
1448 changes, if any are present. (default: "linear")
1450 changes, if any are present. (default: "linear")
1449
1451
1450
1452
1451 $ hg help config.commands.update.check
1453 $ hg help config.commands.update.check
1452 "commands.update.check"
1454 "commands.update.check"
1453 Determines what level of checking 'hg update' will perform before
1455 Determines what level of checking 'hg update' will perform before
1454 moving to a destination revision. Valid values are "abort", "none",
1456 moving to a destination revision. Valid values are "abort", "none",
1455 "linear", and "noconflict". "abort" always fails if the working
1457 "linear", and "noconflict". "abort" always fails if the working
1456 directory has uncommitted changes. "none" performs no checking, and
1458 directory has uncommitted changes. "none" performs no checking, and
1457 may result in a merge with uncommitted changes. "linear" allows any
1459 may result in a merge with uncommitted changes. "linear" allows any
1458 update as long as it follows a straight line in the revision history,
1460 update as long as it follows a straight line in the revision history,
1459 and may trigger a merge with uncommitted changes. "noconflict" will
1461 and may trigger a merge with uncommitted changes. "noconflict" will
1460 allow any update which would not trigger a merge with uncommitted
1462 allow any update which would not trigger a merge with uncommitted
1461 changes, if any are present. (default: "linear")
1463 changes, if any are present. (default: "linear")
1462
1464
1463
1465
1464 $ hg help config.ommands.update.check
1466 $ hg help config.ommands.update.check
1465 abort: help section not found: config.ommands.update.check
1467 abort: help section not found: config.ommands.update.check
1466 [255]
1468 [255]
1467
1469
1468 Unrelated trailing paragraphs shouldn't be included
1470 Unrelated trailing paragraphs shouldn't be included
1469
1471
1470 $ hg help config.extramsg | grep '^$'
1472 $ hg help config.extramsg | grep '^$'
1471
1473
1472
1474
1473 Test capitalized section name
1475 Test capitalized section name
1474
1476
1475 $ hg help scripting.HGPLAIN > /dev/null
1477 $ hg help scripting.HGPLAIN > /dev/null
1476
1478
1477 Help subsection:
1479 Help subsection:
1478
1480
1479 $ hg help config.charsets |grep "Email example:" > /dev/null
1481 $ hg help config.charsets |grep "Email example:" > /dev/null
1480 [1]
1482 [1]
1481
1483
1482 Show nested definitions
1484 Show nested definitions
1483 ("profiling.type"[break]"ls"[break]"stat"[break])
1485 ("profiling.type"[break]"ls"[break]"stat"[break])
1484
1486
1485 $ hg help config.type | egrep '^$'|wc -l
1487 $ hg help config.type | egrep '^$'|wc -l
1486 \s*3 (re)
1488 \s*3 (re)
1487
1489
1488 $ hg help config.profiling.type.ls
1490 $ hg help config.profiling.type.ls
1489 "profiling.type.ls"
1491 "profiling.type.ls"
1490 Use Python's built-in instrumenting profiler. This profiler works on
1492 Use Python's built-in instrumenting profiler. This profiler works on
1491 all platforms, but each line number it reports is the first line of
1493 all platforms, but each line number it reports is the first line of
1492 a function. This restriction makes it difficult to identify the
1494 a function. This restriction makes it difficult to identify the
1493 expensive parts of a non-trivial function.
1495 expensive parts of a non-trivial function.
1494
1496
1495
1497
1496 Separate sections from subsections
1498 Separate sections from subsections
1497
1499
1498 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1500 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1499 "format"
1501 "format"
1500 --------
1502 --------
1501
1503
1502 "usegeneraldelta"
1504 "usegeneraldelta"
1503
1505
1504 "dotencode"
1506 "dotencode"
1505
1507
1506 "usefncache"
1508 "usefncache"
1507
1509
1508 "usestore"
1510 "usestore"
1509
1511
1510 "sparse-revlog"
1512 "sparse-revlog"
1511
1513
1512 "profiling"
1514 "profiling"
1513 -----------
1515 -----------
1514
1516
1515 "format"
1517 "format"
1516
1518
1517 "progress"
1519 "progress"
1518 ----------
1520 ----------
1519
1521
1520 "format"
1522 "format"
1521
1523
1522
1524
1523 Last item in help config.*:
1525 Last item in help config.*:
1524
1526
1525 $ hg help config.`hg help config|grep '^ "'| \
1527 $ hg help config.`hg help config|grep '^ "'| \
1526 > tail -1|sed 's![ "]*!!g'`| \
1528 > tail -1|sed 's![ "]*!!g'`| \
1527 > grep 'hg help -c config' > /dev/null
1529 > grep 'hg help -c config' > /dev/null
1528 [1]
1530 [1]
1529
1531
1530 note to use help -c for general hg help config:
1532 note to use help -c for general hg help config:
1531
1533
1532 $ hg help config |grep 'hg help -c config' > /dev/null
1534 $ hg help config |grep 'hg help -c config' > /dev/null
1533
1535
1534 Test templating help
1536 Test templating help
1535
1537
1536 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1538 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1537 desc String. The text of the changeset description.
1539 desc String. The text of the changeset description.
1538 diffstat String. Statistics of changes with the following format:
1540 diffstat String. Statistics of changes with the following format:
1539 firstline Any text. Returns the first line of text.
1541 firstline Any text. Returns the first line of text.
1540 nonempty Any text. Returns '(none)' if the string is empty.
1542 nonempty Any text. Returns '(none)' if the string is empty.
1541
1543
1542 Test deprecated items
1544 Test deprecated items
1543
1545
1544 $ hg help -v templating | grep currentbookmark
1546 $ hg help -v templating | grep currentbookmark
1545 currentbookmark
1547 currentbookmark
1546 $ hg help templating | (grep currentbookmark || true)
1548 $ hg help templating | (grep currentbookmark || true)
1547
1549
1548 Test help hooks
1550 Test help hooks
1549
1551
1550 $ cat > helphook1.py <<EOF
1552 $ cat > helphook1.py <<EOF
1551 > from mercurial import help
1553 > from mercurial import help
1552 >
1554 >
1553 > def rewrite(ui, topic, doc):
1555 > def rewrite(ui, topic, doc):
1554 > return doc + b'\nhelphook1\n'
1556 > return doc + b'\nhelphook1\n'
1555 >
1557 >
1556 > def extsetup(ui):
1558 > def extsetup(ui):
1557 > help.addtopichook(b'revisions', rewrite)
1559 > help.addtopichook(b'revisions', rewrite)
1558 > EOF
1560 > EOF
1559 $ cat > helphook2.py <<EOF
1561 $ cat > helphook2.py <<EOF
1560 > from mercurial import help
1562 > from mercurial import help
1561 >
1563 >
1562 > def rewrite(ui, topic, doc):
1564 > def rewrite(ui, topic, doc):
1563 > return doc + b'\nhelphook2\n'
1565 > return doc + b'\nhelphook2\n'
1564 >
1566 >
1565 > def extsetup(ui):
1567 > def extsetup(ui):
1566 > help.addtopichook(b'revisions', rewrite)
1568 > help.addtopichook(b'revisions', rewrite)
1567 > EOF
1569 > EOF
1568 $ echo '[extensions]' >> $HGRCPATH
1570 $ echo '[extensions]' >> $HGRCPATH
1569 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1571 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1570 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1572 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1571 $ hg help revsets | grep helphook
1573 $ hg help revsets | grep helphook
1572 helphook1
1574 helphook1
1573 helphook2
1575 helphook2
1574
1576
1575 help -c should only show debug --debug
1577 help -c should only show debug --debug
1576
1578
1577 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1579 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1578 [1]
1580 [1]
1579
1581
1580 help -c should only show deprecated for -v
1582 help -c should only show deprecated for -v
1581
1583
1582 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1584 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1583 [1]
1585 [1]
1584
1586
1585 Test -s / --system
1587 Test -s / --system
1586
1588
1587 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1589 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1588 > wc -l | sed -e 's/ //g'
1590 > wc -l | sed -e 's/ //g'
1589 0
1591 0
1590 $ hg help config.files --system unix | grep 'USER' | \
1592 $ hg help config.files --system unix | grep 'USER' | \
1591 > wc -l | sed -e 's/ //g'
1593 > wc -l | sed -e 's/ //g'
1592 0
1594 0
1593
1595
1594 Test -e / -c / -k combinations
1596 Test -e / -c / -k combinations
1595
1597
1596 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1598 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1597 Commands:
1599 Commands:
1598 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1600 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1599 Extensions:
1601 Extensions:
1600 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1602 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1601 Topics:
1603 Topics:
1602 Commands:
1604 Commands:
1603 Extensions:
1605 Extensions:
1604 Extension Commands:
1606 Extension Commands:
1605 $ hg help -c schemes
1607 $ hg help -c schemes
1606 abort: no such help topic: schemes
1608 abort: no such help topic: schemes
1607 (try 'hg help --keyword schemes')
1609 (try 'hg help --keyword schemes')
1608 [255]
1610 [255]
1609 $ hg help -e schemes |head -1
1611 $ hg help -e schemes |head -1
1610 schemes extension - extend schemes with shortcuts to repository swarms
1612 schemes extension - extend schemes with shortcuts to repository swarms
1611 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1613 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1612 Commands:
1614 Commands:
1613 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1615 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1614 Extensions:
1616 Extensions:
1615 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1617 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1616 Extensions:
1618 Extensions:
1617 Commands:
1619 Commands:
1618 $ hg help -c commit > /dev/null
1620 $ hg help -c commit > /dev/null
1619 $ hg help -e -c commit > /dev/null
1621 $ hg help -e -c commit > /dev/null
1620 $ hg help -e commit
1622 $ hg help -e commit
1621 abort: no such help topic: commit
1623 abort: no such help topic: commit
1622 (try 'hg help --keyword commit')
1624 (try 'hg help --keyword commit')
1623 [255]
1625 [255]
1624
1626
1625 Test keyword search help
1627 Test keyword search help
1626
1628
1627 $ cat > prefixedname.py <<EOF
1629 $ cat > prefixedname.py <<EOF
1628 > '''matched against word "clone"
1630 > '''matched against word "clone"
1629 > '''
1631 > '''
1630 > EOF
1632 > EOF
1631 $ echo '[extensions]' >> $HGRCPATH
1633 $ echo '[extensions]' >> $HGRCPATH
1632 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1634 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1633 $ hg help -k clone
1635 $ hg help -k clone
1634 Topics:
1636 Topics:
1635
1637
1636 config Configuration Files
1638 config Configuration Files
1637 extensions Using Additional Features
1639 extensions Using Additional Features
1638 glossary Glossary
1640 glossary Glossary
1639 phases Working with Phases
1641 phases Working with Phases
1640 subrepos Subrepositories
1642 subrepos Subrepositories
1641 urls URL Paths
1643 urls URL Paths
1642
1644
1643 Commands:
1645 Commands:
1644
1646
1645 bookmarks create a new bookmark or list existing bookmarks
1647 bookmarks create a new bookmark or list existing bookmarks
1646 clone make a copy of an existing repository
1648 clone make a copy of an existing repository
1647 paths show aliases for remote repositories
1649 paths show aliases for remote repositories
1648 pull pull changes from the specified source
1650 pull pull changes from the specified source
1649 update update working directory (or switch revisions)
1651 update update working directory (or switch revisions)
1650
1652
1651 Extensions:
1653 Extensions:
1652
1654
1653 clonebundles advertise pre-generated bundles to seed clones
1655 clonebundles advertise pre-generated bundles to seed clones
1654 narrow create clones which fetch history data for subset of files
1656 narrow create clones which fetch history data for subset of files
1655 (EXPERIMENTAL)
1657 (EXPERIMENTAL)
1656 prefixedname matched against word "clone"
1658 prefixedname matched against word "clone"
1657 relink recreates hardlinks between repository clones
1659 relink recreates hardlinks between repository clones
1658
1660
1659 Extension Commands:
1661 Extension Commands:
1660
1662
1661 qclone clone main and patch repository at same time
1663 qclone clone main and patch repository at same time
1662
1664
1663 Test unfound topic
1665 Test unfound topic
1664
1666
1665 $ hg help nonexistingtopicthatwillneverexisteverever
1667 $ hg help nonexistingtopicthatwillneverexisteverever
1666 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1668 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1667 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1669 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1668 [255]
1670 [255]
1669
1671
1670 Test unfound keyword
1672 Test unfound keyword
1671
1673
1672 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1674 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1673 abort: no matches
1675 abort: no matches
1674 (try 'hg help' for a list of topics)
1676 (try 'hg help' for a list of topics)
1675 [255]
1677 [255]
1676
1678
1677 Test omit indicating for help
1679 Test omit indicating for help
1678
1680
1679 $ cat > addverboseitems.py <<EOF
1681 $ cat > addverboseitems.py <<EOF
1680 > r'''extension to test omit indicating.
1682 > r'''extension to test omit indicating.
1681 >
1683 >
1682 > This paragraph is never omitted (for extension)
1684 > This paragraph is never omitted (for extension)
1683 >
1685 >
1684 > .. container:: verbose
1686 > .. container:: verbose
1685 >
1687 >
1686 > This paragraph is omitted,
1688 > This paragraph is omitted,
1687 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1689 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1688 >
1690 >
1689 > This paragraph is never omitted, too (for extension)
1691 > This paragraph is never omitted, too (for extension)
1690 > '''
1692 > '''
1691 > from __future__ import absolute_import
1693 > from __future__ import absolute_import
1692 > from mercurial import commands, help
1694 > from mercurial import commands, help
1693 > testtopic = br"""This paragraph is never omitted (for topic).
1695 > testtopic = br"""This paragraph is never omitted (for topic).
1694 >
1696 >
1695 > .. container:: verbose
1697 > .. container:: verbose
1696 >
1698 >
1697 > This paragraph is omitted,
1699 > This paragraph is omitted,
1698 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1700 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1699 >
1701 >
1700 > This paragraph is never omitted, too (for topic)
1702 > This paragraph is never omitted, too (for topic)
1701 > """
1703 > """
1702 > def extsetup(ui):
1704 > def extsetup(ui):
1703 > help.helptable.append(([b"topic-containing-verbose"],
1705 > help.helptable.append(([b"topic-containing-verbose"],
1704 > b"This is the topic to test omit indicating.",
1706 > b"This is the topic to test omit indicating.",
1705 > lambda ui: testtopic))
1707 > lambda ui: testtopic))
1706 > EOF
1708 > EOF
1707 $ echo '[extensions]' >> $HGRCPATH
1709 $ echo '[extensions]' >> $HGRCPATH
1708 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1710 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1709 $ hg help addverboseitems
1711 $ hg help addverboseitems
1710 addverboseitems extension - extension to test omit indicating.
1712 addverboseitems extension - extension to test omit indicating.
1711
1713
1712 This paragraph is never omitted (for extension)
1714 This paragraph is never omitted (for extension)
1713
1715
1714 This paragraph is never omitted, too (for extension)
1716 This paragraph is never omitted, too (for extension)
1715
1717
1716 (some details hidden, use --verbose to show complete help)
1718 (some details hidden, use --verbose to show complete help)
1717
1719
1718 no commands defined
1720 no commands defined
1719 $ hg help -v addverboseitems
1721 $ hg help -v addverboseitems
1720 addverboseitems extension - extension to test omit indicating.
1722 addverboseitems extension - extension to test omit indicating.
1721
1723
1722 This paragraph is never omitted (for extension)
1724 This paragraph is never omitted (for extension)
1723
1725
1724 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1726 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1725 extension)
1727 extension)
1726
1728
1727 This paragraph is never omitted, too (for extension)
1729 This paragraph is never omitted, too (for extension)
1728
1730
1729 no commands defined
1731 no commands defined
1730 $ hg help topic-containing-verbose
1732 $ hg help topic-containing-verbose
1731 This is the topic to test omit indicating.
1733 This is the topic to test omit indicating.
1732 """"""""""""""""""""""""""""""""""""""""""
1734 """"""""""""""""""""""""""""""""""""""""""
1733
1735
1734 This paragraph is never omitted (for topic).
1736 This paragraph is never omitted (for topic).
1735
1737
1736 This paragraph is never omitted, too (for topic)
1738 This paragraph is never omitted, too (for topic)
1737
1739
1738 (some details hidden, use --verbose to show complete help)
1740 (some details hidden, use --verbose to show complete help)
1739 $ hg help -v topic-containing-verbose
1741 $ hg help -v topic-containing-verbose
1740 This is the topic to test omit indicating.
1742 This is the topic to test omit indicating.
1741 """"""""""""""""""""""""""""""""""""""""""
1743 """"""""""""""""""""""""""""""""""""""""""
1742
1744
1743 This paragraph is never omitted (for topic).
1745 This paragraph is never omitted (for topic).
1744
1746
1745 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1747 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1746 topic)
1748 topic)
1747
1749
1748 This paragraph is never omitted, too (for topic)
1750 This paragraph is never omitted, too (for topic)
1749
1751
1750 Test section lookup
1752 Test section lookup
1751
1753
1752 $ hg help revset.merge
1754 $ hg help revset.merge
1753 "merge()"
1755 "merge()"
1754 Changeset is a merge changeset.
1756 Changeset is a merge changeset.
1755
1757
1756 $ hg help glossary.dag
1758 $ hg help glossary.dag
1757 DAG
1759 DAG
1758 The repository of changesets of a distributed version control system
1760 The repository of changesets of a distributed version control system
1759 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1761 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1760 of nodes and edges, where nodes correspond to changesets and edges
1762 of nodes and edges, where nodes correspond to changesets and edges
1761 imply a parent -> child relation. This graph can be visualized by
1763 imply a parent -> child relation. This graph can be visualized by
1762 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1764 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1763 limited by the requirement for children to have at most two parents.
1765 limited by the requirement for children to have at most two parents.
1764
1766
1765
1767
1766 $ hg help hgrc.paths
1768 $ hg help hgrc.paths
1767 "paths"
1769 "paths"
1768 -------
1770 -------
1769
1771
1770 Assigns symbolic names and behavior to repositories.
1772 Assigns symbolic names and behavior to repositories.
1771
1773
1772 Options are symbolic names defining the URL or directory that is the
1774 Options are symbolic names defining the URL or directory that is the
1773 location of the repository. Example:
1775 location of the repository. Example:
1774
1776
1775 [paths]
1777 [paths]
1776 my_server = https://example.com/my_repo
1778 my_server = https://example.com/my_repo
1777 local_path = /home/me/repo
1779 local_path = /home/me/repo
1778
1780
1779 These symbolic names can be used from the command line. To pull from
1781 These symbolic names can be used from the command line. To pull from
1780 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1782 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1781 local_path'.
1783 local_path'.
1782
1784
1783 Options containing colons (":") denote sub-options that can influence
1785 Options containing colons (":") denote sub-options that can influence
1784 behavior for that specific path. Example:
1786 behavior for that specific path. Example:
1785
1787
1786 [paths]
1788 [paths]
1787 my_server = https://example.com/my_path
1789 my_server = https://example.com/my_path
1788 my_server:pushurl = ssh://example.com/my_path
1790 my_server:pushurl = ssh://example.com/my_path
1789
1791
1790 The following sub-options can be defined:
1792 The following sub-options can be defined:
1791
1793
1792 "pushurl"
1794 "pushurl"
1793 The URL to use for push operations. If not defined, the location
1795 The URL to use for push operations. If not defined, the location
1794 defined by the path's main entry is used.
1796 defined by the path's main entry is used.
1795
1797
1796 "pushrev"
1798 "pushrev"
1797 A revset defining which revisions to push by default.
1799 A revset defining which revisions to push by default.
1798
1800
1799 When 'hg push' is executed without a "-r" argument, the revset defined
1801 When 'hg push' is executed without a "-r" argument, the revset defined
1800 by this sub-option is evaluated to determine what to push.
1802 by this sub-option is evaluated to determine what to push.
1801
1803
1802 For example, a value of "." will push the working directory's revision
1804 For example, a value of "." will push the working directory's revision
1803 by default.
1805 by default.
1804
1806
1805 Revsets specifying bookmarks will not result in the bookmark being
1807 Revsets specifying bookmarks will not result in the bookmark being
1806 pushed.
1808 pushed.
1807
1809
1808 The following special named paths exist:
1810 The following special named paths exist:
1809
1811
1810 "default"
1812 "default"
1811 The URL or directory to use when no source or remote is specified.
1813 The URL or directory to use when no source or remote is specified.
1812
1814
1813 'hg clone' will automatically define this path to the location the
1815 'hg clone' will automatically define this path to the location the
1814 repository was cloned from.
1816 repository was cloned from.
1815
1817
1816 "default-push"
1818 "default-push"
1817 (deprecated) The URL or directory for the default 'hg push' location.
1819 (deprecated) The URL or directory for the default 'hg push' location.
1818 "default:pushurl" should be used instead.
1820 "default:pushurl" should be used instead.
1819
1821
1820 $ hg help glossary.mcguffin
1822 $ hg help glossary.mcguffin
1821 abort: help section not found: glossary.mcguffin
1823 abort: help section not found: glossary.mcguffin
1822 [255]
1824 [255]
1823
1825
1824 $ hg help glossary.mc.guffin
1826 $ hg help glossary.mc.guffin
1825 abort: help section not found: glossary.mc.guffin
1827 abort: help section not found: glossary.mc.guffin
1826 [255]
1828 [255]
1827
1829
1828 $ hg help template.files
1830 $ hg help template.files
1829 files List of strings. All files modified, added, or removed by
1831 files List of strings. All files modified, added, or removed by
1830 this changeset.
1832 this changeset.
1831 files(pattern)
1833 files(pattern)
1832 All files of the current changeset matching the pattern. See
1834 All files of the current changeset matching the pattern. See
1833 'hg help patterns'.
1835 'hg help patterns'.
1834
1836
1835 Test section lookup by translated message
1837 Test section lookup by translated message
1836
1838
1837 str.lower() instead of encoding.lower(str) on translated message might
1839 str.lower() instead of encoding.lower(str) on translated message might
1838 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1840 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1839 as the second or later byte of multi-byte character.
1841 as the second or later byte of multi-byte character.
1840
1842
1841 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1843 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1842 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1844 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1843 replacement makes message meaningless.
1845 replacement makes message meaningless.
1844
1846
1845 This tests that section lookup by translated string isn't broken by
1847 This tests that section lookup by translated string isn't broken by
1846 such str.lower().
1848 such str.lower().
1847
1849
1848 $ "$PYTHON" <<EOF
1850 $ "$PYTHON" <<EOF
1849 > def escape(s):
1851 > def escape(s):
1850 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1852 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1851 > # translation of "record" in ja_JP.cp932
1853 > # translation of "record" in ja_JP.cp932
1852 > upper = b"\x8bL\x98^"
1854 > upper = b"\x8bL\x98^"
1853 > # str.lower()-ed section name should be treated as different one
1855 > # str.lower()-ed section name should be treated as different one
1854 > lower = b"\x8bl\x98^"
1856 > lower = b"\x8bl\x98^"
1855 > with open('ambiguous.py', 'wb') as fp:
1857 > with open('ambiguous.py', 'wb') as fp:
1856 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1858 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1857 > u'''summary of extension
1859 > u'''summary of extension
1858 >
1860 >
1859 > %s
1861 > %s
1860 > ----
1862 > ----
1861 >
1863 >
1862 > Upper name should show only this message
1864 > Upper name should show only this message
1863 >
1865 >
1864 > %s
1866 > %s
1865 > ----
1867 > ----
1866 >
1868 >
1867 > Lower name should show only this message
1869 > Lower name should show only this message
1868 >
1870 >
1869 > subsequent section
1871 > subsequent section
1870 > ------------------
1872 > ------------------
1871 >
1873 >
1872 > This should be hidden at 'hg help ambiguous' with section name.
1874 > This should be hidden at 'hg help ambiguous' with section name.
1873 > '''
1875 > '''
1874 > """ % (escape(upper), escape(lower)))
1876 > """ % (escape(upper), escape(lower)))
1875 > EOF
1877 > EOF
1876
1878
1877 $ cat >> $HGRCPATH <<EOF
1879 $ cat >> $HGRCPATH <<EOF
1878 > [extensions]
1880 > [extensions]
1879 > ambiguous = ./ambiguous.py
1881 > ambiguous = ./ambiguous.py
1880 > EOF
1882 > EOF
1881
1883
1882 $ "$PYTHON" <<EOF | sh
1884 $ "$PYTHON" <<EOF | sh
1883 > from mercurial import pycompat
1885 > from mercurial import pycompat
1884 > upper = b"\x8bL\x98^"
1886 > upper = b"\x8bL\x98^"
1885 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1887 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1886 > EOF
1888 > EOF
1887 \x8bL\x98^ (esc)
1889 \x8bL\x98^ (esc)
1888 ----
1890 ----
1889
1891
1890 Upper name should show only this message
1892 Upper name should show only this message
1891
1893
1892
1894
1893 $ "$PYTHON" <<EOF | sh
1895 $ "$PYTHON" <<EOF | sh
1894 > from mercurial import pycompat
1896 > from mercurial import pycompat
1895 > lower = b"\x8bl\x98^"
1897 > lower = b"\x8bl\x98^"
1896 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1898 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1897 > EOF
1899 > EOF
1898 \x8bl\x98^ (esc)
1900 \x8bl\x98^ (esc)
1899 ----
1901 ----
1900
1902
1901 Lower name should show only this message
1903 Lower name should show only this message
1902
1904
1903
1905
1904 $ cat >> $HGRCPATH <<EOF
1906 $ cat >> $HGRCPATH <<EOF
1905 > [extensions]
1907 > [extensions]
1906 > ambiguous = !
1908 > ambiguous = !
1907 > EOF
1909 > EOF
1908
1910
1909 Show help content of disabled extensions
1911 Show help content of disabled extensions
1910
1912
1911 $ cat >> $HGRCPATH <<EOF
1913 $ cat >> $HGRCPATH <<EOF
1912 > [extensions]
1914 > [extensions]
1913 > ambiguous = !./ambiguous.py
1915 > ambiguous = !./ambiguous.py
1914 > EOF
1916 > EOF
1915 $ hg help -e ambiguous
1917 $ hg help -e ambiguous
1916 ambiguous extension - (no help text available)
1918 ambiguous extension - (no help text available)
1917
1919
1918 (use 'hg help extensions' for information on enabling extensions)
1920 (use 'hg help extensions' for information on enabling extensions)
1919
1921
1920 Test dynamic list of merge tools only shows up once
1922 Test dynamic list of merge tools only shows up once
1921 $ hg help merge-tools
1923 $ hg help merge-tools
1922 Merge Tools
1924 Merge Tools
1923 """""""""""
1925 """""""""""
1924
1926
1925 To merge files Mercurial uses merge tools.
1927 To merge files Mercurial uses merge tools.
1926
1928
1927 A merge tool combines two different versions of a file into a merged file.
1929 A merge tool combines two different versions of a file into a merged file.
1928 Merge tools are given the two files and the greatest common ancestor of
1930 Merge tools are given the two files and the greatest common ancestor of
1929 the two file versions, so they can determine the changes made on both
1931 the two file versions, so they can determine the changes made on both
1930 branches.
1932 branches.
1931
1933
1932 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1934 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1933 backout' and in several extensions.
1935 backout' and in several extensions.
1934
1936
1935 Usually, the merge tool tries to automatically reconcile the files by
1937 Usually, the merge tool tries to automatically reconcile the files by
1936 combining all non-overlapping changes that occurred separately in the two
1938 combining all non-overlapping changes that occurred separately in the two
1937 different evolutions of the same initial base file. Furthermore, some
1939 different evolutions of the same initial base file. Furthermore, some
1938 interactive merge programs make it easier to manually resolve conflicting
1940 interactive merge programs make it easier to manually resolve conflicting
1939 merges, either in a graphical way, or by inserting some conflict markers.
1941 merges, either in a graphical way, or by inserting some conflict markers.
1940 Mercurial does not include any interactive merge programs but relies on
1942 Mercurial does not include any interactive merge programs but relies on
1941 external tools for that.
1943 external tools for that.
1942
1944
1943 Available merge tools
1945 Available merge tools
1944 =====================
1946 =====================
1945
1947
1946 External merge tools and their properties are configured in the merge-
1948 External merge tools and their properties are configured in the merge-
1947 tools configuration section - see hgrc(5) - but they can often just be
1949 tools configuration section - see hgrc(5) - but they can often just be
1948 named by their executable.
1950 named by their executable.
1949
1951
1950 A merge tool is generally usable if its executable can be found on the
1952 A merge tool is generally usable if its executable can be found on the
1951 system and if it can handle the merge. The executable is found if it is an
1953 system and if it can handle the merge. The executable is found if it is an
1952 absolute or relative executable path or the name of an application in the
1954 absolute or relative executable path or the name of an application in the
1953 executable search path. The tool is assumed to be able to handle the merge
1955 executable search path. The tool is assumed to be able to handle the merge
1954 if it can handle symlinks if the file is a symlink, if it can handle
1956 if it can handle symlinks if the file is a symlink, if it can handle
1955 binary files if the file is binary, and if a GUI is available if the tool
1957 binary files if the file is binary, and if a GUI is available if the tool
1956 requires a GUI.
1958 requires a GUI.
1957
1959
1958 There are some internal merge tools which can be used. The internal merge
1960 There are some internal merge tools which can be used. The internal merge
1959 tools are:
1961 tools are:
1960
1962
1961 ":dump"
1963 ":dump"
1962 Creates three versions of the files to merge, containing the contents of
1964 Creates three versions of the files to merge, containing the contents of
1963 local, other and base. These files can then be used to perform a merge
1965 local, other and base. These files can then be used to perform a merge
1964 manually. If the file to be merged is named "a.txt", these files will
1966 manually. If the file to be merged is named "a.txt", these files will
1965 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1967 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1966 they will be placed in the same directory as "a.txt".
1968 they will be placed in the same directory as "a.txt".
1967
1969
1968 This implies premerge. Therefore, files aren't dumped, if premerge runs
1970 This implies premerge. Therefore, files aren't dumped, if premerge runs
1969 successfully. Use :forcedump to forcibly write files out.
1971 successfully. Use :forcedump to forcibly write files out.
1970
1972
1971 (actual capabilities: binary, symlink)
1973 (actual capabilities: binary, symlink)
1972
1974
1973 ":fail"
1975 ":fail"
1974 Rather than attempting to merge files that were modified on both
1976 Rather than attempting to merge files that were modified on both
1975 branches, it marks them as unresolved. The resolve command must be used
1977 branches, it marks them as unresolved. The resolve command must be used
1976 to resolve these conflicts.
1978 to resolve these conflicts.
1977
1979
1978 (actual capabilities: binary, symlink)
1980 (actual capabilities: binary, symlink)
1979
1981
1980 ":forcedump"
1982 ":forcedump"
1981 Creates three versions of the files as same as :dump, but omits
1983 Creates three versions of the files as same as :dump, but omits
1982 premerge.
1984 premerge.
1983
1985
1984 (actual capabilities: binary, symlink)
1986 (actual capabilities: binary, symlink)
1985
1987
1986 ":local"
1988 ":local"
1987 Uses the local 'p1()' version of files as the merged version.
1989 Uses the local 'p1()' version of files as the merged version.
1988
1990
1989 (actual capabilities: binary, symlink)
1991 (actual capabilities: binary, symlink)
1990
1992
1991 ":merge"
1993 ":merge"
1992 Uses the internal non-interactive simple merge algorithm for merging
1994 Uses the internal non-interactive simple merge algorithm for merging
1993 files. It will fail if there are any conflicts and leave markers in the
1995 files. It will fail if there are any conflicts and leave markers in the
1994 partially merged file. Markers will have two sections, one for each side
1996 partially merged file. Markers will have two sections, one for each side
1995 of merge.
1997 of merge.
1996
1998
1997 ":merge-local"
1999 ":merge-local"
1998 Like :merge, but resolve all conflicts non-interactively in favor of the
2000 Like :merge, but resolve all conflicts non-interactively in favor of the
1999 local 'p1()' changes.
2001 local 'p1()' changes.
2000
2002
2001 ":merge-other"
2003 ":merge-other"
2002 Like :merge, but resolve all conflicts non-interactively in favor of the
2004 Like :merge, but resolve all conflicts non-interactively in favor of the
2003 other 'p2()' changes.
2005 other 'p2()' changes.
2004
2006
2005 ":merge3"
2007 ":merge3"
2006 Uses the internal non-interactive simple merge algorithm for merging
2008 Uses the internal non-interactive simple merge algorithm for merging
2007 files. It will fail if there are any conflicts and leave markers in the
2009 files. It will fail if there are any conflicts and leave markers in the
2008 partially merged file. Marker will have three sections, one from each
2010 partially merged file. Marker will have three sections, one from each
2009 side of the merge and one for the base content.
2011 side of the merge and one for the base content.
2010
2012
2011 ":other"
2013 ":other"
2012 Uses the other 'p2()' version of files as the merged version.
2014 Uses the other 'p2()' version of files as the merged version.
2013
2015
2014 (actual capabilities: binary, symlink)
2016 (actual capabilities: binary, symlink)
2015
2017
2016 ":prompt"
2018 ":prompt"
2017 Asks the user which of the local 'p1()' or the other 'p2()' version to
2019 Asks the user which of the local 'p1()' or the other 'p2()' version to
2018 keep as the merged version.
2020 keep as the merged version.
2019
2021
2020 (actual capabilities: binary, symlink)
2022 (actual capabilities: binary, symlink)
2021
2023
2022 ":tagmerge"
2024 ":tagmerge"
2023 Uses the internal tag merge algorithm (experimental).
2025 Uses the internal tag merge algorithm (experimental).
2024
2026
2025 ":union"
2027 ":union"
2026 Uses the internal non-interactive simple merge algorithm for merging
2028 Uses the internal non-interactive simple merge algorithm for merging
2027 files. It will use both left and right sides for conflict regions. No
2029 files. It will use both left and right sides for conflict regions. No
2028 markers are inserted.
2030 markers are inserted.
2029
2031
2030 Internal tools are always available and do not require a GUI but will by
2032 Internal tools are always available and do not require a GUI but will by
2031 default not handle symlinks or binary files. See next section for detail
2033 default not handle symlinks or binary files. See next section for detail
2032 about "actual capabilities" described above.
2034 about "actual capabilities" described above.
2033
2035
2034 Choosing a merge tool
2036 Choosing a merge tool
2035 =====================
2037 =====================
2036
2038
2037 Mercurial uses these rules when deciding which merge tool to use:
2039 Mercurial uses these rules when deciding which merge tool to use:
2038
2040
2039 1. If a tool has been specified with the --tool option to merge or
2041 1. If a tool has been specified with the --tool option to merge or
2040 resolve, it is used. If it is the name of a tool in the merge-tools
2042 resolve, it is used. If it is the name of a tool in the merge-tools
2041 configuration, its configuration is used. Otherwise the specified tool
2043 configuration, its configuration is used. Otherwise the specified tool
2042 must be executable by the shell.
2044 must be executable by the shell.
2043 2. If the "HGMERGE" environment variable is present, its value is used and
2045 2. If the "HGMERGE" environment variable is present, its value is used and
2044 must be executable by the shell.
2046 must be executable by the shell.
2045 3. If the filename of the file to be merged matches any of the patterns in
2047 3. If the filename of the file to be merged matches any of the patterns in
2046 the merge-patterns configuration section, the first usable merge tool
2048 the merge-patterns configuration section, the first usable merge tool
2047 corresponding to a matching pattern is used.
2049 corresponding to a matching pattern is used.
2048 4. If ui.merge is set it will be considered next. If the value is not the
2050 4. If ui.merge is set it will be considered next. If the value is not the
2049 name of a configured tool, the specified value is used and must be
2051 name of a configured tool, the specified value is used and must be
2050 executable by the shell. Otherwise the named tool is used if it is
2052 executable by the shell. Otherwise the named tool is used if it is
2051 usable.
2053 usable.
2052 5. If any usable merge tools are present in the merge-tools configuration
2054 5. If any usable merge tools are present in the merge-tools configuration
2053 section, the one with the highest priority is used.
2055 section, the one with the highest priority is used.
2054 6. If a program named "hgmerge" can be found on the system, it is used -
2056 6. If a program named "hgmerge" can be found on the system, it is used -
2055 but it will by default not be used for symlinks and binary files.
2057 but it will by default not be used for symlinks and binary files.
2056 7. If the file to be merged is not binary and is not a symlink, then
2058 7. If the file to be merged is not binary and is not a symlink, then
2057 internal ":merge" is used.
2059 internal ":merge" is used.
2058 8. Otherwise, ":prompt" is used.
2060 8. Otherwise, ":prompt" is used.
2059
2061
2060 For historical reason, Mercurial treats merge tools as below while
2062 For historical reason, Mercurial treats merge tools as below while
2061 examining rules above.
2063 examining rules above.
2062
2064
2063 step specified via binary symlink
2065 step specified via binary symlink
2064 ----------------------------------
2066 ----------------------------------
2065 1. --tool o/o o/o
2067 1. --tool o/o o/o
2066 2. HGMERGE o/o o/o
2068 2. HGMERGE o/o o/o
2067 3. merge-patterns o/o(*) x/?(*)
2069 3. merge-patterns o/o(*) x/?(*)
2068 4. ui.merge x/?(*) x/?(*)
2070 4. ui.merge x/?(*) x/?(*)
2069
2071
2070 Each capability column indicates Mercurial behavior for internal/external
2072 Each capability column indicates Mercurial behavior for internal/external
2071 merge tools at examining each rule.
2073 merge tools at examining each rule.
2072
2074
2073 - "o": "assume that a tool has capability"
2075 - "o": "assume that a tool has capability"
2074 - "x": "assume that a tool does not have capability"
2076 - "x": "assume that a tool does not have capability"
2075 - "?": "check actual capability of a tool"
2077 - "?": "check actual capability of a tool"
2076
2078
2077 If "merge.strict-capability-check" configuration is true, Mercurial checks
2079 If "merge.strict-capability-check" configuration is true, Mercurial checks
2078 capabilities of merge tools strictly in (*) cases above (= each capability
2080 capabilities of merge tools strictly in (*) cases above (= each capability
2079 column becomes "?/?"). It is false by default for backward compatibility.
2081 column becomes "?/?"). It is false by default for backward compatibility.
2080
2082
2081 Note:
2083 Note:
2082 After selecting a merge program, Mercurial will by default attempt to
2084 After selecting a merge program, Mercurial will by default attempt to
2083 merge the files using a simple merge algorithm first. Only if it
2085 merge the files using a simple merge algorithm first. Only if it
2084 doesn't succeed because of conflicting changes will Mercurial actually
2086 doesn't succeed because of conflicting changes will Mercurial actually
2085 execute the merge program. Whether to use the simple merge algorithm
2087 execute the merge program. Whether to use the simple merge algorithm
2086 first can be controlled by the premerge setting of the merge tool.
2088 first can be controlled by the premerge setting of the merge tool.
2087 Premerge is enabled by default unless the file is binary or a symlink.
2089 Premerge is enabled by default unless the file is binary or a symlink.
2088
2090
2089 See the merge-tools and ui sections of hgrc(5) for details on the
2091 See the merge-tools and ui sections of hgrc(5) for details on the
2090 configuration of merge tools.
2092 configuration of merge tools.
2091
2093
2092 Compression engines listed in `hg help bundlespec`
2094 Compression engines listed in `hg help bundlespec`
2093
2095
2094 $ hg help bundlespec | grep gzip
2096 $ hg help bundlespec | grep gzip
2095 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2097 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2096 An algorithm that produces smaller bundles than "gzip".
2098 An algorithm that produces smaller bundles than "gzip".
2097 This engine will likely produce smaller bundles than "gzip" but will be
2099 This engine will likely produce smaller bundles than "gzip" but will be
2098 "gzip"
2100 "gzip"
2099 better compression than "gzip". It also frequently yields better (?)
2101 better compression than "gzip". It also frequently yields better (?)
2100
2102
2101 Test usage of section marks in help documents
2103 Test usage of section marks in help documents
2102
2104
2103 $ cd "$TESTDIR"/../doc
2105 $ cd "$TESTDIR"/../doc
2104 $ "$PYTHON" check-seclevel.py
2106 $ "$PYTHON" check-seclevel.py
2105 $ cd $TESTTMP
2107 $ cd $TESTTMP
2106
2108
2107 #if serve
2109 #if serve
2108
2110
2109 Test the help pages in hgweb.
2111 Test the help pages in hgweb.
2110
2112
2111 Dish up an empty repo; serve it cold.
2113 Dish up an empty repo; serve it cold.
2112
2114
2113 $ hg init "$TESTTMP/test"
2115 $ hg init "$TESTTMP/test"
2114 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2116 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2115 $ cat hg.pid >> $DAEMON_PIDS
2117 $ cat hg.pid >> $DAEMON_PIDS
2116
2118
2117 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2119 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2118 200 Script output follows
2120 200 Script output follows
2119
2121
2120 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2122 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2121 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2123 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2122 <head>
2124 <head>
2123 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2125 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2124 <meta name="robots" content="index, nofollow" />
2126 <meta name="robots" content="index, nofollow" />
2125 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2127 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2126 <script type="text/javascript" src="/static/mercurial.js"></script>
2128 <script type="text/javascript" src="/static/mercurial.js"></script>
2127
2129
2128 <title>Help: Index</title>
2130 <title>Help: Index</title>
2129 </head>
2131 </head>
2130 <body>
2132 <body>
2131
2133
2132 <div class="container">
2134 <div class="container">
2133 <div class="menu">
2135 <div class="menu">
2134 <div class="logo">
2136 <div class="logo">
2135 <a href="https://mercurial-scm.org/">
2137 <a href="https://mercurial-scm.org/">
2136 <img src="/static/hglogo.png" alt="mercurial" /></a>
2138 <img src="/static/hglogo.png" alt="mercurial" /></a>
2137 </div>
2139 </div>
2138 <ul>
2140 <ul>
2139 <li><a href="/shortlog">log</a></li>
2141 <li><a href="/shortlog">log</a></li>
2140 <li><a href="/graph">graph</a></li>
2142 <li><a href="/graph">graph</a></li>
2141 <li><a href="/tags">tags</a></li>
2143 <li><a href="/tags">tags</a></li>
2142 <li><a href="/bookmarks">bookmarks</a></li>
2144 <li><a href="/bookmarks">bookmarks</a></li>
2143 <li><a href="/branches">branches</a></li>
2145 <li><a href="/branches">branches</a></li>
2144 </ul>
2146 </ul>
2145 <ul>
2147 <ul>
2146 <li class="active">help</li>
2148 <li class="active">help</li>
2147 </ul>
2149 </ul>
2148 </div>
2150 </div>
2149
2151
2150 <div class="main">
2152 <div class="main">
2151 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2153 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2152
2154
2153 <form class="search" action="/log">
2155 <form class="search" action="/log">
2154
2156
2155 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2157 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2156 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2158 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2157 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2159 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2158 </form>
2160 </form>
2159 <table class="bigtable">
2161 <table class="bigtable">
2160 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2162 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2161
2163
2162 <tr><td>
2164 <tr><td>
2163 <a href="/help/bundlespec">
2165 <a href="/help/bundlespec">
2164 bundlespec
2166 bundlespec
2165 </a>
2167 </a>
2166 </td><td>
2168 </td><td>
2167 Bundle File Formats
2169 Bundle File Formats
2168 </td></tr>
2170 </td></tr>
2169 <tr><td>
2171 <tr><td>
2170 <a href="/help/color">
2172 <a href="/help/color">
2171 color
2173 color
2172 </a>
2174 </a>
2173 </td><td>
2175 </td><td>
2174 Colorizing Outputs
2176 Colorizing Outputs
2175 </td></tr>
2177 </td></tr>
2176 <tr><td>
2178 <tr><td>
2177 <a href="/help/config">
2179 <a href="/help/config">
2178 config
2180 config
2179 </a>
2181 </a>
2180 </td><td>
2182 </td><td>
2181 Configuration Files
2183 Configuration Files
2182 </td></tr>
2184 </td></tr>
2183 <tr><td>
2185 <tr><td>
2184 <a href="/help/dates">
2186 <a href="/help/dates">
2185 dates
2187 dates
2186 </a>
2188 </a>
2187 </td><td>
2189 </td><td>
2188 Date Formats
2190 Date Formats
2189 </td></tr>
2191 </td></tr>
2190 <tr><td>
2192 <tr><td>
2191 <a href="/help/deprecated">
2193 <a href="/help/deprecated">
2192 deprecated
2194 deprecated
2193 </a>
2195 </a>
2194 </td><td>
2196 </td><td>
2195 Deprecated Features
2197 Deprecated Features
2196 </td></tr>
2198 </td></tr>
2197 <tr><td>
2199 <tr><td>
2198 <a href="/help/diffs">
2200 <a href="/help/diffs">
2199 diffs
2201 diffs
2200 </a>
2202 </a>
2201 </td><td>
2203 </td><td>
2202 Diff Formats
2204 Diff Formats
2203 </td></tr>
2205 </td></tr>
2204 <tr><td>
2206 <tr><td>
2205 <a href="/help/environment">
2207 <a href="/help/environment">
2206 environment
2208 environment
2207 </a>
2209 </a>
2208 </td><td>
2210 </td><td>
2209 Environment Variables
2211 Environment Variables
2210 </td></tr>
2212 </td></tr>
2211 <tr><td>
2213 <tr><td>
2212 <a href="/help/extensions">
2214 <a href="/help/extensions">
2213 extensions
2215 extensions
2214 </a>
2216 </a>
2215 </td><td>
2217 </td><td>
2216 Using Additional Features
2218 Using Additional Features
2217 </td></tr>
2219 </td></tr>
2218 <tr><td>
2220 <tr><td>
2219 <a href="/help/filesets">
2221 <a href="/help/filesets">
2220 filesets
2222 filesets
2221 </a>
2223 </a>
2222 </td><td>
2224 </td><td>
2223 Specifying File Sets
2225 Specifying File Sets
2224 </td></tr>
2226 </td></tr>
2225 <tr><td>
2227 <tr><td>
2226 <a href="/help/flags">
2228 <a href="/help/flags">
2227 flags
2229 flags
2228 </a>
2230 </a>
2229 </td><td>
2231 </td><td>
2230 Command-line flags
2232 Command-line flags
2231 </td></tr>
2233 </td></tr>
2232 <tr><td>
2234 <tr><td>
2233 <a href="/help/glossary">
2235 <a href="/help/glossary">
2234 glossary
2236 glossary
2235 </a>
2237 </a>
2236 </td><td>
2238 </td><td>
2237 Glossary
2239 Glossary
2238 </td></tr>
2240 </td></tr>
2239 <tr><td>
2241 <tr><td>
2240 <a href="/help/hgignore">
2242 <a href="/help/hgignore">
2241 hgignore
2243 hgignore
2242 </a>
2244 </a>
2243 </td><td>
2245 </td><td>
2244 Syntax for Mercurial Ignore Files
2246 Syntax for Mercurial Ignore Files
2245 </td></tr>
2247 </td></tr>
2246 <tr><td>
2248 <tr><td>
2247 <a href="/help/hgweb">
2249 <a href="/help/hgweb">
2248 hgweb
2250 hgweb
2249 </a>
2251 </a>
2250 </td><td>
2252 </td><td>
2251 Configuring hgweb
2253 Configuring hgweb
2252 </td></tr>
2254 </td></tr>
2253 <tr><td>
2255 <tr><td>
2254 <a href="/help/internals">
2256 <a href="/help/internals">
2255 internals
2257 internals
2256 </a>
2258 </a>
2257 </td><td>
2259 </td><td>
2258 Technical implementation topics
2260 Technical implementation topics
2259 </td></tr>
2261 </td></tr>
2260 <tr><td>
2262 <tr><td>
2261 <a href="/help/merge-tools">
2263 <a href="/help/merge-tools">
2262 merge-tools
2264 merge-tools
2263 </a>
2265 </a>
2264 </td><td>
2266 </td><td>
2265 Merge Tools
2267 Merge Tools
2266 </td></tr>
2268 </td></tr>
2267 <tr><td>
2269 <tr><td>
2268 <a href="/help/pager">
2270 <a href="/help/pager">
2269 pager
2271 pager
2270 </a>
2272 </a>
2271 </td><td>
2273 </td><td>
2272 Pager Support
2274 Pager Support
2273 </td></tr>
2275 </td></tr>
2274 <tr><td>
2276 <tr><td>
2275 <a href="/help/patterns">
2277 <a href="/help/patterns">
2276 patterns
2278 patterns
2277 </a>
2279 </a>
2278 </td><td>
2280 </td><td>
2279 File Name Patterns
2281 File Name Patterns
2280 </td></tr>
2282 </td></tr>
2281 <tr><td>
2283 <tr><td>
2282 <a href="/help/phases">
2284 <a href="/help/phases">
2283 phases
2285 phases
2284 </a>
2286 </a>
2285 </td><td>
2287 </td><td>
2286 Working with Phases
2288 Working with Phases
2287 </td></tr>
2289 </td></tr>
2288 <tr><td>
2290 <tr><td>
2289 <a href="/help/revisions">
2291 <a href="/help/revisions">
2290 revisions
2292 revisions
2291 </a>
2293 </a>
2292 </td><td>
2294 </td><td>
2293 Specifying Revisions
2295 Specifying Revisions
2294 </td></tr>
2296 </td></tr>
2295 <tr><td>
2297 <tr><td>
2296 <a href="/help/scripting">
2298 <a href="/help/scripting">
2297 scripting
2299 scripting
2298 </a>
2300 </a>
2299 </td><td>
2301 </td><td>
2300 Using Mercurial from scripts and automation
2302 Using Mercurial from scripts and automation
2301 </td></tr>
2303 </td></tr>
2302 <tr><td>
2304 <tr><td>
2303 <a href="/help/subrepos">
2305 <a href="/help/subrepos">
2304 subrepos
2306 subrepos
2305 </a>
2307 </a>
2306 </td><td>
2308 </td><td>
2307 Subrepositories
2309 Subrepositories
2308 </td></tr>
2310 </td></tr>
2309 <tr><td>
2311 <tr><td>
2310 <a href="/help/templating">
2312 <a href="/help/templating">
2311 templating
2313 templating
2312 </a>
2314 </a>
2313 </td><td>
2315 </td><td>
2314 Template Usage
2316 Template Usage
2315 </td></tr>
2317 </td></tr>
2316 <tr><td>
2318 <tr><td>
2317 <a href="/help/urls">
2319 <a href="/help/urls">
2318 urls
2320 urls
2319 </a>
2321 </a>
2320 </td><td>
2322 </td><td>
2321 URL Paths
2323 URL Paths
2322 </td></tr>
2324 </td></tr>
2323 <tr><td>
2325 <tr><td>
2324 <a href="/help/topic-containing-verbose">
2326 <a href="/help/topic-containing-verbose">
2325 topic-containing-verbose
2327 topic-containing-verbose
2326 </a>
2328 </a>
2327 </td><td>
2329 </td><td>
2328 This is the topic to test omit indicating.
2330 This is the topic to test omit indicating.
2329 </td></tr>
2331 </td></tr>
2330
2332
2331
2333
2332 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2334 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2333
2335
2334 <tr><td>
2336 <tr><td>
2335 <a href="/help/add">
2337 <a href="/help/add">
2336 add
2338 add
2337 </a>
2339 </a>
2338 </td><td>
2340 </td><td>
2339 add the specified files on the next commit
2341 add the specified files on the next commit
2340 </td></tr>
2342 </td></tr>
2341 <tr><td>
2343 <tr><td>
2342 <a href="/help/annotate">
2344 <a href="/help/annotate">
2343 annotate
2345 annotate
2344 </a>
2346 </a>
2345 </td><td>
2347 </td><td>
2346 show changeset information by line for each file
2348 show changeset information by line for each file
2347 </td></tr>
2349 </td></tr>
2348 <tr><td>
2350 <tr><td>
2349 <a href="/help/clone">
2351 <a href="/help/clone">
2350 clone
2352 clone
2351 </a>
2353 </a>
2352 </td><td>
2354 </td><td>
2353 make a copy of an existing repository
2355 make a copy of an existing repository
2354 </td></tr>
2356 </td></tr>
2355 <tr><td>
2357 <tr><td>
2356 <a href="/help/commit">
2358 <a href="/help/commit">
2357 commit
2359 commit
2358 </a>
2360 </a>
2359 </td><td>
2361 </td><td>
2360 commit the specified files or all outstanding changes
2362 commit the specified files or all outstanding changes
2361 </td></tr>
2363 </td></tr>
2362 <tr><td>
2364 <tr><td>
2363 <a href="/help/diff">
2365 <a href="/help/diff">
2364 diff
2366 diff
2365 </a>
2367 </a>
2366 </td><td>
2368 </td><td>
2367 diff repository (or selected files)
2369 diff repository (or selected files)
2368 </td></tr>
2370 </td></tr>
2369 <tr><td>
2371 <tr><td>
2370 <a href="/help/export">
2372 <a href="/help/export">
2371 export
2373 export
2372 </a>
2374 </a>
2373 </td><td>
2375 </td><td>
2374 dump the header and diffs for one or more changesets
2376 dump the header and diffs for one or more changesets
2375 </td></tr>
2377 </td></tr>
2376 <tr><td>
2378 <tr><td>
2377 <a href="/help/forget">
2379 <a href="/help/forget">
2378 forget
2380 forget
2379 </a>
2381 </a>
2380 </td><td>
2382 </td><td>
2381 forget the specified files on the next commit
2383 forget the specified files on the next commit
2382 </td></tr>
2384 </td></tr>
2383 <tr><td>
2385 <tr><td>
2384 <a href="/help/init">
2386 <a href="/help/init">
2385 init
2387 init
2386 </a>
2388 </a>
2387 </td><td>
2389 </td><td>
2388 create a new repository in the given directory
2390 create a new repository in the given directory
2389 </td></tr>
2391 </td></tr>
2390 <tr><td>
2392 <tr><td>
2391 <a href="/help/log">
2393 <a href="/help/log">
2392 log
2394 log
2393 </a>
2395 </a>
2394 </td><td>
2396 </td><td>
2395 show revision history of entire repository or files
2397 show revision history of entire repository or files
2396 </td></tr>
2398 </td></tr>
2397 <tr><td>
2399 <tr><td>
2398 <a href="/help/merge">
2400 <a href="/help/merge">
2399 merge
2401 merge
2400 </a>
2402 </a>
2401 </td><td>
2403 </td><td>
2402 merge another revision into working directory
2404 merge another revision into working directory
2403 </td></tr>
2405 </td></tr>
2404 <tr><td>
2406 <tr><td>
2405 <a href="/help/pull">
2407 <a href="/help/pull">
2406 pull
2408 pull
2407 </a>
2409 </a>
2408 </td><td>
2410 </td><td>
2409 pull changes from the specified source
2411 pull changes from the specified source
2410 </td></tr>
2412 </td></tr>
2411 <tr><td>
2413 <tr><td>
2412 <a href="/help/push">
2414 <a href="/help/push">
2413 push
2415 push
2414 </a>
2416 </a>
2415 </td><td>
2417 </td><td>
2416 push changes to the specified destination
2418 push changes to the specified destination
2417 </td></tr>
2419 </td></tr>
2418 <tr><td>
2420 <tr><td>
2419 <a href="/help/remove">
2421 <a href="/help/remove">
2420 remove
2422 remove
2421 </a>
2423 </a>
2422 </td><td>
2424 </td><td>
2423 remove the specified files on the next commit
2425 remove the specified files on the next commit
2424 </td></tr>
2426 </td></tr>
2425 <tr><td>
2427 <tr><td>
2426 <a href="/help/serve">
2428 <a href="/help/serve">
2427 serve
2429 serve
2428 </a>
2430 </a>
2429 </td><td>
2431 </td><td>
2430 start stand-alone webserver
2432 start stand-alone webserver
2431 </td></tr>
2433 </td></tr>
2432 <tr><td>
2434 <tr><td>
2433 <a href="/help/status">
2435 <a href="/help/status">
2434 status
2436 status
2435 </a>
2437 </a>
2436 </td><td>
2438 </td><td>
2437 show changed files in the working directory
2439 show changed files in the working directory
2438 </td></tr>
2440 </td></tr>
2439 <tr><td>
2441 <tr><td>
2440 <a href="/help/summary">
2442 <a href="/help/summary">
2441 summary
2443 summary
2442 </a>
2444 </a>
2443 </td><td>
2445 </td><td>
2444 summarize working directory state
2446 summarize working directory state
2445 </td></tr>
2447 </td></tr>
2446 <tr><td>
2448 <tr><td>
2447 <a href="/help/update">
2449 <a href="/help/update">
2448 update
2450 update
2449 </a>
2451 </a>
2450 </td><td>
2452 </td><td>
2451 update working directory (or switch revisions)
2453 update working directory (or switch revisions)
2452 </td></tr>
2454 </td></tr>
2453
2455
2454
2456
2455
2457
2456 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2458 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2457
2459
2458 <tr><td>
2460 <tr><td>
2459 <a href="/help/addremove">
2461 <a href="/help/addremove">
2460 addremove
2462 addremove
2461 </a>
2463 </a>
2462 </td><td>
2464 </td><td>
2463 add all new files, delete all missing files
2465 add all new files, delete all missing files
2464 </td></tr>
2466 </td></tr>
2465 <tr><td>
2467 <tr><td>
2466 <a href="/help/archive">
2468 <a href="/help/archive">
2467 archive
2469 archive
2468 </a>
2470 </a>
2469 </td><td>
2471 </td><td>
2470 create an unversioned archive of a repository revision
2472 create an unversioned archive of a repository revision
2471 </td></tr>
2473 </td></tr>
2472 <tr><td>
2474 <tr><td>
2473 <a href="/help/backout">
2475 <a href="/help/backout">
2474 backout
2476 backout
2475 </a>
2477 </a>
2476 </td><td>
2478 </td><td>
2477 reverse effect of earlier changeset
2479 reverse effect of earlier changeset
2478 </td></tr>
2480 </td></tr>
2479 <tr><td>
2481 <tr><td>
2480 <a href="/help/bisect">
2482 <a href="/help/bisect">
2481 bisect
2483 bisect
2482 </a>
2484 </a>
2483 </td><td>
2485 </td><td>
2484 subdivision search of changesets
2486 subdivision search of changesets
2485 </td></tr>
2487 </td></tr>
2486 <tr><td>
2488 <tr><td>
2487 <a href="/help/bookmarks">
2489 <a href="/help/bookmarks">
2488 bookmarks
2490 bookmarks
2489 </a>
2491 </a>
2490 </td><td>
2492 </td><td>
2491 create a new bookmark or list existing bookmarks
2493 create a new bookmark or list existing bookmarks
2492 </td></tr>
2494 </td></tr>
2493 <tr><td>
2495 <tr><td>
2494 <a href="/help/branch">
2496 <a href="/help/branch">
2495 branch
2497 branch
2496 </a>
2498 </a>
2497 </td><td>
2499 </td><td>
2498 set or show the current branch name
2500 set or show the current branch name
2499 </td></tr>
2501 </td></tr>
2500 <tr><td>
2502 <tr><td>
2501 <a href="/help/branches">
2503 <a href="/help/branches">
2502 branches
2504 branches
2503 </a>
2505 </a>
2504 </td><td>
2506 </td><td>
2505 list repository named branches
2507 list repository named branches
2506 </td></tr>
2508 </td></tr>
2507 <tr><td>
2509 <tr><td>
2508 <a href="/help/bundle">
2510 <a href="/help/bundle">
2509 bundle
2511 bundle
2510 </a>
2512 </a>
2511 </td><td>
2513 </td><td>
2512 create a bundle file
2514 create a bundle file
2513 </td></tr>
2515 </td></tr>
2514 <tr><td>
2516 <tr><td>
2515 <a href="/help/cat">
2517 <a href="/help/cat">
2516 cat
2518 cat
2517 </a>
2519 </a>
2518 </td><td>
2520 </td><td>
2519 output the current or given revision of files
2521 output the current or given revision of files
2520 </td></tr>
2522 </td></tr>
2521 <tr><td>
2523 <tr><td>
2522 <a href="/help/config">
2524 <a href="/help/config">
2523 config
2525 config
2524 </a>
2526 </a>
2525 </td><td>
2527 </td><td>
2526 show combined config settings from all hgrc files
2528 show combined config settings from all hgrc files
2527 </td></tr>
2529 </td></tr>
2528 <tr><td>
2530 <tr><td>
2529 <a href="/help/copy">
2531 <a href="/help/copy">
2530 copy
2532 copy
2531 </a>
2533 </a>
2532 </td><td>
2534 </td><td>
2533 mark files as copied for the next commit
2535 mark files as copied for the next commit
2534 </td></tr>
2536 </td></tr>
2535 <tr><td>
2537 <tr><td>
2536 <a href="/help/files">
2538 <a href="/help/files">
2537 files
2539 files
2538 </a>
2540 </a>
2539 </td><td>
2541 </td><td>
2540 list tracked files
2542 list tracked files
2541 </td></tr>
2543 </td></tr>
2542 <tr><td>
2544 <tr><td>
2543 <a href="/help/graft">
2545 <a href="/help/graft">
2544 graft
2546 graft
2545 </a>
2547 </a>
2546 </td><td>
2548 </td><td>
2547 copy changes from other branches onto the current branch
2549 copy changes from other branches onto the current branch
2548 </td></tr>
2550 </td></tr>
2549 <tr><td>
2551 <tr><td>
2550 <a href="/help/grep">
2552 <a href="/help/grep">
2551 grep
2553 grep
2552 </a>
2554 </a>
2553 </td><td>
2555 </td><td>
2554 search revision history for a pattern in specified files
2556 search revision history for a pattern in specified files
2555 </td></tr>
2557 </td></tr>
2556 <tr><td>
2558 <tr><td>
2557 <a href="/help/hashelp">
2559 <a href="/help/hashelp">
2558 hashelp
2560 hashelp
2559 </a>
2561 </a>
2560 </td><td>
2562 </td><td>
2561 Extension command's help
2563 Extension command's help
2562 </td></tr>
2564 </td></tr>
2563 <tr><td>
2565 <tr><td>
2564 <a href="/help/heads">
2566 <a href="/help/heads">
2565 heads
2567 heads
2566 </a>
2568 </a>
2567 </td><td>
2569 </td><td>
2568 show branch heads
2570 show branch heads
2569 </td></tr>
2571 </td></tr>
2570 <tr><td>
2572 <tr><td>
2571 <a href="/help/help">
2573 <a href="/help/help">
2572 help
2574 help
2573 </a>
2575 </a>
2574 </td><td>
2576 </td><td>
2575 show help for a given topic or a help overview
2577 show help for a given topic or a help overview
2576 </td></tr>
2578 </td></tr>
2577 <tr><td>
2579 <tr><td>
2578 <a href="/help/hgalias">
2580 <a href="/help/hgalias">
2579 hgalias
2581 hgalias
2580 </a>
2582 </a>
2581 </td><td>
2583 </td><td>
2582 My doc
2584 My doc
2583 </td></tr>
2585 </td></tr>
2584 <tr><td>
2586 <tr><td>
2585 <a href="/help/hgaliasnodoc">
2587 <a href="/help/hgaliasnodoc">
2586 hgaliasnodoc
2588 hgaliasnodoc
2587 </a>
2589 </a>
2588 </td><td>
2590 </td><td>
2589 summarize working directory state
2591 summarize working directory state
2590 </td></tr>
2592 </td></tr>
2591 <tr><td>
2593 <tr><td>
2592 <a href="/help/identify">
2594 <a href="/help/identify">
2593 identify
2595 identify
2594 </a>
2596 </a>
2595 </td><td>
2597 </td><td>
2596 identify the working directory or specified revision
2598 identify the working directory or specified revision
2597 </td></tr>
2599 </td></tr>
2598 <tr><td>
2600 <tr><td>
2599 <a href="/help/import">
2601 <a href="/help/import">
2600 import
2602 import
2601 </a>
2603 </a>
2602 </td><td>
2604 </td><td>
2603 import an ordered set of patches
2605 import an ordered set of patches
2604 </td></tr>
2606 </td></tr>
2605 <tr><td>
2607 <tr><td>
2606 <a href="/help/incoming">
2608 <a href="/help/incoming">
2607 incoming
2609 incoming
2608 </a>
2610 </a>
2609 </td><td>
2611 </td><td>
2610 show new changesets found in source
2612 show new changesets found in source
2611 </td></tr>
2613 </td></tr>
2612 <tr><td>
2614 <tr><td>
2613 <a href="/help/manifest">
2615 <a href="/help/manifest">
2614 manifest
2616 manifest
2615 </a>
2617 </a>
2616 </td><td>
2618 </td><td>
2617 output the current or given revision of the project manifest
2619 output the current or given revision of the project manifest
2618 </td></tr>
2620 </td></tr>
2619 <tr><td>
2621 <tr><td>
2620 <a href="/help/nohelp">
2622 <a href="/help/nohelp">
2621 nohelp
2623 nohelp
2622 </a>
2624 </a>
2623 </td><td>
2625 </td><td>
2624 (no help text available)
2626 (no help text available)
2625 </td></tr>
2627 </td></tr>
2626 <tr><td>
2628 <tr><td>
2627 <a href="/help/outgoing">
2629 <a href="/help/outgoing">
2628 outgoing
2630 outgoing
2629 </a>
2631 </a>
2630 </td><td>
2632 </td><td>
2631 show changesets not found in the destination
2633 show changesets not found in the destination
2632 </td></tr>
2634 </td></tr>
2633 <tr><td>
2635 <tr><td>
2634 <a href="/help/paths">
2636 <a href="/help/paths">
2635 paths
2637 paths
2636 </a>
2638 </a>
2637 </td><td>
2639 </td><td>
2638 show aliases for remote repositories
2640 show aliases for remote repositories
2639 </td></tr>
2641 </td></tr>
2640 <tr><td>
2642 <tr><td>
2641 <a href="/help/phase">
2643 <a href="/help/phase">
2642 phase
2644 phase
2643 </a>
2645 </a>
2644 </td><td>
2646 </td><td>
2645 set or show the current phase name
2647 set or show the current phase name
2646 </td></tr>
2648 </td></tr>
2647 <tr><td>
2649 <tr><td>
2648 <a href="/help/recover">
2650 <a href="/help/recover">
2649 recover
2651 recover
2650 </a>
2652 </a>
2651 </td><td>
2653 </td><td>
2652 roll back an interrupted transaction
2654 roll back an interrupted transaction
2653 </td></tr>
2655 </td></tr>
2654 <tr><td>
2656 <tr><td>
2655 <a href="/help/rename">
2657 <a href="/help/rename">
2656 rename
2658 rename
2657 </a>
2659 </a>
2658 </td><td>
2660 </td><td>
2659 rename files; equivalent of copy + remove
2661 rename files; equivalent of copy + remove
2660 </td></tr>
2662 </td></tr>
2661 <tr><td>
2663 <tr><td>
2662 <a href="/help/resolve">
2664 <a href="/help/resolve">
2663 resolve
2665 resolve
2664 </a>
2666 </a>
2665 </td><td>
2667 </td><td>
2666 redo merges or set/view the merge status of files
2668 redo merges or set/view the merge status of files
2667 </td></tr>
2669 </td></tr>
2668 <tr><td>
2670 <tr><td>
2669 <a href="/help/revert">
2671 <a href="/help/revert">
2670 revert
2672 revert
2671 </a>
2673 </a>
2672 </td><td>
2674 </td><td>
2673 restore files to their checkout state
2675 restore files to their checkout state
2674 </td></tr>
2676 </td></tr>
2675 <tr><td>
2677 <tr><td>
2676 <a href="/help/root">
2678 <a href="/help/root">
2677 root
2679 root
2678 </a>
2680 </a>
2679 </td><td>
2681 </td><td>
2680 print the root (top) of the current working directory
2682 print the root (top) of the current working directory
2681 </td></tr>
2683 </td></tr>
2682 <tr><td>
2684 <tr><td>
2683 <a href="/help/shellalias">
2685 <a href="/help/shellalias">
2684 shellalias
2686 shellalias
2685 </a>
2687 </a>
2686 </td><td>
2688 </td><td>
2687 (no help text available)
2689 (no help text available)
2688 </td></tr>
2690 </td></tr>
2689 <tr><td>
2691 <tr><td>
2690 <a href="/help/tag">
2692 <a href="/help/tag">
2691 tag
2693 tag
2692 </a>
2694 </a>
2693 </td><td>
2695 </td><td>
2694 add one or more tags for the current or given revision
2696 add one or more tags for the current or given revision
2695 </td></tr>
2697 </td></tr>
2696 <tr><td>
2698 <tr><td>
2697 <a href="/help/tags">
2699 <a href="/help/tags">
2698 tags
2700 tags
2699 </a>
2701 </a>
2700 </td><td>
2702 </td><td>
2701 list repository tags
2703 list repository tags
2702 </td></tr>
2704 </td></tr>
2703 <tr><td>
2705 <tr><td>
2704 <a href="/help/unbundle">
2706 <a href="/help/unbundle">
2705 unbundle
2707 unbundle
2706 </a>
2708 </a>
2707 </td><td>
2709 </td><td>
2708 apply one or more bundle files
2710 apply one or more bundle files
2709 </td></tr>
2711 </td></tr>
2710 <tr><td>
2712 <tr><td>
2711 <a href="/help/verify">
2713 <a href="/help/verify">
2712 verify
2714 verify
2713 </a>
2715 </a>
2714 </td><td>
2716 </td><td>
2715 verify the integrity of the repository
2717 verify the integrity of the repository
2716 </td></tr>
2718 </td></tr>
2717 <tr><td>
2719 <tr><td>
2718 <a href="/help/version">
2720 <a href="/help/version">
2719 version
2721 version
2720 </a>
2722 </a>
2721 </td><td>
2723 </td><td>
2722 output version and copyright information
2724 output version and copyright information
2723 </td></tr>
2725 </td></tr>
2724
2726
2725
2727
2726 </table>
2728 </table>
2727 </div>
2729 </div>
2728 </div>
2730 </div>
2729
2731
2730
2732
2731
2733
2732 </body>
2734 </body>
2733 </html>
2735 </html>
2734
2736
2735
2737
2736 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2738 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2737 200 Script output follows
2739 200 Script output follows
2738
2740
2739 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2741 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2740 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2742 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2741 <head>
2743 <head>
2742 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2744 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2743 <meta name="robots" content="index, nofollow" />
2745 <meta name="robots" content="index, nofollow" />
2744 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2746 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2745 <script type="text/javascript" src="/static/mercurial.js"></script>
2747 <script type="text/javascript" src="/static/mercurial.js"></script>
2746
2748
2747 <title>Help: add</title>
2749 <title>Help: add</title>
2748 </head>
2750 </head>
2749 <body>
2751 <body>
2750
2752
2751 <div class="container">
2753 <div class="container">
2752 <div class="menu">
2754 <div class="menu">
2753 <div class="logo">
2755 <div class="logo">
2754 <a href="https://mercurial-scm.org/">
2756 <a href="https://mercurial-scm.org/">
2755 <img src="/static/hglogo.png" alt="mercurial" /></a>
2757 <img src="/static/hglogo.png" alt="mercurial" /></a>
2756 </div>
2758 </div>
2757 <ul>
2759 <ul>
2758 <li><a href="/shortlog">log</a></li>
2760 <li><a href="/shortlog">log</a></li>
2759 <li><a href="/graph">graph</a></li>
2761 <li><a href="/graph">graph</a></li>
2760 <li><a href="/tags">tags</a></li>
2762 <li><a href="/tags">tags</a></li>
2761 <li><a href="/bookmarks">bookmarks</a></li>
2763 <li><a href="/bookmarks">bookmarks</a></li>
2762 <li><a href="/branches">branches</a></li>
2764 <li><a href="/branches">branches</a></li>
2763 </ul>
2765 </ul>
2764 <ul>
2766 <ul>
2765 <li class="active"><a href="/help">help</a></li>
2767 <li class="active"><a href="/help">help</a></li>
2766 </ul>
2768 </ul>
2767 </div>
2769 </div>
2768
2770
2769 <div class="main">
2771 <div class="main">
2770 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2772 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2771 <h3>Help: add</h3>
2773 <h3>Help: add</h3>
2772
2774
2773 <form class="search" action="/log">
2775 <form class="search" action="/log">
2774
2776
2775 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2777 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2776 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2778 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2777 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2779 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2778 </form>
2780 </form>
2779 <div id="doc">
2781 <div id="doc">
2780 <p>
2782 <p>
2781 hg add [OPTION]... [FILE]...
2783 hg add [OPTION]... [FILE]...
2782 </p>
2784 </p>
2783 <p>
2785 <p>
2784 add the specified files on the next commit
2786 add the specified files on the next commit
2785 </p>
2787 </p>
2786 <p>
2788 <p>
2787 Schedule files to be version controlled and added to the
2789 Schedule files to be version controlled and added to the
2788 repository.
2790 repository.
2789 </p>
2791 </p>
2790 <p>
2792 <p>
2791 The files will be added to the repository at the next commit. To
2793 The files will be added to the repository at the next commit. To
2792 undo an add before that, see 'hg forget'.
2794 undo an add before that, see 'hg forget'.
2793 </p>
2795 </p>
2794 <p>
2796 <p>
2795 If no names are given, add all files to the repository (except
2797 If no names are given, add all files to the repository (except
2796 files matching &quot;.hgignore&quot;).
2798 files matching &quot;.hgignore&quot;).
2797 </p>
2799 </p>
2798 <p>
2800 <p>
2799 Examples:
2801 Examples:
2800 </p>
2802 </p>
2801 <ul>
2803 <ul>
2802 <li> New (unknown) files are added automatically by 'hg add':
2804 <li> New (unknown) files are added automatically by 'hg add':
2803 <pre>
2805 <pre>
2804 \$ ls (re)
2806 \$ ls (re)
2805 foo.c
2807 foo.c
2806 \$ hg status (re)
2808 \$ hg status (re)
2807 ? foo.c
2809 ? foo.c
2808 \$ hg add (re)
2810 \$ hg add (re)
2809 adding foo.c
2811 adding foo.c
2810 \$ hg status (re)
2812 \$ hg status (re)
2811 A foo.c
2813 A foo.c
2812 </pre>
2814 </pre>
2813 <li> Specific files to be added can be specified:
2815 <li> Specific files to be added can be specified:
2814 <pre>
2816 <pre>
2815 \$ ls (re)
2817 \$ ls (re)
2816 bar.c foo.c
2818 bar.c foo.c
2817 \$ hg status (re)
2819 \$ hg status (re)
2818 ? bar.c
2820 ? bar.c
2819 ? foo.c
2821 ? foo.c
2820 \$ hg add bar.c (re)
2822 \$ hg add bar.c (re)
2821 \$ hg status (re)
2823 \$ hg status (re)
2822 A bar.c
2824 A bar.c
2823 ? foo.c
2825 ? foo.c
2824 </pre>
2826 </pre>
2825 </ul>
2827 </ul>
2826 <p>
2828 <p>
2827 Returns 0 if all files are successfully added.
2829 Returns 0 if all files are successfully added.
2828 </p>
2830 </p>
2829 <p>
2831 <p>
2830 options ([+] can be repeated):
2832 options ([+] can be repeated):
2831 </p>
2833 </p>
2832 <table>
2834 <table>
2833 <tr><td>-I</td>
2835 <tr><td>-I</td>
2834 <td>--include PATTERN [+]</td>
2836 <td>--include PATTERN [+]</td>
2835 <td>include names matching the given patterns</td></tr>
2837 <td>include names matching the given patterns</td></tr>
2836 <tr><td>-X</td>
2838 <tr><td>-X</td>
2837 <td>--exclude PATTERN [+]</td>
2839 <td>--exclude PATTERN [+]</td>
2838 <td>exclude names matching the given patterns</td></tr>
2840 <td>exclude names matching the given patterns</td></tr>
2839 <tr><td>-S</td>
2841 <tr><td>-S</td>
2840 <td>--subrepos</td>
2842 <td>--subrepos</td>
2841 <td>recurse into subrepositories</td></tr>
2843 <td>recurse into subrepositories</td></tr>
2842 <tr><td>-n</td>
2844 <tr><td>-n</td>
2843 <td>--dry-run</td>
2845 <td>--dry-run</td>
2844 <td>do not perform actions, just print output</td></tr>
2846 <td>do not perform actions, just print output</td></tr>
2845 </table>
2847 </table>
2846 <p>
2848 <p>
2847 global options ([+] can be repeated):
2849 global options ([+] can be repeated):
2848 </p>
2850 </p>
2849 <table>
2851 <table>
2850 <tr><td>-R</td>
2852 <tr><td>-R</td>
2851 <td>--repository REPO</td>
2853 <td>--repository REPO</td>
2852 <td>repository root directory or name of overlay bundle file</td></tr>
2854 <td>repository root directory or name of overlay bundle file</td></tr>
2853 <tr><td></td>
2855 <tr><td></td>
2854 <td>--cwd DIR</td>
2856 <td>--cwd DIR</td>
2855 <td>change working directory</td></tr>
2857 <td>change working directory</td></tr>
2856 <tr><td>-y</td>
2858 <tr><td>-y</td>
2857 <td>--noninteractive</td>
2859 <td>--noninteractive</td>
2858 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2860 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2859 <tr><td>-q</td>
2861 <tr><td>-q</td>
2860 <td>--quiet</td>
2862 <td>--quiet</td>
2861 <td>suppress output</td></tr>
2863 <td>suppress output</td></tr>
2862 <tr><td>-v</td>
2864 <tr><td>-v</td>
2863 <td>--verbose</td>
2865 <td>--verbose</td>
2864 <td>enable additional output</td></tr>
2866 <td>enable additional output</td></tr>
2865 <tr><td></td>
2867 <tr><td></td>
2866 <td>--color TYPE</td>
2868 <td>--color TYPE</td>
2867 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2869 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2868 <tr><td></td>
2870 <tr><td></td>
2869 <td>--config CONFIG [+]</td>
2871 <td>--config CONFIG [+]</td>
2870 <td>set/override config option (use 'section.name=value')</td></tr>
2872 <td>set/override config option (use 'section.name=value')</td></tr>
2871 <tr><td></td>
2873 <tr><td></td>
2872 <td>--debug</td>
2874 <td>--debug</td>
2873 <td>enable debugging output</td></tr>
2875 <td>enable debugging output</td></tr>
2874 <tr><td></td>
2876 <tr><td></td>
2875 <td>--debugger</td>
2877 <td>--debugger</td>
2876 <td>start debugger</td></tr>
2878 <td>start debugger</td></tr>
2877 <tr><td></td>
2879 <tr><td></td>
2878 <td>--encoding ENCODE</td>
2880 <td>--encoding ENCODE</td>
2879 <td>set the charset encoding (default: ascii)</td></tr>
2881 <td>set the charset encoding (default: ascii)</td></tr>
2880 <tr><td></td>
2882 <tr><td></td>
2881 <td>--encodingmode MODE</td>
2883 <td>--encodingmode MODE</td>
2882 <td>set the charset encoding mode (default: strict)</td></tr>
2884 <td>set the charset encoding mode (default: strict)</td></tr>
2883 <tr><td></td>
2885 <tr><td></td>
2884 <td>--traceback</td>
2886 <td>--traceback</td>
2885 <td>always print a traceback on exception</td></tr>
2887 <td>always print a traceback on exception</td></tr>
2886 <tr><td></td>
2888 <tr><td></td>
2887 <td>--time</td>
2889 <td>--time</td>
2888 <td>time how long the command takes</td></tr>
2890 <td>time how long the command takes</td></tr>
2889 <tr><td></td>
2891 <tr><td></td>
2890 <td>--profile</td>
2892 <td>--profile</td>
2891 <td>print command execution profile</td></tr>
2893 <td>print command execution profile</td></tr>
2892 <tr><td></td>
2894 <tr><td></td>
2893 <td>--version</td>
2895 <td>--version</td>
2894 <td>output version information and exit</td></tr>
2896 <td>output version information and exit</td></tr>
2895 <tr><td>-h</td>
2897 <tr><td>-h</td>
2896 <td>--help</td>
2898 <td>--help</td>
2897 <td>display help and exit</td></tr>
2899 <td>display help and exit</td></tr>
2898 <tr><td></td>
2900 <tr><td></td>
2899 <td>--hidden</td>
2901 <td>--hidden</td>
2900 <td>consider hidden changesets</td></tr>
2902 <td>consider hidden changesets</td></tr>
2901 <tr><td></td>
2903 <tr><td></td>
2902 <td>--pager TYPE</td>
2904 <td>--pager TYPE</td>
2903 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2905 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2904 </table>
2906 </table>
2905
2907
2906 </div>
2908 </div>
2907 </div>
2909 </div>
2908 </div>
2910 </div>
2909
2911
2910
2912
2911
2913
2912 </body>
2914 </body>
2913 </html>
2915 </html>
2914
2916
2915
2917
2916 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2918 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2917 200 Script output follows
2919 200 Script output follows
2918
2920
2919 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2921 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2920 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2922 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2921 <head>
2923 <head>
2922 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2924 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2923 <meta name="robots" content="index, nofollow" />
2925 <meta name="robots" content="index, nofollow" />
2924 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2926 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2925 <script type="text/javascript" src="/static/mercurial.js"></script>
2927 <script type="text/javascript" src="/static/mercurial.js"></script>
2926
2928
2927 <title>Help: remove</title>
2929 <title>Help: remove</title>
2928 </head>
2930 </head>
2929 <body>
2931 <body>
2930
2932
2931 <div class="container">
2933 <div class="container">
2932 <div class="menu">
2934 <div class="menu">
2933 <div class="logo">
2935 <div class="logo">
2934 <a href="https://mercurial-scm.org/">
2936 <a href="https://mercurial-scm.org/">
2935 <img src="/static/hglogo.png" alt="mercurial" /></a>
2937 <img src="/static/hglogo.png" alt="mercurial" /></a>
2936 </div>
2938 </div>
2937 <ul>
2939 <ul>
2938 <li><a href="/shortlog">log</a></li>
2940 <li><a href="/shortlog">log</a></li>
2939 <li><a href="/graph">graph</a></li>
2941 <li><a href="/graph">graph</a></li>
2940 <li><a href="/tags">tags</a></li>
2942 <li><a href="/tags">tags</a></li>
2941 <li><a href="/bookmarks">bookmarks</a></li>
2943 <li><a href="/bookmarks">bookmarks</a></li>
2942 <li><a href="/branches">branches</a></li>
2944 <li><a href="/branches">branches</a></li>
2943 </ul>
2945 </ul>
2944 <ul>
2946 <ul>
2945 <li class="active"><a href="/help">help</a></li>
2947 <li class="active"><a href="/help">help</a></li>
2946 </ul>
2948 </ul>
2947 </div>
2949 </div>
2948
2950
2949 <div class="main">
2951 <div class="main">
2950 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2952 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2951 <h3>Help: remove</h3>
2953 <h3>Help: remove</h3>
2952
2954
2953 <form class="search" action="/log">
2955 <form class="search" action="/log">
2954
2956
2955 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2957 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2956 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2958 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2957 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2959 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2958 </form>
2960 </form>
2959 <div id="doc">
2961 <div id="doc">
2960 <p>
2962 <p>
2961 hg remove [OPTION]... FILE...
2963 hg remove [OPTION]... FILE...
2962 </p>
2964 </p>
2963 <p>
2965 <p>
2964 aliases: rm
2966 aliases: rm
2965 </p>
2967 </p>
2966 <p>
2968 <p>
2967 remove the specified files on the next commit
2969 remove the specified files on the next commit
2968 </p>
2970 </p>
2969 <p>
2971 <p>
2970 Schedule the indicated files for removal from the current branch.
2972 Schedule the indicated files for removal from the current branch.
2971 </p>
2973 </p>
2972 <p>
2974 <p>
2973 This command schedules the files to be removed at the next commit.
2975 This command schedules the files to be removed at the next commit.
2974 To undo a remove before that, see 'hg revert'. To undo added
2976 To undo a remove before that, see 'hg revert'. To undo added
2975 files, see 'hg forget'.
2977 files, see 'hg forget'.
2976 </p>
2978 </p>
2977 <p>
2979 <p>
2978 -A/--after can be used to remove only files that have already
2980 -A/--after can be used to remove only files that have already
2979 been deleted, -f/--force can be used to force deletion, and -Af
2981 been deleted, -f/--force can be used to force deletion, and -Af
2980 can be used to remove files from the next revision without
2982 can be used to remove files from the next revision without
2981 deleting them from the working directory.
2983 deleting them from the working directory.
2982 </p>
2984 </p>
2983 <p>
2985 <p>
2984 The following table details the behavior of remove for different
2986 The following table details the behavior of remove for different
2985 file states (columns) and option combinations (rows). The file
2987 file states (columns) and option combinations (rows). The file
2986 states are Added [A], Clean [C], Modified [M] and Missing [!]
2988 states are Added [A], Clean [C], Modified [M] and Missing [!]
2987 (as reported by 'hg status'). The actions are Warn, Remove
2989 (as reported by 'hg status'). The actions are Warn, Remove
2988 (from branch) and Delete (from disk):
2990 (from branch) and Delete (from disk):
2989 </p>
2991 </p>
2990 <table>
2992 <table>
2991 <tr><td>opt/state</td>
2993 <tr><td>opt/state</td>
2992 <td>A</td>
2994 <td>A</td>
2993 <td>C</td>
2995 <td>C</td>
2994 <td>M</td>
2996 <td>M</td>
2995 <td>!</td></tr>
2997 <td>!</td></tr>
2996 <tr><td>none</td>
2998 <tr><td>none</td>
2997 <td>W</td>
2999 <td>W</td>
2998 <td>RD</td>
3000 <td>RD</td>
2999 <td>W</td>
3001 <td>W</td>
3000 <td>R</td></tr>
3002 <td>R</td></tr>
3001 <tr><td>-f</td>
3003 <tr><td>-f</td>
3002 <td>R</td>
3004 <td>R</td>
3003 <td>RD</td>
3005 <td>RD</td>
3004 <td>RD</td>
3006 <td>RD</td>
3005 <td>R</td></tr>
3007 <td>R</td></tr>
3006 <tr><td>-A</td>
3008 <tr><td>-A</td>
3007 <td>W</td>
3009 <td>W</td>
3008 <td>W</td>
3010 <td>W</td>
3009 <td>W</td>
3011 <td>W</td>
3010 <td>R</td></tr>
3012 <td>R</td></tr>
3011 <tr><td>-Af</td>
3013 <tr><td>-Af</td>
3012 <td>R</td>
3014 <td>R</td>
3013 <td>R</td>
3015 <td>R</td>
3014 <td>R</td>
3016 <td>R</td>
3015 <td>R</td></tr>
3017 <td>R</td></tr>
3016 </table>
3018 </table>
3017 <p>
3019 <p>
3018 <b>Note:</b>
3020 <b>Note:</b>
3019 </p>
3021 </p>
3020 <p>
3022 <p>
3021 'hg remove' never deletes files in Added [A] state from the
3023 'hg remove' never deletes files in Added [A] state from the
3022 working directory, not even if &quot;--force&quot; is specified.
3024 working directory, not even if &quot;--force&quot; is specified.
3023 </p>
3025 </p>
3024 <p>
3026 <p>
3025 Returns 0 on success, 1 if any warnings encountered.
3027 Returns 0 on success, 1 if any warnings encountered.
3026 </p>
3028 </p>
3027 <p>
3029 <p>
3028 options ([+] can be repeated):
3030 options ([+] can be repeated):
3029 </p>
3031 </p>
3030 <table>
3032 <table>
3031 <tr><td>-A</td>
3033 <tr><td>-A</td>
3032 <td>--after</td>
3034 <td>--after</td>
3033 <td>record delete for missing files</td></tr>
3035 <td>record delete for missing files</td></tr>
3034 <tr><td>-f</td>
3036 <tr><td>-f</td>
3035 <td>--force</td>
3037 <td>--force</td>
3036 <td>forget added files, delete modified files</td></tr>
3038 <td>forget added files, delete modified files</td></tr>
3037 <tr><td>-S</td>
3039 <tr><td>-S</td>
3038 <td>--subrepos</td>
3040 <td>--subrepos</td>
3039 <td>recurse into subrepositories</td></tr>
3041 <td>recurse into subrepositories</td></tr>
3040 <tr><td>-I</td>
3042 <tr><td>-I</td>
3041 <td>--include PATTERN [+]</td>
3043 <td>--include PATTERN [+]</td>
3042 <td>include names matching the given patterns</td></tr>
3044 <td>include names matching the given patterns</td></tr>
3043 <tr><td>-X</td>
3045 <tr><td>-X</td>
3044 <td>--exclude PATTERN [+]</td>
3046 <td>--exclude PATTERN [+]</td>
3045 <td>exclude names matching the given patterns</td></tr>
3047 <td>exclude names matching the given patterns</td></tr>
3046 <tr><td>-n</td>
3048 <tr><td>-n</td>
3047 <td>--dry-run</td>
3049 <td>--dry-run</td>
3048 <td>do not perform actions, just print output</td></tr>
3050 <td>do not perform actions, just print output</td></tr>
3049 </table>
3051 </table>
3050 <p>
3052 <p>
3051 global options ([+] can be repeated):
3053 global options ([+] can be repeated):
3052 </p>
3054 </p>
3053 <table>
3055 <table>
3054 <tr><td>-R</td>
3056 <tr><td>-R</td>
3055 <td>--repository REPO</td>
3057 <td>--repository REPO</td>
3056 <td>repository root directory or name of overlay bundle file</td></tr>
3058 <td>repository root directory or name of overlay bundle file</td></tr>
3057 <tr><td></td>
3059 <tr><td></td>
3058 <td>--cwd DIR</td>
3060 <td>--cwd DIR</td>
3059 <td>change working directory</td></tr>
3061 <td>change working directory</td></tr>
3060 <tr><td>-y</td>
3062 <tr><td>-y</td>
3061 <td>--noninteractive</td>
3063 <td>--noninteractive</td>
3062 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3064 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3063 <tr><td>-q</td>
3065 <tr><td>-q</td>
3064 <td>--quiet</td>
3066 <td>--quiet</td>
3065 <td>suppress output</td></tr>
3067 <td>suppress output</td></tr>
3066 <tr><td>-v</td>
3068 <tr><td>-v</td>
3067 <td>--verbose</td>
3069 <td>--verbose</td>
3068 <td>enable additional output</td></tr>
3070 <td>enable additional output</td></tr>
3069 <tr><td></td>
3071 <tr><td></td>
3070 <td>--color TYPE</td>
3072 <td>--color TYPE</td>
3071 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3073 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3072 <tr><td></td>
3074 <tr><td></td>
3073 <td>--config CONFIG [+]</td>
3075 <td>--config CONFIG [+]</td>
3074 <td>set/override config option (use 'section.name=value')</td></tr>
3076 <td>set/override config option (use 'section.name=value')</td></tr>
3075 <tr><td></td>
3077 <tr><td></td>
3076 <td>--debug</td>
3078 <td>--debug</td>
3077 <td>enable debugging output</td></tr>
3079 <td>enable debugging output</td></tr>
3078 <tr><td></td>
3080 <tr><td></td>
3079 <td>--debugger</td>
3081 <td>--debugger</td>
3080 <td>start debugger</td></tr>
3082 <td>start debugger</td></tr>
3081 <tr><td></td>
3083 <tr><td></td>
3082 <td>--encoding ENCODE</td>
3084 <td>--encoding ENCODE</td>
3083 <td>set the charset encoding (default: ascii)</td></tr>
3085 <td>set the charset encoding (default: ascii)</td></tr>
3084 <tr><td></td>
3086 <tr><td></td>
3085 <td>--encodingmode MODE</td>
3087 <td>--encodingmode MODE</td>
3086 <td>set the charset encoding mode (default: strict)</td></tr>
3088 <td>set the charset encoding mode (default: strict)</td></tr>
3087 <tr><td></td>
3089 <tr><td></td>
3088 <td>--traceback</td>
3090 <td>--traceback</td>
3089 <td>always print a traceback on exception</td></tr>
3091 <td>always print a traceback on exception</td></tr>
3090 <tr><td></td>
3092 <tr><td></td>
3091 <td>--time</td>
3093 <td>--time</td>
3092 <td>time how long the command takes</td></tr>
3094 <td>time how long the command takes</td></tr>
3093 <tr><td></td>
3095 <tr><td></td>
3094 <td>--profile</td>
3096 <td>--profile</td>
3095 <td>print command execution profile</td></tr>
3097 <td>print command execution profile</td></tr>
3096 <tr><td></td>
3098 <tr><td></td>
3097 <td>--version</td>
3099 <td>--version</td>
3098 <td>output version information and exit</td></tr>
3100 <td>output version information and exit</td></tr>
3099 <tr><td>-h</td>
3101 <tr><td>-h</td>
3100 <td>--help</td>
3102 <td>--help</td>
3101 <td>display help and exit</td></tr>
3103 <td>display help and exit</td></tr>
3102 <tr><td></td>
3104 <tr><td></td>
3103 <td>--hidden</td>
3105 <td>--hidden</td>
3104 <td>consider hidden changesets</td></tr>
3106 <td>consider hidden changesets</td></tr>
3105 <tr><td></td>
3107 <tr><td></td>
3106 <td>--pager TYPE</td>
3108 <td>--pager TYPE</td>
3107 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3109 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3108 </table>
3110 </table>
3109
3111
3110 </div>
3112 </div>
3111 </div>
3113 </div>
3112 </div>
3114 </div>
3113
3115
3114
3116
3115
3117
3116 </body>
3118 </body>
3117 </html>
3119 </html>
3118
3120
3119
3121
3120 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3122 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3121 200 Script output follows
3123 200 Script output follows
3122
3124
3123 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3125 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3124 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3126 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3125 <head>
3127 <head>
3126 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3128 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3127 <meta name="robots" content="index, nofollow" />
3129 <meta name="robots" content="index, nofollow" />
3128 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3130 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3129 <script type="text/javascript" src="/static/mercurial.js"></script>
3131 <script type="text/javascript" src="/static/mercurial.js"></script>
3130
3132
3131 <title>Help: dates</title>
3133 <title>Help: dates</title>
3132 </head>
3134 </head>
3133 <body>
3135 <body>
3134
3136
3135 <div class="container">
3137 <div class="container">
3136 <div class="menu">
3138 <div class="menu">
3137 <div class="logo">
3139 <div class="logo">
3138 <a href="https://mercurial-scm.org/">
3140 <a href="https://mercurial-scm.org/">
3139 <img src="/static/hglogo.png" alt="mercurial" /></a>
3141 <img src="/static/hglogo.png" alt="mercurial" /></a>
3140 </div>
3142 </div>
3141 <ul>
3143 <ul>
3142 <li><a href="/shortlog">log</a></li>
3144 <li><a href="/shortlog">log</a></li>
3143 <li><a href="/graph">graph</a></li>
3145 <li><a href="/graph">graph</a></li>
3144 <li><a href="/tags">tags</a></li>
3146 <li><a href="/tags">tags</a></li>
3145 <li><a href="/bookmarks">bookmarks</a></li>
3147 <li><a href="/bookmarks">bookmarks</a></li>
3146 <li><a href="/branches">branches</a></li>
3148 <li><a href="/branches">branches</a></li>
3147 </ul>
3149 </ul>
3148 <ul>
3150 <ul>
3149 <li class="active"><a href="/help">help</a></li>
3151 <li class="active"><a href="/help">help</a></li>
3150 </ul>
3152 </ul>
3151 </div>
3153 </div>
3152
3154
3153 <div class="main">
3155 <div class="main">
3154 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3156 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3155 <h3>Help: dates</h3>
3157 <h3>Help: dates</h3>
3156
3158
3157 <form class="search" action="/log">
3159 <form class="search" action="/log">
3158
3160
3159 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3161 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3160 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3162 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3161 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3163 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3162 </form>
3164 </form>
3163 <div id="doc">
3165 <div id="doc">
3164 <h1>Date Formats</h1>
3166 <h1>Date Formats</h1>
3165 <p>
3167 <p>
3166 Some commands allow the user to specify a date, e.g.:
3168 Some commands allow the user to specify a date, e.g.:
3167 </p>
3169 </p>
3168 <ul>
3170 <ul>
3169 <li> backout, commit, import, tag: Specify the commit date.
3171 <li> backout, commit, import, tag: Specify the commit date.
3170 <li> log, revert, update: Select revision(s) by date.
3172 <li> log, revert, update: Select revision(s) by date.
3171 </ul>
3173 </ul>
3172 <p>
3174 <p>
3173 Many date formats are valid. Here are some examples:
3175 Many date formats are valid. Here are some examples:
3174 </p>
3176 </p>
3175 <ul>
3177 <ul>
3176 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3178 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3177 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3179 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3178 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3180 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3179 <li> &quot;Dec 6&quot; (midnight)
3181 <li> &quot;Dec 6&quot; (midnight)
3180 <li> &quot;13:18&quot; (today assumed)
3182 <li> &quot;13:18&quot; (today assumed)
3181 <li> &quot;3:39&quot; (3:39AM assumed)
3183 <li> &quot;3:39&quot; (3:39AM assumed)
3182 <li> &quot;3:39pm&quot; (15:39)
3184 <li> &quot;3:39pm&quot; (15:39)
3183 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3185 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3184 <li> &quot;2006-12-6 13:18&quot;
3186 <li> &quot;2006-12-6 13:18&quot;
3185 <li> &quot;2006-12-6&quot;
3187 <li> &quot;2006-12-6&quot;
3186 <li> &quot;12-6&quot;
3188 <li> &quot;12-6&quot;
3187 <li> &quot;12/6&quot;
3189 <li> &quot;12/6&quot;
3188 <li> &quot;12/6/6&quot; (Dec 6 2006)
3190 <li> &quot;12/6/6&quot; (Dec 6 2006)
3189 <li> &quot;today&quot; (midnight)
3191 <li> &quot;today&quot; (midnight)
3190 <li> &quot;yesterday&quot; (midnight)
3192 <li> &quot;yesterday&quot; (midnight)
3191 <li> &quot;now&quot; - right now
3193 <li> &quot;now&quot; - right now
3192 </ul>
3194 </ul>
3193 <p>
3195 <p>
3194 Lastly, there is Mercurial's internal format:
3196 Lastly, there is Mercurial's internal format:
3195 </p>
3197 </p>
3196 <ul>
3198 <ul>
3197 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3199 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3198 </ul>
3200 </ul>
3199 <p>
3201 <p>
3200 This is the internal representation format for dates. The first number
3202 This is the internal representation format for dates. The first number
3201 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3203 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3202 second is the offset of the local timezone, in seconds west of UTC
3204 second is the offset of the local timezone, in seconds west of UTC
3203 (negative if the timezone is east of UTC).
3205 (negative if the timezone is east of UTC).
3204 </p>
3206 </p>
3205 <p>
3207 <p>
3206 The log command also accepts date ranges:
3208 The log command also accepts date ranges:
3207 </p>
3209 </p>
3208 <ul>
3210 <ul>
3209 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3211 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3210 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3212 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3211 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3213 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3212 <li> &quot;-DAYS&quot; - within a given number of days of today
3214 <li> &quot;-DAYS&quot; - within a given number of days of today
3213 </ul>
3215 </ul>
3214
3216
3215 </div>
3217 </div>
3216 </div>
3218 </div>
3217 </div>
3219 </div>
3218
3220
3219
3221
3220
3222
3221 </body>
3223 </body>
3222 </html>
3224 </html>
3223
3225
3224
3226
3225 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3227 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3226 200 Script output follows
3228 200 Script output follows
3227
3229
3228 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3230 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3229 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3231 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3230 <head>
3232 <head>
3231 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3233 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3232 <meta name="robots" content="index, nofollow" />
3234 <meta name="robots" content="index, nofollow" />
3233 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3235 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3234 <script type="text/javascript" src="/static/mercurial.js"></script>
3236 <script type="text/javascript" src="/static/mercurial.js"></script>
3235
3237
3236 <title>Help: pager</title>
3238 <title>Help: pager</title>
3237 </head>
3239 </head>
3238 <body>
3240 <body>
3239
3241
3240 <div class="container">
3242 <div class="container">
3241 <div class="menu">
3243 <div class="menu">
3242 <div class="logo">
3244 <div class="logo">
3243 <a href="https://mercurial-scm.org/">
3245 <a href="https://mercurial-scm.org/">
3244 <img src="/static/hglogo.png" alt="mercurial" /></a>
3246 <img src="/static/hglogo.png" alt="mercurial" /></a>
3245 </div>
3247 </div>
3246 <ul>
3248 <ul>
3247 <li><a href="/shortlog">log</a></li>
3249 <li><a href="/shortlog">log</a></li>
3248 <li><a href="/graph">graph</a></li>
3250 <li><a href="/graph">graph</a></li>
3249 <li><a href="/tags">tags</a></li>
3251 <li><a href="/tags">tags</a></li>
3250 <li><a href="/bookmarks">bookmarks</a></li>
3252 <li><a href="/bookmarks">bookmarks</a></li>
3251 <li><a href="/branches">branches</a></li>
3253 <li><a href="/branches">branches</a></li>
3252 </ul>
3254 </ul>
3253 <ul>
3255 <ul>
3254 <li class="active"><a href="/help">help</a></li>
3256 <li class="active"><a href="/help">help</a></li>
3255 </ul>
3257 </ul>
3256 </div>
3258 </div>
3257
3259
3258 <div class="main">
3260 <div class="main">
3259 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3261 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3260 <h3>Help: pager</h3>
3262 <h3>Help: pager</h3>
3261
3263
3262 <form class="search" action="/log">
3264 <form class="search" action="/log">
3263
3265
3264 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3266 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3265 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3267 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3266 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3268 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3267 </form>
3269 </form>
3268 <div id="doc">
3270 <div id="doc">
3269 <h1>Pager Support</h1>
3271 <h1>Pager Support</h1>
3270 <p>
3272 <p>
3271 Some Mercurial commands can produce a lot of output, and Mercurial will
3273 Some Mercurial commands can produce a lot of output, and Mercurial will
3272 attempt to use a pager to make those commands more pleasant.
3274 attempt to use a pager to make those commands more pleasant.
3273 </p>
3275 </p>
3274 <p>
3276 <p>
3275 To set the pager that should be used, set the application variable:
3277 To set the pager that should be used, set the application variable:
3276 </p>
3278 </p>
3277 <pre>
3279 <pre>
3278 [pager]
3280 [pager]
3279 pager = less -FRX
3281 pager = less -FRX
3280 </pre>
3282 </pre>
3281 <p>
3283 <p>
3282 If no pager is set in the user or repository configuration, Mercurial uses the
3284 If no pager is set in the user or repository configuration, Mercurial uses the
3283 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3285 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3284 or system configuration is used. If none of these are set, a default pager will
3286 or system configuration is used. If none of these are set, a default pager will
3285 be used, typically 'less' on Unix and 'more' on Windows.
3287 be used, typically 'less' on Unix and 'more' on Windows.
3286 </p>
3288 </p>
3287 <p>
3289 <p>
3288 You can disable the pager for certain commands by adding them to the
3290 You can disable the pager for certain commands by adding them to the
3289 pager.ignore list:
3291 pager.ignore list:
3290 </p>
3292 </p>
3291 <pre>
3293 <pre>
3292 [pager]
3294 [pager]
3293 ignore = version, help, update
3295 ignore = version, help, update
3294 </pre>
3296 </pre>
3295 <p>
3297 <p>
3296 To ignore global commands like 'hg version' or 'hg help', you have
3298 To ignore global commands like 'hg version' or 'hg help', you have
3297 to specify them in your user configuration file.
3299 to specify them in your user configuration file.
3298 </p>
3300 </p>
3299 <p>
3301 <p>
3300 To control whether the pager is used at all for an individual command,
3302 To control whether the pager is used at all for an individual command,
3301 you can use --pager=&lt;value&gt;:
3303 you can use --pager=&lt;value&gt;:
3302 </p>
3304 </p>
3303 <ul>
3305 <ul>
3304 <li> use as needed: 'auto'.
3306 <li> use as needed: 'auto'.
3305 <li> require the pager: 'yes' or 'on'.
3307 <li> require the pager: 'yes' or 'on'.
3306 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3308 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3307 </ul>
3309 </ul>
3308 <p>
3310 <p>
3309 To globally turn off all attempts to use a pager, set:
3311 To globally turn off all attempts to use a pager, set:
3310 </p>
3312 </p>
3311 <pre>
3313 <pre>
3312 [ui]
3314 [ui]
3313 paginate = never
3315 paginate = never
3314 </pre>
3316 </pre>
3315 <p>
3317 <p>
3316 which will prevent the pager from running.
3318 which will prevent the pager from running.
3317 </p>
3319 </p>
3318
3320
3319 </div>
3321 </div>
3320 </div>
3322 </div>
3321 </div>
3323 </div>
3322
3324
3323
3325
3324
3326
3325 </body>
3327 </body>
3326 </html>
3328 </html>
3327
3329
3328
3330
3329 Sub-topic indexes rendered properly
3331 Sub-topic indexes rendered properly
3330
3332
3331 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3333 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3332 200 Script output follows
3334 200 Script output follows
3333
3335
3334 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3336 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3335 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3337 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3336 <head>
3338 <head>
3337 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3339 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3338 <meta name="robots" content="index, nofollow" />
3340 <meta name="robots" content="index, nofollow" />
3339 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3341 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3340 <script type="text/javascript" src="/static/mercurial.js"></script>
3342 <script type="text/javascript" src="/static/mercurial.js"></script>
3341
3343
3342 <title>Help: internals</title>
3344 <title>Help: internals</title>
3343 </head>
3345 </head>
3344 <body>
3346 <body>
3345
3347
3346 <div class="container">
3348 <div class="container">
3347 <div class="menu">
3349 <div class="menu">
3348 <div class="logo">
3350 <div class="logo">
3349 <a href="https://mercurial-scm.org/">
3351 <a href="https://mercurial-scm.org/">
3350 <img src="/static/hglogo.png" alt="mercurial" /></a>
3352 <img src="/static/hglogo.png" alt="mercurial" /></a>
3351 </div>
3353 </div>
3352 <ul>
3354 <ul>
3353 <li><a href="/shortlog">log</a></li>
3355 <li><a href="/shortlog">log</a></li>
3354 <li><a href="/graph">graph</a></li>
3356 <li><a href="/graph">graph</a></li>
3355 <li><a href="/tags">tags</a></li>
3357 <li><a href="/tags">tags</a></li>
3356 <li><a href="/bookmarks">bookmarks</a></li>
3358 <li><a href="/bookmarks">bookmarks</a></li>
3357 <li><a href="/branches">branches</a></li>
3359 <li><a href="/branches">branches</a></li>
3358 </ul>
3360 </ul>
3359 <ul>
3361 <ul>
3360 <li><a href="/help">help</a></li>
3362 <li><a href="/help">help</a></li>
3361 </ul>
3363 </ul>
3362 </div>
3364 </div>
3363
3365
3364 <div class="main">
3366 <div class="main">
3365 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3367 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3366
3368
3367 <form class="search" action="/log">
3369 <form class="search" action="/log">
3368
3370
3369 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3371 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3370 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3372 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3371 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3373 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3372 </form>
3374 </form>
3373 <table class="bigtable">
3375 <table class="bigtable">
3374 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3376 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3375
3377
3376 <tr><td>
3378 <tr><td>
3377 <a href="/help/internals.bundle2">
3379 <a href="/help/internals.bundle2">
3378 bundle2
3380 bundle2
3379 </a>
3381 </a>
3380 </td><td>
3382 </td><td>
3381 Bundle2
3383 Bundle2
3382 </td></tr>
3384 </td></tr>
3383 <tr><td>
3385 <tr><td>
3384 <a href="/help/internals.bundles">
3386 <a href="/help/internals.bundles">
3385 bundles
3387 bundles
3386 </a>
3388 </a>
3387 </td><td>
3389 </td><td>
3388 Bundles
3390 Bundles
3389 </td></tr>
3391 </td></tr>
3390 <tr><td>
3392 <tr><td>
3391 <a href="/help/internals.cbor">
3393 <a href="/help/internals.cbor">
3392 cbor
3394 cbor
3393 </a>
3395 </a>
3394 </td><td>
3396 </td><td>
3395 CBOR
3397 CBOR
3396 </td></tr>
3398 </td></tr>
3397 <tr><td>
3399 <tr><td>
3398 <a href="/help/internals.censor">
3400 <a href="/help/internals.censor">
3399 censor
3401 censor
3400 </a>
3402 </a>
3401 </td><td>
3403 </td><td>
3402 Censor
3404 Censor
3403 </td></tr>
3405 </td></tr>
3404 <tr><td>
3406 <tr><td>
3405 <a href="/help/internals.changegroups">
3407 <a href="/help/internals.changegroups">
3406 changegroups
3408 changegroups
3407 </a>
3409 </a>
3408 </td><td>
3410 </td><td>
3409 Changegroups
3411 Changegroups
3410 </td></tr>
3412 </td></tr>
3411 <tr><td>
3413 <tr><td>
3412 <a href="/help/internals.config">
3414 <a href="/help/internals.config">
3413 config
3415 config
3414 </a>
3416 </a>
3415 </td><td>
3417 </td><td>
3416 Config Registrar
3418 Config Registrar
3417 </td></tr>
3419 </td></tr>
3418 <tr><td>
3420 <tr><td>
3419 <a href="/help/internals.extensions">
3421 <a href="/help/internals.extensions">
3420 extensions
3422 extensions
3421 </a>
3423 </a>
3422 </td><td>
3424 </td><td>
3423 Extension API
3425 Extension API
3424 </td></tr>
3426 </td></tr>
3425 <tr><td>
3427 <tr><td>
3426 <a href="/help/internals.requirements">
3428 <a href="/help/internals.requirements">
3427 requirements
3429 requirements
3428 </a>
3430 </a>
3429 </td><td>
3431 </td><td>
3430 Repository Requirements
3432 Repository Requirements
3431 </td></tr>
3433 </td></tr>
3432 <tr><td>
3434 <tr><td>
3433 <a href="/help/internals.revlogs">
3435 <a href="/help/internals.revlogs">
3434 revlogs
3436 revlogs
3435 </a>
3437 </a>
3436 </td><td>
3438 </td><td>
3437 Revision Logs
3439 Revision Logs
3438 </td></tr>
3440 </td></tr>
3439 <tr><td>
3441 <tr><td>
3440 <a href="/help/internals.wireprotocol">
3442 <a href="/help/internals.wireprotocol">
3441 wireprotocol
3443 wireprotocol
3442 </a>
3444 </a>
3443 </td><td>
3445 </td><td>
3444 Wire Protocol
3446 Wire Protocol
3445 </td></tr>
3447 </td></tr>
3446 <tr><td>
3448 <tr><td>
3447 <a href="/help/internals.wireprotocolrpc">
3449 <a href="/help/internals.wireprotocolrpc">
3448 wireprotocolrpc
3450 wireprotocolrpc
3449 </a>
3451 </a>
3450 </td><td>
3452 </td><td>
3451 Wire Protocol RPC
3453 Wire Protocol RPC
3452 </td></tr>
3454 </td></tr>
3453 <tr><td>
3455 <tr><td>
3454 <a href="/help/internals.wireprotocolv2">
3456 <a href="/help/internals.wireprotocolv2">
3455 wireprotocolv2
3457 wireprotocolv2
3456 </a>
3458 </a>
3457 </td><td>
3459 </td><td>
3458 Wire Protocol Version 2
3460 Wire Protocol Version 2
3459 </td></tr>
3461 </td></tr>
3460
3462
3461
3463
3462
3464
3463
3465
3464
3466
3465 </table>
3467 </table>
3466 </div>
3468 </div>
3467 </div>
3469 </div>
3468
3470
3469
3471
3470
3472
3471 </body>
3473 </body>
3472 </html>
3474 </html>
3473
3475
3474
3476
3475 Sub-topic topics rendered properly
3477 Sub-topic topics rendered properly
3476
3478
3477 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3479 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3478 200 Script output follows
3480 200 Script output follows
3479
3481
3480 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3482 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3481 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3483 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3482 <head>
3484 <head>
3483 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3485 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3484 <meta name="robots" content="index, nofollow" />
3486 <meta name="robots" content="index, nofollow" />
3485 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3487 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3486 <script type="text/javascript" src="/static/mercurial.js"></script>
3488 <script type="text/javascript" src="/static/mercurial.js"></script>
3487
3489
3488 <title>Help: internals.changegroups</title>
3490 <title>Help: internals.changegroups</title>
3489 </head>
3491 </head>
3490 <body>
3492 <body>
3491
3493
3492 <div class="container">
3494 <div class="container">
3493 <div class="menu">
3495 <div class="menu">
3494 <div class="logo">
3496 <div class="logo">
3495 <a href="https://mercurial-scm.org/">
3497 <a href="https://mercurial-scm.org/">
3496 <img src="/static/hglogo.png" alt="mercurial" /></a>
3498 <img src="/static/hglogo.png" alt="mercurial" /></a>
3497 </div>
3499 </div>
3498 <ul>
3500 <ul>
3499 <li><a href="/shortlog">log</a></li>
3501 <li><a href="/shortlog">log</a></li>
3500 <li><a href="/graph">graph</a></li>
3502 <li><a href="/graph">graph</a></li>
3501 <li><a href="/tags">tags</a></li>
3503 <li><a href="/tags">tags</a></li>
3502 <li><a href="/bookmarks">bookmarks</a></li>
3504 <li><a href="/bookmarks">bookmarks</a></li>
3503 <li><a href="/branches">branches</a></li>
3505 <li><a href="/branches">branches</a></li>
3504 </ul>
3506 </ul>
3505 <ul>
3507 <ul>
3506 <li class="active"><a href="/help">help</a></li>
3508 <li class="active"><a href="/help">help</a></li>
3507 </ul>
3509 </ul>
3508 </div>
3510 </div>
3509
3511
3510 <div class="main">
3512 <div class="main">
3511 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3513 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3512 <h3>Help: internals.changegroups</h3>
3514 <h3>Help: internals.changegroups</h3>
3513
3515
3514 <form class="search" action="/log">
3516 <form class="search" action="/log">
3515
3517
3516 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3518 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3517 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3519 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3518 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3520 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3519 </form>
3521 </form>
3520 <div id="doc">
3522 <div id="doc">
3521 <h1>Changegroups</h1>
3523 <h1>Changegroups</h1>
3522 <p>
3524 <p>
3523 Changegroups are representations of repository revlog data, specifically
3525 Changegroups are representations of repository revlog data, specifically
3524 the changelog data, root/flat manifest data, treemanifest data, and
3526 the changelog data, root/flat manifest data, treemanifest data, and
3525 filelogs.
3527 filelogs.
3526 </p>
3528 </p>
3527 <p>
3529 <p>
3528 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3530 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3529 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3531 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3530 only difference being an additional item in the *delta header*. Version
3532 only difference being an additional item in the *delta header*. Version
3531 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3533 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3532 exchanging treemanifests (enabled by setting an option on the
3534 exchanging treemanifests (enabled by setting an option on the
3533 &quot;changegroup&quot; part in the bundle2).
3535 &quot;changegroup&quot; part in the bundle2).
3534 </p>
3536 </p>
3535 <p>
3537 <p>
3536 Changegroups when not exchanging treemanifests consist of 3 logical
3538 Changegroups when not exchanging treemanifests consist of 3 logical
3537 segments:
3539 segments:
3538 </p>
3540 </p>
3539 <pre>
3541 <pre>
3540 +---------------------------------+
3542 +---------------------------------+
3541 | | | |
3543 | | | |
3542 | changeset | manifest | filelogs |
3544 | changeset | manifest | filelogs |
3543 | | | |
3545 | | | |
3544 | | | |
3546 | | | |
3545 +---------------------------------+
3547 +---------------------------------+
3546 </pre>
3548 </pre>
3547 <p>
3549 <p>
3548 When exchanging treemanifests, there are 4 logical segments:
3550 When exchanging treemanifests, there are 4 logical segments:
3549 </p>
3551 </p>
3550 <pre>
3552 <pre>
3551 +-------------------------------------------------+
3553 +-------------------------------------------------+
3552 | | | | |
3554 | | | | |
3553 | changeset | root | treemanifests | filelogs |
3555 | changeset | root | treemanifests | filelogs |
3554 | | manifest | | |
3556 | | manifest | | |
3555 | | | | |
3557 | | | | |
3556 +-------------------------------------------------+
3558 +-------------------------------------------------+
3557 </pre>
3559 </pre>
3558 <p>
3560 <p>
3559 The principle building block of each segment is a *chunk*. A *chunk*
3561 The principle building block of each segment is a *chunk*. A *chunk*
3560 is a framed piece of data:
3562 is a framed piece of data:
3561 </p>
3563 </p>
3562 <pre>
3564 <pre>
3563 +---------------------------------------+
3565 +---------------------------------------+
3564 | | |
3566 | | |
3565 | length | data |
3567 | length | data |
3566 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3568 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3567 | | |
3569 | | |
3568 +---------------------------------------+
3570 +---------------------------------------+
3569 </pre>
3571 </pre>
3570 <p>
3572 <p>
3571 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3573 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3572 integer indicating the length of the entire chunk (including the length field
3574 integer indicating the length of the entire chunk (including the length field
3573 itself).
3575 itself).
3574 </p>
3576 </p>
3575 <p>
3577 <p>
3576 There is a special case chunk that has a value of 0 for the length
3578 There is a special case chunk that has a value of 0 for the length
3577 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3579 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3578 </p>
3580 </p>
3579 <h2>Delta Groups</h2>
3581 <h2>Delta Groups</h2>
3580 <p>
3582 <p>
3581 A *delta group* expresses the content of a revlog as a series of deltas,
3583 A *delta group* expresses the content of a revlog as a series of deltas,
3582 or patches against previous revisions.
3584 or patches against previous revisions.
3583 </p>
3585 </p>
3584 <p>
3586 <p>
3585 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3587 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3586 to signal the end of the delta group:
3588 to signal the end of the delta group:
3587 </p>
3589 </p>
3588 <pre>
3590 <pre>
3589 +------------------------------------------------------------------------+
3591 +------------------------------------------------------------------------+
3590 | | | | | |
3592 | | | | | |
3591 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3593 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3592 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3594 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3593 | | | | | |
3595 | | | | | |
3594 +------------------------------------------------------------------------+
3596 +------------------------------------------------------------------------+
3595 </pre>
3597 </pre>
3596 <p>
3598 <p>
3597 Each *chunk*'s data consists of the following:
3599 Each *chunk*'s data consists of the following:
3598 </p>
3600 </p>
3599 <pre>
3601 <pre>
3600 +---------------------------------------+
3602 +---------------------------------------+
3601 | | |
3603 | | |
3602 | delta header | delta data |
3604 | delta header | delta data |
3603 | (various by version) | (various) |
3605 | (various by version) | (various) |
3604 | | |
3606 | | |
3605 +---------------------------------------+
3607 +---------------------------------------+
3606 </pre>
3608 </pre>
3607 <p>
3609 <p>
3608 The *delta data* is a series of *delta*s that describe a diff from an existing
3610 The *delta data* is a series of *delta*s that describe a diff from an existing
3609 entry (either that the recipient already has, or previously specified in the
3611 entry (either that the recipient already has, or previously specified in the
3610 bundle/changegroup).
3612 bundle/changegroup).
3611 </p>
3613 </p>
3612 <p>
3614 <p>
3613 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3615 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3614 &quot;3&quot; of the changegroup format.
3616 &quot;3&quot; of the changegroup format.
3615 </p>
3617 </p>
3616 <p>
3618 <p>
3617 Version 1 (headerlen=80):
3619 Version 1 (headerlen=80):
3618 </p>
3620 </p>
3619 <pre>
3621 <pre>
3620 +------------------------------------------------------+
3622 +------------------------------------------------------+
3621 | | | | |
3623 | | | | |
3622 | node | p1 node | p2 node | link node |
3624 | node | p1 node | p2 node | link node |
3623 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3625 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3624 | | | | |
3626 | | | | |
3625 +------------------------------------------------------+
3627 +------------------------------------------------------+
3626 </pre>
3628 </pre>
3627 <p>
3629 <p>
3628 Version 2 (headerlen=100):
3630 Version 2 (headerlen=100):
3629 </p>
3631 </p>
3630 <pre>
3632 <pre>
3631 +------------------------------------------------------------------+
3633 +------------------------------------------------------------------+
3632 | | | | | |
3634 | | | | | |
3633 | node | p1 node | p2 node | base node | link node |
3635 | node | p1 node | p2 node | base node | link node |
3634 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3636 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3635 | | | | | |
3637 | | | | | |
3636 +------------------------------------------------------------------+
3638 +------------------------------------------------------------------+
3637 </pre>
3639 </pre>
3638 <p>
3640 <p>
3639 Version 3 (headerlen=102):
3641 Version 3 (headerlen=102):
3640 </p>
3642 </p>
3641 <pre>
3643 <pre>
3642 +------------------------------------------------------------------------------+
3644 +------------------------------------------------------------------------------+
3643 | | | | | | |
3645 | | | | | | |
3644 | node | p1 node | p2 node | base node | link node | flags |
3646 | node | p1 node | p2 node | base node | link node | flags |
3645 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3647 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3646 | | | | | | |
3648 | | | | | | |
3647 +------------------------------------------------------------------------------+
3649 +------------------------------------------------------------------------------+
3648 </pre>
3650 </pre>
3649 <p>
3651 <p>
3650 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3652 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3651 series of *delta*s, densely packed (no separators). These deltas describe a diff
3653 series of *delta*s, densely packed (no separators). These deltas describe a diff
3652 from an existing entry (either that the recipient already has, or previously
3654 from an existing entry (either that the recipient already has, or previously
3653 specified in the bundle/changegroup). The format is described more fully in
3655 specified in the bundle/changegroup). The format is described more fully in
3654 &quot;hg help internals.bdiff&quot;, but briefly:
3656 &quot;hg help internals.bdiff&quot;, but briefly:
3655 </p>
3657 </p>
3656 <pre>
3658 <pre>
3657 +---------------------------------------------------------------+
3659 +---------------------------------------------------------------+
3658 | | | | |
3660 | | | | |
3659 | start offset | end offset | new length | content |
3661 | start offset | end offset | new length | content |
3660 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3662 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3661 | | | | |
3663 | | | | |
3662 +---------------------------------------------------------------+
3664 +---------------------------------------------------------------+
3663 </pre>
3665 </pre>
3664 <p>
3666 <p>
3665 Please note that the length field in the delta data does *not* include itself.
3667 Please note that the length field in the delta data does *not* include itself.
3666 </p>
3668 </p>
3667 <p>
3669 <p>
3668 In version 1, the delta is always applied against the previous node from
3670 In version 1, the delta is always applied against the previous node from
3669 the changegroup or the first parent if this is the first entry in the
3671 the changegroup or the first parent if this is the first entry in the
3670 changegroup.
3672 changegroup.
3671 </p>
3673 </p>
3672 <p>
3674 <p>
3673 In version 2 and up, the delta base node is encoded in the entry in the
3675 In version 2 and up, the delta base node is encoded in the entry in the
3674 changegroup. This allows the delta to be expressed against any parent,
3676 changegroup. This allows the delta to be expressed against any parent,
3675 which can result in smaller deltas and more efficient encoding of data.
3677 which can result in smaller deltas and more efficient encoding of data.
3676 </p>
3678 </p>
3677 <p>
3679 <p>
3678 The *flags* field holds bitwise flags affecting the processing of revision
3680 The *flags* field holds bitwise flags affecting the processing of revision
3679 data. The following flags are defined:
3681 data. The following flags are defined:
3680 </p>
3682 </p>
3681 <dl>
3683 <dl>
3682 <dt>32768
3684 <dt>32768
3683 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3685 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3684 <dt>16384
3686 <dt>16384
3685 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3687 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3686 <dt>8192
3688 <dt>8192
3687 <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.
3689 <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.
3688 </dl>
3690 </dl>
3689 <p>
3691 <p>
3690 For historical reasons, the integer values are identical to revlog version 1
3692 For historical reasons, the integer values are identical to revlog version 1
3691 per-revision storage flags and correspond to bits being set in this 2-byte
3693 per-revision storage flags and correspond to bits being set in this 2-byte
3692 field. Bits were allocated starting from the most-significant bit, hence the
3694 field. Bits were allocated starting from the most-significant bit, hence the
3693 reverse ordering and allocation of these flags.
3695 reverse ordering and allocation of these flags.
3694 </p>
3696 </p>
3695 <h2>Changeset Segment</h2>
3697 <h2>Changeset Segment</h2>
3696 <p>
3698 <p>
3697 The *changeset segment* consists of a single *delta group* holding
3699 The *changeset segment* consists of a single *delta group* holding
3698 changelog data. The *empty chunk* at the end of the *delta group* denotes
3700 changelog data. The *empty chunk* at the end of the *delta group* denotes
3699 the boundary to the *manifest segment*.
3701 the boundary to the *manifest segment*.
3700 </p>
3702 </p>
3701 <h2>Manifest Segment</h2>
3703 <h2>Manifest Segment</h2>
3702 <p>
3704 <p>
3703 The *manifest segment* consists of a single *delta group* holding manifest
3705 The *manifest segment* consists of a single *delta group* holding manifest
3704 data. If treemanifests are in use, it contains only the manifest for the
3706 data. If treemanifests are in use, it contains only the manifest for the
3705 root directory of the repository. Otherwise, it contains the entire
3707 root directory of the repository. Otherwise, it contains the entire
3706 manifest data. The *empty chunk* at the end of the *delta group* denotes
3708 manifest data. The *empty chunk* at the end of the *delta group* denotes
3707 the boundary to the next segment (either the *treemanifests segment* or the
3709 the boundary to the next segment (either the *treemanifests segment* or the
3708 *filelogs segment*, depending on version and the request options).
3710 *filelogs segment*, depending on version and the request options).
3709 </p>
3711 </p>
3710 <h3>Treemanifests Segment</h3>
3712 <h3>Treemanifests Segment</h3>
3711 <p>
3713 <p>
3712 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3714 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3713 only if the 'treemanifest' param is part of the bundle2 changegroup part
3715 only if the 'treemanifest' param is part of the bundle2 changegroup part
3714 (it is not possible to use changegroup version 3 outside of bundle2).
3716 (it is not possible to use changegroup version 3 outside of bundle2).
3715 Aside from the filenames in the *treemanifests segment* containing a
3717 Aside from the filenames in the *treemanifests segment* containing a
3716 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3718 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3717 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3719 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3718 a sub-segment with filename size 0). This denotes the boundary to the
3720 a sub-segment with filename size 0). This denotes the boundary to the
3719 *filelogs segment*.
3721 *filelogs segment*.
3720 </p>
3722 </p>
3721 <h2>Filelogs Segment</h2>
3723 <h2>Filelogs Segment</h2>
3722 <p>
3724 <p>
3723 The *filelogs segment* consists of multiple sub-segments, each
3725 The *filelogs segment* consists of multiple sub-segments, each
3724 corresponding to an individual file whose data is being described:
3726 corresponding to an individual file whose data is being described:
3725 </p>
3727 </p>
3726 <pre>
3728 <pre>
3727 +--------------------------------------------------+
3729 +--------------------------------------------------+
3728 | | | | | |
3730 | | | | | |
3729 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3731 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3730 | | | | | (4 bytes) |
3732 | | | | | (4 bytes) |
3731 | | | | | |
3733 | | | | | |
3732 +--------------------------------------------------+
3734 +--------------------------------------------------+
3733 </pre>
3735 </pre>
3734 <p>
3736 <p>
3735 The final filelog sub-segment is followed by an *empty chunk* (logically,
3737 The final filelog sub-segment is followed by an *empty chunk* (logically,
3736 a sub-segment with filename size 0). This denotes the end of the segment
3738 a sub-segment with filename size 0). This denotes the end of the segment
3737 and of the overall changegroup.
3739 and of the overall changegroup.
3738 </p>
3740 </p>
3739 <p>
3741 <p>
3740 Each filelog sub-segment consists of the following:
3742 Each filelog sub-segment consists of the following:
3741 </p>
3743 </p>
3742 <pre>
3744 <pre>
3743 +------------------------------------------------------+
3745 +------------------------------------------------------+
3744 | | | |
3746 | | | |
3745 | filename length | filename | delta group |
3747 | filename length | filename | delta group |
3746 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3748 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3747 | | | |
3749 | | | |
3748 +------------------------------------------------------+
3750 +------------------------------------------------------+
3749 </pre>
3751 </pre>
3750 <p>
3752 <p>
3751 That is, a *chunk* consisting of the filename (not terminated or padded)
3753 That is, a *chunk* consisting of the filename (not terminated or padded)
3752 followed by N chunks constituting the *delta group* for this file. The
3754 followed by N chunks constituting the *delta group* for this file. The
3753 *empty chunk* at the end of each *delta group* denotes the boundary to the
3755 *empty chunk* at the end of each *delta group* denotes the boundary to the
3754 next filelog sub-segment.
3756 next filelog sub-segment.
3755 </p>
3757 </p>
3756
3758
3757 </div>
3759 </div>
3758 </div>
3760 </div>
3759 </div>
3761 </div>
3760
3762
3761
3763
3762
3764
3763 </body>
3765 </body>
3764 </html>
3766 </html>
3765
3767
3766
3768
3767 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3769 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3768 404 Not Found
3770 404 Not Found
3769
3771
3770 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3772 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3771 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3773 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3772 <head>
3774 <head>
3773 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3775 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3774 <meta name="robots" content="index, nofollow" />
3776 <meta name="robots" content="index, nofollow" />
3775 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3777 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3776 <script type="text/javascript" src="/static/mercurial.js"></script>
3778 <script type="text/javascript" src="/static/mercurial.js"></script>
3777
3779
3778 <title>test: error</title>
3780 <title>test: error</title>
3779 </head>
3781 </head>
3780 <body>
3782 <body>
3781
3783
3782 <div class="container">
3784 <div class="container">
3783 <div class="menu">
3785 <div class="menu">
3784 <div class="logo">
3786 <div class="logo">
3785 <a href="https://mercurial-scm.org/">
3787 <a href="https://mercurial-scm.org/">
3786 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3788 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3787 </div>
3789 </div>
3788 <ul>
3790 <ul>
3789 <li><a href="/shortlog">log</a></li>
3791 <li><a href="/shortlog">log</a></li>
3790 <li><a href="/graph">graph</a></li>
3792 <li><a href="/graph">graph</a></li>
3791 <li><a href="/tags">tags</a></li>
3793 <li><a href="/tags">tags</a></li>
3792 <li><a href="/bookmarks">bookmarks</a></li>
3794 <li><a href="/bookmarks">bookmarks</a></li>
3793 <li><a href="/branches">branches</a></li>
3795 <li><a href="/branches">branches</a></li>
3794 </ul>
3796 </ul>
3795 <ul>
3797 <ul>
3796 <li><a href="/help">help</a></li>
3798 <li><a href="/help">help</a></li>
3797 </ul>
3799 </ul>
3798 </div>
3800 </div>
3799
3801
3800 <div class="main">
3802 <div class="main">
3801
3803
3802 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3804 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3803 <h3>error</h3>
3805 <h3>error</h3>
3804
3806
3805
3807
3806 <form class="search" action="/log">
3808 <form class="search" action="/log">
3807
3809
3808 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3810 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3809 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3811 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3810 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3812 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3811 </form>
3813 </form>
3812
3814
3813 <div class="description">
3815 <div class="description">
3814 <p>
3816 <p>
3815 An error occurred while processing your request:
3817 An error occurred while processing your request:
3816 </p>
3818 </p>
3817 <p>
3819 <p>
3818 Not Found
3820 Not Found
3819 </p>
3821 </p>
3820 </div>
3822 </div>
3821 </div>
3823 </div>
3822 </div>
3824 </div>
3823
3825
3824
3826
3825
3827
3826 </body>
3828 </body>
3827 </html>
3829 </html>
3828
3830
3829 [1]
3831 [1]
3830
3832
3831 $ killdaemons.py
3833 $ killdaemons.py
3832
3834
3833 #endif
3835 #endif
General Comments 0
You need to be logged in to leave comments. Login now