##// END OF EJS Templates
commit: add ability to print file status after each successful invocation...
av6 -
r42430:0f013944 default
parent child Browse files
Show More
@@ -1,6260 +1,6264 b''
1 1 # commands.py - command processing for mercurial
2 2 #
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import difflib
11 11 import errno
12 12 import os
13 13 import re
14 14 import sys
15 15
16 16 from .i18n import _
17 17 from .node import (
18 18 hex,
19 19 nullid,
20 20 nullrev,
21 21 short,
22 22 wdirhex,
23 23 wdirrev,
24 24 )
25 25 from . import (
26 26 archival,
27 27 bookmarks,
28 28 bundle2,
29 29 changegroup,
30 30 cmdutil,
31 31 copies,
32 32 debugcommands as debugcommandsmod,
33 33 destutil,
34 34 dirstateguard,
35 35 discovery,
36 36 encoding,
37 37 error,
38 38 exchange,
39 39 extensions,
40 40 filemerge,
41 41 formatter,
42 42 graphmod,
43 43 hbisect,
44 44 help,
45 45 hg,
46 46 logcmdutil,
47 47 merge as mergemod,
48 48 narrowspec,
49 49 obsolete,
50 50 obsutil,
51 51 patch,
52 52 phases,
53 53 pycompat,
54 54 rcutil,
55 55 registrar,
56 56 repair,
57 57 revsetlang,
58 58 rewriteutil,
59 59 scmutil,
60 60 server,
61 61 state as statemod,
62 62 streamclone,
63 63 tags as tagsmod,
64 64 ui as uimod,
65 65 util,
66 66 verify as verifymod,
67 67 wireprotoserver,
68 68 )
69 69 from .utils import (
70 70 dateutil,
71 71 stringutil,
72 72 )
73 73
74 74 table = {}
75 75 table.update(debugcommandsmod.command._table)
76 76
77 77 command = registrar.command(table)
78 78 INTENT_READONLY = registrar.INTENT_READONLY
79 79
80 80 # common command options
81 81
82 82 globalopts = [
83 83 ('R', 'repository', '',
84 84 _('repository root directory or name of overlay bundle file'),
85 85 _('REPO')),
86 86 ('', 'cwd', '',
87 87 _('change working directory'), _('DIR')),
88 88 ('y', 'noninteractive', None,
89 89 _('do not prompt, automatically pick the first choice for all prompts')),
90 90 ('q', 'quiet', None, _('suppress output')),
91 91 ('v', 'verbose', None, _('enable additional output')),
92 92 ('', 'color', '',
93 93 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
94 94 # and should not be translated
95 95 _("when to colorize (boolean, always, auto, never, or debug)"),
96 96 _('TYPE')),
97 97 ('', 'config', [],
98 98 _('set/override config option (use \'section.name=value\')'),
99 99 _('CONFIG')),
100 100 ('', 'debug', None, _('enable debugging output')),
101 101 ('', 'debugger', None, _('start debugger')),
102 102 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
103 103 _('ENCODE')),
104 104 ('', 'encodingmode', encoding.encodingmode,
105 105 _('set the charset encoding mode'), _('MODE')),
106 106 ('', 'traceback', None, _('always print a traceback on exception')),
107 107 ('', 'time', None, _('time how long the command takes')),
108 108 ('', 'profile', None, _('print command execution profile')),
109 109 ('', 'version', None, _('output version information and exit')),
110 110 ('h', 'help', None, _('display help and exit')),
111 111 ('', 'hidden', False, _('consider hidden changesets')),
112 112 ('', 'pager', 'auto',
113 113 _("when to paginate (boolean, always, auto, or never)"), _('TYPE')),
114 114 ]
115 115
116 116 dryrunopts = cmdutil.dryrunopts
117 117 remoteopts = cmdutil.remoteopts
118 118 walkopts = cmdutil.walkopts
119 119 commitopts = cmdutil.commitopts
120 120 commitopts2 = cmdutil.commitopts2
121 121 formatteropts = cmdutil.formatteropts
122 122 templateopts = cmdutil.templateopts
123 123 logopts = cmdutil.logopts
124 124 diffopts = cmdutil.diffopts
125 125 diffwsopts = cmdutil.diffwsopts
126 126 diffopts2 = cmdutil.diffopts2
127 127 mergetoolopts = cmdutil.mergetoolopts
128 128 similarityopts = cmdutil.similarityopts
129 129 subrepoopts = cmdutil.subrepoopts
130 130 debugrevlogopts = cmdutil.debugrevlogopts
131 131
132 132 # Commands start here, listed alphabetically
133 133
134 134 @command('add',
135 135 walkopts + subrepoopts + dryrunopts,
136 136 _('[OPTION]... [FILE]...'),
137 137 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
138 138 helpbasic=True, inferrepo=True)
139 139 def add(ui, repo, *pats, **opts):
140 140 """add the specified files on the next commit
141 141
142 142 Schedule files to be version controlled and added to the
143 143 repository.
144 144
145 145 The files will be added to the repository at the next commit. To
146 146 undo an add before that, see :hg:`forget`.
147 147
148 148 If no names are given, add all files to the repository (except
149 149 files matching ``.hgignore``).
150 150
151 151 .. container:: verbose
152 152
153 153 Examples:
154 154
155 155 - New (unknown) files are added
156 156 automatically by :hg:`add`::
157 157
158 158 $ ls
159 159 foo.c
160 160 $ hg status
161 161 ? foo.c
162 162 $ hg add
163 163 adding foo.c
164 164 $ hg status
165 165 A foo.c
166 166
167 167 - Specific files to be added can be specified::
168 168
169 169 $ ls
170 170 bar.c foo.c
171 171 $ hg status
172 172 ? bar.c
173 173 ? foo.c
174 174 $ hg add bar.c
175 175 $ hg status
176 176 A bar.c
177 177 ? foo.c
178 178
179 179 Returns 0 if all files are successfully added.
180 180 """
181 181
182 182 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
183 183 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
184 184 rejected = cmdutil.add(ui, repo, m, "", uipathfn, False, **opts)
185 185 return rejected and 1 or 0
186 186
187 187 @command('addremove',
188 188 similarityopts + subrepoopts + walkopts + dryrunopts,
189 189 _('[OPTION]... [FILE]...'),
190 190 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
191 191 inferrepo=True)
192 192 def addremove(ui, repo, *pats, **opts):
193 193 """add all new files, delete all missing files
194 194
195 195 Add all new files and remove all missing files from the
196 196 repository.
197 197
198 198 Unless names are given, new files are ignored if they match any of
199 199 the patterns in ``.hgignore``. As with add, these changes take
200 200 effect at the next commit.
201 201
202 202 Use the -s/--similarity option to detect renamed files. This
203 203 option takes a percentage between 0 (disabled) and 100 (files must
204 204 be identical) as its parameter. With a parameter greater than 0,
205 205 this compares every removed file with every added file and records
206 206 those similar enough as renames. Detecting renamed files this way
207 207 can be expensive. After using this option, :hg:`status -C` can be
208 208 used to check which files were identified as moved or renamed. If
209 209 not specified, -s/--similarity defaults to 100 and only renames of
210 210 identical files are detected.
211 211
212 212 .. container:: verbose
213 213
214 214 Examples:
215 215
216 216 - A number of files (bar.c and foo.c) are new,
217 217 while foobar.c has been removed (without using :hg:`remove`)
218 218 from the repository::
219 219
220 220 $ ls
221 221 bar.c foo.c
222 222 $ hg status
223 223 ! foobar.c
224 224 ? bar.c
225 225 ? foo.c
226 226 $ hg addremove
227 227 adding bar.c
228 228 adding foo.c
229 229 removing foobar.c
230 230 $ hg status
231 231 A bar.c
232 232 A foo.c
233 233 R foobar.c
234 234
235 235 - A file foobar.c was moved to foo.c without using :hg:`rename`.
236 236 Afterwards, it was edited slightly::
237 237
238 238 $ ls
239 239 foo.c
240 240 $ hg status
241 241 ! foobar.c
242 242 ? foo.c
243 243 $ hg addremove --similarity 90
244 244 removing foobar.c
245 245 adding foo.c
246 246 recording removal of foobar.c as rename to foo.c (94% similar)
247 247 $ hg status -C
248 248 A foo.c
249 249 foobar.c
250 250 R foobar.c
251 251
252 252 Returns 0 if all files are successfully added.
253 253 """
254 254 opts = pycompat.byteskwargs(opts)
255 255 if not opts.get('similarity'):
256 256 opts['similarity'] = '100'
257 257 matcher = scmutil.match(repo[None], pats, opts)
258 258 relative = scmutil.anypats(pats, opts)
259 259 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
260 260 return scmutil.addremove(repo, matcher, "", uipathfn, opts)
261 261
262 262 @command('annotate|blame',
263 263 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
264 264 ('', 'follow', None,
265 265 _('follow copies/renames and list the filename (DEPRECATED)')),
266 266 ('', 'no-follow', None, _("don't follow copies and renames")),
267 267 ('a', 'text', None, _('treat all files as text')),
268 268 ('u', 'user', None, _('list the author (long with -v)')),
269 269 ('f', 'file', None, _('list the filename')),
270 270 ('d', 'date', None, _('list the date (short with -q)')),
271 271 ('n', 'number', None, _('list the revision number (default)')),
272 272 ('c', 'changeset', None, _('list the changeset')),
273 273 ('l', 'line-number', None, _('show line number at the first appearance')),
274 274 ('', 'skip', [], _('revision to not display (EXPERIMENTAL)'), _('REV')),
275 275 ] + diffwsopts + walkopts + formatteropts,
276 276 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
277 277 helpcategory=command.CATEGORY_FILE_CONTENTS,
278 278 helpbasic=True, inferrepo=True)
279 279 def annotate(ui, repo, *pats, **opts):
280 280 """show changeset information by line for each file
281 281
282 282 List changes in files, showing the revision id responsible for
283 283 each line.
284 284
285 285 This command is useful for discovering when a change was made and
286 286 by whom.
287 287
288 288 If you include --file, --user, or --date, the revision number is
289 289 suppressed unless you also include --number.
290 290
291 291 Without the -a/--text option, annotate will avoid processing files
292 292 it detects as binary. With -a, annotate will annotate the file
293 293 anyway, although the results will probably be neither useful
294 294 nor desirable.
295 295
296 296 .. container:: verbose
297 297
298 298 Template:
299 299
300 300 The following keywords are supported in addition to the common template
301 301 keywords and functions. See also :hg:`help templates`.
302 302
303 303 :lines: List of lines with annotation data.
304 304 :path: String. Repository-absolute path of the specified file.
305 305
306 306 And each entry of ``{lines}`` provides the following sub-keywords in
307 307 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
308 308
309 309 :line: String. Line content.
310 310 :lineno: Integer. Line number at that revision.
311 311 :path: String. Repository-absolute path of the file at that revision.
312 312
313 313 See :hg:`help templates.operators` for the list expansion syntax.
314 314
315 315 Returns 0 on success.
316 316 """
317 317 opts = pycompat.byteskwargs(opts)
318 318 if not pats:
319 319 raise error.Abort(_('at least one filename or pattern is required'))
320 320
321 321 if opts.get('follow'):
322 322 # --follow is deprecated and now just an alias for -f/--file
323 323 # to mimic the behavior of Mercurial before version 1.5
324 324 opts['file'] = True
325 325
326 326 if (not opts.get('user') and not opts.get('changeset')
327 327 and not opts.get('date') and not opts.get('file')):
328 328 opts['number'] = True
329 329
330 330 linenumber = opts.get('line_number') is not None
331 331 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
332 332 raise error.Abort(_('at least one of -n/-c is required for -l'))
333 333
334 334 rev = opts.get('rev')
335 335 if rev:
336 336 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
337 337 ctx = scmutil.revsingle(repo, rev)
338 338
339 339 ui.pager('annotate')
340 340 rootfm = ui.formatter('annotate', opts)
341 341 if ui.debugflag:
342 342 shorthex = pycompat.identity
343 343 else:
344 344 def shorthex(h):
345 345 return h[:12]
346 346 if ui.quiet:
347 347 datefunc = dateutil.shortdate
348 348 else:
349 349 datefunc = dateutil.datestr
350 350 if ctx.rev() is None:
351 351 if opts.get('changeset'):
352 352 # omit "+" suffix which is appended to node hex
353 353 def formatrev(rev):
354 354 if rev == wdirrev:
355 355 return '%d' % ctx.p1().rev()
356 356 else:
357 357 return '%d' % rev
358 358 else:
359 359 def formatrev(rev):
360 360 if rev == wdirrev:
361 361 return '%d+' % ctx.p1().rev()
362 362 else:
363 363 return '%d ' % rev
364 364 def formathex(h):
365 365 if h == wdirhex:
366 366 return '%s+' % shorthex(hex(ctx.p1().node()))
367 367 else:
368 368 return '%s ' % shorthex(h)
369 369 else:
370 370 formatrev = b'%d'.__mod__
371 371 formathex = shorthex
372 372
373 373 opmap = [
374 374 ('user', ' ', lambda x: x.fctx.user(), ui.shortuser),
375 375 ('rev', ' ', lambda x: scmutil.intrev(x.fctx), formatrev),
376 376 ('node', ' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
377 377 ('date', ' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
378 378 ('path', ' ', lambda x: x.fctx.path(), pycompat.bytestr),
379 379 ('lineno', ':', lambda x: x.lineno, pycompat.bytestr),
380 380 ]
381 381 opnamemap = {
382 382 'rev': 'number',
383 383 'node': 'changeset',
384 384 'path': 'file',
385 385 'lineno': 'line_number',
386 386 }
387 387
388 388 if rootfm.isplain():
389 389 def makefunc(get, fmt):
390 390 return lambda x: fmt(get(x))
391 391 else:
392 392 def makefunc(get, fmt):
393 393 return get
394 394 datahint = rootfm.datahint()
395 395 funcmap = [(makefunc(get, fmt), sep) for fn, sep, get, fmt in opmap
396 396 if opts.get(opnamemap.get(fn, fn)) or fn in datahint]
397 397 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
398 398 fields = ' '.join(fn for fn, sep, get, fmt in opmap
399 399 if opts.get(opnamemap.get(fn, fn)) or fn in datahint)
400 400
401 401 def bad(x, y):
402 402 raise error.Abort("%s: %s" % (x, y))
403 403
404 404 m = scmutil.match(ctx, pats, opts, badfn=bad)
405 405
406 406 follow = not opts.get('no_follow')
407 407 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
408 408 whitespace=True)
409 409 skiprevs = opts.get('skip')
410 410 if skiprevs:
411 411 skiprevs = scmutil.revrange(repo, skiprevs)
412 412
413 413 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
414 414 for abs in ctx.walk(m):
415 415 fctx = ctx[abs]
416 416 rootfm.startitem()
417 417 rootfm.data(path=abs)
418 418 if not opts.get('text') and fctx.isbinary():
419 419 rootfm.plain(_("%s: binary file\n") % uipathfn(abs))
420 420 continue
421 421
422 422 fm = rootfm.nested('lines', tmpl='{rev}: {line}')
423 423 lines = fctx.annotate(follow=follow, skiprevs=skiprevs,
424 424 diffopts=diffopts)
425 425 if not lines:
426 426 fm.end()
427 427 continue
428 428 formats = []
429 429 pieces = []
430 430
431 431 for f, sep in funcmap:
432 432 l = [f(n) for n in lines]
433 433 if fm.isplain():
434 434 sizes = [encoding.colwidth(x) for x in l]
435 435 ml = max(sizes)
436 436 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
437 437 else:
438 438 formats.append(['%s' for x in l])
439 439 pieces.append(l)
440 440
441 441 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
442 442 fm.startitem()
443 443 fm.context(fctx=n.fctx)
444 444 fm.write(fields, "".join(f), *p)
445 445 if n.skip:
446 446 fmt = "* %s"
447 447 else:
448 448 fmt = ": %s"
449 449 fm.write('line', fmt, n.text)
450 450
451 451 if not lines[-1].text.endswith('\n'):
452 452 fm.plain('\n')
453 453 fm.end()
454 454
455 455 rootfm.end()
456 456
457 457 @command('archive',
458 458 [('', 'no-decode', None, _('do not pass files through decoders')),
459 459 ('p', 'prefix', '', _('directory prefix for files in archive'),
460 460 _('PREFIX')),
461 461 ('r', 'rev', '', _('revision to distribute'), _('REV')),
462 462 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
463 463 ] + subrepoopts + walkopts,
464 464 _('[OPTION]... DEST'),
465 465 helpcategory=command.CATEGORY_IMPORT_EXPORT)
466 466 def archive(ui, repo, dest, **opts):
467 467 '''create an unversioned archive of a repository revision
468 468
469 469 By default, the revision used is the parent of the working
470 470 directory; use -r/--rev to specify a different revision.
471 471
472 472 The archive type is automatically detected based on file
473 473 extension (to override, use -t/--type).
474 474
475 475 .. container:: verbose
476 476
477 477 Examples:
478 478
479 479 - create a zip file containing the 1.0 release::
480 480
481 481 hg archive -r 1.0 project-1.0.zip
482 482
483 483 - create a tarball excluding .hg files::
484 484
485 485 hg archive project.tar.gz -X ".hg*"
486 486
487 487 Valid types are:
488 488
489 489 :``files``: a directory full of files (default)
490 490 :``tar``: tar archive, uncompressed
491 491 :``tbz2``: tar archive, compressed using bzip2
492 492 :``tgz``: tar archive, compressed using gzip
493 493 :``uzip``: zip archive, uncompressed
494 494 :``zip``: zip archive, compressed using deflate
495 495
496 496 The exact name of the destination archive or directory is given
497 497 using a format string; see :hg:`help export` for details.
498 498
499 499 Each member added to an archive file has a directory prefix
500 500 prepended. Use -p/--prefix to specify a format string for the
501 501 prefix. The default is the basename of the archive, with suffixes
502 502 removed.
503 503
504 504 Returns 0 on success.
505 505 '''
506 506
507 507 opts = pycompat.byteskwargs(opts)
508 508 rev = opts.get('rev')
509 509 if rev:
510 510 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
511 511 ctx = scmutil.revsingle(repo, rev)
512 512 if not ctx:
513 513 raise error.Abort(_('no working directory: please specify a revision'))
514 514 node = ctx.node()
515 515 dest = cmdutil.makefilename(ctx, dest)
516 516 if os.path.realpath(dest) == repo.root:
517 517 raise error.Abort(_('repository root cannot be destination'))
518 518
519 519 kind = opts.get('type') or archival.guesskind(dest) or 'files'
520 520 prefix = opts.get('prefix')
521 521
522 522 if dest == '-':
523 523 if kind == 'files':
524 524 raise error.Abort(_('cannot archive plain files to stdout'))
525 525 dest = cmdutil.makefileobj(ctx, dest)
526 526 if not prefix:
527 527 prefix = os.path.basename(repo.root) + '-%h'
528 528
529 529 prefix = cmdutil.makefilename(ctx, prefix)
530 530 match = scmutil.match(ctx, [], opts)
531 531 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
532 532 match, prefix, subrepos=opts.get('subrepos'))
533 533
534 534 @command('backout',
535 535 [('', 'merge', None, _('merge with old dirstate parent after backout')),
536 536 ('', 'commit', None,
537 537 _('commit if no conflicts were encountered (DEPRECATED)')),
538 538 ('', 'no-commit', None, _('do not commit')),
539 539 ('', 'parent', '',
540 540 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
541 541 ('r', 'rev', '', _('revision to backout'), _('REV')),
542 542 ('e', 'edit', False, _('invoke editor on commit messages')),
543 543 ] + mergetoolopts + walkopts + commitopts + commitopts2,
544 544 _('[OPTION]... [-r] REV'),
545 545 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
546 546 def backout(ui, repo, node=None, rev=None, **opts):
547 547 '''reverse effect of earlier changeset
548 548
549 549 Prepare a new changeset with the effect of REV undone in the
550 550 current working directory. If no conflicts were encountered,
551 551 it will be committed immediately.
552 552
553 553 If REV is the parent of the working directory, then this new changeset
554 554 is committed automatically (unless --no-commit is specified).
555 555
556 556 .. note::
557 557
558 558 :hg:`backout` cannot be used to fix either an unwanted or
559 559 incorrect merge.
560 560
561 561 .. container:: verbose
562 562
563 563 Examples:
564 564
565 565 - Reverse the effect of the parent of the working directory.
566 566 This backout will be committed immediately::
567 567
568 568 hg backout -r .
569 569
570 570 - Reverse the effect of previous bad revision 23::
571 571
572 572 hg backout -r 23
573 573
574 574 - Reverse the effect of previous bad revision 23 and
575 575 leave changes uncommitted::
576 576
577 577 hg backout -r 23 --no-commit
578 578 hg commit -m "Backout revision 23"
579 579
580 580 By default, the pending changeset will have one parent,
581 581 maintaining a linear history. With --merge, the pending
582 582 changeset will instead have two parents: the old parent of the
583 583 working directory and a new child of REV that simply undoes REV.
584 584
585 585 Before version 1.7, the behavior without --merge was equivalent
586 586 to specifying --merge followed by :hg:`update --clean .` to
587 587 cancel the merge and leave the child of REV as a head to be
588 588 merged separately.
589 589
590 590 See :hg:`help dates` for a list of formats valid for -d/--date.
591 591
592 592 See :hg:`help revert` for a way to restore files to the state
593 593 of another revision.
594 594
595 595 Returns 0 on success, 1 if nothing to backout or there are unresolved
596 596 files.
597 597 '''
598 598 with repo.wlock(), repo.lock():
599 599 return _dobackout(ui, repo, node, rev, **opts)
600 600
601 601 def _dobackout(ui, repo, node=None, rev=None, **opts):
602 602 opts = pycompat.byteskwargs(opts)
603 603 if opts.get('commit') and opts.get('no_commit'):
604 604 raise error.Abort(_("cannot use --commit with --no-commit"))
605 605 if opts.get('merge') and opts.get('no_commit'):
606 606 raise error.Abort(_("cannot use --merge with --no-commit"))
607 607
608 608 if rev and node:
609 609 raise error.Abort(_("please specify just one revision"))
610 610
611 611 if not rev:
612 612 rev = node
613 613
614 614 if not rev:
615 615 raise error.Abort(_("please specify a revision to backout"))
616 616
617 617 date = opts.get('date')
618 618 if date:
619 619 opts['date'] = dateutil.parsedate(date)
620 620
621 621 cmdutil.checkunfinished(repo)
622 622 cmdutil.bailifchanged(repo)
623 623 node = scmutil.revsingle(repo, rev).node()
624 624
625 625 op1, op2 = repo.dirstate.parents()
626 626 if not repo.changelog.isancestor(node, op1):
627 627 raise error.Abort(_('cannot backout change that is not an ancestor'))
628 628
629 629 p1, p2 = repo.changelog.parents(node)
630 630 if p1 == nullid:
631 631 raise error.Abort(_('cannot backout a change with no parents'))
632 632 if p2 != nullid:
633 633 if not opts.get('parent'):
634 634 raise error.Abort(_('cannot backout a merge changeset'))
635 635 p = repo.lookup(opts['parent'])
636 636 if p not in (p1, p2):
637 637 raise error.Abort(_('%s is not a parent of %s') %
638 638 (short(p), short(node)))
639 639 parent = p
640 640 else:
641 641 if opts.get('parent'):
642 642 raise error.Abort(_('cannot use --parent on non-merge changeset'))
643 643 parent = p1
644 644
645 645 # the backout should appear on the same branch
646 646 branch = repo.dirstate.branch()
647 647 bheads = repo.branchheads(branch)
648 648 rctx = scmutil.revsingle(repo, hex(parent))
649 649 if not opts.get('merge') and op1 != node:
650 650 with dirstateguard.dirstateguard(repo, 'backout'):
651 651 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
652 652 with ui.configoverride(overrides, 'backout'):
653 653 stats = mergemod.update(repo, parent, branchmerge=True,
654 654 force=True, ancestor=node,
655 655 mergeancestor=False)
656 656 repo.setparents(op1, op2)
657 657 hg._showstats(repo, stats)
658 658 if stats.unresolvedcount:
659 659 repo.ui.status(_("use 'hg resolve' to retry unresolved "
660 660 "file merges\n"))
661 661 return 1
662 662 else:
663 663 hg.clean(repo, node, show_stats=False)
664 664 repo.dirstate.setbranch(branch)
665 665 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
666 666
667 667 if opts.get('no_commit'):
668 668 msg = _("changeset %s backed out, "
669 669 "don't forget to commit.\n")
670 670 ui.status(msg % short(node))
671 671 return 0
672 672
673 673 def commitfunc(ui, repo, message, match, opts):
674 674 editform = 'backout'
675 675 e = cmdutil.getcommiteditor(editform=editform,
676 676 **pycompat.strkwargs(opts))
677 677 if not message:
678 678 # we don't translate commit messages
679 679 message = "Backed out changeset %s" % short(node)
680 680 e = cmdutil.getcommiteditor(edit=True, editform=editform)
681 681 return repo.commit(message, opts.get('user'), opts.get('date'),
682 682 match, editor=e)
683 683 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
684 684 if not newnode:
685 685 ui.status(_("nothing changed\n"))
686 686 return 1
687 687 cmdutil.commitstatus(repo, newnode, branch, bheads)
688 688
689 689 def nice(node):
690 690 return '%d:%s' % (repo.changelog.rev(node), short(node))
691 691 ui.status(_('changeset %s backs out changeset %s\n') %
692 692 (nice(repo.changelog.tip()), nice(node)))
693 693 if opts.get('merge') and op1 != node:
694 694 hg.clean(repo, op1, show_stats=False)
695 695 ui.status(_('merging with changeset %s\n')
696 696 % nice(repo.changelog.tip()))
697 697 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
698 698 with ui.configoverride(overrides, 'backout'):
699 699 return hg.merge(repo, hex(repo.changelog.tip()))
700 700 return 0
701 701
702 702 @command('bisect',
703 703 [('r', 'reset', False, _('reset bisect state')),
704 704 ('g', 'good', False, _('mark changeset good')),
705 705 ('b', 'bad', False, _('mark changeset bad')),
706 706 ('s', 'skip', False, _('skip testing changeset')),
707 707 ('e', 'extend', False, _('extend the bisect range')),
708 708 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
709 709 ('U', 'noupdate', False, _('do not update to target'))],
710 710 _("[-gbsr] [-U] [-c CMD] [REV]"),
711 711 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
712 712 def bisect(ui, repo, rev=None, extra=None, command=None,
713 713 reset=None, good=None, bad=None, skip=None, extend=None,
714 714 noupdate=None):
715 715 """subdivision search of changesets
716 716
717 717 This command helps to find changesets which introduce problems. To
718 718 use, mark the earliest changeset you know exhibits the problem as
719 719 bad, then mark the latest changeset which is free from the problem
720 720 as good. Bisect will update your working directory to a revision
721 721 for testing (unless the -U/--noupdate option is specified). Once
722 722 you have performed tests, mark the working directory as good or
723 723 bad, and bisect will either update to another candidate changeset
724 724 or announce that it has found the bad revision.
725 725
726 726 As a shortcut, you can also use the revision argument to mark a
727 727 revision as good or bad without checking it out first.
728 728
729 729 If you supply a command, it will be used for automatic bisection.
730 730 The environment variable HG_NODE will contain the ID of the
731 731 changeset being tested. The exit status of the command will be
732 732 used to mark revisions as good or bad: status 0 means good, 125
733 733 means to skip the revision, 127 (command not found) will abort the
734 734 bisection, and any other non-zero exit status means the revision
735 735 is bad.
736 736
737 737 .. container:: verbose
738 738
739 739 Some examples:
740 740
741 741 - start a bisection with known bad revision 34, and good revision 12::
742 742
743 743 hg bisect --bad 34
744 744 hg bisect --good 12
745 745
746 746 - advance the current bisection by marking current revision as good or
747 747 bad::
748 748
749 749 hg bisect --good
750 750 hg bisect --bad
751 751
752 752 - mark the current revision, or a known revision, to be skipped (e.g. if
753 753 that revision is not usable because of another issue)::
754 754
755 755 hg bisect --skip
756 756 hg bisect --skip 23
757 757
758 758 - skip all revisions that do not touch directories ``foo`` or ``bar``::
759 759
760 760 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
761 761
762 762 - forget the current bisection::
763 763
764 764 hg bisect --reset
765 765
766 766 - use 'make && make tests' to automatically find the first broken
767 767 revision::
768 768
769 769 hg bisect --reset
770 770 hg bisect --bad 34
771 771 hg bisect --good 12
772 772 hg bisect --command "make && make tests"
773 773
774 774 - see all changesets whose states are already known in the current
775 775 bisection::
776 776
777 777 hg log -r "bisect(pruned)"
778 778
779 779 - see the changeset currently being bisected (especially useful
780 780 if running with -U/--noupdate)::
781 781
782 782 hg log -r "bisect(current)"
783 783
784 784 - see all changesets that took part in the current bisection::
785 785
786 786 hg log -r "bisect(range)"
787 787
788 788 - you can even get a nice graph::
789 789
790 790 hg log --graph -r "bisect(range)"
791 791
792 792 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
793 793
794 794 Returns 0 on success.
795 795 """
796 796 # backward compatibility
797 797 if rev in "good bad reset init".split():
798 798 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
799 799 cmd, rev, extra = rev, extra, None
800 800 if cmd == "good":
801 801 good = True
802 802 elif cmd == "bad":
803 803 bad = True
804 804 else:
805 805 reset = True
806 806 elif extra:
807 807 raise error.Abort(_('incompatible arguments'))
808 808
809 809 incompatibles = {
810 810 '--bad': bad,
811 811 '--command': bool(command),
812 812 '--extend': extend,
813 813 '--good': good,
814 814 '--reset': reset,
815 815 '--skip': skip,
816 816 }
817 817
818 818 enabled = [x for x in incompatibles if incompatibles[x]]
819 819
820 820 if len(enabled) > 1:
821 821 raise error.Abort(_('%s and %s are incompatible') %
822 822 tuple(sorted(enabled)[0:2]))
823 823
824 824 if reset:
825 825 hbisect.resetstate(repo)
826 826 return
827 827
828 828 state = hbisect.load_state(repo)
829 829
830 830 # update state
831 831 if good or bad or skip:
832 832 if rev:
833 833 nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
834 834 else:
835 835 nodes = [repo.lookup('.')]
836 836 if good:
837 837 state['good'] += nodes
838 838 elif bad:
839 839 state['bad'] += nodes
840 840 elif skip:
841 841 state['skip'] += nodes
842 842 hbisect.save_state(repo, state)
843 843 if not (state['good'] and state['bad']):
844 844 return
845 845
846 846 def mayupdate(repo, node, show_stats=True):
847 847 """common used update sequence"""
848 848 if noupdate:
849 849 return
850 850 cmdutil.checkunfinished(repo)
851 851 cmdutil.bailifchanged(repo)
852 852 return hg.clean(repo, node, show_stats=show_stats)
853 853
854 854 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
855 855
856 856 if command:
857 857 changesets = 1
858 858 if noupdate:
859 859 try:
860 860 node = state['current'][0]
861 861 except LookupError:
862 862 raise error.Abort(_('current bisect revision is unknown - '
863 863 'start a new bisect to fix'))
864 864 else:
865 865 node, p2 = repo.dirstate.parents()
866 866 if p2 != nullid:
867 867 raise error.Abort(_('current bisect revision is a merge'))
868 868 if rev:
869 869 node = repo[scmutil.revsingle(repo, rev, node)].node()
870 870 try:
871 871 while changesets:
872 872 # update state
873 873 state['current'] = [node]
874 874 hbisect.save_state(repo, state)
875 875 status = ui.system(command, environ={'HG_NODE': hex(node)},
876 876 blockedtag='bisect_check')
877 877 if status == 125:
878 878 transition = "skip"
879 879 elif status == 0:
880 880 transition = "good"
881 881 # status < 0 means process was killed
882 882 elif status == 127:
883 883 raise error.Abort(_("failed to execute %s") % command)
884 884 elif status < 0:
885 885 raise error.Abort(_("%s killed") % command)
886 886 else:
887 887 transition = "bad"
888 888 state[transition].append(node)
889 889 ctx = repo[node]
890 890 ui.status(_('changeset %d:%s: %s\n') % (ctx.rev(), ctx,
891 891 transition))
892 892 hbisect.checkstate(state)
893 893 # bisect
894 894 nodes, changesets, bgood = hbisect.bisect(repo, state)
895 895 # update to next check
896 896 node = nodes[0]
897 897 mayupdate(repo, node, show_stats=False)
898 898 finally:
899 899 state['current'] = [node]
900 900 hbisect.save_state(repo, state)
901 901 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
902 902 return
903 903
904 904 hbisect.checkstate(state)
905 905
906 906 # actually bisect
907 907 nodes, changesets, good = hbisect.bisect(repo, state)
908 908 if extend:
909 909 if not changesets:
910 910 extendnode = hbisect.extendrange(repo, state, nodes, good)
911 911 if extendnode is not None:
912 912 ui.write(_("Extending search to changeset %d:%s\n")
913 913 % (extendnode.rev(), extendnode))
914 914 state['current'] = [extendnode.node()]
915 915 hbisect.save_state(repo, state)
916 916 return mayupdate(repo, extendnode.node())
917 917 raise error.Abort(_("nothing to extend"))
918 918
919 919 if changesets == 0:
920 920 hbisect.printresult(ui, repo, state, displayer, nodes, good)
921 921 else:
922 922 assert len(nodes) == 1 # only a single node can be tested next
923 923 node = nodes[0]
924 924 # compute the approximate number of remaining tests
925 925 tests, size = 0, 2
926 926 while size <= changesets:
927 927 tests, size = tests + 1, size * 2
928 928 rev = repo.changelog.rev(node)
929 929 ui.write(_("Testing changeset %d:%s "
930 930 "(%d changesets remaining, ~%d tests)\n")
931 931 % (rev, short(node), changesets, tests))
932 932 state['current'] = [node]
933 933 hbisect.save_state(repo, state)
934 934 return mayupdate(repo, node)
935 935
936 936 @command('bookmarks|bookmark',
937 937 [('f', 'force', False, _('force')),
938 938 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
939 939 ('d', 'delete', False, _('delete a given bookmark')),
940 940 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
941 941 ('i', 'inactive', False, _('mark a bookmark inactive')),
942 942 ('l', 'list', False, _('list existing bookmarks')),
943 943 ] + formatteropts,
944 944 _('hg bookmarks [OPTIONS]... [NAME]...'),
945 945 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
946 946 def bookmark(ui, repo, *names, **opts):
947 947 '''create a new bookmark or list existing bookmarks
948 948
949 949 Bookmarks are labels on changesets to help track lines of development.
950 950 Bookmarks are unversioned and can be moved, renamed and deleted.
951 951 Deleting or moving a bookmark has no effect on the associated changesets.
952 952
953 953 Creating or updating to a bookmark causes it to be marked as 'active'.
954 954 The active bookmark is indicated with a '*'.
955 955 When a commit is made, the active bookmark will advance to the new commit.
956 956 A plain :hg:`update` will also advance an active bookmark, if possible.
957 957 Updating away from a bookmark will cause it to be deactivated.
958 958
959 959 Bookmarks can be pushed and pulled between repositories (see
960 960 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
961 961 diverged, a new 'divergent bookmark' of the form 'name@path' will
962 962 be created. Using :hg:`merge` will resolve the divergence.
963 963
964 964 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
965 965 the active bookmark's name.
966 966
967 967 A bookmark named '@' has the special property that :hg:`clone` will
968 968 check it out by default if it exists.
969 969
970 970 .. container:: verbose
971 971
972 972 Template:
973 973
974 974 The following keywords are supported in addition to the common template
975 975 keywords and functions such as ``{bookmark}``. See also
976 976 :hg:`help templates`.
977 977
978 978 :active: Boolean. True if the bookmark is active.
979 979
980 980 Examples:
981 981
982 982 - create an active bookmark for a new line of development::
983 983
984 984 hg book new-feature
985 985
986 986 - create an inactive bookmark as a place marker::
987 987
988 988 hg book -i reviewed
989 989
990 990 - create an inactive bookmark on another changeset::
991 991
992 992 hg book -r .^ tested
993 993
994 994 - rename bookmark turkey to dinner::
995 995
996 996 hg book -m turkey dinner
997 997
998 998 - move the '@' bookmark from another branch::
999 999
1000 1000 hg book -f @
1001 1001
1002 1002 - print only the active bookmark name::
1003 1003
1004 1004 hg book -ql .
1005 1005 '''
1006 1006 opts = pycompat.byteskwargs(opts)
1007 1007 force = opts.get('force')
1008 1008 rev = opts.get('rev')
1009 1009 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark
1010 1010
1011 1011 selactions = [k for k in ['delete', 'rename', 'list'] if opts.get(k)]
1012 1012 if len(selactions) > 1:
1013 1013 raise error.Abort(_('--%s and --%s are incompatible')
1014 1014 % tuple(selactions[:2]))
1015 1015 if selactions:
1016 1016 action = selactions[0]
1017 1017 elif names or rev:
1018 1018 action = 'add'
1019 1019 elif inactive:
1020 1020 action = 'inactive' # meaning deactivate
1021 1021 else:
1022 1022 action = 'list'
1023 1023
1024 1024 if rev and action in {'delete', 'rename', 'list'}:
1025 1025 raise error.Abort(_("--rev is incompatible with --%s") % action)
1026 1026 if inactive and action in {'delete', 'list'}:
1027 1027 raise error.Abort(_("--inactive is incompatible with --%s") % action)
1028 1028 if not names and action in {'add', 'delete'}:
1029 1029 raise error.Abort(_("bookmark name required"))
1030 1030
1031 1031 if action in {'add', 'delete', 'rename', 'inactive'}:
1032 1032 with repo.wlock(), repo.lock(), repo.transaction('bookmark') as tr:
1033 1033 if action == 'delete':
1034 1034 names = pycompat.maplist(repo._bookmarks.expandname, names)
1035 1035 bookmarks.delete(repo, tr, names)
1036 1036 elif action == 'rename':
1037 1037 if not names:
1038 1038 raise error.Abort(_("new bookmark name required"))
1039 1039 elif len(names) > 1:
1040 1040 raise error.Abort(_("only one new bookmark name allowed"))
1041 1041 oldname = repo._bookmarks.expandname(opts['rename'])
1042 1042 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1043 1043 elif action == 'add':
1044 1044 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1045 1045 elif action == 'inactive':
1046 1046 if len(repo._bookmarks) == 0:
1047 1047 ui.status(_("no bookmarks set\n"))
1048 1048 elif not repo._activebookmark:
1049 1049 ui.status(_("no active bookmark\n"))
1050 1050 else:
1051 1051 bookmarks.deactivate(repo)
1052 1052 elif action == 'list':
1053 1053 names = pycompat.maplist(repo._bookmarks.expandname, names)
1054 1054 with ui.formatter('bookmarks', opts) as fm:
1055 1055 bookmarks.printbookmarks(ui, repo, fm, names)
1056 1056 else:
1057 1057 raise error.ProgrammingError('invalid action: %s' % action)
1058 1058
1059 1059 @command('branch',
1060 1060 [('f', 'force', None,
1061 1061 _('set branch name even if it shadows an existing branch')),
1062 1062 ('C', 'clean', None, _('reset branch name to parent branch name')),
1063 1063 ('r', 'rev', [], _('change branches of the given revs (EXPERIMENTAL)')),
1064 1064 ],
1065 1065 _('[-fC] [NAME]'),
1066 1066 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
1067 1067 def branch(ui, repo, label=None, **opts):
1068 1068 """set or show the current branch name
1069 1069
1070 1070 .. note::
1071 1071
1072 1072 Branch names are permanent and global. Use :hg:`bookmark` to create a
1073 1073 light-weight bookmark instead. See :hg:`help glossary` for more
1074 1074 information about named branches and bookmarks.
1075 1075
1076 1076 With no argument, show the current branch name. With one argument,
1077 1077 set the working directory branch name (the branch will not exist
1078 1078 in the repository until the next commit). Standard practice
1079 1079 recommends that primary development take place on the 'default'
1080 1080 branch.
1081 1081
1082 1082 Unless -f/--force is specified, branch will not let you set a
1083 1083 branch name that already exists.
1084 1084
1085 1085 Use -C/--clean to reset the working directory branch to that of
1086 1086 the parent of the working directory, negating a previous branch
1087 1087 change.
1088 1088
1089 1089 Use the command :hg:`update` to switch to an existing branch. Use
1090 1090 :hg:`commit --close-branch` to mark this branch head as closed.
1091 1091 When all heads of a branch are closed, the branch will be
1092 1092 considered closed.
1093 1093
1094 1094 Returns 0 on success.
1095 1095 """
1096 1096 opts = pycompat.byteskwargs(opts)
1097 1097 revs = opts.get('rev')
1098 1098 if label:
1099 1099 label = label.strip()
1100 1100
1101 1101 if not opts.get('clean') and not label:
1102 1102 if revs:
1103 1103 raise error.Abort(_("no branch name specified for the revisions"))
1104 1104 ui.write("%s\n" % repo.dirstate.branch())
1105 1105 return
1106 1106
1107 1107 with repo.wlock():
1108 1108 if opts.get('clean'):
1109 1109 label = repo['.'].branch()
1110 1110 repo.dirstate.setbranch(label)
1111 1111 ui.status(_('reset working directory to branch %s\n') % label)
1112 1112 elif label:
1113 1113
1114 1114 scmutil.checknewlabel(repo, label, 'branch')
1115 1115 if revs:
1116 1116 return cmdutil.changebranch(ui, repo, revs, label)
1117 1117
1118 1118 if not opts.get('force') and label in repo.branchmap():
1119 1119 if label not in [p.branch() for p in repo[None].parents()]:
1120 1120 raise error.Abort(_('a branch of the same name already'
1121 1121 ' exists'),
1122 1122 # i18n: "it" refers to an existing branch
1123 1123 hint=_("use 'hg update' to switch to it"))
1124 1124
1125 1125 repo.dirstate.setbranch(label)
1126 1126 ui.status(_('marked working directory as branch %s\n') % label)
1127 1127
1128 1128 # find any open named branches aside from default
1129 1129 for n, h, t, c in repo.branchmap().iterbranches():
1130 1130 if n != "default" and not c:
1131 1131 return 0
1132 1132 ui.status(_('(branches are permanent and global, '
1133 1133 'did you want a bookmark?)\n'))
1134 1134
1135 1135 @command('branches',
1136 1136 [('a', 'active', False,
1137 1137 _('show only branches that have unmerged heads (DEPRECATED)')),
1138 1138 ('c', 'closed', False, _('show normal and closed branches')),
1139 1139 ('r', 'rev', [], _('show branch name(s) of the given rev'))
1140 1140 ] + formatteropts,
1141 1141 _('[-c]'),
1142 1142 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1143 1143 intents={INTENT_READONLY})
1144 1144 def branches(ui, repo, active=False, closed=False, **opts):
1145 1145 """list repository named branches
1146 1146
1147 1147 List the repository's named branches, indicating which ones are
1148 1148 inactive. If -c/--closed is specified, also list branches which have
1149 1149 been marked closed (see :hg:`commit --close-branch`).
1150 1150
1151 1151 Use the command :hg:`update` to switch to an existing branch.
1152 1152
1153 1153 .. container:: verbose
1154 1154
1155 1155 Template:
1156 1156
1157 1157 The following keywords are supported in addition to the common template
1158 1158 keywords and functions such as ``{branch}``. See also
1159 1159 :hg:`help templates`.
1160 1160
1161 1161 :active: Boolean. True if the branch is active.
1162 1162 :closed: Boolean. True if the branch is closed.
1163 1163 :current: Boolean. True if it is the current branch.
1164 1164
1165 1165 Returns 0.
1166 1166 """
1167 1167
1168 1168 opts = pycompat.byteskwargs(opts)
1169 1169 revs = opts.get('rev')
1170 1170 selectedbranches = None
1171 1171 if revs:
1172 1172 revs = scmutil.revrange(repo, revs)
1173 1173 getbi = repo.revbranchcache().branchinfo
1174 1174 selectedbranches = {getbi(r)[0] for r in revs}
1175 1175
1176 1176 ui.pager('branches')
1177 1177 fm = ui.formatter('branches', opts)
1178 1178 hexfunc = fm.hexfunc
1179 1179
1180 1180 allheads = set(repo.heads())
1181 1181 branches = []
1182 1182 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1183 1183 if selectedbranches is not None and tag not in selectedbranches:
1184 1184 continue
1185 1185 isactive = False
1186 1186 if not isclosed:
1187 1187 openheads = set(repo.branchmap().iteropen(heads))
1188 1188 isactive = bool(openheads & allheads)
1189 1189 branches.append((tag, repo[tip], isactive, not isclosed))
1190 1190 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1191 1191 reverse=True)
1192 1192
1193 1193 for tag, ctx, isactive, isopen in branches:
1194 1194 if active and not isactive:
1195 1195 continue
1196 1196 if isactive:
1197 1197 label = 'branches.active'
1198 1198 notice = ''
1199 1199 elif not isopen:
1200 1200 if not closed:
1201 1201 continue
1202 1202 label = 'branches.closed'
1203 1203 notice = _(' (closed)')
1204 1204 else:
1205 1205 label = 'branches.inactive'
1206 1206 notice = _(' (inactive)')
1207 1207 current = (tag == repo.dirstate.branch())
1208 1208 if current:
1209 1209 label = 'branches.current'
1210 1210
1211 1211 fm.startitem()
1212 1212 fm.write('branch', '%s', tag, label=label)
1213 1213 rev = ctx.rev()
1214 1214 padsize = max(31 - len("%d" % rev) - encoding.colwidth(tag), 0)
1215 1215 fmt = ' ' * padsize + ' %d:%s'
1216 1216 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1217 1217 label='log.changeset changeset.%s' % ctx.phasestr())
1218 1218 fm.context(ctx=ctx)
1219 1219 fm.data(active=isactive, closed=not isopen, current=current)
1220 1220 if not ui.quiet:
1221 1221 fm.plain(notice)
1222 1222 fm.plain('\n')
1223 1223 fm.end()
1224 1224
1225 1225 @command('bundle',
1226 1226 [('f', 'force', None, _('run even when the destination is unrelated')),
1227 1227 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1228 1228 _('REV')),
1229 1229 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1230 1230 _('BRANCH')),
1231 1231 ('', 'base', [],
1232 1232 _('a base changeset assumed to be available at the destination'),
1233 1233 _('REV')),
1234 1234 ('a', 'all', None, _('bundle all changesets in the repository')),
1235 1235 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1236 1236 ] + remoteopts,
1237 1237 _('[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1238 1238 helpcategory=command.CATEGORY_IMPORT_EXPORT)
1239 1239 def bundle(ui, repo, fname, dest=None, **opts):
1240 1240 """create a bundle file
1241 1241
1242 1242 Generate a bundle file containing data to be transferred to another
1243 1243 repository.
1244 1244
1245 1245 To create a bundle containing all changesets, use -a/--all
1246 1246 (or --base null). Otherwise, hg assumes the destination will have
1247 1247 all the nodes you specify with --base parameters. Otherwise, hg
1248 1248 will assume the repository has all the nodes in destination, or
1249 1249 default-push/default if no destination is specified, where destination
1250 1250 is the repository you provide through DEST option.
1251 1251
1252 1252 You can change bundle format with the -t/--type option. See
1253 1253 :hg:`help bundlespec` for documentation on this format. By default,
1254 1254 the most appropriate format is used and compression defaults to
1255 1255 bzip2.
1256 1256
1257 1257 The bundle file can then be transferred using conventional means
1258 1258 and applied to another repository with the unbundle or pull
1259 1259 command. This is useful when direct push and pull are not
1260 1260 available or when exporting an entire repository is undesirable.
1261 1261
1262 1262 Applying bundles preserves all changeset contents including
1263 1263 permissions, copy/rename information, and revision history.
1264 1264
1265 1265 Returns 0 on success, 1 if no changes found.
1266 1266 """
1267 1267 opts = pycompat.byteskwargs(opts)
1268 1268 revs = None
1269 1269 if 'rev' in opts:
1270 1270 revstrings = opts['rev']
1271 1271 revs = scmutil.revrange(repo, revstrings)
1272 1272 if revstrings and not revs:
1273 1273 raise error.Abort(_('no commits to bundle'))
1274 1274
1275 1275 bundletype = opts.get('type', 'bzip2').lower()
1276 1276 try:
1277 1277 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
1278 1278 except error.UnsupportedBundleSpecification as e:
1279 1279 raise error.Abort(pycompat.bytestr(e),
1280 1280 hint=_("see 'hg help bundlespec' for supported "
1281 1281 "values for --type"))
1282 1282 cgversion = bundlespec.contentopts["cg.version"]
1283 1283
1284 1284 # Packed bundles are a pseudo bundle format for now.
1285 1285 if cgversion == 's1':
1286 1286 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1287 1287 hint=_("use 'hg debugcreatestreamclonebundle'"))
1288 1288
1289 1289 if opts.get('all'):
1290 1290 if dest:
1291 1291 raise error.Abort(_("--all is incompatible with specifying "
1292 1292 "a destination"))
1293 1293 if opts.get('base'):
1294 1294 ui.warn(_("ignoring --base because --all was specified\n"))
1295 1295 base = [nullrev]
1296 1296 else:
1297 1297 base = scmutil.revrange(repo, opts.get('base'))
1298 1298 if cgversion not in changegroup.supportedoutgoingversions(repo):
1299 1299 raise error.Abort(_("repository does not support bundle version %s") %
1300 1300 cgversion)
1301 1301
1302 1302 if base:
1303 1303 if dest:
1304 1304 raise error.Abort(_("--base is incompatible with specifying "
1305 1305 "a destination"))
1306 1306 common = [repo[rev].node() for rev in base]
1307 1307 heads = [repo[r].node() for r in revs] if revs else None
1308 1308 outgoing = discovery.outgoing(repo, common, heads)
1309 1309 else:
1310 1310 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1311 1311 dest, branches = hg.parseurl(dest, opts.get('branch'))
1312 1312 other = hg.peer(repo, opts, dest)
1313 1313 revs = [repo[r].hex() for r in revs]
1314 1314 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1315 1315 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1316 1316 outgoing = discovery.findcommonoutgoing(repo, other,
1317 1317 onlyheads=heads,
1318 1318 force=opts.get('force'),
1319 1319 portable=True)
1320 1320
1321 1321 if not outgoing.missing:
1322 1322 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1323 1323 return 1
1324 1324
1325 1325 if cgversion == '01': #bundle1
1326 1326 bversion = 'HG10' + bundlespec.wirecompression
1327 1327 bcompression = None
1328 1328 elif cgversion in ('02', '03'):
1329 1329 bversion = 'HG20'
1330 1330 bcompression = bundlespec.wirecompression
1331 1331 else:
1332 1332 raise error.ProgrammingError(
1333 1333 'bundle: unexpected changegroup version %s' % cgversion)
1334 1334
1335 1335 # TODO compression options should be derived from bundlespec parsing.
1336 1336 # This is a temporary hack to allow adjusting bundle compression
1337 1337 # level without a) formalizing the bundlespec changes to declare it
1338 1338 # b) introducing a command flag.
1339 1339 compopts = {}
1340 1340 complevel = ui.configint('experimental',
1341 1341 'bundlecomplevel.' + bundlespec.compression)
1342 1342 if complevel is None:
1343 1343 complevel = ui.configint('experimental', 'bundlecomplevel')
1344 1344 if complevel is not None:
1345 1345 compopts['level'] = complevel
1346 1346
1347 1347 # Allow overriding the bundling of obsmarker in phases through
1348 1348 # configuration while we don't have a bundle version that include them
1349 1349 if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'):
1350 1350 bundlespec.contentopts['obsolescence'] = True
1351 1351 if repo.ui.configbool('experimental', 'bundle-phases'):
1352 1352 bundlespec.contentopts['phases'] = True
1353 1353
1354 1354 bundle2.writenewbundle(ui, repo, 'bundle', fname, bversion, outgoing,
1355 1355 bundlespec.contentopts, compression=bcompression,
1356 1356 compopts=compopts)
1357 1357
1358 1358 @command('cat',
1359 1359 [('o', 'output', '',
1360 1360 _('print output to file with formatted name'), _('FORMAT')),
1361 1361 ('r', 'rev', '', _('print the given revision'), _('REV')),
1362 1362 ('', 'decode', None, _('apply any matching decode filter')),
1363 1363 ] + walkopts + formatteropts,
1364 1364 _('[OPTION]... FILE...'),
1365 1365 helpcategory=command.CATEGORY_FILE_CONTENTS,
1366 1366 inferrepo=True,
1367 1367 intents={INTENT_READONLY})
1368 1368 def cat(ui, repo, file1, *pats, **opts):
1369 1369 """output the current or given revision of files
1370 1370
1371 1371 Print the specified files as they were at the given revision. If
1372 1372 no revision is given, the parent of the working directory is used.
1373 1373
1374 1374 Output may be to a file, in which case the name of the file is
1375 1375 given using a template string. See :hg:`help templates`. In addition
1376 1376 to the common template keywords, the following formatting rules are
1377 1377 supported:
1378 1378
1379 1379 :``%%``: literal "%" character
1380 1380 :``%s``: basename of file being printed
1381 1381 :``%d``: dirname of file being printed, or '.' if in repository root
1382 1382 :``%p``: root-relative path name of file being printed
1383 1383 :``%H``: changeset hash (40 hexadecimal digits)
1384 1384 :``%R``: changeset revision number
1385 1385 :``%h``: short-form changeset hash (12 hexadecimal digits)
1386 1386 :``%r``: zero-padded changeset revision number
1387 1387 :``%b``: basename of the exporting repository
1388 1388 :``\\``: literal "\\" character
1389 1389
1390 1390 .. container:: verbose
1391 1391
1392 1392 Template:
1393 1393
1394 1394 The following keywords are supported in addition to the common template
1395 1395 keywords and functions. See also :hg:`help templates`.
1396 1396
1397 1397 :data: String. File content.
1398 1398 :path: String. Repository-absolute path of the file.
1399 1399
1400 1400 Returns 0 on success.
1401 1401 """
1402 1402 opts = pycompat.byteskwargs(opts)
1403 1403 rev = opts.get('rev')
1404 1404 if rev:
1405 1405 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
1406 1406 ctx = scmutil.revsingle(repo, rev)
1407 1407 m = scmutil.match(ctx, (file1,) + pats, opts)
1408 1408 fntemplate = opts.pop('output', '')
1409 1409 if cmdutil.isstdiofilename(fntemplate):
1410 1410 fntemplate = ''
1411 1411
1412 1412 if fntemplate:
1413 1413 fm = formatter.nullformatter(ui, 'cat', opts)
1414 1414 else:
1415 1415 ui.pager('cat')
1416 1416 fm = ui.formatter('cat', opts)
1417 1417 with fm:
1418 1418 return cmdutil.cat(ui, repo, ctx, m, fm, fntemplate, '',
1419 1419 **pycompat.strkwargs(opts))
1420 1420
1421 1421 @command('clone',
1422 1422 [('U', 'noupdate', None, _('the clone will include an empty working '
1423 1423 'directory (only a repository)')),
1424 1424 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1425 1425 _('REV')),
1426 1426 ('r', 'rev', [], _('do not clone everything, but include this changeset'
1427 1427 ' and its ancestors'), _('REV')),
1428 1428 ('b', 'branch', [], _('do not clone everything, but include this branch\'s'
1429 1429 ' changesets and their ancestors'), _('BRANCH')),
1430 1430 ('', 'pull', None, _('use pull protocol to copy metadata')),
1431 1431 ('', 'uncompressed', None,
1432 1432 _('an alias to --stream (DEPRECATED)')),
1433 1433 ('', 'stream', None,
1434 1434 _('clone with minimal data processing')),
1435 1435 ] + remoteopts,
1436 1436 _('[OPTION]... SOURCE [DEST]'),
1437 1437 helpcategory=command.CATEGORY_REPO_CREATION,
1438 1438 helpbasic=True, norepo=True)
1439 1439 def clone(ui, source, dest=None, **opts):
1440 1440 """make a copy of an existing repository
1441 1441
1442 1442 Create a copy of an existing repository in a new directory.
1443 1443
1444 1444 If no destination directory name is specified, it defaults to the
1445 1445 basename of the source.
1446 1446
1447 1447 The location of the source is added to the new repository's
1448 1448 ``.hg/hgrc`` file, as the default to be used for future pulls.
1449 1449
1450 1450 Only local paths and ``ssh://`` URLs are supported as
1451 1451 destinations. For ``ssh://`` destinations, no working directory or
1452 1452 ``.hg/hgrc`` will be created on the remote side.
1453 1453
1454 1454 If the source repository has a bookmark called '@' set, that
1455 1455 revision will be checked out in the new repository by default.
1456 1456
1457 1457 To check out a particular version, use -u/--update, or
1458 1458 -U/--noupdate to create a clone with no working directory.
1459 1459
1460 1460 To pull only a subset of changesets, specify one or more revisions
1461 1461 identifiers with -r/--rev or branches with -b/--branch. The
1462 1462 resulting clone will contain only the specified changesets and
1463 1463 their ancestors. These options (or 'clone src#rev dest') imply
1464 1464 --pull, even for local source repositories.
1465 1465
1466 1466 In normal clone mode, the remote normalizes repository data into a common
1467 1467 exchange format and the receiving end translates this data into its local
1468 1468 storage format. --stream activates a different clone mode that essentially
1469 1469 copies repository files from the remote with minimal data processing. This
1470 1470 significantly reduces the CPU cost of a clone both remotely and locally.
1471 1471 However, it often increases the transferred data size by 30-40%. This can
1472 1472 result in substantially faster clones where I/O throughput is plentiful,
1473 1473 especially for larger repositories. A side-effect of --stream clones is
1474 1474 that storage settings and requirements on the remote are applied locally:
1475 1475 a modern client may inherit legacy or inefficient storage used by the
1476 1476 remote or a legacy Mercurial client may not be able to clone from a
1477 1477 modern Mercurial remote.
1478 1478
1479 1479 .. note::
1480 1480
1481 1481 Specifying a tag will include the tagged changeset but not the
1482 1482 changeset containing the tag.
1483 1483
1484 1484 .. container:: verbose
1485 1485
1486 1486 For efficiency, hardlinks are used for cloning whenever the
1487 1487 source and destination are on the same filesystem (note this
1488 1488 applies only to the repository data, not to the working
1489 1489 directory). Some filesystems, such as AFS, implement hardlinking
1490 1490 incorrectly, but do not report errors. In these cases, use the
1491 1491 --pull option to avoid hardlinking.
1492 1492
1493 1493 Mercurial will update the working directory to the first applicable
1494 1494 revision from this list:
1495 1495
1496 1496 a) null if -U or the source repository has no changesets
1497 1497 b) if -u . and the source repository is local, the first parent of
1498 1498 the source repository's working directory
1499 1499 c) the changeset specified with -u (if a branch name, this means the
1500 1500 latest head of that branch)
1501 1501 d) the changeset specified with -r
1502 1502 e) the tipmost head specified with -b
1503 1503 f) the tipmost head specified with the url#branch source syntax
1504 1504 g) the revision marked with the '@' bookmark, if present
1505 1505 h) the tipmost head of the default branch
1506 1506 i) tip
1507 1507
1508 1508 When cloning from servers that support it, Mercurial may fetch
1509 1509 pre-generated data from a server-advertised URL or inline from the
1510 1510 same stream. When this is done, hooks operating on incoming changesets
1511 1511 and changegroups may fire more than once, once for each pre-generated
1512 1512 bundle and as well as for any additional remaining data. In addition,
1513 1513 if an error occurs, the repository may be rolled back to a partial
1514 1514 clone. This behavior may change in future releases.
1515 1515 See :hg:`help -e clonebundles` for more.
1516 1516
1517 1517 Examples:
1518 1518
1519 1519 - clone a remote repository to a new directory named hg/::
1520 1520
1521 1521 hg clone https://www.mercurial-scm.org/repo/hg/
1522 1522
1523 1523 - create a lightweight local clone::
1524 1524
1525 1525 hg clone project/ project-feature/
1526 1526
1527 1527 - clone from an absolute path on an ssh server (note double-slash)::
1528 1528
1529 1529 hg clone ssh://user@server//home/projects/alpha/
1530 1530
1531 1531 - do a streaming clone while checking out a specified version::
1532 1532
1533 1533 hg clone --stream http://server/repo -u 1.5
1534 1534
1535 1535 - create a repository without changesets after a particular revision::
1536 1536
1537 1537 hg clone -r 04e544 experimental/ good/
1538 1538
1539 1539 - clone (and track) a particular named branch::
1540 1540
1541 1541 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1542 1542
1543 1543 See :hg:`help urls` for details on specifying URLs.
1544 1544
1545 1545 Returns 0 on success.
1546 1546 """
1547 1547 opts = pycompat.byteskwargs(opts)
1548 1548 if opts.get('noupdate') and opts.get('updaterev'):
1549 1549 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1550 1550
1551 1551 # --include/--exclude can come from narrow or sparse.
1552 1552 includepats, excludepats = None, None
1553 1553
1554 1554 # hg.clone() differentiates between None and an empty set. So make sure
1555 1555 # patterns are sets if narrow is requested without patterns.
1556 1556 if opts.get('narrow'):
1557 1557 includepats = set()
1558 1558 excludepats = set()
1559 1559
1560 1560 if opts.get('include'):
1561 1561 includepats = narrowspec.parsepatterns(opts.get('include'))
1562 1562 if opts.get('exclude'):
1563 1563 excludepats = narrowspec.parsepatterns(opts.get('exclude'))
1564 1564
1565 1565 r = hg.clone(ui, opts, source, dest,
1566 1566 pull=opts.get('pull'),
1567 1567 stream=opts.get('stream') or opts.get('uncompressed'),
1568 1568 revs=opts.get('rev'),
1569 1569 update=opts.get('updaterev') or not opts.get('noupdate'),
1570 1570 branch=opts.get('branch'),
1571 1571 shareopts=opts.get('shareopts'),
1572 1572 storeincludepats=includepats,
1573 1573 storeexcludepats=excludepats,
1574 1574 depth=opts.get('depth') or None)
1575 1575
1576 1576 return r is None
1577 1577
1578 1578 @command('commit|ci',
1579 1579 [('A', 'addremove', None,
1580 1580 _('mark new/missing files as added/removed before committing')),
1581 1581 ('', 'close-branch', None,
1582 1582 _('mark a branch head as closed')),
1583 1583 ('', 'amend', None, _('amend the parent of the working directory')),
1584 1584 ('s', 'secret', None, _('use the secret phase for committing')),
1585 1585 ('e', 'edit', None, _('invoke editor on commit messages')),
1586 1586 ('i', 'interactive', None, _('use interactive mode')),
1587 1587 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1588 1588 _('[OPTION]... [FILE]...'),
1589 1589 helpcategory=command.CATEGORY_COMMITTING, helpbasic=True,
1590 1590 inferrepo=True)
1591 1591 def commit(ui, repo, *pats, **opts):
1592 1592 """commit the specified files or all outstanding changes
1593 1593
1594 1594 Commit changes to the given files into the repository. Unlike a
1595 1595 centralized SCM, this operation is a local operation. See
1596 1596 :hg:`push` for a way to actively distribute your changes.
1597 1597
1598 1598 If a list of files is omitted, all changes reported by :hg:`status`
1599 1599 will be committed.
1600 1600
1601 1601 If you are committing the result of a merge, do not provide any
1602 1602 filenames or -I/-X filters.
1603 1603
1604 1604 If no commit message is specified, Mercurial starts your
1605 1605 configured editor where you can enter a message. In case your
1606 1606 commit fails, you will find a backup of your message in
1607 1607 ``.hg/last-message.txt``.
1608 1608
1609 1609 The --close-branch flag can be used to mark the current branch
1610 1610 head closed. When all heads of a branch are closed, the branch
1611 1611 will be considered closed and no longer listed.
1612 1612
1613 1613 The --amend flag can be used to amend the parent of the
1614 1614 working directory with a new commit that contains the changes
1615 1615 in the parent in addition to those currently reported by :hg:`status`,
1616 1616 if there are any. The old commit is stored in a backup bundle in
1617 1617 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1618 1618 on how to restore it).
1619 1619
1620 1620 Message, user and date are taken from the amended commit unless
1621 1621 specified. When a message isn't specified on the command line,
1622 1622 the editor will open with the message of the amended commit.
1623 1623
1624 1624 It is not possible to amend public changesets (see :hg:`help phases`)
1625 1625 or changesets that have children.
1626 1626
1627 1627 See :hg:`help dates` for a list of formats valid for -d/--date.
1628 1628
1629 1629 Returns 0 on success, 1 if nothing changed.
1630 1630
1631 1631 .. container:: verbose
1632 1632
1633 1633 Examples:
1634 1634
1635 1635 - commit all files ending in .py::
1636 1636
1637 1637 hg commit --include "set:**.py"
1638 1638
1639 1639 - commit all non-binary files::
1640 1640
1641 1641 hg commit --exclude "set:binary()"
1642 1642
1643 1643 - amend the current commit and set the date to now::
1644 1644
1645 1645 hg commit --amend --date now
1646 1646 """
1647 1647 with repo.wlock(), repo.lock():
1648 1648 return _docommit(ui, repo, *pats, **opts)
1649 1649
1650 1650 def _docommit(ui, repo, *pats, **opts):
1651 1651 if opts.get(r'interactive'):
1652 1652 opts.pop(r'interactive')
1653 1653 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1654 1654 cmdutil.recordfilter, *pats,
1655 1655 **opts)
1656 1656 # ret can be 0 (no changes to record) or the value returned by
1657 1657 # commit(), 1 if nothing changed or None on success.
1658 1658 return 1 if ret == 0 else ret
1659 1659
1660 1660 opts = pycompat.byteskwargs(opts)
1661 1661 if opts.get('subrepos'):
1662 1662 if opts.get('amend'):
1663 1663 raise error.Abort(_('cannot amend with --subrepos'))
1664 1664 # Let --subrepos on the command line override config setting.
1665 1665 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1666 1666
1667 1667 cmdutil.checkunfinished(repo, commit=True)
1668 1668
1669 1669 branch = repo[None].branch()
1670 1670 bheads = repo.branchheads(branch)
1671 1671
1672 1672 extra = {}
1673 1673 if opts.get('close_branch'):
1674 1674 extra['close'] = '1'
1675 1675
1676 1676 if not bheads:
1677 1677 raise error.Abort(_('can only close branch heads'))
1678 1678 elif branch == repo['.'].branch() and repo['.'].node() not in bheads:
1679 1679 raise error.Abort(_('can only close branch heads'))
1680 1680 elif opts.get('amend'):
1681 1681 if (repo['.'].p1().branch() != branch and
1682 1682 repo['.'].p2().branch() != branch):
1683 1683 raise error.Abort(_('can only close branch heads'))
1684 1684
1685 1685 if opts.get('amend'):
1686 1686 if ui.configbool('ui', 'commitsubrepos'):
1687 1687 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1688 1688
1689 1689 old = repo['.']
1690 1690 rewriteutil.precheck(repo, [old.rev()], 'amend')
1691 1691
1692 1692 # Currently histedit gets confused if an amend happens while histedit
1693 1693 # is in progress. Since we have a checkunfinished command, we are
1694 1694 # temporarily honoring it.
1695 1695 #
1696 1696 # Note: eventually this guard will be removed. Please do not expect
1697 1697 # this behavior to remain.
1698 1698 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1699 1699 cmdutil.checkunfinished(repo)
1700 1700
1701 1701 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
1702 1702 if node == old.node():
1703 1703 ui.status(_("nothing changed\n"))
1704 1704 return 1
1705 1705 else:
1706 1706 def commitfunc(ui, repo, message, match, opts):
1707 1707 overrides = {}
1708 1708 if opts.get('secret'):
1709 1709 overrides[('phases', 'new-commit')] = 'secret'
1710 1710
1711 1711 baseui = repo.baseui
1712 1712 with baseui.configoverride(overrides, 'commit'):
1713 1713 with ui.configoverride(overrides, 'commit'):
1714 1714 editform = cmdutil.mergeeditform(repo[None],
1715 1715 'commit.normal')
1716 1716 editor = cmdutil.getcommiteditor(
1717 1717 editform=editform, **pycompat.strkwargs(opts))
1718 1718 return repo.commit(message,
1719 1719 opts.get('user'),
1720 1720 opts.get('date'),
1721 1721 match,
1722 1722 editor=editor,
1723 1723 extra=extra)
1724 1724
1725 1725 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1726 1726
1727 1727 if not node:
1728 1728 stat = cmdutil.postcommitstatus(repo, pats, opts)
1729 1729 if stat[3]:
1730 1730 ui.status(_("nothing changed (%d missing files, see "
1731 1731 "'hg status')\n") % len(stat[3]))
1732 1732 else:
1733 1733 ui.status(_("nothing changed\n"))
1734 1734 return 1
1735 1735
1736 1736 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1737 1737
1738 if not ui.quiet and ui.configbool('commands', 'commit.post-status'):
1739 status(ui, repo, modified=True, added=True, removed=True, deleted=True,
1740 unknown=True, subrepos=opts.get('subrepos'))
1741
1738 1742 @command('config|showconfig|debugconfig',
1739 1743 [('u', 'untrusted', None, _('show untrusted configuration options')),
1740 1744 ('e', 'edit', None, _('edit user config')),
1741 1745 ('l', 'local', None, _('edit repository config')),
1742 1746 ('g', 'global', None, _('edit global config'))] + formatteropts,
1743 1747 _('[-u] [NAME]...'),
1744 1748 helpcategory=command.CATEGORY_HELP,
1745 1749 optionalrepo=True,
1746 1750 intents={INTENT_READONLY})
1747 1751 def config(ui, repo, *values, **opts):
1748 1752 """show combined config settings from all hgrc files
1749 1753
1750 1754 With no arguments, print names and values of all config items.
1751 1755
1752 1756 With one argument of the form section.name, print just the value
1753 1757 of that config item.
1754 1758
1755 1759 With multiple arguments, print names and values of all config
1756 1760 items with matching section names or section.names.
1757 1761
1758 1762 With --edit, start an editor on the user-level config file. With
1759 1763 --global, edit the system-wide config file. With --local, edit the
1760 1764 repository-level config file.
1761 1765
1762 1766 With --debug, the source (filename and line number) is printed
1763 1767 for each config item.
1764 1768
1765 1769 See :hg:`help config` for more information about config files.
1766 1770
1767 1771 .. container:: verbose
1768 1772
1769 1773 Template:
1770 1774
1771 1775 The following keywords are supported. See also :hg:`help templates`.
1772 1776
1773 1777 :name: String. Config name.
1774 1778 :source: String. Filename and line number where the item is defined.
1775 1779 :value: String. Config value.
1776 1780
1777 1781 Returns 0 on success, 1 if NAME does not exist.
1778 1782
1779 1783 """
1780 1784
1781 1785 opts = pycompat.byteskwargs(opts)
1782 1786 if opts.get('edit') or opts.get('local') or opts.get('global'):
1783 1787 if opts.get('local') and opts.get('global'):
1784 1788 raise error.Abort(_("can't use --local and --global together"))
1785 1789
1786 1790 if opts.get('local'):
1787 1791 if not repo:
1788 1792 raise error.Abort(_("can't use --local outside a repository"))
1789 1793 paths = [repo.vfs.join('hgrc')]
1790 1794 elif opts.get('global'):
1791 1795 paths = rcutil.systemrcpath()
1792 1796 else:
1793 1797 paths = rcutil.userrcpath()
1794 1798
1795 1799 for f in paths:
1796 1800 if os.path.exists(f):
1797 1801 break
1798 1802 else:
1799 1803 if opts.get('global'):
1800 1804 samplehgrc = uimod.samplehgrcs['global']
1801 1805 elif opts.get('local'):
1802 1806 samplehgrc = uimod.samplehgrcs['local']
1803 1807 else:
1804 1808 samplehgrc = uimod.samplehgrcs['user']
1805 1809
1806 1810 f = paths[0]
1807 1811 fp = open(f, "wb")
1808 1812 fp.write(util.tonativeeol(samplehgrc))
1809 1813 fp.close()
1810 1814
1811 1815 editor = ui.geteditor()
1812 1816 ui.system("%s \"%s\"" % (editor, f),
1813 1817 onerr=error.Abort, errprefix=_("edit failed"),
1814 1818 blockedtag='config_edit')
1815 1819 return
1816 1820 ui.pager('config')
1817 1821 fm = ui.formatter('config', opts)
1818 1822 for t, f in rcutil.rccomponents():
1819 1823 if t == 'path':
1820 1824 ui.debug('read config from: %s\n' % f)
1821 1825 elif t == 'items':
1822 1826 for section, name, value, source in f:
1823 1827 ui.debug('set config by: %s\n' % source)
1824 1828 else:
1825 1829 raise error.ProgrammingError('unknown rctype: %s' % t)
1826 1830 untrusted = bool(opts.get('untrusted'))
1827 1831
1828 1832 selsections = selentries = []
1829 1833 if values:
1830 1834 selsections = [v for v in values if '.' not in v]
1831 1835 selentries = [v for v in values if '.' in v]
1832 1836 uniquesel = (len(selentries) == 1 and not selsections)
1833 1837 selsections = set(selsections)
1834 1838 selentries = set(selentries)
1835 1839
1836 1840 matched = False
1837 1841 for section, name, value in ui.walkconfig(untrusted=untrusted):
1838 1842 source = ui.configsource(section, name, untrusted)
1839 1843 value = pycompat.bytestr(value)
1840 1844 if fm.isplain():
1841 1845 source = source or 'none'
1842 1846 value = value.replace('\n', '\\n')
1843 1847 entryname = section + '.' + name
1844 1848 if values and not (section in selsections or entryname in selentries):
1845 1849 continue
1846 1850 fm.startitem()
1847 1851 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1848 1852 if uniquesel:
1849 1853 fm.data(name=entryname)
1850 1854 fm.write('value', '%s\n', value)
1851 1855 else:
1852 1856 fm.write('name value', '%s=%s\n', entryname, value)
1853 1857 matched = True
1854 1858 fm.end()
1855 1859 if matched:
1856 1860 return 0
1857 1861 return 1
1858 1862
1859 1863 @command('copy|cp',
1860 1864 [('A', 'after', None, _('record a copy that has already occurred')),
1861 1865 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1862 1866 ] + walkopts + dryrunopts,
1863 1867 _('[OPTION]... [SOURCE]... DEST'),
1864 1868 helpcategory=command.CATEGORY_FILE_CONTENTS)
1865 1869 def copy(ui, repo, *pats, **opts):
1866 1870 """mark files as copied for the next commit
1867 1871
1868 1872 Mark dest as having copies of source files. If dest is a
1869 1873 directory, copies are put in that directory. If dest is a file,
1870 1874 the source must be a single file.
1871 1875
1872 1876 By default, this command copies the contents of files as they
1873 1877 exist in the working directory. If invoked with -A/--after, the
1874 1878 operation is recorded, but no copying is performed.
1875 1879
1876 1880 This command takes effect with the next commit. To undo a copy
1877 1881 before that, see :hg:`revert`.
1878 1882
1879 1883 Returns 0 on success, 1 if errors are encountered.
1880 1884 """
1881 1885 opts = pycompat.byteskwargs(opts)
1882 1886 with repo.wlock(False):
1883 1887 return cmdutil.copy(ui, repo, pats, opts)
1884 1888
1885 1889 @command(
1886 1890 'debugcommands', [], _('[COMMAND]'),
1887 1891 helpcategory=command.CATEGORY_HELP,
1888 1892 norepo=True)
1889 1893 def debugcommands(ui, cmd='', *args):
1890 1894 """list all available commands and options"""
1891 1895 for cmd, vals in sorted(table.iteritems()):
1892 1896 cmd = cmd.split('|')[0]
1893 1897 opts = ', '.join([i[1] for i in vals[1]])
1894 1898 ui.write('%s: %s\n' % (cmd, opts))
1895 1899
1896 1900 @command('debugcomplete',
1897 1901 [('o', 'options', None, _('show the command options'))],
1898 1902 _('[-o] CMD'),
1899 1903 helpcategory=command.CATEGORY_HELP,
1900 1904 norepo=True)
1901 1905 def debugcomplete(ui, cmd='', **opts):
1902 1906 """returns the completion list associated with the given command"""
1903 1907
1904 1908 if opts.get(r'options'):
1905 1909 options = []
1906 1910 otables = [globalopts]
1907 1911 if cmd:
1908 1912 aliases, entry = cmdutil.findcmd(cmd, table, False)
1909 1913 otables.append(entry[1])
1910 1914 for t in otables:
1911 1915 for o in t:
1912 1916 if "(DEPRECATED)" in o[3]:
1913 1917 continue
1914 1918 if o[0]:
1915 1919 options.append('-%s' % o[0])
1916 1920 options.append('--%s' % o[1])
1917 1921 ui.write("%s\n" % "\n".join(options))
1918 1922 return
1919 1923
1920 1924 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
1921 1925 if ui.verbose:
1922 1926 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1923 1927 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1924 1928
1925 1929 @command('diff',
1926 1930 [('r', 'rev', [], _('revision'), _('REV')),
1927 1931 ('c', 'change', '', _('change made by revision'), _('REV'))
1928 1932 ] + diffopts + diffopts2 + walkopts + subrepoopts,
1929 1933 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1930 1934 helpcategory=command.CATEGORY_FILE_CONTENTS,
1931 1935 helpbasic=True, inferrepo=True, intents={INTENT_READONLY})
1932 1936 def diff(ui, repo, *pats, **opts):
1933 1937 """diff repository (or selected files)
1934 1938
1935 1939 Show differences between revisions for the specified files.
1936 1940
1937 1941 Differences between files are shown using the unified diff format.
1938 1942
1939 1943 .. note::
1940 1944
1941 1945 :hg:`diff` may generate unexpected results for merges, as it will
1942 1946 default to comparing against the working directory's first
1943 1947 parent changeset if no revisions are specified.
1944 1948
1945 1949 When two revision arguments are given, then changes are shown
1946 1950 between those revisions. If only one revision is specified then
1947 1951 that revision is compared to the working directory, and, when no
1948 1952 revisions are specified, the working directory files are compared
1949 1953 to its first parent.
1950 1954
1951 1955 Alternatively you can specify -c/--change with a revision to see
1952 1956 the changes in that changeset relative to its first parent.
1953 1957
1954 1958 Without the -a/--text option, diff will avoid generating diffs of
1955 1959 files it detects as binary. With -a, diff will generate a diff
1956 1960 anyway, probably with undesirable results.
1957 1961
1958 1962 Use the -g/--git option to generate diffs in the git extended diff
1959 1963 format. For more information, read :hg:`help diffs`.
1960 1964
1961 1965 .. container:: verbose
1962 1966
1963 1967 Examples:
1964 1968
1965 1969 - compare a file in the current working directory to its parent::
1966 1970
1967 1971 hg diff foo.c
1968 1972
1969 1973 - compare two historical versions of a directory, with rename info::
1970 1974
1971 1975 hg diff --git -r 1.0:1.2 lib/
1972 1976
1973 1977 - get change stats relative to the last change on some date::
1974 1978
1975 1979 hg diff --stat -r "date('may 2')"
1976 1980
1977 1981 - diff all newly-added files that contain a keyword::
1978 1982
1979 1983 hg diff "set:added() and grep(GNU)"
1980 1984
1981 1985 - compare a revision and its parents::
1982 1986
1983 1987 hg diff -c 9353 # compare against first parent
1984 1988 hg diff -r 9353^:9353 # same using revset syntax
1985 1989 hg diff -r 9353^2:9353 # compare against the second parent
1986 1990
1987 1991 Returns 0 on success.
1988 1992 """
1989 1993
1990 1994 opts = pycompat.byteskwargs(opts)
1991 1995 revs = opts.get('rev')
1992 1996 change = opts.get('change')
1993 1997 stat = opts.get('stat')
1994 1998 reverse = opts.get('reverse')
1995 1999
1996 2000 if revs and change:
1997 2001 msg = _('cannot specify --rev and --change at the same time')
1998 2002 raise error.Abort(msg)
1999 2003 elif change:
2000 2004 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
2001 2005 ctx2 = scmutil.revsingle(repo, change, None)
2002 2006 ctx1 = ctx2.p1()
2003 2007 else:
2004 2008 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
2005 2009 ctx1, ctx2 = scmutil.revpair(repo, revs)
2006 2010 node1, node2 = ctx1.node(), ctx2.node()
2007 2011
2008 2012 if reverse:
2009 2013 node1, node2 = node2, node1
2010 2014
2011 2015 diffopts = patch.diffallopts(ui, opts)
2012 2016 m = scmutil.match(ctx2, pats, opts)
2013 2017 m = repo.narrowmatch(m)
2014 2018 ui.pager('diff')
2015 2019 logcmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2016 2020 listsubrepos=opts.get('subrepos'),
2017 2021 root=opts.get('root'))
2018 2022
2019 2023 @command('export',
2020 2024 [('B', 'bookmark', '',
2021 2025 _('export changes only reachable by given bookmark'), _('BOOKMARK')),
2022 2026 ('o', 'output', '',
2023 2027 _('print output to file with formatted name'), _('FORMAT')),
2024 2028 ('', 'switch-parent', None, _('diff against the second parent')),
2025 2029 ('r', 'rev', [], _('revisions to export'), _('REV')),
2026 2030 ] + diffopts + formatteropts,
2027 2031 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2028 2032 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2029 2033 helpbasic=True, intents={INTENT_READONLY})
2030 2034 def export(ui, repo, *changesets, **opts):
2031 2035 """dump the header and diffs for one or more changesets
2032 2036
2033 2037 Print the changeset header and diffs for one or more revisions.
2034 2038 If no revision is given, the parent of the working directory is used.
2035 2039
2036 2040 The information shown in the changeset header is: author, date,
2037 2041 branch name (if non-default), changeset hash, parent(s) and commit
2038 2042 comment.
2039 2043
2040 2044 .. note::
2041 2045
2042 2046 :hg:`export` may generate unexpected diff output for merge
2043 2047 changesets, as it will compare the merge changeset against its
2044 2048 first parent only.
2045 2049
2046 2050 Output may be to a file, in which case the name of the file is
2047 2051 given using a template string. See :hg:`help templates`. In addition
2048 2052 to the common template keywords, the following formatting rules are
2049 2053 supported:
2050 2054
2051 2055 :``%%``: literal "%" character
2052 2056 :``%H``: changeset hash (40 hexadecimal digits)
2053 2057 :``%N``: number of patches being generated
2054 2058 :``%R``: changeset revision number
2055 2059 :``%b``: basename of the exporting repository
2056 2060 :``%h``: short-form changeset hash (12 hexadecimal digits)
2057 2061 :``%m``: first line of the commit message (only alphanumeric characters)
2058 2062 :``%n``: zero-padded sequence number, starting at 1
2059 2063 :``%r``: zero-padded changeset revision number
2060 2064 :``\\``: literal "\\" character
2061 2065
2062 2066 Without the -a/--text option, export will avoid generating diffs
2063 2067 of files it detects as binary. With -a, export will generate a
2064 2068 diff anyway, probably with undesirable results.
2065 2069
2066 2070 With -B/--bookmark changesets reachable by the given bookmark are
2067 2071 selected.
2068 2072
2069 2073 Use the -g/--git option to generate diffs in the git extended diff
2070 2074 format. See :hg:`help diffs` for more information.
2071 2075
2072 2076 With the --switch-parent option, the diff will be against the
2073 2077 second parent. It can be useful to review a merge.
2074 2078
2075 2079 .. container:: verbose
2076 2080
2077 2081 Template:
2078 2082
2079 2083 The following keywords are supported in addition to the common template
2080 2084 keywords and functions. See also :hg:`help templates`.
2081 2085
2082 2086 :diff: String. Diff content.
2083 2087 :parents: List of strings. Parent nodes of the changeset.
2084 2088
2085 2089 Examples:
2086 2090
2087 2091 - use export and import to transplant a bugfix to the current
2088 2092 branch::
2089 2093
2090 2094 hg export -r 9353 | hg import -
2091 2095
2092 2096 - export all the changesets between two revisions to a file with
2093 2097 rename information::
2094 2098
2095 2099 hg export --git -r 123:150 > changes.txt
2096 2100
2097 2101 - split outgoing changes into a series of patches with
2098 2102 descriptive names::
2099 2103
2100 2104 hg export -r "outgoing()" -o "%n-%m.patch"
2101 2105
2102 2106 Returns 0 on success.
2103 2107 """
2104 2108 opts = pycompat.byteskwargs(opts)
2105 2109 bookmark = opts.get('bookmark')
2106 2110 changesets += tuple(opts.get('rev', []))
2107 2111
2108 2112 if bookmark and changesets:
2109 2113 raise error.Abort(_("-r and -B are mutually exclusive"))
2110 2114
2111 2115 if bookmark:
2112 2116 if bookmark not in repo._bookmarks:
2113 2117 raise error.Abort(_("bookmark '%s' not found") % bookmark)
2114 2118
2115 2119 revs = scmutil.bookmarkrevs(repo, bookmark)
2116 2120 else:
2117 2121 if not changesets:
2118 2122 changesets = ['.']
2119 2123
2120 2124 repo = scmutil.unhidehashlikerevs(repo, changesets, 'nowarn')
2121 2125 revs = scmutil.revrange(repo, changesets)
2122 2126
2123 2127 if not revs:
2124 2128 raise error.Abort(_("export requires at least one changeset"))
2125 2129 if len(revs) > 1:
2126 2130 ui.note(_('exporting patches:\n'))
2127 2131 else:
2128 2132 ui.note(_('exporting patch:\n'))
2129 2133
2130 2134 fntemplate = opts.get('output')
2131 2135 if cmdutil.isstdiofilename(fntemplate):
2132 2136 fntemplate = ''
2133 2137
2134 2138 if fntemplate:
2135 2139 fm = formatter.nullformatter(ui, 'export', opts)
2136 2140 else:
2137 2141 ui.pager('export')
2138 2142 fm = ui.formatter('export', opts)
2139 2143 with fm:
2140 2144 cmdutil.export(repo, revs, fm, fntemplate=fntemplate,
2141 2145 switch_parent=opts.get('switch_parent'),
2142 2146 opts=patch.diffallopts(ui, opts))
2143 2147
2144 2148 @command('files',
2145 2149 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2146 2150 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2147 2151 ] + walkopts + formatteropts + subrepoopts,
2148 2152 _('[OPTION]... [FILE]...'),
2149 2153 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2150 2154 intents={INTENT_READONLY})
2151 2155 def files(ui, repo, *pats, **opts):
2152 2156 """list tracked files
2153 2157
2154 2158 Print files under Mercurial control in the working directory or
2155 2159 specified revision for given files (excluding removed files).
2156 2160 Files can be specified as filenames or filesets.
2157 2161
2158 2162 If no files are given to match, this command prints the names
2159 2163 of all files under Mercurial control.
2160 2164
2161 2165 .. container:: verbose
2162 2166
2163 2167 Template:
2164 2168
2165 2169 The following keywords are supported in addition to the common template
2166 2170 keywords and functions. See also :hg:`help templates`.
2167 2171
2168 2172 :flags: String. Character denoting file's symlink and executable bits.
2169 2173 :path: String. Repository-absolute path of the file.
2170 2174 :size: Integer. Size of the file in bytes.
2171 2175
2172 2176 Examples:
2173 2177
2174 2178 - list all files under the current directory::
2175 2179
2176 2180 hg files .
2177 2181
2178 2182 - shows sizes and flags for current revision::
2179 2183
2180 2184 hg files -vr .
2181 2185
2182 2186 - list all files named README::
2183 2187
2184 2188 hg files -I "**/README"
2185 2189
2186 2190 - list all binary files::
2187 2191
2188 2192 hg files "set:binary()"
2189 2193
2190 2194 - find files containing a regular expression::
2191 2195
2192 2196 hg files "set:grep('bob')"
2193 2197
2194 2198 - search tracked file contents with xargs and grep::
2195 2199
2196 2200 hg files -0 | xargs -0 grep foo
2197 2201
2198 2202 See :hg:`help patterns` and :hg:`help filesets` for more information
2199 2203 on specifying file patterns.
2200 2204
2201 2205 Returns 0 if a match is found, 1 otherwise.
2202 2206
2203 2207 """
2204 2208
2205 2209 opts = pycompat.byteskwargs(opts)
2206 2210 rev = opts.get('rev')
2207 2211 if rev:
2208 2212 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
2209 2213 ctx = scmutil.revsingle(repo, rev, None)
2210 2214
2211 2215 end = '\n'
2212 2216 if opts.get('print0'):
2213 2217 end = '\0'
2214 2218 fmt = '%s' + end
2215 2219
2216 2220 m = scmutil.match(ctx, pats, opts)
2217 2221 ui.pager('files')
2218 2222 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2219 2223 with ui.formatter('files', opts) as fm:
2220 2224 return cmdutil.files(ui, ctx, m, uipathfn, fm, fmt,
2221 2225 opts.get('subrepos'))
2222 2226
2223 2227 @command(
2224 2228 'forget',
2225 2229 [('i', 'interactive', None, _('use interactive mode')),
2226 2230 ] + walkopts + dryrunopts,
2227 2231 _('[OPTION]... FILE...'),
2228 2232 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2229 2233 helpbasic=True, inferrepo=True)
2230 2234 def forget(ui, repo, *pats, **opts):
2231 2235 """forget the specified files on the next commit
2232 2236
2233 2237 Mark the specified files so they will no longer be tracked
2234 2238 after the next commit.
2235 2239
2236 2240 This only removes files from the current branch, not from the
2237 2241 entire project history, and it does not delete them from the
2238 2242 working directory.
2239 2243
2240 2244 To delete the file from the working directory, see :hg:`remove`.
2241 2245
2242 2246 To undo a forget before the next commit, see :hg:`add`.
2243 2247
2244 2248 .. container:: verbose
2245 2249
2246 2250 Examples:
2247 2251
2248 2252 - forget newly-added binary files::
2249 2253
2250 2254 hg forget "set:added() and binary()"
2251 2255
2252 2256 - forget files that would be excluded by .hgignore::
2253 2257
2254 2258 hg forget "set:hgignore()"
2255 2259
2256 2260 Returns 0 on success.
2257 2261 """
2258 2262
2259 2263 opts = pycompat.byteskwargs(opts)
2260 2264 if not pats:
2261 2265 raise error.Abort(_('no files specified'))
2262 2266
2263 2267 m = scmutil.match(repo[None], pats, opts)
2264 2268 dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
2265 2269 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2266 2270 rejected = cmdutil.forget(ui, repo, m, prefix="", uipathfn=uipathfn,
2267 2271 explicitonly=False, dryrun=dryrun,
2268 2272 interactive=interactive)[0]
2269 2273 return rejected and 1 or 0
2270 2274
2271 2275 @command(
2272 2276 'graft',
2273 2277 [('r', 'rev', [], _('revisions to graft'), _('REV')),
2274 2278 ('', 'base', '',
2275 2279 _('base revision when doing the graft merge (ADVANCED)'), _('REV')),
2276 2280 ('c', 'continue', False, _('resume interrupted graft')),
2277 2281 ('', 'stop', False, _('stop interrupted graft')),
2278 2282 ('', 'abort', False, _('abort interrupted graft')),
2279 2283 ('e', 'edit', False, _('invoke editor on commit messages')),
2280 2284 ('', 'log', None, _('append graft info to log message')),
2281 2285 ('', 'no-commit', None,
2282 2286 _("don't commit, just apply the changes in working directory")),
2283 2287 ('f', 'force', False, _('force graft')),
2284 2288 ('D', 'currentdate', False,
2285 2289 _('record the current date as commit date')),
2286 2290 ('U', 'currentuser', False,
2287 2291 _('record the current user as committer'))]
2288 2292 + commitopts2 + mergetoolopts + dryrunopts,
2289 2293 _('[OPTION]... [-r REV]... REV...'),
2290 2294 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
2291 2295 def graft(ui, repo, *revs, **opts):
2292 2296 '''copy changes from other branches onto the current branch
2293 2297
2294 2298 This command uses Mercurial's merge logic to copy individual
2295 2299 changes from other branches without merging branches in the
2296 2300 history graph. This is sometimes known as 'backporting' or
2297 2301 'cherry-picking'. By default, graft will copy user, date, and
2298 2302 description from the source changesets.
2299 2303
2300 2304 Changesets that are ancestors of the current revision, that have
2301 2305 already been grafted, or that are merges will be skipped.
2302 2306
2303 2307 If --log is specified, log messages will have a comment appended
2304 2308 of the form::
2305 2309
2306 2310 (grafted from CHANGESETHASH)
2307 2311
2308 2312 If --force is specified, revisions will be grafted even if they
2309 2313 are already ancestors of, or have been grafted to, the destination.
2310 2314 This is useful when the revisions have since been backed out.
2311 2315
2312 2316 If a graft merge results in conflicts, the graft process is
2313 2317 interrupted so that the current merge can be manually resolved.
2314 2318 Once all conflicts are addressed, the graft process can be
2315 2319 continued with the -c/--continue option.
2316 2320
2317 2321 The -c/--continue option reapplies all the earlier options.
2318 2322
2319 2323 .. container:: verbose
2320 2324
2321 2325 The --base option exposes more of how graft internally uses merge with a
2322 2326 custom base revision. --base can be used to specify another ancestor than
2323 2327 the first and only parent.
2324 2328
2325 2329 The command::
2326 2330
2327 2331 hg graft -r 345 --base 234
2328 2332
2329 2333 is thus pretty much the same as::
2330 2334
2331 2335 hg diff -r 234 -r 345 | hg import
2332 2336
2333 2337 but using merge to resolve conflicts and track moved files.
2334 2338
2335 2339 The result of a merge can thus be backported as a single commit by
2336 2340 specifying one of the merge parents as base, and thus effectively
2337 2341 grafting the changes from the other side.
2338 2342
2339 2343 It is also possible to collapse multiple changesets and clean up history
2340 2344 by specifying another ancestor as base, much like rebase --collapse
2341 2345 --keep.
2342 2346
2343 2347 The commit message can be tweaked after the fact using commit --amend .
2344 2348
2345 2349 For using non-ancestors as the base to backout changes, see the backout
2346 2350 command and the hidden --parent option.
2347 2351
2348 2352 .. container:: verbose
2349 2353
2350 2354 Examples:
2351 2355
2352 2356 - copy a single change to the stable branch and edit its description::
2353 2357
2354 2358 hg update stable
2355 2359 hg graft --edit 9393
2356 2360
2357 2361 - graft a range of changesets with one exception, updating dates::
2358 2362
2359 2363 hg graft -D "2085::2093 and not 2091"
2360 2364
2361 2365 - continue a graft after resolving conflicts::
2362 2366
2363 2367 hg graft -c
2364 2368
2365 2369 - show the source of a grafted changeset::
2366 2370
2367 2371 hg log --debug -r .
2368 2372
2369 2373 - show revisions sorted by date::
2370 2374
2371 2375 hg log -r "sort(all(), date)"
2372 2376
2373 2377 - backport the result of a merge as a single commit::
2374 2378
2375 2379 hg graft -r 123 --base 123^
2376 2380
2377 2381 - land a feature branch as one changeset::
2378 2382
2379 2383 hg up -cr default
2380 2384 hg graft -r featureX --base "ancestor('featureX', 'default')"
2381 2385
2382 2386 See :hg:`help revisions` for more about specifying revisions.
2383 2387
2384 2388 Returns 0 on successful completion.
2385 2389 '''
2386 2390 with repo.wlock():
2387 2391 return _dograft(ui, repo, *revs, **opts)
2388 2392
2389 2393 def _dograft(ui, repo, *revs, **opts):
2390 2394 opts = pycompat.byteskwargs(opts)
2391 2395 if revs and opts.get('rev'):
2392 2396 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
2393 2397 'revision ordering!\n'))
2394 2398
2395 2399 revs = list(revs)
2396 2400 revs.extend(opts.get('rev'))
2397 2401 basectx = None
2398 2402 if opts.get('base'):
2399 2403 basectx = scmutil.revsingle(repo, opts['base'], None)
2400 2404 # a dict of data to be stored in state file
2401 2405 statedata = {}
2402 2406 # list of new nodes created by ongoing graft
2403 2407 statedata['newnodes'] = []
2404 2408
2405 2409 if opts.get('user') and opts.get('currentuser'):
2406 2410 raise error.Abort(_('--user and --currentuser are mutually exclusive'))
2407 2411 if opts.get('date') and opts.get('currentdate'):
2408 2412 raise error.Abort(_('--date and --currentdate are mutually exclusive'))
2409 2413 if not opts.get('user') and opts.get('currentuser'):
2410 2414 opts['user'] = ui.username()
2411 2415 if not opts.get('date') and opts.get('currentdate'):
2412 2416 opts['date'] = "%d %d" % dateutil.makedate()
2413 2417
2414 2418 editor = cmdutil.getcommiteditor(editform='graft',
2415 2419 **pycompat.strkwargs(opts))
2416 2420
2417 2421 cont = False
2418 2422 if opts.get('no_commit'):
2419 2423 if opts.get('edit'):
2420 2424 raise error.Abort(_("cannot specify --no-commit and "
2421 2425 "--edit together"))
2422 2426 if opts.get('currentuser'):
2423 2427 raise error.Abort(_("cannot specify --no-commit and "
2424 2428 "--currentuser together"))
2425 2429 if opts.get('currentdate'):
2426 2430 raise error.Abort(_("cannot specify --no-commit and "
2427 2431 "--currentdate together"))
2428 2432 if opts.get('log'):
2429 2433 raise error.Abort(_("cannot specify --no-commit and "
2430 2434 "--log together"))
2431 2435
2432 2436 graftstate = statemod.cmdstate(repo, 'graftstate')
2433 2437
2434 2438 if opts.get('stop'):
2435 2439 if opts.get('continue'):
2436 2440 raise error.Abort(_("cannot use '--continue' and "
2437 2441 "'--stop' together"))
2438 2442 if opts.get('abort'):
2439 2443 raise error.Abort(_("cannot use '--abort' and '--stop' together"))
2440 2444
2441 2445 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2442 2446 opts.get('date'), opts.get('currentdate'),
2443 2447 opts.get('currentuser'), opts.get('rev'))):
2444 2448 raise error.Abort(_("cannot specify any other flag with '--stop'"))
2445 2449 return _stopgraft(ui, repo, graftstate)
2446 2450 elif opts.get('abort'):
2447 2451 if opts.get('continue'):
2448 2452 raise error.Abort(_("cannot use '--continue' and "
2449 2453 "'--abort' together"))
2450 2454 if any((opts.get('edit'), opts.get('log'), opts.get('user'),
2451 2455 opts.get('date'), opts.get('currentdate'),
2452 2456 opts.get('currentuser'), opts.get('rev'))):
2453 2457 raise error.Abort(_("cannot specify any other flag with '--abort'"))
2454 2458
2455 2459 return _abortgraft(ui, repo, graftstate)
2456 2460 elif opts.get('continue'):
2457 2461 cont = True
2458 2462 if revs:
2459 2463 raise error.Abort(_("can't specify --continue and revisions"))
2460 2464 # read in unfinished revisions
2461 2465 if graftstate.exists():
2462 2466 statedata = _readgraftstate(repo, graftstate)
2463 2467 if statedata.get('date'):
2464 2468 opts['date'] = statedata['date']
2465 2469 if statedata.get('user'):
2466 2470 opts['user'] = statedata['user']
2467 2471 if statedata.get('log'):
2468 2472 opts['log'] = True
2469 2473 if statedata.get('no_commit'):
2470 2474 opts['no_commit'] = statedata.get('no_commit')
2471 2475 nodes = statedata['nodes']
2472 2476 revs = [repo[node].rev() for node in nodes]
2473 2477 else:
2474 2478 cmdutil.wrongtooltocontinue(repo, _('graft'))
2475 2479 else:
2476 2480 if not revs:
2477 2481 raise error.Abort(_('no revisions specified'))
2478 2482 cmdutil.checkunfinished(repo)
2479 2483 cmdutil.bailifchanged(repo)
2480 2484 revs = scmutil.revrange(repo, revs)
2481 2485
2482 2486 skipped = set()
2483 2487 if basectx is None:
2484 2488 # check for merges
2485 2489 for rev in repo.revs('%ld and merge()', revs):
2486 2490 ui.warn(_('skipping ungraftable merge revision %d\n') % rev)
2487 2491 skipped.add(rev)
2488 2492 revs = [r for r in revs if r not in skipped]
2489 2493 if not revs:
2490 2494 return -1
2491 2495 if basectx is not None and len(revs) != 1:
2492 2496 raise error.Abort(_('only one revision allowed with --base '))
2493 2497
2494 2498 # Don't check in the --continue case, in effect retaining --force across
2495 2499 # --continues. That's because without --force, any revisions we decided to
2496 2500 # skip would have been filtered out here, so they wouldn't have made their
2497 2501 # way to the graftstate. With --force, any revisions we would have otherwise
2498 2502 # skipped would not have been filtered out, and if they hadn't been applied
2499 2503 # already, they'd have been in the graftstate.
2500 2504 if not (cont or opts.get('force')) and basectx is None:
2501 2505 # check for ancestors of dest branch
2502 2506 crev = repo['.'].rev()
2503 2507 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2504 2508 # XXX make this lazy in the future
2505 2509 # don't mutate while iterating, create a copy
2506 2510 for rev in list(revs):
2507 2511 if rev in ancestors:
2508 2512 ui.warn(_('skipping ancestor revision %d:%s\n') %
2509 2513 (rev, repo[rev]))
2510 2514 # XXX remove on list is slow
2511 2515 revs.remove(rev)
2512 2516 if not revs:
2513 2517 return -1
2514 2518
2515 2519 # analyze revs for earlier grafts
2516 2520 ids = {}
2517 2521 for ctx in repo.set("%ld", revs):
2518 2522 ids[ctx.hex()] = ctx.rev()
2519 2523 n = ctx.extra().get('source')
2520 2524 if n:
2521 2525 ids[n] = ctx.rev()
2522 2526
2523 2527 # check ancestors for earlier grafts
2524 2528 ui.debug('scanning for duplicate grafts\n')
2525 2529
2526 2530 # The only changesets we can be sure doesn't contain grafts of any
2527 2531 # revs, are the ones that are common ancestors of *all* revs:
2528 2532 for rev in repo.revs('only(%d,ancestor(%ld))', crev, revs):
2529 2533 ctx = repo[rev]
2530 2534 n = ctx.extra().get('source')
2531 2535 if n in ids:
2532 2536 try:
2533 2537 r = repo[n].rev()
2534 2538 except error.RepoLookupError:
2535 2539 r = None
2536 2540 if r in revs:
2537 2541 ui.warn(_('skipping revision %d:%s '
2538 2542 '(already grafted to %d:%s)\n')
2539 2543 % (r, repo[r], rev, ctx))
2540 2544 revs.remove(r)
2541 2545 elif ids[n] in revs:
2542 2546 if r is None:
2543 2547 ui.warn(_('skipping already grafted revision %d:%s '
2544 2548 '(%d:%s also has unknown origin %s)\n')
2545 2549 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
2546 2550 else:
2547 2551 ui.warn(_('skipping already grafted revision %d:%s '
2548 2552 '(%d:%s also has origin %d:%s)\n')
2549 2553 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
2550 2554 revs.remove(ids[n])
2551 2555 elif ctx.hex() in ids:
2552 2556 r = ids[ctx.hex()]
2553 2557 if r in revs:
2554 2558 ui.warn(_('skipping already grafted revision %d:%s '
2555 2559 '(was grafted from %d:%s)\n') %
2556 2560 (r, repo[r], rev, ctx))
2557 2561 revs.remove(r)
2558 2562 if not revs:
2559 2563 return -1
2560 2564
2561 2565 if opts.get('no_commit'):
2562 2566 statedata['no_commit'] = True
2563 2567 for pos, ctx in enumerate(repo.set("%ld", revs)):
2564 2568 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
2565 2569 ctx.description().split('\n', 1)[0])
2566 2570 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2567 2571 if names:
2568 2572 desc += ' (%s)' % ' '.join(names)
2569 2573 ui.status(_('grafting %s\n') % desc)
2570 2574 if opts.get('dry_run'):
2571 2575 continue
2572 2576
2573 2577 source = ctx.extra().get('source')
2574 2578 extra = {}
2575 2579 if source:
2576 2580 extra['source'] = source
2577 2581 extra['intermediate-source'] = ctx.hex()
2578 2582 else:
2579 2583 extra['source'] = ctx.hex()
2580 2584 user = ctx.user()
2581 2585 if opts.get('user'):
2582 2586 user = opts['user']
2583 2587 statedata['user'] = user
2584 2588 date = ctx.date()
2585 2589 if opts.get('date'):
2586 2590 date = opts['date']
2587 2591 statedata['date'] = date
2588 2592 message = ctx.description()
2589 2593 if opts.get('log'):
2590 2594 message += '\n(grafted from %s)' % ctx.hex()
2591 2595 statedata['log'] = True
2592 2596
2593 2597 # we don't merge the first commit when continuing
2594 2598 if not cont:
2595 2599 # perform the graft merge with p1(rev) as 'ancestor'
2596 2600 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
2597 2601 base = ctx.p1() if basectx is None else basectx
2598 2602 with ui.configoverride(overrides, 'graft'):
2599 2603 stats = mergemod.graft(repo, ctx, base, ['local', 'graft'])
2600 2604 # report any conflicts
2601 2605 if stats.unresolvedcount > 0:
2602 2606 # write out state for --continue
2603 2607 nodes = [repo[rev].hex() for rev in revs[pos:]]
2604 2608 statedata['nodes'] = nodes
2605 2609 stateversion = 1
2606 2610 graftstate.save(stateversion, statedata)
2607 2611 hint = _("use 'hg resolve' and 'hg graft --continue'")
2608 2612 raise error.Abort(
2609 2613 _("unresolved conflicts, can't continue"),
2610 2614 hint=hint)
2611 2615 else:
2612 2616 cont = False
2613 2617
2614 2618 # commit if --no-commit is false
2615 2619 if not opts.get('no_commit'):
2616 2620 node = repo.commit(text=message, user=user, date=date, extra=extra,
2617 2621 editor=editor)
2618 2622 if node is None:
2619 2623 ui.warn(
2620 2624 _('note: graft of %d:%s created no changes to commit\n') %
2621 2625 (ctx.rev(), ctx))
2622 2626 # checking that newnodes exist because old state files won't have it
2623 2627 elif statedata.get('newnodes') is not None:
2624 2628 statedata['newnodes'].append(node)
2625 2629
2626 2630 # remove state when we complete successfully
2627 2631 if not opts.get('dry_run'):
2628 2632 graftstate.delete()
2629 2633
2630 2634 return 0
2631 2635
2632 2636 def _abortgraft(ui, repo, graftstate):
2633 2637 """abort the interrupted graft and rollbacks to the state before interrupted
2634 2638 graft"""
2635 2639 if not graftstate.exists():
2636 2640 raise error.Abort(_("no interrupted graft to abort"))
2637 2641 statedata = _readgraftstate(repo, graftstate)
2638 2642 newnodes = statedata.get('newnodes')
2639 2643 if newnodes is None:
2640 2644 # and old graft state which does not have all the data required to abort
2641 2645 # the graft
2642 2646 raise error.Abort(_("cannot abort using an old graftstate"))
2643 2647
2644 2648 # changeset from which graft operation was started
2645 2649 if len(newnodes) > 0:
2646 2650 startctx = repo[newnodes[0]].p1()
2647 2651 else:
2648 2652 startctx = repo['.']
2649 2653 # whether to strip or not
2650 2654 cleanup = False
2651 2655 if newnodes:
2652 2656 newnodes = [repo[r].rev() for r in newnodes]
2653 2657 cleanup = True
2654 2658 # checking that none of the newnodes turned public or is public
2655 2659 immutable = [c for c in newnodes if not repo[c].mutable()]
2656 2660 if immutable:
2657 2661 repo.ui.warn(_("cannot clean up public changesets %s\n")
2658 2662 % ', '.join(bytes(repo[r]) for r in immutable),
2659 2663 hint=_("see 'hg help phases' for details"))
2660 2664 cleanup = False
2661 2665
2662 2666 # checking that no new nodes are created on top of grafted revs
2663 2667 desc = set(repo.changelog.descendants(newnodes))
2664 2668 if desc - set(newnodes):
2665 2669 repo.ui.warn(_("new changesets detected on destination "
2666 2670 "branch, can't strip\n"))
2667 2671 cleanup = False
2668 2672
2669 2673 if cleanup:
2670 2674 with repo.wlock(), repo.lock():
2671 2675 hg.updaterepo(repo, startctx.node(), overwrite=True)
2672 2676 # stripping the new nodes created
2673 2677 strippoints = [c.node() for c in repo.set("roots(%ld)",
2674 2678 newnodes)]
2675 2679 repair.strip(repo.ui, repo, strippoints, backup=False)
2676 2680
2677 2681 if not cleanup:
2678 2682 # we don't update to the startnode if we can't strip
2679 2683 startctx = repo['.']
2680 2684 hg.updaterepo(repo, startctx.node(), overwrite=True)
2681 2685
2682 2686 ui.status(_("graft aborted\n"))
2683 2687 ui.status(_("working directory is now at %s\n") % startctx.hex()[:12])
2684 2688 graftstate.delete()
2685 2689 return 0
2686 2690
2687 2691 def _readgraftstate(repo, graftstate):
2688 2692 """read the graft state file and return a dict of the data stored in it"""
2689 2693 try:
2690 2694 return graftstate.read()
2691 2695 except error.CorruptedState:
2692 2696 nodes = repo.vfs.read('graftstate').splitlines()
2693 2697 return {'nodes': nodes}
2694 2698
2695 2699 def _stopgraft(ui, repo, graftstate):
2696 2700 """stop the interrupted graft"""
2697 2701 if not graftstate.exists():
2698 2702 raise error.Abort(_("no interrupted graft found"))
2699 2703 pctx = repo['.']
2700 2704 hg.updaterepo(repo, pctx.node(), overwrite=True)
2701 2705 graftstate.delete()
2702 2706 ui.status(_("stopped the interrupted graft\n"))
2703 2707 ui.status(_("working directory is now at %s\n") % pctx.hex()[:12])
2704 2708 return 0
2705 2709
2706 2710 @command('grep',
2707 2711 [('0', 'print0', None, _('end fields with NUL')),
2708 2712 ('', 'all', None, _('print all revisions that match (DEPRECATED) ')),
2709 2713 ('', 'diff', None, _('print all revisions when the term was introduced '
2710 2714 'or removed')),
2711 2715 ('a', 'text', None, _('treat all files as text')),
2712 2716 ('f', 'follow', None,
2713 2717 _('follow changeset history,'
2714 2718 ' or file history across copies and renames')),
2715 2719 ('i', 'ignore-case', None, _('ignore case when matching')),
2716 2720 ('l', 'files-with-matches', None,
2717 2721 _('print only filenames and revisions that match')),
2718 2722 ('n', 'line-number', None, _('print matching line numbers')),
2719 2723 ('r', 'rev', [],
2720 2724 _('only search files changed within revision range'), _('REV')),
2721 2725 ('', 'all-files', None,
2722 2726 _('include all files in the changeset while grepping (EXPERIMENTAL)')),
2723 2727 ('u', 'user', None, _('list the author (long with -v)')),
2724 2728 ('d', 'date', None, _('list the date (short with -q)')),
2725 2729 ] + formatteropts + walkopts,
2726 2730 _('[OPTION]... PATTERN [FILE]...'),
2727 2731 helpcategory=command.CATEGORY_FILE_CONTENTS,
2728 2732 inferrepo=True,
2729 2733 intents={INTENT_READONLY})
2730 2734 def grep(ui, repo, pattern, *pats, **opts):
2731 2735 """search revision history for a pattern in specified files
2732 2736
2733 2737 Search revision history for a regular expression in the specified
2734 2738 files or the entire project.
2735 2739
2736 2740 By default, grep prints the most recent revision number for each
2737 2741 file in which it finds a match. To get it to print every revision
2738 2742 that contains a change in match status ("-" for a match that becomes
2739 2743 a non-match, or "+" for a non-match that becomes a match), use the
2740 2744 --diff flag.
2741 2745
2742 2746 PATTERN can be any Python (roughly Perl-compatible) regular
2743 2747 expression.
2744 2748
2745 2749 If no FILEs are specified (and -f/--follow isn't set), all files in
2746 2750 the repository are searched, including those that don't exist in the
2747 2751 current branch or have been deleted in a prior changeset.
2748 2752
2749 2753 .. container:: verbose
2750 2754
2751 2755 Template:
2752 2756
2753 2757 The following keywords are supported in addition to the common template
2754 2758 keywords and functions. See also :hg:`help templates`.
2755 2759
2756 2760 :change: String. Character denoting insertion ``+`` or removal ``-``.
2757 2761 Available if ``--diff`` is specified.
2758 2762 :lineno: Integer. Line number of the match.
2759 2763 :path: String. Repository-absolute path of the file.
2760 2764 :texts: List of text chunks.
2761 2765
2762 2766 And each entry of ``{texts}`` provides the following sub-keywords.
2763 2767
2764 2768 :matched: Boolean. True if the chunk matches the specified pattern.
2765 2769 :text: String. Chunk content.
2766 2770
2767 2771 See :hg:`help templates.operators` for the list expansion syntax.
2768 2772
2769 2773 Returns 0 if a match is found, 1 otherwise.
2770 2774 """
2771 2775 opts = pycompat.byteskwargs(opts)
2772 2776 diff = opts.get('all') or opts.get('diff')
2773 2777 all_files = opts.get('all_files')
2774 2778 if diff and opts.get('all_files'):
2775 2779 raise error.Abort(_('--diff and --all-files are mutually exclusive'))
2776 2780 # TODO: remove "not opts.get('rev')" if --all-files -rMULTIREV gets working
2777 2781 if opts.get('all_files') is None and not opts.get('rev') and not diff:
2778 2782 # experimental config: commands.grep.all-files
2779 2783 opts['all_files'] = ui.configbool('commands', 'grep.all-files')
2780 2784 plaingrep = opts.get('all_files') and not opts.get('rev')
2781 2785 if plaingrep:
2782 2786 opts['rev'] = ['wdir()']
2783 2787
2784 2788 reflags = re.M
2785 2789 if opts.get('ignore_case'):
2786 2790 reflags |= re.I
2787 2791 try:
2788 2792 regexp = util.re.compile(pattern, reflags)
2789 2793 except re.error as inst:
2790 2794 ui.warn(_("grep: invalid match pattern: %s\n") % pycompat.bytestr(inst))
2791 2795 return 1
2792 2796 sep, eol = ':', '\n'
2793 2797 if opts.get('print0'):
2794 2798 sep = eol = '\0'
2795 2799
2796 2800 getfile = util.lrucachefunc(repo.file)
2797 2801
2798 2802 def matchlines(body):
2799 2803 begin = 0
2800 2804 linenum = 0
2801 2805 while begin < len(body):
2802 2806 match = regexp.search(body, begin)
2803 2807 if not match:
2804 2808 break
2805 2809 mstart, mend = match.span()
2806 2810 linenum += body.count('\n', begin, mstart) + 1
2807 2811 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2808 2812 begin = body.find('\n', mend) + 1 or len(body) + 1
2809 2813 lend = begin - 1
2810 2814 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2811 2815
2812 2816 class linestate(object):
2813 2817 def __init__(self, line, linenum, colstart, colend):
2814 2818 self.line = line
2815 2819 self.linenum = linenum
2816 2820 self.colstart = colstart
2817 2821 self.colend = colend
2818 2822
2819 2823 def __hash__(self):
2820 2824 return hash((self.linenum, self.line))
2821 2825
2822 2826 def __eq__(self, other):
2823 2827 return self.line == other.line
2824 2828
2825 2829 def findpos(self):
2826 2830 """Iterate all (start, end) indices of matches"""
2827 2831 yield self.colstart, self.colend
2828 2832 p = self.colend
2829 2833 while p < len(self.line):
2830 2834 m = regexp.search(self.line, p)
2831 2835 if not m:
2832 2836 break
2833 2837 yield m.span()
2834 2838 p = m.end()
2835 2839
2836 2840 matches = {}
2837 2841 copies = {}
2838 2842 def grepbody(fn, rev, body):
2839 2843 matches[rev].setdefault(fn, [])
2840 2844 m = matches[rev][fn]
2841 2845 for lnum, cstart, cend, line in matchlines(body):
2842 2846 s = linestate(line, lnum, cstart, cend)
2843 2847 m.append(s)
2844 2848
2845 2849 def difflinestates(a, b):
2846 2850 sm = difflib.SequenceMatcher(None, a, b)
2847 2851 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2848 2852 if tag == r'insert':
2849 2853 for i in pycompat.xrange(blo, bhi):
2850 2854 yield ('+', b[i])
2851 2855 elif tag == r'delete':
2852 2856 for i in pycompat.xrange(alo, ahi):
2853 2857 yield ('-', a[i])
2854 2858 elif tag == r'replace':
2855 2859 for i in pycompat.xrange(alo, ahi):
2856 2860 yield ('-', a[i])
2857 2861 for i in pycompat.xrange(blo, bhi):
2858 2862 yield ('+', b[i])
2859 2863
2860 2864 uipathfn = scmutil.getuipathfn(repo)
2861 2865 def display(fm, fn, ctx, pstates, states):
2862 2866 rev = scmutil.intrev(ctx)
2863 2867 if fm.isplain():
2864 2868 formatuser = ui.shortuser
2865 2869 else:
2866 2870 formatuser = pycompat.bytestr
2867 2871 if ui.quiet:
2868 2872 datefmt = '%Y-%m-%d'
2869 2873 else:
2870 2874 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2871 2875 found = False
2872 2876 @util.cachefunc
2873 2877 def binary():
2874 2878 flog = getfile(fn)
2875 2879 try:
2876 2880 return stringutil.binary(flog.read(ctx.filenode(fn)))
2877 2881 except error.WdirUnsupported:
2878 2882 return ctx[fn].isbinary()
2879 2883
2880 2884 fieldnamemap = {'linenumber': 'lineno'}
2881 2885 if diff:
2882 2886 iter = difflinestates(pstates, states)
2883 2887 else:
2884 2888 iter = [('', l) for l in states]
2885 2889 for change, l in iter:
2886 2890 fm.startitem()
2887 2891 fm.context(ctx=ctx)
2888 2892 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
2889 2893 fm.plain(uipathfn(fn), label='grep.filename')
2890 2894
2891 2895 cols = [
2892 2896 ('rev', '%d', rev, not plaingrep, ''),
2893 2897 ('linenumber', '%d', l.linenum, opts.get('line_number'), ''),
2894 2898 ]
2895 2899 if diff:
2896 2900 cols.append(
2897 2901 ('change', '%s', change, True,
2898 2902 'grep.inserted ' if change == '+' else 'grep.deleted ')
2899 2903 )
2900 2904 cols.extend([
2901 2905 ('user', '%s', formatuser(ctx.user()), opts.get('user'), ''),
2902 2906 ('date', '%s', fm.formatdate(ctx.date(), datefmt),
2903 2907 opts.get('date'), ''),
2904 2908 ])
2905 2909 for name, fmt, data, cond, extra_label in cols:
2906 2910 if cond:
2907 2911 fm.plain(sep, label='grep.sep')
2908 2912 field = fieldnamemap.get(name, name)
2909 2913 label = extra_label + ('grep.%s' % name)
2910 2914 fm.condwrite(cond, field, fmt, data, label=label)
2911 2915 if not opts.get('files_with_matches'):
2912 2916 fm.plain(sep, label='grep.sep')
2913 2917 if not opts.get('text') and binary():
2914 2918 fm.plain(_(" Binary file matches"))
2915 2919 else:
2916 2920 displaymatches(fm.nested('texts', tmpl='{text}'), l)
2917 2921 fm.plain(eol)
2918 2922 found = True
2919 2923 if opts.get('files_with_matches'):
2920 2924 break
2921 2925 return found
2922 2926
2923 2927 def displaymatches(fm, l):
2924 2928 p = 0
2925 2929 for s, e in l.findpos():
2926 2930 if p < s:
2927 2931 fm.startitem()
2928 2932 fm.write('text', '%s', l.line[p:s])
2929 2933 fm.data(matched=False)
2930 2934 fm.startitem()
2931 2935 fm.write('text', '%s', l.line[s:e], label='grep.match')
2932 2936 fm.data(matched=True)
2933 2937 p = e
2934 2938 if p < len(l.line):
2935 2939 fm.startitem()
2936 2940 fm.write('text', '%s', l.line[p:])
2937 2941 fm.data(matched=False)
2938 2942 fm.end()
2939 2943
2940 2944 skip = set()
2941 2945 revfiles = {}
2942 2946 match = scmutil.match(repo[None], pats, opts)
2943 2947 found = False
2944 2948 follow = opts.get('follow')
2945 2949
2946 2950 getrenamed = scmutil.getrenamedfn(repo)
2947 2951 def prep(ctx, fns):
2948 2952 rev = ctx.rev()
2949 2953 pctx = ctx.p1()
2950 2954 parent = pctx.rev()
2951 2955 matches.setdefault(rev, {})
2952 2956 matches.setdefault(parent, {})
2953 2957 files = revfiles.setdefault(rev, [])
2954 2958 for fn in fns:
2955 2959 flog = getfile(fn)
2956 2960 try:
2957 2961 fnode = ctx.filenode(fn)
2958 2962 except error.LookupError:
2959 2963 continue
2960 2964
2961 2965 copy = None
2962 2966 if follow:
2963 2967 copy = getrenamed(fn, rev)
2964 2968 if copy:
2965 2969 copies.setdefault(rev, {})[fn] = copy
2966 2970 if fn in skip:
2967 2971 skip.add(copy)
2968 2972 if fn in skip:
2969 2973 continue
2970 2974 files.append(fn)
2971 2975
2972 2976 if fn not in matches[rev]:
2973 2977 try:
2974 2978 content = flog.read(fnode)
2975 2979 except error.WdirUnsupported:
2976 2980 content = ctx[fn].data()
2977 2981 grepbody(fn, rev, content)
2978 2982
2979 2983 pfn = copy or fn
2980 2984 if pfn not in matches[parent]:
2981 2985 try:
2982 2986 fnode = pctx.filenode(pfn)
2983 2987 grepbody(pfn, parent, flog.read(fnode))
2984 2988 except error.LookupError:
2985 2989 pass
2986 2990
2987 2991 ui.pager('grep')
2988 2992 fm = ui.formatter('grep', opts)
2989 2993 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
2990 2994 rev = ctx.rev()
2991 2995 parent = ctx.p1().rev()
2992 2996 for fn in sorted(revfiles.get(rev, [])):
2993 2997 states = matches[rev][fn]
2994 2998 copy = copies.get(rev, {}).get(fn)
2995 2999 if fn in skip:
2996 3000 if copy:
2997 3001 skip.add(copy)
2998 3002 continue
2999 3003 pstates = matches.get(parent, {}).get(copy or fn, [])
3000 3004 if pstates or states:
3001 3005 r = display(fm, fn, ctx, pstates, states)
3002 3006 found = found or r
3003 3007 if r and not diff and not all_files:
3004 3008 skip.add(fn)
3005 3009 if copy:
3006 3010 skip.add(copy)
3007 3011 del revfiles[rev]
3008 3012 # We will keep the matches dict for the duration of the window
3009 3013 # clear the matches dict once the window is over
3010 3014 if not revfiles:
3011 3015 matches.clear()
3012 3016 fm.end()
3013 3017
3014 3018 return not found
3015 3019
3016 3020 @command('heads',
3017 3021 [('r', 'rev', '',
3018 3022 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3019 3023 ('t', 'topo', False, _('show topological heads only')),
3020 3024 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3021 3025 ('c', 'closed', False, _('show normal and closed branch heads')),
3022 3026 ] + templateopts,
3023 3027 _('[-ct] [-r STARTREV] [REV]...'),
3024 3028 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3025 3029 intents={INTENT_READONLY})
3026 3030 def heads(ui, repo, *branchrevs, **opts):
3027 3031 """show branch heads
3028 3032
3029 3033 With no arguments, show all open branch heads in the repository.
3030 3034 Branch heads are changesets that have no descendants on the
3031 3035 same branch. They are where development generally takes place and
3032 3036 are the usual targets for update and merge operations.
3033 3037
3034 3038 If one or more REVs are given, only open branch heads on the
3035 3039 branches associated with the specified changesets are shown. This
3036 3040 means that you can use :hg:`heads .` to see the heads on the
3037 3041 currently checked-out branch.
3038 3042
3039 3043 If -c/--closed is specified, also show branch heads marked closed
3040 3044 (see :hg:`commit --close-branch`).
3041 3045
3042 3046 If STARTREV is specified, only those heads that are descendants of
3043 3047 STARTREV will be displayed.
3044 3048
3045 3049 If -t/--topo is specified, named branch mechanics will be ignored and only
3046 3050 topological heads (changesets with no children) will be shown.
3047 3051
3048 3052 Returns 0 if matching heads are found, 1 if not.
3049 3053 """
3050 3054
3051 3055 opts = pycompat.byteskwargs(opts)
3052 3056 start = None
3053 3057 rev = opts.get('rev')
3054 3058 if rev:
3055 3059 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3056 3060 start = scmutil.revsingle(repo, rev, None).node()
3057 3061
3058 3062 if opts.get('topo'):
3059 3063 heads = [repo[h] for h in repo.heads(start)]
3060 3064 else:
3061 3065 heads = []
3062 3066 for branch in repo.branchmap():
3063 3067 heads += repo.branchheads(branch, start, opts.get('closed'))
3064 3068 heads = [repo[h] for h in heads]
3065 3069
3066 3070 if branchrevs:
3067 3071 branches = set(repo[r].branch()
3068 3072 for r in scmutil.revrange(repo, branchrevs))
3069 3073 heads = [h for h in heads if h.branch() in branches]
3070 3074
3071 3075 if opts.get('active') and branchrevs:
3072 3076 dagheads = repo.heads(start)
3073 3077 heads = [h for h in heads if h.node() in dagheads]
3074 3078
3075 3079 if branchrevs:
3076 3080 haveheads = set(h.branch() for h in heads)
3077 3081 if branches - haveheads:
3078 3082 headless = ', '.join(b for b in branches - haveheads)
3079 3083 msg = _('no open branch heads found on branches %s')
3080 3084 if opts.get('rev'):
3081 3085 msg += _(' (started at %s)') % opts['rev']
3082 3086 ui.warn((msg + '\n') % headless)
3083 3087
3084 3088 if not heads:
3085 3089 return 1
3086 3090
3087 3091 ui.pager('heads')
3088 3092 heads = sorted(heads, key=lambda x: -x.rev())
3089 3093 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3090 3094 for ctx in heads:
3091 3095 displayer.show(ctx)
3092 3096 displayer.close()
3093 3097
3094 3098 @command('help',
3095 3099 [('e', 'extension', None, _('show only help for extensions')),
3096 3100 ('c', 'command', None, _('show only help for commands')),
3097 3101 ('k', 'keyword', None, _('show topics matching keyword')),
3098 3102 ('s', 'system', [],
3099 3103 _('show help for specific platform(s)'), _('PLATFORM')),
3100 3104 ],
3101 3105 _('[-eck] [-s PLATFORM] [TOPIC]'),
3102 3106 helpcategory=command.CATEGORY_HELP,
3103 3107 norepo=True,
3104 3108 intents={INTENT_READONLY})
3105 3109 def help_(ui, name=None, **opts):
3106 3110 """show help for a given topic or a help overview
3107 3111
3108 3112 With no arguments, print a list of commands with short help messages.
3109 3113
3110 3114 Given a topic, extension, or command name, print help for that
3111 3115 topic.
3112 3116
3113 3117 Returns 0 if successful.
3114 3118 """
3115 3119
3116 3120 keep = opts.get(r'system') or []
3117 3121 if len(keep) == 0:
3118 3122 if pycompat.sysplatform.startswith('win'):
3119 3123 keep.append('windows')
3120 3124 elif pycompat.sysplatform == 'OpenVMS':
3121 3125 keep.append('vms')
3122 3126 elif pycompat.sysplatform == 'plan9':
3123 3127 keep.append('plan9')
3124 3128 else:
3125 3129 keep.append('unix')
3126 3130 keep.append(pycompat.sysplatform.lower())
3127 3131 if ui.verbose:
3128 3132 keep.append('verbose')
3129 3133
3130 3134 commands = sys.modules[__name__]
3131 3135 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3132 3136 ui.pager('help')
3133 3137 ui.write(formatted)
3134 3138
3135 3139
3136 3140 @command('identify|id',
3137 3141 [('r', 'rev', '',
3138 3142 _('identify the specified revision'), _('REV')),
3139 3143 ('n', 'num', None, _('show local revision number')),
3140 3144 ('i', 'id', None, _('show global revision id')),
3141 3145 ('b', 'branch', None, _('show branch')),
3142 3146 ('t', 'tags', None, _('show tags')),
3143 3147 ('B', 'bookmarks', None, _('show bookmarks')),
3144 3148 ] + remoteopts + formatteropts,
3145 3149 _('[-nibtB] [-r REV] [SOURCE]'),
3146 3150 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3147 3151 optionalrepo=True,
3148 3152 intents={INTENT_READONLY})
3149 3153 def identify(ui, repo, source=None, rev=None,
3150 3154 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3151 3155 """identify the working directory or specified revision
3152 3156
3153 3157 Print a summary identifying the repository state at REV using one or
3154 3158 two parent hash identifiers, followed by a "+" if the working
3155 3159 directory has uncommitted changes, the branch name (if not default),
3156 3160 a list of tags, and a list of bookmarks.
3157 3161
3158 3162 When REV is not given, print a summary of the current state of the
3159 3163 repository including the working directory. Specify -r. to get information
3160 3164 of the working directory parent without scanning uncommitted changes.
3161 3165
3162 3166 Specifying a path to a repository root or Mercurial bundle will
3163 3167 cause lookup to operate on that repository/bundle.
3164 3168
3165 3169 .. container:: verbose
3166 3170
3167 3171 Template:
3168 3172
3169 3173 The following keywords are supported in addition to the common template
3170 3174 keywords and functions. See also :hg:`help templates`.
3171 3175
3172 3176 :dirty: String. Character ``+`` denoting if the working directory has
3173 3177 uncommitted changes.
3174 3178 :id: String. One or two nodes, optionally followed by ``+``.
3175 3179 :parents: List of strings. Parent nodes of the changeset.
3176 3180
3177 3181 Examples:
3178 3182
3179 3183 - generate a build identifier for the working directory::
3180 3184
3181 3185 hg id --id > build-id.dat
3182 3186
3183 3187 - find the revision corresponding to a tag::
3184 3188
3185 3189 hg id -n -r 1.3
3186 3190
3187 3191 - check the most recent revision of a remote repository::
3188 3192
3189 3193 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3190 3194
3191 3195 See :hg:`log` for generating more information about specific revisions,
3192 3196 including full hash identifiers.
3193 3197
3194 3198 Returns 0 if successful.
3195 3199 """
3196 3200
3197 3201 opts = pycompat.byteskwargs(opts)
3198 3202 if not repo and not source:
3199 3203 raise error.Abort(_("there is no Mercurial repository here "
3200 3204 "(.hg not found)"))
3201 3205
3202 3206 default = not (num or id or branch or tags or bookmarks)
3203 3207 output = []
3204 3208 revs = []
3205 3209
3206 3210 if source:
3207 3211 source, branches = hg.parseurl(ui.expandpath(source))
3208 3212 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3209 3213 repo = peer.local()
3210 3214 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3211 3215
3212 3216 fm = ui.formatter('identify', opts)
3213 3217 fm.startitem()
3214 3218
3215 3219 if not repo:
3216 3220 if num or branch or tags:
3217 3221 raise error.Abort(
3218 3222 _("can't query remote revision number, branch, or tags"))
3219 3223 if not rev and revs:
3220 3224 rev = revs[0]
3221 3225 if not rev:
3222 3226 rev = "tip"
3223 3227
3224 3228 remoterev = peer.lookup(rev)
3225 3229 hexrev = fm.hexfunc(remoterev)
3226 3230 if default or id:
3227 3231 output = [hexrev]
3228 3232 fm.data(id=hexrev)
3229 3233
3230 3234 @util.cachefunc
3231 3235 def getbms():
3232 3236 bms = []
3233 3237
3234 3238 if 'bookmarks' in peer.listkeys('namespaces'):
3235 3239 hexremoterev = hex(remoterev)
3236 3240 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3237 3241 if bmr == hexremoterev]
3238 3242
3239 3243 return sorted(bms)
3240 3244
3241 3245 if fm.isplain():
3242 3246 if bookmarks:
3243 3247 output.extend(getbms())
3244 3248 elif default and not ui.quiet:
3245 3249 # multiple bookmarks for a single parent separated by '/'
3246 3250 bm = '/'.join(getbms())
3247 3251 if bm:
3248 3252 output.append(bm)
3249 3253 else:
3250 3254 fm.data(node=hex(remoterev))
3251 3255 if bookmarks or 'bookmarks' in fm.datahint():
3252 3256 fm.data(bookmarks=fm.formatlist(getbms(), name='bookmark'))
3253 3257 else:
3254 3258 if rev:
3255 3259 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
3256 3260 ctx = scmutil.revsingle(repo, rev, None)
3257 3261
3258 3262 if ctx.rev() is None:
3259 3263 ctx = repo[None]
3260 3264 parents = ctx.parents()
3261 3265 taglist = []
3262 3266 for p in parents:
3263 3267 taglist.extend(p.tags())
3264 3268
3265 3269 dirty = ""
3266 3270 if ctx.dirty(missing=True, merge=False, branch=False):
3267 3271 dirty = '+'
3268 3272 fm.data(dirty=dirty)
3269 3273
3270 3274 hexoutput = [fm.hexfunc(p.node()) for p in parents]
3271 3275 if default or id:
3272 3276 output = ["%s%s" % ('+'.join(hexoutput), dirty)]
3273 3277 fm.data(id="%s%s" % ('+'.join(hexoutput), dirty))
3274 3278
3275 3279 if num:
3276 3280 numoutput = ["%d" % p.rev() for p in parents]
3277 3281 output.append("%s%s" % ('+'.join(numoutput), dirty))
3278 3282
3279 3283 fm.data(parents=fm.formatlist([fm.hexfunc(p.node())
3280 3284 for p in parents], name='node'))
3281 3285 else:
3282 3286 hexoutput = fm.hexfunc(ctx.node())
3283 3287 if default or id:
3284 3288 output = [hexoutput]
3285 3289 fm.data(id=hexoutput)
3286 3290
3287 3291 if num:
3288 3292 output.append(pycompat.bytestr(ctx.rev()))
3289 3293 taglist = ctx.tags()
3290 3294
3291 3295 if default and not ui.quiet:
3292 3296 b = ctx.branch()
3293 3297 if b != 'default':
3294 3298 output.append("(%s)" % b)
3295 3299
3296 3300 # multiple tags for a single parent separated by '/'
3297 3301 t = '/'.join(taglist)
3298 3302 if t:
3299 3303 output.append(t)
3300 3304
3301 3305 # multiple bookmarks for a single parent separated by '/'
3302 3306 bm = '/'.join(ctx.bookmarks())
3303 3307 if bm:
3304 3308 output.append(bm)
3305 3309 else:
3306 3310 if branch:
3307 3311 output.append(ctx.branch())
3308 3312
3309 3313 if tags:
3310 3314 output.extend(taglist)
3311 3315
3312 3316 if bookmarks:
3313 3317 output.extend(ctx.bookmarks())
3314 3318
3315 3319 fm.data(node=ctx.hex())
3316 3320 fm.data(branch=ctx.branch())
3317 3321 fm.data(tags=fm.formatlist(taglist, name='tag', sep=':'))
3318 3322 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'))
3319 3323 fm.context(ctx=ctx)
3320 3324
3321 3325 fm.plain("%s\n" % ' '.join(output))
3322 3326 fm.end()
3323 3327
3324 3328 @command('import|patch',
3325 3329 [('p', 'strip', 1,
3326 3330 _('directory strip option for patch. This has the same '
3327 3331 'meaning as the corresponding patch option'), _('NUM')),
3328 3332 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3329 3333 ('e', 'edit', False, _('invoke editor on commit messages')),
3330 3334 ('f', 'force', None,
3331 3335 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3332 3336 ('', 'no-commit', None,
3333 3337 _("don't commit, just update the working directory")),
3334 3338 ('', 'bypass', None,
3335 3339 _("apply patch without touching the working directory")),
3336 3340 ('', 'partial', None,
3337 3341 _('commit even if some hunks fail')),
3338 3342 ('', 'exact', None,
3339 3343 _('abort if patch would apply lossily')),
3340 3344 ('', 'prefix', '',
3341 3345 _('apply patch to subdirectory'), _('DIR')),
3342 3346 ('', 'import-branch', None,
3343 3347 _('use any branch information in patch (implied by --exact)'))] +
3344 3348 commitopts + commitopts2 + similarityopts,
3345 3349 _('[OPTION]... PATCH...'),
3346 3350 helpcategory=command.CATEGORY_IMPORT_EXPORT)
3347 3351 def import_(ui, repo, patch1=None, *patches, **opts):
3348 3352 """import an ordered set of patches
3349 3353
3350 3354 Import a list of patches and commit them individually (unless
3351 3355 --no-commit is specified).
3352 3356
3353 3357 To read a patch from standard input (stdin), use "-" as the patch
3354 3358 name. If a URL is specified, the patch will be downloaded from
3355 3359 there.
3356 3360
3357 3361 Import first applies changes to the working directory (unless
3358 3362 --bypass is specified), import will abort if there are outstanding
3359 3363 changes.
3360 3364
3361 3365 Use --bypass to apply and commit patches directly to the
3362 3366 repository, without affecting the working directory. Without
3363 3367 --exact, patches will be applied on top of the working directory
3364 3368 parent revision.
3365 3369
3366 3370 You can import a patch straight from a mail message. Even patches
3367 3371 as attachments work (to use the body part, it must have type
3368 3372 text/plain or text/x-patch). From and Subject headers of email
3369 3373 message are used as default committer and commit message. All
3370 3374 text/plain body parts before first diff are added to the commit
3371 3375 message.
3372 3376
3373 3377 If the imported patch was generated by :hg:`export`, user and
3374 3378 description from patch override values from message headers and
3375 3379 body. Values given on command line with -m/--message and -u/--user
3376 3380 override these.
3377 3381
3378 3382 If --exact is specified, import will set the working directory to
3379 3383 the parent of each patch before applying it, and will abort if the
3380 3384 resulting changeset has a different ID than the one recorded in
3381 3385 the patch. This will guard against various ways that portable
3382 3386 patch formats and mail systems might fail to transfer Mercurial
3383 3387 data or metadata. See :hg:`bundle` for lossless transmission.
3384 3388
3385 3389 Use --partial to ensure a changeset will be created from the patch
3386 3390 even if some hunks fail to apply. Hunks that fail to apply will be
3387 3391 written to a <target-file>.rej file. Conflicts can then be resolved
3388 3392 by hand before :hg:`commit --amend` is run to update the created
3389 3393 changeset. This flag exists to let people import patches that
3390 3394 partially apply without losing the associated metadata (author,
3391 3395 date, description, ...).
3392 3396
3393 3397 .. note::
3394 3398
3395 3399 When no hunks apply cleanly, :hg:`import --partial` will create
3396 3400 an empty changeset, importing only the patch metadata.
3397 3401
3398 3402 With -s/--similarity, hg will attempt to discover renames and
3399 3403 copies in the patch in the same way as :hg:`addremove`.
3400 3404
3401 3405 It is possible to use external patch programs to perform the patch
3402 3406 by setting the ``ui.patch`` configuration option. For the default
3403 3407 internal tool, the fuzz can also be configured via ``patch.fuzz``.
3404 3408 See :hg:`help config` for more information about configuration
3405 3409 files and how to use these options.
3406 3410
3407 3411 See :hg:`help dates` for a list of formats valid for -d/--date.
3408 3412
3409 3413 .. container:: verbose
3410 3414
3411 3415 Examples:
3412 3416
3413 3417 - import a traditional patch from a website and detect renames::
3414 3418
3415 3419 hg import -s 80 http://example.com/bugfix.patch
3416 3420
3417 3421 - import a changeset from an hgweb server::
3418 3422
3419 3423 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
3420 3424
3421 3425 - import all the patches in an Unix-style mbox::
3422 3426
3423 3427 hg import incoming-patches.mbox
3424 3428
3425 3429 - import patches from stdin::
3426 3430
3427 3431 hg import -
3428 3432
3429 3433 - attempt to exactly restore an exported changeset (not always
3430 3434 possible)::
3431 3435
3432 3436 hg import --exact proposed-fix.patch
3433 3437
3434 3438 - use an external tool to apply a patch which is too fuzzy for
3435 3439 the default internal tool.
3436 3440
3437 3441 hg import --config ui.patch="patch --merge" fuzzy.patch
3438 3442
3439 3443 - change the default fuzzing from 2 to a less strict 7
3440 3444
3441 3445 hg import --config ui.fuzz=7 fuzz.patch
3442 3446
3443 3447 Returns 0 on success, 1 on partial success (see --partial).
3444 3448 """
3445 3449
3446 3450 opts = pycompat.byteskwargs(opts)
3447 3451 if not patch1:
3448 3452 raise error.Abort(_('need at least one patch to import'))
3449 3453
3450 3454 patches = (patch1,) + patches
3451 3455
3452 3456 date = opts.get('date')
3453 3457 if date:
3454 3458 opts['date'] = dateutil.parsedate(date)
3455 3459
3456 3460 exact = opts.get('exact')
3457 3461 update = not opts.get('bypass')
3458 3462 if not update and opts.get('no_commit'):
3459 3463 raise error.Abort(_('cannot use --no-commit with --bypass'))
3460 3464 try:
3461 3465 sim = float(opts.get('similarity') or 0)
3462 3466 except ValueError:
3463 3467 raise error.Abort(_('similarity must be a number'))
3464 3468 if sim < 0 or sim > 100:
3465 3469 raise error.Abort(_('similarity must be between 0 and 100'))
3466 3470 if sim and not update:
3467 3471 raise error.Abort(_('cannot use --similarity with --bypass'))
3468 3472 if exact:
3469 3473 if opts.get('edit'):
3470 3474 raise error.Abort(_('cannot use --exact with --edit'))
3471 3475 if opts.get('prefix'):
3472 3476 raise error.Abort(_('cannot use --exact with --prefix'))
3473 3477
3474 3478 base = opts["base"]
3475 3479 msgs = []
3476 3480 ret = 0
3477 3481
3478 3482 with repo.wlock():
3479 3483 if update:
3480 3484 cmdutil.checkunfinished(repo)
3481 3485 if (exact or not opts.get('force')):
3482 3486 cmdutil.bailifchanged(repo)
3483 3487
3484 3488 if not opts.get('no_commit'):
3485 3489 lock = repo.lock
3486 3490 tr = lambda: repo.transaction('import')
3487 3491 dsguard = util.nullcontextmanager
3488 3492 else:
3489 3493 lock = util.nullcontextmanager
3490 3494 tr = util.nullcontextmanager
3491 3495 dsguard = lambda: dirstateguard.dirstateguard(repo, 'import')
3492 3496 with lock(), tr(), dsguard():
3493 3497 parents = repo[None].parents()
3494 3498 for patchurl in patches:
3495 3499 if patchurl == '-':
3496 3500 ui.status(_('applying patch from stdin\n'))
3497 3501 patchfile = ui.fin
3498 3502 patchurl = 'stdin' # for error message
3499 3503 else:
3500 3504 patchurl = os.path.join(base, patchurl)
3501 3505 ui.status(_('applying %s\n') % patchurl)
3502 3506 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
3503 3507
3504 3508 haspatch = False
3505 3509 for hunk in patch.split(patchfile):
3506 3510 with patch.extract(ui, hunk) as patchdata:
3507 3511 msg, node, rej = cmdutil.tryimportone(ui, repo,
3508 3512 patchdata,
3509 3513 parents, opts,
3510 3514 msgs, hg.clean)
3511 3515 if msg:
3512 3516 haspatch = True
3513 3517 ui.note(msg + '\n')
3514 3518 if update or exact:
3515 3519 parents = repo[None].parents()
3516 3520 else:
3517 3521 parents = [repo[node]]
3518 3522 if rej:
3519 3523 ui.write_err(_("patch applied partially\n"))
3520 3524 ui.write_err(_("(fix the .rej files and run "
3521 3525 "`hg commit --amend`)\n"))
3522 3526 ret = 1
3523 3527 break
3524 3528
3525 3529 if not haspatch:
3526 3530 raise error.Abort(_('%s: no diffs found') % patchurl)
3527 3531
3528 3532 if msgs:
3529 3533 repo.savecommitmessage('\n* * *\n'.join(msgs))
3530 3534 return ret
3531 3535
3532 3536 @command('incoming|in',
3533 3537 [('f', 'force', None,
3534 3538 _('run even if remote repository is unrelated')),
3535 3539 ('n', 'newest-first', None, _('show newest record first')),
3536 3540 ('', 'bundle', '',
3537 3541 _('file to store the bundles into'), _('FILE')),
3538 3542 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3539 3543 ('B', 'bookmarks', False, _("compare bookmarks")),
3540 3544 ('b', 'branch', [],
3541 3545 _('a specific branch you would like to pull'), _('BRANCH')),
3542 3546 ] + logopts + remoteopts + subrepoopts,
3543 3547 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
3544 3548 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
3545 3549 def incoming(ui, repo, source="default", **opts):
3546 3550 """show new changesets found in source
3547 3551
3548 3552 Show new changesets found in the specified path/URL or the default
3549 3553 pull location. These are the changesets that would have been pulled
3550 3554 by :hg:`pull` at the time you issued this command.
3551 3555
3552 3556 See pull for valid source format details.
3553 3557
3554 3558 .. container:: verbose
3555 3559
3556 3560 With -B/--bookmarks, the result of bookmark comparison between
3557 3561 local and remote repositories is displayed. With -v/--verbose,
3558 3562 status is also displayed for each bookmark like below::
3559 3563
3560 3564 BM1 01234567890a added
3561 3565 BM2 1234567890ab advanced
3562 3566 BM3 234567890abc diverged
3563 3567 BM4 34567890abcd changed
3564 3568
3565 3569 The action taken locally when pulling depends on the
3566 3570 status of each bookmark:
3567 3571
3568 3572 :``added``: pull will create it
3569 3573 :``advanced``: pull will update it
3570 3574 :``diverged``: pull will create a divergent bookmark
3571 3575 :``changed``: result depends on remote changesets
3572 3576
3573 3577 From the point of view of pulling behavior, bookmark
3574 3578 existing only in the remote repository are treated as ``added``,
3575 3579 even if it is in fact locally deleted.
3576 3580
3577 3581 .. container:: verbose
3578 3582
3579 3583 For remote repository, using --bundle avoids downloading the
3580 3584 changesets twice if the incoming is followed by a pull.
3581 3585
3582 3586 Examples:
3583 3587
3584 3588 - show incoming changes with patches and full description::
3585 3589
3586 3590 hg incoming -vp
3587 3591
3588 3592 - show incoming changes excluding merges, store a bundle::
3589 3593
3590 3594 hg in -vpM --bundle incoming.hg
3591 3595 hg pull incoming.hg
3592 3596
3593 3597 - briefly list changes inside a bundle::
3594 3598
3595 3599 hg in changes.hg -T "{desc|firstline}\\n"
3596 3600
3597 3601 Returns 0 if there are incoming changes, 1 otherwise.
3598 3602 """
3599 3603 opts = pycompat.byteskwargs(opts)
3600 3604 if opts.get('graph'):
3601 3605 logcmdutil.checkunsupportedgraphflags([], opts)
3602 3606 def display(other, chlist, displayer):
3603 3607 revdag = logcmdutil.graphrevs(other, chlist, opts)
3604 3608 logcmdutil.displaygraph(ui, repo, revdag, displayer,
3605 3609 graphmod.asciiedges)
3606 3610
3607 3611 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3608 3612 return 0
3609 3613
3610 3614 if opts.get('bundle') and opts.get('subrepos'):
3611 3615 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3612 3616
3613 3617 if opts.get('bookmarks'):
3614 3618 source, branches = hg.parseurl(ui.expandpath(source),
3615 3619 opts.get('branch'))
3616 3620 other = hg.peer(repo, opts, source)
3617 3621 if 'bookmarks' not in other.listkeys('namespaces'):
3618 3622 ui.warn(_("remote doesn't support bookmarks\n"))
3619 3623 return 0
3620 3624 ui.pager('incoming')
3621 3625 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3622 3626 return bookmarks.incoming(ui, repo, other)
3623 3627
3624 3628 repo._subtoppath = ui.expandpath(source)
3625 3629 try:
3626 3630 return hg.incoming(ui, repo, source, opts)
3627 3631 finally:
3628 3632 del repo._subtoppath
3629 3633
3630 3634
3631 3635 @command('init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
3632 3636 helpcategory=command.CATEGORY_REPO_CREATION,
3633 3637 helpbasic=True, norepo=True)
3634 3638 def init(ui, dest=".", **opts):
3635 3639 """create a new repository in the given directory
3636 3640
3637 3641 Initialize a new repository in the given directory. If the given
3638 3642 directory does not exist, it will be created.
3639 3643
3640 3644 If no directory is given, the current directory is used.
3641 3645
3642 3646 It is possible to specify an ``ssh://`` URL as the destination.
3643 3647 See :hg:`help urls` for more information.
3644 3648
3645 3649 Returns 0 on success.
3646 3650 """
3647 3651 opts = pycompat.byteskwargs(opts)
3648 3652 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3649 3653
3650 3654 @command('locate',
3651 3655 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3652 3656 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3653 3657 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3654 3658 ] + walkopts,
3655 3659 _('[OPTION]... [PATTERN]...'),
3656 3660 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
3657 3661 def locate(ui, repo, *pats, **opts):
3658 3662 """locate files matching specific patterns (DEPRECATED)
3659 3663
3660 3664 Print files under Mercurial control in the working directory whose
3661 3665 names match the given patterns.
3662 3666
3663 3667 By default, this command searches all directories in the working
3664 3668 directory. To search just the current directory and its
3665 3669 subdirectories, use "--include .".
3666 3670
3667 3671 If no patterns are given to match, this command prints the names
3668 3672 of all files under Mercurial control in the working directory.
3669 3673
3670 3674 If you want to feed the output of this command into the "xargs"
3671 3675 command, use the -0 option to both this command and "xargs". This
3672 3676 will avoid the problem of "xargs" treating single filenames that
3673 3677 contain whitespace as multiple filenames.
3674 3678
3675 3679 See :hg:`help files` for a more versatile command.
3676 3680
3677 3681 Returns 0 if a match is found, 1 otherwise.
3678 3682 """
3679 3683 opts = pycompat.byteskwargs(opts)
3680 3684 if opts.get('print0'):
3681 3685 end = '\0'
3682 3686 else:
3683 3687 end = '\n'
3684 3688 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3685 3689
3686 3690 ret = 1
3687 3691 m = scmutil.match(ctx, pats, opts, default='relglob',
3688 3692 badfn=lambda x, y: False)
3689 3693
3690 3694 ui.pager('locate')
3691 3695 if ctx.rev() is None:
3692 3696 # When run on the working copy, "locate" includes removed files, so
3693 3697 # we get the list of files from the dirstate.
3694 3698 filesgen = sorted(repo.dirstate.matches(m))
3695 3699 else:
3696 3700 filesgen = ctx.matches(m)
3697 3701 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
3698 3702 for abs in filesgen:
3699 3703 if opts.get('fullpath'):
3700 3704 ui.write(repo.wjoin(abs), end)
3701 3705 else:
3702 3706 ui.write(uipathfn(abs), end)
3703 3707 ret = 0
3704 3708
3705 3709 return ret
3706 3710
3707 3711 @command('log|history',
3708 3712 [('f', 'follow', None,
3709 3713 _('follow changeset history, or file history across copies and renames')),
3710 3714 ('', 'follow-first', None,
3711 3715 _('only follow the first parent of merge changesets (DEPRECATED)')),
3712 3716 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3713 3717 ('C', 'copies', None, _('show copied files')),
3714 3718 ('k', 'keyword', [],
3715 3719 _('do case-insensitive search for a given text'), _('TEXT')),
3716 3720 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3717 3721 ('L', 'line-range', [],
3718 3722 _('follow line range of specified file (EXPERIMENTAL)'),
3719 3723 _('FILE,RANGE')),
3720 3724 ('', 'removed', None, _('include revisions where files were removed')),
3721 3725 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3722 3726 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3723 3727 ('', 'only-branch', [],
3724 3728 _('show only changesets within the given named branch (DEPRECATED)'),
3725 3729 _('BRANCH')),
3726 3730 ('b', 'branch', [],
3727 3731 _('show changesets within the given named branch'), _('BRANCH')),
3728 3732 ('P', 'prune', [],
3729 3733 _('do not display revision or any of its ancestors'), _('REV')),
3730 3734 ] + logopts + walkopts,
3731 3735 _('[OPTION]... [FILE]'),
3732 3736 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3733 3737 helpbasic=True, inferrepo=True,
3734 3738 intents={INTENT_READONLY})
3735 3739 def log(ui, repo, *pats, **opts):
3736 3740 """show revision history of entire repository or files
3737 3741
3738 3742 Print the revision history of the specified files or the entire
3739 3743 project.
3740 3744
3741 3745 If no revision range is specified, the default is ``tip:0`` unless
3742 3746 --follow is set, in which case the working directory parent is
3743 3747 used as the starting revision.
3744 3748
3745 3749 File history is shown without following rename or copy history of
3746 3750 files. Use -f/--follow with a filename to follow history across
3747 3751 renames and copies. --follow without a filename will only show
3748 3752 ancestors of the starting revision.
3749 3753
3750 3754 By default this command prints revision number and changeset id,
3751 3755 tags, non-trivial parents, user, date and time, and a summary for
3752 3756 each commit. When the -v/--verbose switch is used, the list of
3753 3757 changed files and full commit message are shown.
3754 3758
3755 3759 With --graph the revisions are shown as an ASCII art DAG with the most
3756 3760 recent changeset at the top.
3757 3761 'o' is a changeset, '@' is a working directory parent, '_' closes a branch,
3758 3762 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
3759 3763 changeset from the lines below is a parent of the 'o' merge on the same
3760 3764 line.
3761 3765 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
3762 3766 of a '|' indicates one or more revisions in a path are omitted.
3763 3767
3764 3768 .. container:: verbose
3765 3769
3766 3770 Use -L/--line-range FILE,M:N options to follow the history of lines
3767 3771 from M to N in FILE. With -p/--patch only diff hunks affecting
3768 3772 specified line range will be shown. This option requires --follow;
3769 3773 it can be specified multiple times. Currently, this option is not
3770 3774 compatible with --graph. This option is experimental.
3771 3775
3772 3776 .. note::
3773 3777
3774 3778 :hg:`log --patch` may generate unexpected diff output for merge
3775 3779 changesets, as it will only compare the merge changeset against
3776 3780 its first parent. Also, only files different from BOTH parents
3777 3781 will appear in files:.
3778 3782
3779 3783 .. note::
3780 3784
3781 3785 For performance reasons, :hg:`log FILE` may omit duplicate changes
3782 3786 made on branches and will not show removals or mode changes. To
3783 3787 see all such changes, use the --removed switch.
3784 3788
3785 3789 .. container:: verbose
3786 3790
3787 3791 .. note::
3788 3792
3789 3793 The history resulting from -L/--line-range options depends on diff
3790 3794 options; for instance if white-spaces are ignored, respective changes
3791 3795 with only white-spaces in specified line range will not be listed.
3792 3796
3793 3797 .. container:: verbose
3794 3798
3795 3799 Some examples:
3796 3800
3797 3801 - changesets with full descriptions and file lists::
3798 3802
3799 3803 hg log -v
3800 3804
3801 3805 - changesets ancestral to the working directory::
3802 3806
3803 3807 hg log -f
3804 3808
3805 3809 - last 10 commits on the current branch::
3806 3810
3807 3811 hg log -l 10 -b .
3808 3812
3809 3813 - changesets showing all modifications of a file, including removals::
3810 3814
3811 3815 hg log --removed file.c
3812 3816
3813 3817 - all changesets that touch a directory, with diffs, excluding merges::
3814 3818
3815 3819 hg log -Mp lib/
3816 3820
3817 3821 - all revision numbers that match a keyword::
3818 3822
3819 3823 hg log -k bug --template "{rev}\\n"
3820 3824
3821 3825 - the full hash identifier of the working directory parent::
3822 3826
3823 3827 hg log -r . --template "{node}\\n"
3824 3828
3825 3829 - list available log templates::
3826 3830
3827 3831 hg log -T list
3828 3832
3829 3833 - check if a given changeset is included in a tagged release::
3830 3834
3831 3835 hg log -r "a21ccf and ancestor(1.9)"
3832 3836
3833 3837 - find all changesets by some user in a date range::
3834 3838
3835 3839 hg log -k alice -d "may 2008 to jul 2008"
3836 3840
3837 3841 - summary of all changesets after the last tag::
3838 3842
3839 3843 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3840 3844
3841 3845 - changesets touching lines 13 to 23 for file.c::
3842 3846
3843 3847 hg log -L file.c,13:23
3844 3848
3845 3849 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
3846 3850 main.c with patch::
3847 3851
3848 3852 hg log -L file.c,13:23 -L main.c,2:6 -p
3849 3853
3850 3854 See :hg:`help dates` for a list of formats valid for -d/--date.
3851 3855
3852 3856 See :hg:`help revisions` for more about specifying and ordering
3853 3857 revisions.
3854 3858
3855 3859 See :hg:`help templates` for more about pre-packaged styles and
3856 3860 specifying custom templates. The default template used by the log
3857 3861 command can be customized via the ``ui.logtemplate`` configuration
3858 3862 setting.
3859 3863
3860 3864 Returns 0 on success.
3861 3865
3862 3866 """
3863 3867 opts = pycompat.byteskwargs(opts)
3864 3868 linerange = opts.get('line_range')
3865 3869
3866 3870 if linerange and not opts.get('follow'):
3867 3871 raise error.Abort(_('--line-range requires --follow'))
3868 3872
3869 3873 if linerange and pats:
3870 3874 # TODO: take pats as patterns with no line-range filter
3871 3875 raise error.Abort(
3872 3876 _('FILE arguments are not compatible with --line-range option')
3873 3877 )
3874 3878
3875 3879 repo = scmutil.unhidehashlikerevs(repo, opts.get('rev'), 'nowarn')
3876 3880 revs, differ = logcmdutil.getrevs(repo, pats, opts)
3877 3881 if linerange:
3878 3882 # TODO: should follow file history from logcmdutil._initialrevs(),
3879 3883 # then filter the result by logcmdutil._makerevset() and --limit
3880 3884 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
3881 3885
3882 3886 getrenamed = None
3883 3887 if opts.get('copies'):
3884 3888 endrev = None
3885 3889 if revs:
3886 3890 endrev = revs.max() + 1
3887 3891 getrenamed = scmutil.getrenamedfn(repo, endrev=endrev)
3888 3892
3889 3893 ui.pager('log')
3890 3894 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, differ,
3891 3895 buffered=True)
3892 3896 if opts.get('graph'):
3893 3897 displayfn = logcmdutil.displaygraphrevs
3894 3898 else:
3895 3899 displayfn = logcmdutil.displayrevs
3896 3900 displayfn(ui, repo, revs, displayer, getrenamed)
3897 3901
3898 3902 @command('manifest',
3899 3903 [('r', 'rev', '', _('revision to display'), _('REV')),
3900 3904 ('', 'all', False, _("list files from all revisions"))]
3901 3905 + formatteropts,
3902 3906 _('[-r REV]'),
3903 3907 helpcategory=command.CATEGORY_MAINTENANCE,
3904 3908 intents={INTENT_READONLY})
3905 3909 def manifest(ui, repo, node=None, rev=None, **opts):
3906 3910 """output the current or given revision of the project manifest
3907 3911
3908 3912 Print a list of version controlled files for the given revision.
3909 3913 If no revision is given, the first parent of the working directory
3910 3914 is used, or the null revision if no revision is checked out.
3911 3915
3912 3916 With -v, print file permissions, symlink and executable bits.
3913 3917 With --debug, print file revision hashes.
3914 3918
3915 3919 If option --all is specified, the list of all files from all revisions
3916 3920 is printed. This includes deleted and renamed files.
3917 3921
3918 3922 Returns 0 on success.
3919 3923 """
3920 3924 opts = pycompat.byteskwargs(opts)
3921 3925 fm = ui.formatter('manifest', opts)
3922 3926
3923 3927 if opts.get('all'):
3924 3928 if rev or node:
3925 3929 raise error.Abort(_("can't specify a revision with --all"))
3926 3930
3927 3931 res = set()
3928 3932 for rev in repo:
3929 3933 ctx = repo[rev]
3930 3934 res |= set(ctx.files())
3931 3935
3932 3936 ui.pager('manifest')
3933 3937 for f in sorted(res):
3934 3938 fm.startitem()
3935 3939 fm.write("path", '%s\n', f)
3936 3940 fm.end()
3937 3941 return
3938 3942
3939 3943 if rev and node:
3940 3944 raise error.Abort(_("please specify just one revision"))
3941 3945
3942 3946 if not node:
3943 3947 node = rev
3944 3948
3945 3949 char = {'l': '@', 'x': '*', '': '', 't': 'd'}
3946 3950 mode = {'l': '644', 'x': '755', '': '644', 't': '755'}
3947 3951 if node:
3948 3952 repo = scmutil.unhidehashlikerevs(repo, [node], 'nowarn')
3949 3953 ctx = scmutil.revsingle(repo, node)
3950 3954 mf = ctx.manifest()
3951 3955 ui.pager('manifest')
3952 3956 for f in ctx:
3953 3957 fm.startitem()
3954 3958 fm.context(ctx=ctx)
3955 3959 fl = ctx[f].flags()
3956 3960 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3957 3961 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3958 3962 fm.write('path', '%s\n', f)
3959 3963 fm.end()
3960 3964
3961 3965 @command('merge',
3962 3966 [('f', 'force', None,
3963 3967 _('force a merge including outstanding changes (DEPRECATED)')),
3964 3968 ('r', 'rev', '', _('revision to merge'), _('REV')),
3965 3969 ('P', 'preview', None,
3966 3970 _('review revisions to merge (no merge is performed)')),
3967 3971 ('', 'abort', None, _('abort the ongoing merge')),
3968 3972 ] + mergetoolopts,
3969 3973 _('[-P] [[-r] REV]'),
3970 3974 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, helpbasic=True)
3971 3975 def merge(ui, repo, node=None, **opts):
3972 3976 """merge another revision into working directory
3973 3977
3974 3978 The current working directory is updated with all changes made in
3975 3979 the requested revision since the last common predecessor revision.
3976 3980
3977 3981 Files that changed between either parent are marked as changed for
3978 3982 the next commit and a commit must be performed before any further
3979 3983 updates to the repository are allowed. The next commit will have
3980 3984 two parents.
3981 3985
3982 3986 ``--tool`` can be used to specify the merge tool used for file
3983 3987 merges. It overrides the HGMERGE environment variable and your
3984 3988 configuration files. See :hg:`help merge-tools` for options.
3985 3989
3986 3990 If no revision is specified, the working directory's parent is a
3987 3991 head revision, and the current branch contains exactly one other
3988 3992 head, the other head is merged with by default. Otherwise, an
3989 3993 explicit revision with which to merge with must be provided.
3990 3994
3991 3995 See :hg:`help resolve` for information on handling file conflicts.
3992 3996
3993 3997 To undo an uncommitted merge, use :hg:`merge --abort` which
3994 3998 will check out a clean copy of the original merge parent, losing
3995 3999 all changes.
3996 4000
3997 4001 Returns 0 on success, 1 if there are unresolved files.
3998 4002 """
3999 4003
4000 4004 opts = pycompat.byteskwargs(opts)
4001 4005 abort = opts.get('abort')
4002 4006 if abort and repo.dirstate.p2() == nullid:
4003 4007 cmdutil.wrongtooltocontinue(repo, _('merge'))
4004 4008 if abort:
4005 4009 if node:
4006 4010 raise error.Abort(_("cannot specify a node with --abort"))
4007 4011 if opts.get('rev'):
4008 4012 raise error.Abort(_("cannot specify both --rev and --abort"))
4009 4013 if opts.get('preview'):
4010 4014 raise error.Abort(_("cannot specify --preview with --abort"))
4011 4015 if opts.get('rev') and node:
4012 4016 raise error.Abort(_("please specify just one revision"))
4013 4017 if not node:
4014 4018 node = opts.get('rev')
4015 4019
4016 4020 if node:
4017 4021 node = scmutil.revsingle(repo, node).node()
4018 4022
4019 4023 if not node and not abort:
4020 4024 node = repo[destutil.destmerge(repo)].node()
4021 4025
4022 4026 if opts.get('preview'):
4023 4027 # find nodes that are ancestors of p2 but not of p1
4024 4028 p1 = repo.lookup('.')
4025 4029 p2 = node
4026 4030 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4027 4031
4028 4032 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4029 4033 for node in nodes:
4030 4034 displayer.show(repo[node])
4031 4035 displayer.close()
4032 4036 return 0
4033 4037
4034 4038 # ui.forcemerge is an internal variable, do not document
4035 4039 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4036 4040 with ui.configoverride(overrides, 'merge'):
4037 4041 force = opts.get('force')
4038 4042 labels = ['working copy', 'merge rev']
4039 4043 return hg.merge(repo, node, force=force, mergeforce=force,
4040 4044 labels=labels, abort=abort)
4041 4045
4042 4046 @command('outgoing|out',
4043 4047 [('f', 'force', None, _('run even when the destination is unrelated')),
4044 4048 ('r', 'rev', [],
4045 4049 _('a changeset intended to be included in the destination'), _('REV')),
4046 4050 ('n', 'newest-first', None, _('show newest record first')),
4047 4051 ('B', 'bookmarks', False, _('compare bookmarks')),
4048 4052 ('b', 'branch', [], _('a specific branch you would like to push'),
4049 4053 _('BRANCH')),
4050 4054 ] + logopts + remoteopts + subrepoopts,
4051 4055 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4052 4056 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT)
4053 4057 def outgoing(ui, repo, dest=None, **opts):
4054 4058 """show changesets not found in the destination
4055 4059
4056 4060 Show changesets not found in the specified destination repository
4057 4061 or the default push location. These are the changesets that would
4058 4062 be pushed if a push was requested.
4059 4063
4060 4064 See pull for details of valid destination formats.
4061 4065
4062 4066 .. container:: verbose
4063 4067
4064 4068 With -B/--bookmarks, the result of bookmark comparison between
4065 4069 local and remote repositories is displayed. With -v/--verbose,
4066 4070 status is also displayed for each bookmark like below::
4067 4071
4068 4072 BM1 01234567890a added
4069 4073 BM2 deleted
4070 4074 BM3 234567890abc advanced
4071 4075 BM4 34567890abcd diverged
4072 4076 BM5 4567890abcde changed
4073 4077
4074 4078 The action taken when pushing depends on the
4075 4079 status of each bookmark:
4076 4080
4077 4081 :``added``: push with ``-B`` will create it
4078 4082 :``deleted``: push with ``-B`` will delete it
4079 4083 :``advanced``: push will update it
4080 4084 :``diverged``: push with ``-B`` will update it
4081 4085 :``changed``: push with ``-B`` will update it
4082 4086
4083 4087 From the point of view of pushing behavior, bookmarks
4084 4088 existing only in the remote repository are treated as
4085 4089 ``deleted``, even if it is in fact added remotely.
4086 4090
4087 4091 Returns 0 if there are outgoing changes, 1 otherwise.
4088 4092 """
4089 4093 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4090 4094 # style URLs, so don't overwrite dest.
4091 4095 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4092 4096 if not path:
4093 4097 raise error.Abort(_('default repository not configured!'),
4094 4098 hint=_("see 'hg help config.paths'"))
4095 4099
4096 4100 opts = pycompat.byteskwargs(opts)
4097 4101 if opts.get('graph'):
4098 4102 logcmdutil.checkunsupportedgraphflags([], opts)
4099 4103 o, other = hg._outgoing(ui, repo, dest, opts)
4100 4104 if not o:
4101 4105 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4102 4106 return
4103 4107
4104 4108 revdag = logcmdutil.graphrevs(repo, o, opts)
4105 4109 ui.pager('outgoing')
4106 4110 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4107 4111 logcmdutil.displaygraph(ui, repo, revdag, displayer,
4108 4112 graphmod.asciiedges)
4109 4113 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4110 4114 return 0
4111 4115
4112 4116 if opts.get('bookmarks'):
4113 4117 dest = path.pushloc or path.loc
4114 4118 other = hg.peer(repo, opts, dest)
4115 4119 if 'bookmarks' not in other.listkeys('namespaces'):
4116 4120 ui.warn(_("remote doesn't support bookmarks\n"))
4117 4121 return 0
4118 4122 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4119 4123 ui.pager('outgoing')
4120 4124 return bookmarks.outgoing(ui, repo, other)
4121 4125
4122 4126 repo._subtoppath = path.pushloc or path.loc
4123 4127 try:
4124 4128 return hg.outgoing(ui, repo, dest, opts)
4125 4129 finally:
4126 4130 del repo._subtoppath
4127 4131
4128 4132 @command('parents',
4129 4133 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4130 4134 ] + templateopts,
4131 4135 _('[-r REV] [FILE]'),
4132 4136 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4133 4137 inferrepo=True)
4134 4138 def parents(ui, repo, file_=None, **opts):
4135 4139 """show the parents of the working directory or revision (DEPRECATED)
4136 4140
4137 4141 Print the working directory's parent revisions. If a revision is
4138 4142 given via -r/--rev, the parent of that revision will be printed.
4139 4143 If a file argument is given, the revision in which the file was
4140 4144 last changed (before the working directory revision or the
4141 4145 argument to --rev if given) is printed.
4142 4146
4143 4147 This command is equivalent to::
4144 4148
4145 4149 hg log -r "p1()+p2()" or
4146 4150 hg log -r "p1(REV)+p2(REV)" or
4147 4151 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
4148 4152 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
4149 4153
4150 4154 See :hg:`summary` and :hg:`help revsets` for related information.
4151 4155
4152 4156 Returns 0 on success.
4153 4157 """
4154 4158
4155 4159 opts = pycompat.byteskwargs(opts)
4156 4160 rev = opts.get('rev')
4157 4161 if rev:
4158 4162 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
4159 4163 ctx = scmutil.revsingle(repo, rev, None)
4160 4164
4161 4165 if file_:
4162 4166 m = scmutil.match(ctx, (file_,), opts)
4163 4167 if m.anypats() or len(m.files()) != 1:
4164 4168 raise error.Abort(_('can only specify an explicit filename'))
4165 4169 file_ = m.files()[0]
4166 4170 filenodes = []
4167 4171 for cp in ctx.parents():
4168 4172 if not cp:
4169 4173 continue
4170 4174 try:
4171 4175 filenodes.append(cp.filenode(file_))
4172 4176 except error.LookupError:
4173 4177 pass
4174 4178 if not filenodes:
4175 4179 raise error.Abort(_("'%s' not found in manifest!") % file_)
4176 4180 p = []
4177 4181 for fn in filenodes:
4178 4182 fctx = repo.filectx(file_, fileid=fn)
4179 4183 p.append(fctx.node())
4180 4184 else:
4181 4185 p = [cp.node() for cp in ctx.parents()]
4182 4186
4183 4187 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
4184 4188 for n in p:
4185 4189 if n != nullid:
4186 4190 displayer.show(repo[n])
4187 4191 displayer.close()
4188 4192
4189 4193 @command('paths', formatteropts, _('[NAME]'),
4190 4194 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4191 4195 optionalrepo=True, intents={INTENT_READONLY})
4192 4196 def paths(ui, repo, search=None, **opts):
4193 4197 """show aliases for remote repositories
4194 4198
4195 4199 Show definition of symbolic path name NAME. If no name is given,
4196 4200 show definition of all available names.
4197 4201
4198 4202 Option -q/--quiet suppresses all output when searching for NAME
4199 4203 and shows only the path names when listing all definitions.
4200 4204
4201 4205 Path names are defined in the [paths] section of your
4202 4206 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4203 4207 repository, ``.hg/hgrc`` is used, too.
4204 4208
4205 4209 The path names ``default`` and ``default-push`` have a special
4206 4210 meaning. When performing a push or pull operation, they are used
4207 4211 as fallbacks if no location is specified on the command-line.
4208 4212 When ``default-push`` is set, it will be used for push and
4209 4213 ``default`` will be used for pull; otherwise ``default`` is used
4210 4214 as the fallback for both. When cloning a repository, the clone
4211 4215 source is written as ``default`` in ``.hg/hgrc``.
4212 4216
4213 4217 .. note::
4214 4218
4215 4219 ``default`` and ``default-push`` apply to all inbound (e.g.
4216 4220 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
4217 4221 and :hg:`bundle`) operations.
4218 4222
4219 4223 See :hg:`help urls` for more information.
4220 4224
4221 4225 .. container:: verbose
4222 4226
4223 4227 Template:
4224 4228
4225 4229 The following keywords are supported. See also :hg:`help templates`.
4226 4230
4227 4231 :name: String. Symbolic name of the path alias.
4228 4232 :pushurl: String. URL for push operations.
4229 4233 :url: String. URL or directory path for the other operations.
4230 4234
4231 4235 Returns 0 on success.
4232 4236 """
4233 4237
4234 4238 opts = pycompat.byteskwargs(opts)
4235 4239 ui.pager('paths')
4236 4240 if search:
4237 4241 pathitems = [(name, path) for name, path in ui.paths.iteritems()
4238 4242 if name == search]
4239 4243 else:
4240 4244 pathitems = sorted(ui.paths.iteritems())
4241 4245
4242 4246 fm = ui.formatter('paths', opts)
4243 4247 if fm.isplain():
4244 4248 hidepassword = util.hidepassword
4245 4249 else:
4246 4250 hidepassword = bytes
4247 4251 if ui.quiet:
4248 4252 namefmt = '%s\n'
4249 4253 else:
4250 4254 namefmt = '%s = '
4251 4255 showsubopts = not search and not ui.quiet
4252 4256
4253 4257 for name, path in pathitems:
4254 4258 fm.startitem()
4255 4259 fm.condwrite(not search, 'name', namefmt, name)
4256 4260 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
4257 4261 for subopt, value in sorted(path.suboptions.items()):
4258 4262 assert subopt not in ('name', 'url')
4259 4263 if showsubopts:
4260 4264 fm.plain('%s:%s = ' % (name, subopt))
4261 4265 fm.condwrite(showsubopts, subopt, '%s\n', value)
4262 4266
4263 4267 fm.end()
4264 4268
4265 4269 if search and not pathitems:
4266 4270 if not ui.quiet:
4267 4271 ui.warn(_("not found!\n"))
4268 4272 return 1
4269 4273 else:
4270 4274 return 0
4271 4275
4272 4276 @command('phase',
4273 4277 [('p', 'public', False, _('set changeset phase to public')),
4274 4278 ('d', 'draft', False, _('set changeset phase to draft')),
4275 4279 ('s', 'secret', False, _('set changeset phase to secret')),
4276 4280 ('f', 'force', False, _('allow to move boundary backward')),
4277 4281 ('r', 'rev', [], _('target revision'), _('REV')),
4278 4282 ],
4279 4283 _('[-p|-d|-s] [-f] [-r] [REV...]'),
4280 4284 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
4281 4285 def phase(ui, repo, *revs, **opts):
4282 4286 """set or show the current phase name
4283 4287
4284 4288 With no argument, show the phase name of the current revision(s).
4285 4289
4286 4290 With one of -p/--public, -d/--draft or -s/--secret, change the
4287 4291 phase value of the specified revisions.
4288 4292
4289 4293 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
4290 4294 lower phase to a higher phase. Phases are ordered as follows::
4291 4295
4292 4296 public < draft < secret
4293 4297
4294 4298 Returns 0 on success, 1 if some phases could not be changed.
4295 4299
4296 4300 (For more information about the phases concept, see :hg:`help phases`.)
4297 4301 """
4298 4302 opts = pycompat.byteskwargs(opts)
4299 4303 # search for a unique phase argument
4300 4304 targetphase = None
4301 4305 for idx, name in enumerate(phases.cmdphasenames):
4302 4306 if opts[name]:
4303 4307 if targetphase is not None:
4304 4308 raise error.Abort(_('only one phase can be specified'))
4305 4309 targetphase = idx
4306 4310
4307 4311 # look for specified revision
4308 4312 revs = list(revs)
4309 4313 revs.extend(opts['rev'])
4310 4314 if not revs:
4311 4315 # display both parents as the second parent phase can influence
4312 4316 # the phase of a merge commit
4313 4317 revs = [c.rev() for c in repo[None].parents()]
4314 4318
4315 4319 revs = scmutil.revrange(repo, revs)
4316 4320
4317 4321 ret = 0
4318 4322 if targetphase is None:
4319 4323 # display
4320 4324 for r in revs:
4321 4325 ctx = repo[r]
4322 4326 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4323 4327 else:
4324 4328 with repo.lock(), repo.transaction("phase") as tr:
4325 4329 # set phase
4326 4330 if not revs:
4327 4331 raise error.Abort(_('empty revision set'))
4328 4332 nodes = [repo[r].node() for r in revs]
4329 4333 # moving revision from public to draft may hide them
4330 4334 # We have to check result on an unfiltered repository
4331 4335 unfi = repo.unfiltered()
4332 4336 getphase = unfi._phasecache.phase
4333 4337 olddata = [getphase(unfi, r) for r in unfi]
4334 4338 phases.advanceboundary(repo, tr, targetphase, nodes)
4335 4339 if opts['force']:
4336 4340 phases.retractboundary(repo, tr, targetphase, nodes)
4337 4341 getphase = unfi._phasecache.phase
4338 4342 newdata = [getphase(unfi, r) for r in unfi]
4339 4343 changes = sum(newdata[r] != olddata[r] for r in unfi)
4340 4344 cl = unfi.changelog
4341 4345 rejected = [n for n in nodes
4342 4346 if newdata[cl.rev(n)] < targetphase]
4343 4347 if rejected:
4344 4348 ui.warn(_('cannot move %i changesets to a higher '
4345 4349 'phase, use --force\n') % len(rejected))
4346 4350 ret = 1
4347 4351 if changes:
4348 4352 msg = _('phase changed for %i changesets\n') % changes
4349 4353 if ret:
4350 4354 ui.status(msg)
4351 4355 else:
4352 4356 ui.note(msg)
4353 4357 else:
4354 4358 ui.warn(_('no phases changed\n'))
4355 4359 return ret
4356 4360
4357 4361 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
4358 4362 """Run after a changegroup has been added via pull/unbundle
4359 4363
4360 4364 This takes arguments below:
4361 4365
4362 4366 :modheads: change of heads by pull/unbundle
4363 4367 :optupdate: updating working directory is needed or not
4364 4368 :checkout: update destination revision (or None to default destination)
4365 4369 :brev: a name, which might be a bookmark to be activated after updating
4366 4370 """
4367 4371 if modheads == 0:
4368 4372 return
4369 4373 if optupdate:
4370 4374 try:
4371 4375 return hg.updatetotally(ui, repo, checkout, brev)
4372 4376 except error.UpdateAbort as inst:
4373 4377 msg = _("not updating: %s") % stringutil.forcebytestr(inst)
4374 4378 hint = inst.hint
4375 4379 raise error.UpdateAbort(msg, hint=hint)
4376 4380 if modheads is not None and modheads > 1:
4377 4381 currentbranchheads = len(repo.branchheads())
4378 4382 if currentbranchheads == modheads:
4379 4383 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4380 4384 elif currentbranchheads > 1:
4381 4385 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4382 4386 "merge)\n"))
4383 4387 else:
4384 4388 ui.status(_("(run 'hg heads' to see heads)\n"))
4385 4389 elif not ui.configbool('commands', 'update.requiredest'):
4386 4390 ui.status(_("(run 'hg update' to get a working copy)\n"))
4387 4391
4388 4392 @command('pull',
4389 4393 [('u', 'update', None,
4390 4394 _('update to new branch head if new descendants were pulled')),
4391 4395 ('f', 'force', None, _('run even when remote repository is unrelated')),
4392 4396 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4393 4397 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4394 4398 ('b', 'branch', [], _('a specific branch you would like to pull'),
4395 4399 _('BRANCH')),
4396 4400 ] + remoteopts,
4397 4401 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
4398 4402 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4399 4403 helpbasic=True)
4400 4404 def pull(ui, repo, source="default", **opts):
4401 4405 """pull changes from the specified source
4402 4406
4403 4407 Pull changes from a remote repository to a local one.
4404 4408
4405 4409 This finds all changes from the repository at the specified path
4406 4410 or URL and adds them to a local repository (the current one unless
4407 4411 -R is specified). By default, this does not update the copy of the
4408 4412 project in the working directory.
4409 4413
4410 4414 When cloning from servers that support it, Mercurial may fetch
4411 4415 pre-generated data. When this is done, hooks operating on incoming
4412 4416 changesets and changegroups may fire more than once, once for each
4413 4417 pre-generated bundle and as well as for any additional remaining
4414 4418 data. See :hg:`help -e clonebundles` for more.
4415 4419
4416 4420 Use :hg:`incoming` if you want to see what would have been added
4417 4421 by a pull at the time you issued this command. If you then decide
4418 4422 to add those changes to the repository, you should use :hg:`pull
4419 4423 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4420 4424
4421 4425 If SOURCE is omitted, the 'default' path will be used.
4422 4426 See :hg:`help urls` for more information.
4423 4427
4424 4428 Specifying bookmark as ``.`` is equivalent to specifying the active
4425 4429 bookmark's name.
4426 4430
4427 4431 Returns 0 on success, 1 if an update had unresolved files.
4428 4432 """
4429 4433
4430 4434 opts = pycompat.byteskwargs(opts)
4431 4435 if ui.configbool('commands', 'update.requiredest') and opts.get('update'):
4432 4436 msg = _('update destination required by configuration')
4433 4437 hint = _('use hg pull followed by hg update DEST')
4434 4438 raise error.Abort(msg, hint=hint)
4435 4439
4436 4440 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4437 4441 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4438 4442 other = hg.peer(repo, opts, source)
4439 4443 try:
4440 4444 revs, checkout = hg.addbranchrevs(repo, other, branches,
4441 4445 opts.get('rev'))
4442 4446
4443 4447 pullopargs = {}
4444 4448
4445 4449 nodes = None
4446 4450 if opts.get('bookmark') or revs:
4447 4451 # The list of bookmark used here is the same used to actually update
4448 4452 # the bookmark names, to avoid the race from issue 4689 and we do
4449 4453 # all lookup and bookmark queries in one go so they see the same
4450 4454 # version of the server state (issue 4700).
4451 4455 nodes = []
4452 4456 fnodes = []
4453 4457 revs = revs or []
4454 4458 if revs and not other.capable('lookup'):
4455 4459 err = _("other repository doesn't support revision lookup, "
4456 4460 "so a rev cannot be specified.")
4457 4461 raise error.Abort(err)
4458 4462 with other.commandexecutor() as e:
4459 4463 fremotebookmarks = e.callcommand('listkeys', {
4460 4464 'namespace': 'bookmarks'
4461 4465 })
4462 4466 for r in revs:
4463 4467 fnodes.append(e.callcommand('lookup', {'key': r}))
4464 4468 remotebookmarks = fremotebookmarks.result()
4465 4469 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
4466 4470 pullopargs['remotebookmarks'] = remotebookmarks
4467 4471 for b in opts.get('bookmark', []):
4468 4472 b = repo._bookmarks.expandname(b)
4469 4473 if b not in remotebookmarks:
4470 4474 raise error.Abort(_('remote bookmark %s not found!') % b)
4471 4475 nodes.append(remotebookmarks[b])
4472 4476 for i, rev in enumerate(revs):
4473 4477 node = fnodes[i].result()
4474 4478 nodes.append(node)
4475 4479 if rev == checkout:
4476 4480 checkout = node
4477 4481
4478 4482 wlock = util.nullcontextmanager()
4479 4483 if opts.get('update'):
4480 4484 wlock = repo.wlock()
4481 4485 with wlock:
4482 4486 pullopargs.update(opts.get('opargs', {}))
4483 4487 modheads = exchange.pull(repo, other, heads=nodes,
4484 4488 force=opts.get('force'),
4485 4489 bookmarks=opts.get('bookmark', ()),
4486 4490 opargs=pullopargs).cgresult
4487 4491
4488 4492 # brev is a name, which might be a bookmark to be activated at
4489 4493 # the end of the update. In other words, it is an explicit
4490 4494 # destination of the update
4491 4495 brev = None
4492 4496
4493 4497 if checkout:
4494 4498 checkout = repo.unfiltered().changelog.rev(checkout)
4495 4499
4496 4500 # order below depends on implementation of
4497 4501 # hg.addbranchrevs(). opts['bookmark'] is ignored,
4498 4502 # because 'checkout' is determined without it.
4499 4503 if opts.get('rev'):
4500 4504 brev = opts['rev'][0]
4501 4505 elif opts.get('branch'):
4502 4506 brev = opts['branch'][0]
4503 4507 else:
4504 4508 brev = branches[0]
4505 4509 repo._subtoppath = source
4506 4510 try:
4507 4511 ret = postincoming(ui, repo, modheads, opts.get('update'),
4508 4512 checkout, brev)
4509 4513 except error.FilteredRepoLookupError as exc:
4510 4514 msg = _('cannot update to target: %s') % exc.args[0]
4511 4515 exc.args = (msg,) + exc.args[1:]
4512 4516 raise
4513 4517 finally:
4514 4518 del repo._subtoppath
4515 4519
4516 4520 finally:
4517 4521 other.close()
4518 4522 return ret
4519 4523
4520 4524 @command('push',
4521 4525 [('f', 'force', None, _('force push')),
4522 4526 ('r', 'rev', [],
4523 4527 _('a changeset intended to be included in the destination'),
4524 4528 _('REV')),
4525 4529 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4526 4530 ('b', 'branch', [],
4527 4531 _('a specific branch you would like to push'), _('BRANCH')),
4528 4532 ('', 'new-branch', False, _('allow pushing a new branch')),
4529 4533 ('', 'pushvars', [], _('variables that can be sent to server (ADVANCED)')),
4530 4534 ('', 'publish', False, _('push the changeset as public (EXPERIMENTAL)')),
4531 4535 ] + remoteopts,
4532 4536 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
4533 4537 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4534 4538 helpbasic=True)
4535 4539 def push(ui, repo, dest=None, **opts):
4536 4540 """push changes to the specified destination
4537 4541
4538 4542 Push changesets from the local repository to the specified
4539 4543 destination.
4540 4544
4541 4545 This operation is symmetrical to pull: it is identical to a pull
4542 4546 in the destination repository from the current one.
4543 4547
4544 4548 By default, push will not allow creation of new heads at the
4545 4549 destination, since multiple heads would make it unclear which head
4546 4550 to use. In this situation, it is recommended to pull and merge
4547 4551 before pushing.
4548 4552
4549 4553 Use --new-branch if you want to allow push to create a new named
4550 4554 branch that is not present at the destination. This allows you to
4551 4555 only create a new branch without forcing other changes.
4552 4556
4553 4557 .. note::
4554 4558
4555 4559 Extra care should be taken with the -f/--force option,
4556 4560 which will push all new heads on all branches, an action which will
4557 4561 almost always cause confusion for collaborators.
4558 4562
4559 4563 If -r/--rev is used, the specified revision and all its ancestors
4560 4564 will be pushed to the remote repository.
4561 4565
4562 4566 If -B/--bookmark is used, the specified bookmarked revision, its
4563 4567 ancestors, and the bookmark will be pushed to the remote
4564 4568 repository. Specifying ``.`` is equivalent to specifying the active
4565 4569 bookmark's name.
4566 4570
4567 4571 Please see :hg:`help urls` for important details about ``ssh://``
4568 4572 URLs. If DESTINATION is omitted, a default path will be used.
4569 4573
4570 4574 .. container:: verbose
4571 4575
4572 4576 The --pushvars option sends strings to the server that become
4573 4577 environment variables prepended with ``HG_USERVAR_``. For example,
4574 4578 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
4575 4579 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
4576 4580
4577 4581 pushvars can provide for user-overridable hooks as well as set debug
4578 4582 levels. One example is having a hook that blocks commits containing
4579 4583 conflict markers, but enables the user to override the hook if the file
4580 4584 is using conflict markers for testing purposes or the file format has
4581 4585 strings that look like conflict markers.
4582 4586
4583 4587 By default, servers will ignore `--pushvars`. To enable it add the
4584 4588 following to your configuration file::
4585 4589
4586 4590 [push]
4587 4591 pushvars.server = true
4588 4592
4589 4593 Returns 0 if push was successful, 1 if nothing to push.
4590 4594 """
4591 4595
4592 4596 opts = pycompat.byteskwargs(opts)
4593 4597 if opts.get('bookmark'):
4594 4598 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4595 4599 for b in opts['bookmark']:
4596 4600 # translate -B options to -r so changesets get pushed
4597 4601 b = repo._bookmarks.expandname(b)
4598 4602 if b in repo._bookmarks:
4599 4603 opts.setdefault('rev', []).append(b)
4600 4604 else:
4601 4605 # if we try to push a deleted bookmark, translate it to null
4602 4606 # this lets simultaneous -r, -b options continue working
4603 4607 opts.setdefault('rev', []).append("null")
4604 4608
4605 4609 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4606 4610 if not path:
4607 4611 raise error.Abort(_('default repository not configured!'),
4608 4612 hint=_("see 'hg help config.paths'"))
4609 4613 dest = path.pushloc or path.loc
4610 4614 branches = (path.branch, opts.get('branch') or [])
4611 4615 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4612 4616 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4613 4617 other = hg.peer(repo, opts, dest)
4614 4618
4615 4619 if revs:
4616 4620 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
4617 4621 if not revs:
4618 4622 raise error.Abort(_("specified revisions evaluate to an empty set"),
4619 4623 hint=_("use different revision arguments"))
4620 4624 elif path.pushrev:
4621 4625 # It doesn't make any sense to specify ancestor revisions. So limit
4622 4626 # to DAG heads to make discovery simpler.
4623 4627 expr = revsetlang.formatspec('heads(%r)', path.pushrev)
4624 4628 revs = scmutil.revrange(repo, [expr])
4625 4629 revs = [repo[rev].node() for rev in revs]
4626 4630 if not revs:
4627 4631 raise error.Abort(_('default push revset for path evaluates to an '
4628 4632 'empty set'))
4629 4633
4630 4634 repo._subtoppath = dest
4631 4635 try:
4632 4636 # push subrepos depth-first for coherent ordering
4633 4637 c = repo['.']
4634 4638 subs = c.substate # only repos that are committed
4635 4639 for s in sorted(subs):
4636 4640 result = c.sub(s).push(opts)
4637 4641 if result == 0:
4638 4642 return not result
4639 4643 finally:
4640 4644 del repo._subtoppath
4641 4645
4642 4646 opargs = dict(opts.get('opargs', {})) # copy opargs since we may mutate it
4643 4647 opargs.setdefault('pushvars', []).extend(opts.get('pushvars', []))
4644 4648
4645 4649 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
4646 4650 newbranch=opts.get('new_branch'),
4647 4651 bookmarks=opts.get('bookmark', ()),
4648 4652 publish=opts.get('publish'),
4649 4653 opargs=opargs)
4650 4654
4651 4655 result = not pushop.cgresult
4652 4656
4653 4657 if pushop.bkresult is not None:
4654 4658 if pushop.bkresult == 2:
4655 4659 result = 2
4656 4660 elif not result and pushop.bkresult:
4657 4661 result = 2
4658 4662
4659 4663 return result
4660 4664
4661 4665 @command('recover',
4662 4666 [('','verify', True, "run `hg verify` after succesful recover"),
4663 4667 ],
4664 4668 helpcategory=command.CATEGORY_MAINTENANCE)
4665 4669 def recover(ui, repo, **opts):
4666 4670 """roll back an interrupted transaction
4667 4671
4668 4672 Recover from an interrupted commit or pull.
4669 4673
4670 4674 This command tries to fix the repository status after an
4671 4675 interrupted operation. It should only be necessary when Mercurial
4672 4676 suggests it.
4673 4677
4674 4678 Returns 0 if successful, 1 if nothing to recover or verify fails.
4675 4679 """
4676 4680 ret = repo.recover()
4677 4681 if ret:
4678 4682 if opts['verify']:
4679 4683 return hg.verify(repo)
4680 4684 else:
4681 4685 msg = _("(verify step skipped, run `hg verify` to check your "
4682 4686 "repository content)\n")
4683 4687 ui.warn(msg)
4684 4688 return 0
4685 4689 return 1
4686 4690
4687 4691 @command('remove|rm',
4688 4692 [('A', 'after', None, _('record delete for missing files')),
4689 4693 ('f', 'force', None,
4690 4694 _('forget added files, delete modified files')),
4691 4695 ] + subrepoopts + walkopts + dryrunopts,
4692 4696 _('[OPTION]... FILE...'),
4693 4697 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4694 4698 helpbasic=True, inferrepo=True)
4695 4699 def remove(ui, repo, *pats, **opts):
4696 4700 """remove the specified files on the next commit
4697 4701
4698 4702 Schedule the indicated files for removal from the current branch.
4699 4703
4700 4704 This command schedules the files to be removed at the next commit.
4701 4705 To undo a remove before that, see :hg:`revert`. To undo added
4702 4706 files, see :hg:`forget`.
4703 4707
4704 4708 .. container:: verbose
4705 4709
4706 4710 -A/--after can be used to remove only files that have already
4707 4711 been deleted, -f/--force can be used to force deletion, and -Af
4708 4712 can be used to remove files from the next revision without
4709 4713 deleting them from the working directory.
4710 4714
4711 4715 The following table details the behavior of remove for different
4712 4716 file states (columns) and option combinations (rows). The file
4713 4717 states are Added [A], Clean [C], Modified [M] and Missing [!]
4714 4718 (as reported by :hg:`status`). The actions are Warn, Remove
4715 4719 (from branch) and Delete (from disk):
4716 4720
4717 4721 ========= == == == ==
4718 4722 opt/state A C M !
4719 4723 ========= == == == ==
4720 4724 none W RD W R
4721 4725 -f R RD RD R
4722 4726 -A W W W R
4723 4727 -Af R R R R
4724 4728 ========= == == == ==
4725 4729
4726 4730 .. note::
4727 4731
4728 4732 :hg:`remove` never deletes files in Added [A] state from the
4729 4733 working directory, not even if ``--force`` is specified.
4730 4734
4731 4735 Returns 0 on success, 1 if any warnings encountered.
4732 4736 """
4733 4737
4734 4738 opts = pycompat.byteskwargs(opts)
4735 4739 after, force = opts.get('after'), opts.get('force')
4736 4740 dryrun = opts.get('dry_run')
4737 4741 if not pats and not after:
4738 4742 raise error.Abort(_('no files specified'))
4739 4743
4740 4744 m = scmutil.match(repo[None], pats, opts)
4741 4745 subrepos = opts.get('subrepos')
4742 4746 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
4743 4747 return cmdutil.remove(ui, repo, m, "", uipathfn, after, force, subrepos,
4744 4748 dryrun=dryrun)
4745 4749
4746 4750 @command('rename|move|mv',
4747 4751 [('A', 'after', None, _('record a rename that has already occurred')),
4748 4752 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4749 4753 ] + walkopts + dryrunopts,
4750 4754 _('[OPTION]... SOURCE... DEST'),
4751 4755 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
4752 4756 def rename(ui, repo, *pats, **opts):
4753 4757 """rename files; equivalent of copy + remove
4754 4758
4755 4759 Mark dest as copies of sources; mark sources for deletion. If dest
4756 4760 is a directory, copies are put in that directory. If dest is a
4757 4761 file, there can only be one source.
4758 4762
4759 4763 By default, this command copies the contents of files as they
4760 4764 exist in the working directory. If invoked with -A/--after, the
4761 4765 operation is recorded, but no copying is performed.
4762 4766
4763 4767 This command takes effect at the next commit. To undo a rename
4764 4768 before that, see :hg:`revert`.
4765 4769
4766 4770 Returns 0 on success, 1 if errors are encountered.
4767 4771 """
4768 4772 opts = pycompat.byteskwargs(opts)
4769 4773 with repo.wlock(False):
4770 4774 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4771 4775
4772 4776 @command('resolve',
4773 4777 [('a', 'all', None, _('select all unresolved files')),
4774 4778 ('l', 'list', None, _('list state of files needing merge')),
4775 4779 ('m', 'mark', None, _('mark files as resolved')),
4776 4780 ('u', 'unmark', None, _('mark files as unresolved')),
4777 4781 ('n', 'no-status', None, _('hide status prefix')),
4778 4782 ('', 're-merge', None, _('re-merge files'))]
4779 4783 + mergetoolopts + walkopts + formatteropts,
4780 4784 _('[OPTION]... [FILE]...'),
4781 4785 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4782 4786 inferrepo=True)
4783 4787 def resolve(ui, repo, *pats, **opts):
4784 4788 """redo merges or set/view the merge status of files
4785 4789
4786 4790 Merges with unresolved conflicts are often the result of
4787 4791 non-interactive merging using the ``internal:merge`` configuration
4788 4792 setting, or a command-line merge tool like ``diff3``. The resolve
4789 4793 command is used to manage the files involved in a merge, after
4790 4794 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4791 4795 working directory must have two parents). See :hg:`help
4792 4796 merge-tools` for information on configuring merge tools.
4793 4797
4794 4798 The resolve command can be used in the following ways:
4795 4799
4796 4800 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
4797 4801 the specified files, discarding any previous merge attempts. Re-merging
4798 4802 is not performed for files already marked as resolved. Use ``--all/-a``
4799 4803 to select all unresolved files. ``--tool`` can be used to specify
4800 4804 the merge tool used for the given files. It overrides the HGMERGE
4801 4805 environment variable and your configuration files. Previous file
4802 4806 contents are saved with a ``.orig`` suffix.
4803 4807
4804 4808 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4805 4809 (e.g. after having manually fixed-up the files). The default is
4806 4810 to mark all unresolved files.
4807 4811
4808 4812 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4809 4813 default is to mark all resolved files.
4810 4814
4811 4815 - :hg:`resolve -l`: list files which had or still have conflicts.
4812 4816 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4813 4817 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
4814 4818 the list. See :hg:`help filesets` for details.
4815 4819
4816 4820 .. note::
4817 4821
4818 4822 Mercurial will not let you commit files with unresolved merge
4819 4823 conflicts. You must use :hg:`resolve -m ...` before you can
4820 4824 commit after a conflicting merge.
4821 4825
4822 4826 .. container:: verbose
4823 4827
4824 4828 Template:
4825 4829
4826 4830 The following keywords are supported in addition to the common template
4827 4831 keywords and functions. See also :hg:`help templates`.
4828 4832
4829 4833 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
4830 4834 :path: String. Repository-absolute path of the file.
4831 4835
4832 4836 Returns 0 on success, 1 if any files fail a resolve attempt.
4833 4837 """
4834 4838
4835 4839 opts = pycompat.byteskwargs(opts)
4836 4840 confirm = ui.configbool('commands', 'resolve.confirm')
4837 4841 flaglist = 'all mark unmark list no_status re_merge'.split()
4838 4842 all, mark, unmark, show, nostatus, remerge = [
4839 4843 opts.get(o) for o in flaglist]
4840 4844
4841 4845 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
4842 4846 if actioncount > 1:
4843 4847 raise error.Abort(_("too many actions specified"))
4844 4848 elif (actioncount == 0
4845 4849 and ui.configbool('commands', 'resolve.explicit-re-merge')):
4846 4850 hint = _('use --mark, --unmark, --list or --re-merge')
4847 4851 raise error.Abort(_('no action specified'), hint=hint)
4848 4852 if pats and all:
4849 4853 raise error.Abort(_("can't specify --all and patterns"))
4850 4854 if not (all or pats or show or mark or unmark):
4851 4855 raise error.Abort(_('no files or directories specified'),
4852 4856 hint=('use --all to re-merge all unresolved files'))
4853 4857
4854 4858 if confirm:
4855 4859 if all:
4856 4860 if ui.promptchoice(_(b're-merge all unresolved files (yn)?'
4857 4861 b'$$ &Yes $$ &No')):
4858 4862 raise error.Abort(_('user quit'))
4859 4863 if mark and not pats:
4860 4864 if ui.promptchoice(_(b'mark all unresolved files as resolved (yn)?'
4861 4865 b'$$ &Yes $$ &No')):
4862 4866 raise error.Abort(_('user quit'))
4863 4867 if unmark and not pats:
4864 4868 if ui.promptchoice(_(b'mark all resolved files as unresolved (yn)?'
4865 4869 b'$$ &Yes $$ &No')):
4866 4870 raise error.Abort(_('user quit'))
4867 4871
4868 4872 uipathfn = scmutil.getuipathfn(repo)
4869 4873
4870 4874 if show:
4871 4875 ui.pager('resolve')
4872 4876 fm = ui.formatter('resolve', opts)
4873 4877 ms = mergemod.mergestate.read(repo)
4874 4878 wctx = repo[None]
4875 4879 m = scmutil.match(wctx, pats, opts)
4876 4880
4877 4881 # Labels and keys based on merge state. Unresolved path conflicts show
4878 4882 # as 'P'. Resolved path conflicts show as 'R', the same as normal
4879 4883 # resolved conflicts.
4880 4884 mergestateinfo = {
4881 4885 mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'),
4882 4886 mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'),
4883 4887 mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'),
4884 4888 mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'),
4885 4889 mergemod.MERGE_RECORD_DRIVER_RESOLVED: ('resolve.driverresolved',
4886 4890 'D'),
4887 4891 }
4888 4892
4889 4893 for f in ms:
4890 4894 if not m(f):
4891 4895 continue
4892 4896
4893 4897 label, key = mergestateinfo[ms[f]]
4894 4898 fm.startitem()
4895 4899 fm.context(ctx=wctx)
4896 4900 fm.condwrite(not nostatus, 'mergestatus', '%s ', key, label=label)
4897 4901 fm.data(path=f)
4898 4902 fm.plain('%s\n' % uipathfn(f), label=label)
4899 4903 fm.end()
4900 4904 return 0
4901 4905
4902 4906 with repo.wlock():
4903 4907 ms = mergemod.mergestate.read(repo)
4904 4908
4905 4909 if not (ms.active() or repo.dirstate.p2() != nullid):
4906 4910 raise error.Abort(
4907 4911 _('resolve command not applicable when not merging'))
4908 4912
4909 4913 wctx = repo[None]
4910 4914
4911 4915 if (ms.mergedriver
4912 4916 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED):
4913 4917 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4914 4918 ms.commit()
4915 4919 # allow mark and unmark to go through
4916 4920 if not mark and not unmark and not proceed:
4917 4921 return 1
4918 4922
4919 4923 m = scmutil.match(wctx, pats, opts)
4920 4924 ret = 0
4921 4925 didwork = False
4922 4926 runconclude = False
4923 4927
4924 4928 tocomplete = []
4925 4929 hasconflictmarkers = []
4926 4930 if mark:
4927 4931 markcheck = ui.config('commands', 'resolve.mark-check')
4928 4932 if markcheck not in ['warn', 'abort']:
4929 4933 # Treat all invalid / unrecognized values as 'none'.
4930 4934 markcheck = False
4931 4935 for f in ms:
4932 4936 if not m(f):
4933 4937 continue
4934 4938
4935 4939 didwork = True
4936 4940
4937 4941 # don't let driver-resolved files be marked, and run the conclude
4938 4942 # step if asked to resolve
4939 4943 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
4940 4944 exact = m.exact(f)
4941 4945 if mark:
4942 4946 if exact:
4943 4947 ui.warn(_('not marking %s as it is driver-resolved\n')
4944 4948 % uipathfn(f))
4945 4949 elif unmark:
4946 4950 if exact:
4947 4951 ui.warn(_('not unmarking %s as it is driver-resolved\n')
4948 4952 % uipathfn(f))
4949 4953 else:
4950 4954 runconclude = True
4951 4955 continue
4952 4956
4953 4957 # path conflicts must be resolved manually
4954 4958 if ms[f] in (mergemod.MERGE_RECORD_UNRESOLVED_PATH,
4955 4959 mergemod.MERGE_RECORD_RESOLVED_PATH):
4956 4960 if mark:
4957 4961 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
4958 4962 elif unmark:
4959 4963 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
4960 4964 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
4961 4965 ui.warn(_('%s: path conflict must be resolved manually\n')
4962 4966 % uipathfn(f))
4963 4967 continue
4964 4968
4965 4969 if mark:
4966 4970 if markcheck:
4967 4971 fdata = repo.wvfs.tryread(f)
4968 4972 if (filemerge.hasconflictmarkers(fdata) and
4969 4973 ms[f] != mergemod.MERGE_RECORD_RESOLVED):
4970 4974 hasconflictmarkers.append(f)
4971 4975 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
4972 4976 elif unmark:
4973 4977 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
4974 4978 else:
4975 4979 # backup pre-resolve (merge uses .orig for its own purposes)
4976 4980 a = repo.wjoin(f)
4977 4981 try:
4978 4982 util.copyfile(a, a + ".resolve")
4979 4983 except (IOError, OSError) as inst:
4980 4984 if inst.errno != errno.ENOENT:
4981 4985 raise
4982 4986
4983 4987 try:
4984 4988 # preresolve file
4985 4989 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4986 4990 with ui.configoverride(overrides, 'resolve'):
4987 4991 complete, r = ms.preresolve(f, wctx)
4988 4992 if not complete:
4989 4993 tocomplete.append(f)
4990 4994 elif r:
4991 4995 ret = 1
4992 4996 finally:
4993 4997 ms.commit()
4994 4998
4995 4999 # replace filemerge's .orig file with our resolve file, but only
4996 5000 # for merges that are complete
4997 5001 if complete:
4998 5002 try:
4999 5003 util.rename(a + ".resolve",
5000 5004 scmutil.backuppath(ui, repo, f))
5001 5005 except OSError as inst:
5002 5006 if inst.errno != errno.ENOENT:
5003 5007 raise
5004 5008
5005 5009 if hasconflictmarkers:
5006 5010 ui.warn(_('warning: the following files still have conflict '
5007 5011 'markers:\n') + ''.join(' ' + uipathfn(f) + '\n'
5008 5012 for f in hasconflictmarkers))
5009 5013 if markcheck == 'abort' and not all and not pats:
5010 5014 raise error.Abort(_('conflict markers detected'),
5011 5015 hint=_('use --all to mark anyway'))
5012 5016
5013 5017 for f in tocomplete:
5014 5018 try:
5015 5019 # resolve file
5016 5020 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
5017 5021 with ui.configoverride(overrides, 'resolve'):
5018 5022 r = ms.resolve(f, wctx)
5019 5023 if r:
5020 5024 ret = 1
5021 5025 finally:
5022 5026 ms.commit()
5023 5027
5024 5028 # replace filemerge's .orig file with our resolve file
5025 5029 a = repo.wjoin(f)
5026 5030 try:
5027 5031 util.rename(a + ".resolve", scmutil.backuppath(ui, repo, f))
5028 5032 except OSError as inst:
5029 5033 if inst.errno != errno.ENOENT:
5030 5034 raise
5031 5035
5032 5036 ms.commit()
5033 5037 ms.recordactions()
5034 5038
5035 5039 if not didwork and pats:
5036 5040 hint = None
5037 5041 if not any([p for p in pats if p.find(':') >= 0]):
5038 5042 pats = ['path:%s' % p for p in pats]
5039 5043 m = scmutil.match(wctx, pats, opts)
5040 5044 for f in ms:
5041 5045 if not m(f):
5042 5046 continue
5043 5047 def flag(o):
5044 5048 if o == 're_merge':
5045 5049 return '--re-merge '
5046 5050 return '-%s ' % o[0:1]
5047 5051 flags = ''.join([flag(o) for o in flaglist if opts.get(o)])
5048 5052 hint = _("(try: hg resolve %s%s)\n") % (
5049 5053 flags,
5050 5054 ' '.join(pats))
5051 5055 break
5052 5056 ui.warn(_("arguments do not match paths that need resolving\n"))
5053 5057 if hint:
5054 5058 ui.warn(hint)
5055 5059 elif ms.mergedriver and ms.mdstate() != 's':
5056 5060 # run conclude step when either a driver-resolved file is requested
5057 5061 # or there are no driver-resolved files
5058 5062 # we can't use 'ret' to determine whether any files are unresolved
5059 5063 # because we might not have tried to resolve some
5060 5064 if ((runconclude or not list(ms.driverresolved()))
5061 5065 and not list(ms.unresolved())):
5062 5066 proceed = mergemod.driverconclude(repo, ms, wctx)
5063 5067 ms.commit()
5064 5068 if not proceed:
5065 5069 return 1
5066 5070
5067 5071 # Nudge users into finishing an unfinished operation
5068 5072 unresolvedf = list(ms.unresolved())
5069 5073 driverresolvedf = list(ms.driverresolved())
5070 5074 if not unresolvedf and not driverresolvedf:
5071 5075 ui.status(_('(no more unresolved files)\n'))
5072 5076 cmdutil.checkafterresolved(repo)
5073 5077 elif not unresolvedf:
5074 5078 ui.status(_('(no more unresolved files -- '
5075 5079 'run "hg resolve --all" to conclude)\n'))
5076 5080
5077 5081 return ret
5078 5082
5079 5083 @command('revert',
5080 5084 [('a', 'all', None, _('revert all changes when no arguments given')),
5081 5085 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5082 5086 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5083 5087 ('C', 'no-backup', None, _('do not save backup copies of files')),
5084 5088 ('i', 'interactive', None, _('interactively select the changes')),
5085 5089 ] + walkopts + dryrunopts,
5086 5090 _('[OPTION]... [-r REV] [NAME]...'),
5087 5091 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5088 5092 def revert(ui, repo, *pats, **opts):
5089 5093 """restore files to their checkout state
5090 5094
5091 5095 .. note::
5092 5096
5093 5097 To check out earlier revisions, you should use :hg:`update REV`.
5094 5098 To cancel an uncommitted merge (and lose your changes),
5095 5099 use :hg:`merge --abort`.
5096 5100
5097 5101 With no revision specified, revert the specified files or directories
5098 5102 to the contents they had in the parent of the working directory.
5099 5103 This restores the contents of files to an unmodified
5100 5104 state and unschedules adds, removes, copies, and renames. If the
5101 5105 working directory has two parents, you must explicitly specify a
5102 5106 revision.
5103 5107
5104 5108 Using the -r/--rev or -d/--date options, revert the given files or
5105 5109 directories to their states as of a specific revision. Because
5106 5110 revert does not change the working directory parents, this will
5107 5111 cause these files to appear modified. This can be helpful to "back
5108 5112 out" some or all of an earlier change. See :hg:`backout` for a
5109 5113 related method.
5110 5114
5111 5115 Modified files are saved with a .orig suffix before reverting.
5112 5116 To disable these backups, use --no-backup. It is possible to store
5113 5117 the backup files in a custom directory relative to the root of the
5114 5118 repository by setting the ``ui.origbackuppath`` configuration
5115 5119 option.
5116 5120
5117 5121 See :hg:`help dates` for a list of formats valid for -d/--date.
5118 5122
5119 5123 See :hg:`help backout` for a way to reverse the effect of an
5120 5124 earlier changeset.
5121 5125
5122 5126 Returns 0 on success.
5123 5127 """
5124 5128
5125 5129 opts = pycompat.byteskwargs(opts)
5126 5130 if opts.get("date"):
5127 5131 if opts.get("rev"):
5128 5132 raise error.Abort(_("you can't specify a revision and a date"))
5129 5133 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5130 5134
5131 5135 parent, p2 = repo.dirstate.parents()
5132 5136 if not opts.get('rev') and p2 != nullid:
5133 5137 # revert after merge is a trap for new users (issue2915)
5134 5138 raise error.Abort(_('uncommitted merge with no revision specified'),
5135 5139 hint=_("use 'hg update' or see 'hg help revert'"))
5136 5140
5137 5141 rev = opts.get('rev')
5138 5142 if rev:
5139 5143 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
5140 5144 ctx = scmutil.revsingle(repo, rev)
5141 5145
5142 5146 if (not (pats or opts.get('include') or opts.get('exclude') or
5143 5147 opts.get('all') or opts.get('interactive'))):
5144 5148 msg = _("no files or directories specified")
5145 5149 if p2 != nullid:
5146 5150 hint = _("uncommitted merge, use --all to discard all changes,"
5147 5151 " or 'hg update -C .' to abort the merge")
5148 5152 raise error.Abort(msg, hint=hint)
5149 5153 dirty = any(repo.status())
5150 5154 node = ctx.node()
5151 5155 if node != parent:
5152 5156 if dirty:
5153 5157 hint = _("uncommitted changes, use --all to discard all"
5154 5158 " changes, or 'hg update %d' to update") % ctx.rev()
5155 5159 else:
5156 5160 hint = _("use --all to revert all files,"
5157 5161 " or 'hg update %d' to update") % ctx.rev()
5158 5162 elif dirty:
5159 5163 hint = _("uncommitted changes, use --all to discard all changes")
5160 5164 else:
5161 5165 hint = _("use --all to revert all files")
5162 5166 raise error.Abort(msg, hint=hint)
5163 5167
5164 5168 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats,
5165 5169 **pycompat.strkwargs(opts))
5166 5170
5167 5171 @command(
5168 5172 'rollback',
5169 5173 dryrunopts + [('f', 'force', False, _('ignore safety measures'))],
5170 5174 helpcategory=command.CATEGORY_MAINTENANCE)
5171 5175 def rollback(ui, repo, **opts):
5172 5176 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5173 5177
5174 5178 Please use :hg:`commit --amend` instead of rollback to correct
5175 5179 mistakes in the last commit.
5176 5180
5177 5181 This command should be used with care. There is only one level of
5178 5182 rollback, and there is no way to undo a rollback. It will also
5179 5183 restore the dirstate at the time of the last transaction, losing
5180 5184 any dirstate changes since that time. This command does not alter
5181 5185 the working directory.
5182 5186
5183 5187 Transactions are used to encapsulate the effects of all commands
5184 5188 that create new changesets or propagate existing changesets into a
5185 5189 repository.
5186 5190
5187 5191 .. container:: verbose
5188 5192
5189 5193 For example, the following commands are transactional, and their
5190 5194 effects can be rolled back:
5191 5195
5192 5196 - commit
5193 5197 - import
5194 5198 - pull
5195 5199 - push (with this repository as the destination)
5196 5200 - unbundle
5197 5201
5198 5202 To avoid permanent data loss, rollback will refuse to rollback a
5199 5203 commit transaction if it isn't checked out. Use --force to
5200 5204 override this protection.
5201 5205
5202 5206 The rollback command can be entirely disabled by setting the
5203 5207 ``ui.rollback`` configuration setting to false. If you're here
5204 5208 because you want to use rollback and it's disabled, you can
5205 5209 re-enable the command by setting ``ui.rollback`` to true.
5206 5210
5207 5211 This command is not intended for use on public repositories. Once
5208 5212 changes are visible for pull by other users, rolling a transaction
5209 5213 back locally is ineffective (someone else may already have pulled
5210 5214 the changes). Furthermore, a race is possible with readers of the
5211 5215 repository; for example an in-progress pull from the repository
5212 5216 may fail if a rollback is performed.
5213 5217
5214 5218 Returns 0 on success, 1 if no rollback data is available.
5215 5219 """
5216 5220 if not ui.configbool('ui', 'rollback'):
5217 5221 raise error.Abort(_('rollback is disabled because it is unsafe'),
5218 5222 hint=('see `hg help -v rollback` for information'))
5219 5223 return repo.rollback(dryrun=opts.get(r'dry_run'),
5220 5224 force=opts.get(r'force'))
5221 5225
5222 5226 @command(
5223 5227 'root', [], intents={INTENT_READONLY},
5224 5228 helpcategory=command.CATEGORY_WORKING_DIRECTORY)
5225 5229 def root(ui, repo):
5226 5230 """print the root (top) of the current working directory
5227 5231
5228 5232 Print the root directory of the current repository.
5229 5233
5230 5234 Returns 0 on success.
5231 5235 """
5232 5236 ui.write(repo.root + "\n")
5233 5237
5234 5238 @command('serve',
5235 5239 [('A', 'accesslog', '', _('name of access log file to write to'),
5236 5240 _('FILE')),
5237 5241 ('d', 'daemon', None, _('run server in background')),
5238 5242 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
5239 5243 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5240 5244 # use string type, then we can check if something was passed
5241 5245 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5242 5246 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5243 5247 _('ADDR')),
5244 5248 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5245 5249 _('PREFIX')),
5246 5250 ('n', 'name', '',
5247 5251 _('name to show in web pages (default: working directory)'), _('NAME')),
5248 5252 ('', 'web-conf', '',
5249 5253 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
5250 5254 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5251 5255 _('FILE')),
5252 5256 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5253 5257 ('', 'stdio', None, _('for remote clients (ADVANCED)')),
5254 5258 ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')),
5255 5259 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5256 5260 ('', 'style', '', _('template style to use'), _('STYLE')),
5257 5261 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5258 5262 ('', 'certificate', '', _('SSL certificate file'), _('FILE')),
5259 5263 ('', 'print-url', None, _('start and print only the URL'))]
5260 5264 + subrepoopts,
5261 5265 _('[OPTION]...'),
5262 5266 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5263 5267 helpbasic=True, optionalrepo=True)
5264 5268 def serve(ui, repo, **opts):
5265 5269 """start stand-alone webserver
5266 5270
5267 5271 Start a local HTTP repository browser and pull server. You can use
5268 5272 this for ad-hoc sharing and browsing of repositories. It is
5269 5273 recommended to use a real web server to serve a repository for
5270 5274 longer periods of time.
5271 5275
5272 5276 Please note that the server does not implement access control.
5273 5277 This means that, by default, anybody can read from the server and
5274 5278 nobody can write to it by default. Set the ``web.allow-push``
5275 5279 option to ``*`` to allow everybody to push to the server. You
5276 5280 should use a real web server if you need to authenticate users.
5277 5281
5278 5282 By default, the server logs accesses to stdout and errors to
5279 5283 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5280 5284 files.
5281 5285
5282 5286 To have the server choose a free port number to listen on, specify
5283 5287 a port number of 0; in this case, the server will print the port
5284 5288 number it uses.
5285 5289
5286 5290 Returns 0 on success.
5287 5291 """
5288 5292
5289 5293 opts = pycompat.byteskwargs(opts)
5290 5294 if opts["stdio"] and opts["cmdserver"]:
5291 5295 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5292 5296 if opts["print_url"] and ui.verbose:
5293 5297 raise error.Abort(_("cannot use --print-url with --verbose"))
5294 5298
5295 5299 if opts["stdio"]:
5296 5300 if repo is None:
5297 5301 raise error.RepoError(_("there is no Mercurial repository here"
5298 5302 " (.hg not found)"))
5299 5303 s = wireprotoserver.sshserver(ui, repo)
5300 5304 s.serve_forever()
5301 5305
5302 5306 service = server.createservice(ui, repo, opts)
5303 5307 return server.runservice(opts, initfn=service.init, runfn=service.run)
5304 5308
5305 5309 _NOTTERSE = 'nothing'
5306 5310
5307 5311 @command('status|st',
5308 5312 [('A', 'all', None, _('show status of all files')),
5309 5313 ('m', 'modified', None, _('show only modified files')),
5310 5314 ('a', 'added', None, _('show only added files')),
5311 5315 ('r', 'removed', None, _('show only removed files')),
5312 5316 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5313 5317 ('c', 'clean', None, _('show only files without changes')),
5314 5318 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5315 5319 ('i', 'ignored', None, _('show only ignored files')),
5316 5320 ('n', 'no-status', None, _('hide status prefix')),
5317 5321 ('t', 'terse', _NOTTERSE, _('show the terse output (EXPERIMENTAL)')),
5318 5322 ('C', 'copies', None, _('show source of copied files')),
5319 5323 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5320 5324 ('', 'rev', [], _('show difference from revision'), _('REV')),
5321 5325 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5322 5326 ] + walkopts + subrepoopts + formatteropts,
5323 5327 _('[OPTION]... [FILE]...'),
5324 5328 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5325 5329 helpbasic=True, inferrepo=True,
5326 5330 intents={INTENT_READONLY})
5327 5331 def status(ui, repo, *pats, **opts):
5328 5332 """show changed files in the working directory
5329 5333
5330 5334 Show status of files in the repository. If names are given, only
5331 5335 files that match are shown. Files that are clean or ignored or
5332 5336 the source of a copy/move operation, are not listed unless
5333 5337 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5334 5338 Unless options described with "show only ..." are given, the
5335 5339 options -mardu are used.
5336 5340
5337 5341 Option -q/--quiet hides untracked (unknown and ignored) files
5338 5342 unless explicitly requested with -u/--unknown or -i/--ignored.
5339 5343
5340 5344 .. note::
5341 5345
5342 5346 :hg:`status` may appear to disagree with diff if permissions have
5343 5347 changed or a merge has occurred. The standard diff format does
5344 5348 not report permission changes and diff only reports changes
5345 5349 relative to one merge parent.
5346 5350
5347 5351 If one revision is given, it is used as the base revision.
5348 5352 If two revisions are given, the differences between them are
5349 5353 shown. The --change option can also be used as a shortcut to list
5350 5354 the changed files of a revision from its first parent.
5351 5355
5352 5356 The codes used to show the status of files are::
5353 5357
5354 5358 M = modified
5355 5359 A = added
5356 5360 R = removed
5357 5361 C = clean
5358 5362 ! = missing (deleted by non-hg command, but still tracked)
5359 5363 ? = not tracked
5360 5364 I = ignored
5361 5365 = origin of the previous file (with --copies)
5362 5366
5363 5367 .. container:: verbose
5364 5368
5365 5369 The -t/--terse option abbreviates the output by showing only the directory
5366 5370 name if all the files in it share the same status. The option takes an
5367 5371 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
5368 5372 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
5369 5373 for 'ignored' and 'c' for clean.
5370 5374
5371 5375 It abbreviates only those statuses which are passed. Note that clean and
5372 5376 ignored files are not displayed with '--terse ic' unless the -c/--clean
5373 5377 and -i/--ignored options are also used.
5374 5378
5375 5379 The -v/--verbose option shows information when the repository is in an
5376 5380 unfinished merge, shelve, rebase state etc. You can have this behavior
5377 5381 turned on by default by enabling the ``commands.status.verbose`` option.
5378 5382
5379 5383 You can skip displaying some of these states by setting
5380 5384 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
5381 5385 'histedit', 'merge', 'rebase', or 'unshelve'.
5382 5386
5383 5387 Template:
5384 5388
5385 5389 The following keywords are supported in addition to the common template
5386 5390 keywords and functions. See also :hg:`help templates`.
5387 5391
5388 5392 :path: String. Repository-absolute path of the file.
5389 5393 :source: String. Repository-absolute path of the file originated from.
5390 5394 Available if ``--copies`` is specified.
5391 5395 :status: String. Character denoting file's status.
5392 5396
5393 5397 Examples:
5394 5398
5395 5399 - show changes in the working directory relative to a
5396 5400 changeset::
5397 5401
5398 5402 hg status --rev 9353
5399 5403
5400 5404 - show changes in the working directory relative to the
5401 5405 current directory (see :hg:`help patterns` for more information)::
5402 5406
5403 5407 hg status re:
5404 5408
5405 5409 - show all changes including copies in an existing changeset::
5406 5410
5407 5411 hg status --copies --change 9353
5408 5412
5409 5413 - get a NUL separated list of added files, suitable for xargs::
5410 5414
5411 5415 hg status -an0
5412 5416
5413 5417 - show more information about the repository status, abbreviating
5414 5418 added, removed, modified, deleted, and untracked paths::
5415 5419
5416 5420 hg status -v -t mardu
5417 5421
5418 5422 Returns 0 on success.
5419 5423
5420 5424 """
5421 5425
5422 5426 opts = pycompat.byteskwargs(opts)
5423 5427 revs = opts.get('rev')
5424 5428 change = opts.get('change')
5425 5429 terse = opts.get('terse')
5426 5430 if terse is _NOTTERSE:
5427 5431 if revs:
5428 5432 terse = ''
5429 5433 else:
5430 5434 terse = ui.config('commands', 'status.terse')
5431 5435
5432 5436 if revs and change:
5433 5437 msg = _('cannot specify --rev and --change at the same time')
5434 5438 raise error.Abort(msg)
5435 5439 elif revs and terse:
5436 5440 msg = _('cannot use --terse with --rev')
5437 5441 raise error.Abort(msg)
5438 5442 elif change:
5439 5443 repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
5440 5444 ctx2 = scmutil.revsingle(repo, change, None)
5441 5445 ctx1 = ctx2.p1()
5442 5446 else:
5443 5447 repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
5444 5448 ctx1, ctx2 = scmutil.revpair(repo, revs)
5445 5449
5446 5450 forcerelativevalue = None
5447 5451 if ui.hasconfig('commands', 'status.relative'):
5448 5452 forcerelativevalue = ui.configbool('commands', 'status.relative')
5449 5453 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats),
5450 5454 forcerelativevalue=forcerelativevalue)
5451 5455
5452 5456 if opts.get('print0'):
5453 5457 end = '\0'
5454 5458 else:
5455 5459 end = '\n'
5456 5460 copy = {}
5457 5461 states = 'modified added removed deleted unknown ignored clean'.split()
5458 5462 show = [k for k in states if opts.get(k)]
5459 5463 if opts.get('all'):
5460 5464 show += ui.quiet and (states[:4] + ['clean']) or states
5461 5465
5462 5466 if not show:
5463 5467 if ui.quiet:
5464 5468 show = states[:4]
5465 5469 else:
5466 5470 show = states[:5]
5467 5471
5468 5472 m = scmutil.match(ctx2, pats, opts)
5469 5473 if terse:
5470 5474 # we need to compute clean and unknown to terse
5471 5475 stat = repo.status(ctx1.node(), ctx2.node(), m,
5472 5476 'ignored' in show or 'i' in terse,
5473 5477 clean=True, unknown=True,
5474 5478 listsubrepos=opts.get('subrepos'))
5475 5479
5476 5480 stat = cmdutil.tersedir(stat, terse)
5477 5481 else:
5478 5482 stat = repo.status(ctx1.node(), ctx2.node(), m,
5479 5483 'ignored' in show, 'clean' in show,
5480 5484 'unknown' in show, opts.get('subrepos'))
5481 5485
5482 5486 changestates = zip(states, pycompat.iterbytestr('MAR!?IC'), stat)
5483 5487
5484 5488 if (opts.get('all') or opts.get('copies')
5485 5489 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5486 5490 copy = copies.pathcopies(ctx1, ctx2, m)
5487 5491
5488 5492 ui.pager('status')
5489 5493 fm = ui.formatter('status', opts)
5490 5494 fmt = '%s' + end
5491 5495 showchar = not opts.get('no_status')
5492 5496
5493 5497 for state, char, files in changestates:
5494 5498 if state in show:
5495 5499 label = 'status.' + state
5496 5500 for f in files:
5497 5501 fm.startitem()
5498 5502 fm.context(ctx=ctx2)
5499 5503 fm.data(path=f)
5500 5504 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5501 5505 fm.plain(fmt % uipathfn(f), label=label)
5502 5506 if f in copy:
5503 5507 fm.data(source=copy[f])
5504 5508 fm.plain((' %s' + end) % uipathfn(copy[f]),
5505 5509 label='status.copied')
5506 5510
5507 5511 if ((ui.verbose or ui.configbool('commands', 'status.verbose'))
5508 5512 and not ui.plain()):
5509 5513 cmdutil.morestatus(repo, fm)
5510 5514 fm.end()
5511 5515
5512 5516 @command('summary|sum',
5513 5517 [('', 'remote', None, _('check for push and pull'))],
5514 5518 '[--remote]',
5515 5519 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5516 5520 helpbasic=True,
5517 5521 intents={INTENT_READONLY})
5518 5522 def summary(ui, repo, **opts):
5519 5523 """summarize working directory state
5520 5524
5521 5525 This generates a brief summary of the working directory state,
5522 5526 including parents, branch, commit status, phase and available updates.
5523 5527
5524 5528 With the --remote option, this will check the default paths for
5525 5529 incoming and outgoing changes. This can be time-consuming.
5526 5530
5527 5531 Returns 0 on success.
5528 5532 """
5529 5533
5530 5534 opts = pycompat.byteskwargs(opts)
5531 5535 ui.pager('summary')
5532 5536 ctx = repo[None]
5533 5537 parents = ctx.parents()
5534 5538 pnode = parents[0].node()
5535 5539 marks = []
5536 5540
5537 5541 try:
5538 5542 ms = mergemod.mergestate.read(repo)
5539 5543 except error.UnsupportedMergeRecords as e:
5540 5544 s = ' '.join(e.recordtypes)
5541 5545 ui.warn(
5542 5546 _('warning: merge state has unsupported record types: %s\n') % s)
5543 5547 unresolved = []
5544 5548 else:
5545 5549 unresolved = list(ms.unresolved())
5546 5550
5547 5551 for p in parents:
5548 5552 # label with log.changeset (instead of log.parent) since this
5549 5553 # shows a working directory parent *changeset*:
5550 5554 # i18n: column positioning for "hg summary"
5551 5555 ui.write(_('parent: %d:%s ') % (p.rev(), p),
5552 5556 label=logcmdutil.changesetlabels(p))
5553 5557 ui.write(' '.join(p.tags()), label='log.tag')
5554 5558 if p.bookmarks():
5555 5559 marks.extend(p.bookmarks())
5556 5560 if p.rev() == -1:
5557 5561 if not len(repo):
5558 5562 ui.write(_(' (empty repository)'))
5559 5563 else:
5560 5564 ui.write(_(' (no revision checked out)'))
5561 5565 if p.obsolete():
5562 5566 ui.write(_(' (obsolete)'))
5563 5567 if p.isunstable():
5564 5568 instabilities = (ui.label(instability, 'trouble.%s' % instability)
5565 5569 for instability in p.instabilities())
5566 5570 ui.write(' ('
5567 5571 + ', '.join(instabilities)
5568 5572 + ')')
5569 5573 ui.write('\n')
5570 5574 if p.description():
5571 5575 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5572 5576 label='log.summary')
5573 5577
5574 5578 branch = ctx.branch()
5575 5579 bheads = repo.branchheads(branch)
5576 5580 # i18n: column positioning for "hg summary"
5577 5581 m = _('branch: %s\n') % branch
5578 5582 if branch != 'default':
5579 5583 ui.write(m, label='log.branch')
5580 5584 else:
5581 5585 ui.status(m, label='log.branch')
5582 5586
5583 5587 if marks:
5584 5588 active = repo._activebookmark
5585 5589 # i18n: column positioning for "hg summary"
5586 5590 ui.write(_('bookmarks:'), label='log.bookmark')
5587 5591 if active is not None:
5588 5592 if active in marks:
5589 5593 ui.write(' *' + active, label=bookmarks.activebookmarklabel)
5590 5594 marks.remove(active)
5591 5595 else:
5592 5596 ui.write(' [%s]' % active, label=bookmarks.activebookmarklabel)
5593 5597 for m in marks:
5594 5598 ui.write(' ' + m, label='log.bookmark')
5595 5599 ui.write('\n', label='log.bookmark')
5596 5600
5597 5601 status = repo.status(unknown=True)
5598 5602
5599 5603 c = repo.dirstate.copies()
5600 5604 copied, renamed = [], []
5601 5605 for d, s in c.iteritems():
5602 5606 if s in status.removed:
5603 5607 status.removed.remove(s)
5604 5608 renamed.append(d)
5605 5609 else:
5606 5610 copied.append(d)
5607 5611 if d in status.added:
5608 5612 status.added.remove(d)
5609 5613
5610 5614 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5611 5615
5612 5616 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
5613 5617 (ui.label(_('%d added'), 'status.added'), status.added),
5614 5618 (ui.label(_('%d removed'), 'status.removed'), status.removed),
5615 5619 (ui.label(_('%d renamed'), 'status.copied'), renamed),
5616 5620 (ui.label(_('%d copied'), 'status.copied'), copied),
5617 5621 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
5618 5622 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
5619 5623 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
5620 5624 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
5621 5625 t = []
5622 5626 for l, s in labels:
5623 5627 if s:
5624 5628 t.append(l % len(s))
5625 5629
5626 5630 t = ', '.join(t)
5627 5631 cleanworkdir = False
5628 5632
5629 5633 if repo.vfs.exists('graftstate'):
5630 5634 t += _(' (graft in progress)')
5631 5635 if repo.vfs.exists('updatestate'):
5632 5636 t += _(' (interrupted update)')
5633 5637 elif len(parents) > 1:
5634 5638 t += _(' (merge)')
5635 5639 elif branch != parents[0].branch():
5636 5640 t += _(' (new branch)')
5637 5641 elif (parents[0].closesbranch() and
5638 5642 pnode in repo.branchheads(branch, closed=True)):
5639 5643 t += _(' (head closed)')
5640 5644 elif not (status.modified or status.added or status.removed or renamed or
5641 5645 copied or subs):
5642 5646 t += _(' (clean)')
5643 5647 cleanworkdir = True
5644 5648 elif pnode not in bheads:
5645 5649 t += _(' (new branch head)')
5646 5650
5647 5651 if parents:
5648 5652 pendingphase = max(p.phase() for p in parents)
5649 5653 else:
5650 5654 pendingphase = phases.public
5651 5655
5652 5656 if pendingphase > phases.newcommitphase(ui):
5653 5657 t += ' (%s)' % phases.phasenames[pendingphase]
5654 5658
5655 5659 if cleanworkdir:
5656 5660 # i18n: column positioning for "hg summary"
5657 5661 ui.status(_('commit: %s\n') % t.strip())
5658 5662 else:
5659 5663 # i18n: column positioning for "hg summary"
5660 5664 ui.write(_('commit: %s\n') % t.strip())
5661 5665
5662 5666 # all ancestors of branch heads - all ancestors of parent = new csets
5663 5667 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
5664 5668 bheads))
5665 5669
5666 5670 if new == 0:
5667 5671 # i18n: column positioning for "hg summary"
5668 5672 ui.status(_('update: (current)\n'))
5669 5673 elif pnode not in bheads:
5670 5674 # i18n: column positioning for "hg summary"
5671 5675 ui.write(_('update: %d new changesets (update)\n') % new)
5672 5676 else:
5673 5677 # i18n: column positioning for "hg summary"
5674 5678 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5675 5679 (new, len(bheads)))
5676 5680
5677 5681 t = []
5678 5682 draft = len(repo.revs('draft()'))
5679 5683 if draft:
5680 5684 t.append(_('%d draft') % draft)
5681 5685 secret = len(repo.revs('secret()'))
5682 5686 if secret:
5683 5687 t.append(_('%d secret') % secret)
5684 5688
5685 5689 if draft or secret:
5686 5690 ui.status(_('phases: %s\n') % ', '.join(t))
5687 5691
5688 5692 if obsolete.isenabled(repo, obsolete.createmarkersopt):
5689 5693 for trouble in ("orphan", "contentdivergent", "phasedivergent"):
5690 5694 numtrouble = len(repo.revs(trouble + "()"))
5691 5695 # We write all the possibilities to ease translation
5692 5696 troublemsg = {
5693 5697 "orphan": _("orphan: %d changesets"),
5694 5698 "contentdivergent": _("content-divergent: %d changesets"),
5695 5699 "phasedivergent": _("phase-divergent: %d changesets"),
5696 5700 }
5697 5701 if numtrouble > 0:
5698 5702 ui.status(troublemsg[trouble] % numtrouble + "\n")
5699 5703
5700 5704 cmdutil.summaryhooks(ui, repo)
5701 5705
5702 5706 if opts.get('remote'):
5703 5707 needsincoming, needsoutgoing = True, True
5704 5708 else:
5705 5709 needsincoming, needsoutgoing = False, False
5706 5710 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5707 5711 if i:
5708 5712 needsincoming = True
5709 5713 if o:
5710 5714 needsoutgoing = True
5711 5715 if not needsincoming and not needsoutgoing:
5712 5716 return
5713 5717
5714 5718 def getincoming():
5715 5719 source, branches = hg.parseurl(ui.expandpath('default'))
5716 5720 sbranch = branches[0]
5717 5721 try:
5718 5722 other = hg.peer(repo, {}, source)
5719 5723 except error.RepoError:
5720 5724 if opts.get('remote'):
5721 5725 raise
5722 5726 return source, sbranch, None, None, None
5723 5727 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5724 5728 if revs:
5725 5729 revs = [other.lookup(rev) for rev in revs]
5726 5730 ui.debug('comparing with %s\n' % util.hidepassword(source))
5727 5731 repo.ui.pushbuffer()
5728 5732 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5729 5733 repo.ui.popbuffer()
5730 5734 return source, sbranch, other, commoninc, commoninc[1]
5731 5735
5732 5736 if needsincoming:
5733 5737 source, sbranch, sother, commoninc, incoming = getincoming()
5734 5738 else:
5735 5739 source = sbranch = sother = commoninc = incoming = None
5736 5740
5737 5741 def getoutgoing():
5738 5742 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5739 5743 dbranch = branches[0]
5740 5744 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5741 5745 if source != dest:
5742 5746 try:
5743 5747 dother = hg.peer(repo, {}, dest)
5744 5748 except error.RepoError:
5745 5749 if opts.get('remote'):
5746 5750 raise
5747 5751 return dest, dbranch, None, None
5748 5752 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5749 5753 elif sother is None:
5750 5754 # there is no explicit destination peer, but source one is invalid
5751 5755 return dest, dbranch, None, None
5752 5756 else:
5753 5757 dother = sother
5754 5758 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5755 5759 common = None
5756 5760 else:
5757 5761 common = commoninc
5758 5762 if revs:
5759 5763 revs = [repo.lookup(rev) for rev in revs]
5760 5764 repo.ui.pushbuffer()
5761 5765 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5762 5766 commoninc=common)
5763 5767 repo.ui.popbuffer()
5764 5768 return dest, dbranch, dother, outgoing
5765 5769
5766 5770 if needsoutgoing:
5767 5771 dest, dbranch, dother, outgoing = getoutgoing()
5768 5772 else:
5769 5773 dest = dbranch = dother = outgoing = None
5770 5774
5771 5775 if opts.get('remote'):
5772 5776 t = []
5773 5777 if incoming:
5774 5778 t.append(_('1 or more incoming'))
5775 5779 o = outgoing.missing
5776 5780 if o:
5777 5781 t.append(_('%d outgoing') % len(o))
5778 5782 other = dother or sother
5779 5783 if 'bookmarks' in other.listkeys('namespaces'):
5780 5784 counts = bookmarks.summary(repo, other)
5781 5785 if counts[0] > 0:
5782 5786 t.append(_('%d incoming bookmarks') % counts[0])
5783 5787 if counts[1] > 0:
5784 5788 t.append(_('%d outgoing bookmarks') % counts[1])
5785 5789
5786 5790 if t:
5787 5791 # i18n: column positioning for "hg summary"
5788 5792 ui.write(_('remote: %s\n') % (', '.join(t)))
5789 5793 else:
5790 5794 # i18n: column positioning for "hg summary"
5791 5795 ui.status(_('remote: (synced)\n'))
5792 5796
5793 5797 cmdutil.summaryremotehooks(ui, repo, opts,
5794 5798 ((source, sbranch, sother, commoninc),
5795 5799 (dest, dbranch, dother, outgoing)))
5796 5800
5797 5801 @command('tag',
5798 5802 [('f', 'force', None, _('force tag')),
5799 5803 ('l', 'local', None, _('make the tag local')),
5800 5804 ('r', 'rev', '', _('revision to tag'), _('REV')),
5801 5805 ('', 'remove', None, _('remove a tag')),
5802 5806 # -l/--local is already there, commitopts cannot be used
5803 5807 ('e', 'edit', None, _('invoke editor on commit messages')),
5804 5808 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
5805 5809 ] + commitopts2,
5806 5810 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
5807 5811 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION)
5808 5812 def tag(ui, repo, name1, *names, **opts):
5809 5813 """add one or more tags for the current or given revision
5810 5814
5811 5815 Name a particular revision using <name>.
5812 5816
5813 5817 Tags are used to name particular revisions of the repository and are
5814 5818 very useful to compare different revisions, to go back to significant
5815 5819 earlier versions or to mark branch points as releases, etc. Changing
5816 5820 an existing tag is normally disallowed; use -f/--force to override.
5817 5821
5818 5822 If no revision is given, the parent of the working directory is
5819 5823 used.
5820 5824
5821 5825 To facilitate version control, distribution, and merging of tags,
5822 5826 they are stored as a file named ".hgtags" which is managed similarly
5823 5827 to other project files and can be hand-edited if necessary. This
5824 5828 also means that tagging creates a new commit. The file
5825 5829 ".hg/localtags" is used for local tags (not shared among
5826 5830 repositories).
5827 5831
5828 5832 Tag commits are usually made at the head of a branch. If the parent
5829 5833 of the working directory is not a branch head, :hg:`tag` aborts; use
5830 5834 -f/--force to force the tag commit to be based on a non-head
5831 5835 changeset.
5832 5836
5833 5837 See :hg:`help dates` for a list of formats valid for -d/--date.
5834 5838
5835 5839 Since tag names have priority over branch names during revision
5836 5840 lookup, using an existing branch name as a tag name is discouraged.
5837 5841
5838 5842 Returns 0 on success.
5839 5843 """
5840 5844 opts = pycompat.byteskwargs(opts)
5841 5845 with repo.wlock(), repo.lock():
5842 5846 rev_ = "."
5843 5847 names = [t.strip() for t in (name1,) + names]
5844 5848 if len(names) != len(set(names)):
5845 5849 raise error.Abort(_('tag names must be unique'))
5846 5850 for n in names:
5847 5851 scmutil.checknewlabel(repo, n, 'tag')
5848 5852 if not n:
5849 5853 raise error.Abort(_('tag names cannot consist entirely of '
5850 5854 'whitespace'))
5851 5855 if opts.get('rev') and opts.get('remove'):
5852 5856 raise error.Abort(_("--rev and --remove are incompatible"))
5853 5857 if opts.get('rev'):
5854 5858 rev_ = opts['rev']
5855 5859 message = opts.get('message')
5856 5860 if opts.get('remove'):
5857 5861 if opts.get('local'):
5858 5862 expectedtype = 'local'
5859 5863 else:
5860 5864 expectedtype = 'global'
5861 5865
5862 5866 for n in names:
5863 5867 if repo.tagtype(n) == 'global':
5864 5868 alltags = tagsmod.findglobaltags(ui, repo)
5865 5869 if alltags[n][0] == nullid:
5866 5870 raise error.Abort(_("tag '%s' is already removed") % n)
5867 5871 if not repo.tagtype(n):
5868 5872 raise error.Abort(_("tag '%s' does not exist") % n)
5869 5873 if repo.tagtype(n) != expectedtype:
5870 5874 if expectedtype == 'global':
5871 5875 raise error.Abort(_("tag '%s' is not a global tag") % n)
5872 5876 else:
5873 5877 raise error.Abort(_("tag '%s' is not a local tag") % n)
5874 5878 rev_ = 'null'
5875 5879 if not message:
5876 5880 # we don't translate commit messages
5877 5881 message = 'Removed tag %s' % ', '.join(names)
5878 5882 elif not opts.get('force'):
5879 5883 for n in names:
5880 5884 if n in repo.tags():
5881 5885 raise error.Abort(_("tag '%s' already exists "
5882 5886 "(use -f to force)") % n)
5883 5887 if not opts.get('local'):
5884 5888 p1, p2 = repo.dirstate.parents()
5885 5889 if p2 != nullid:
5886 5890 raise error.Abort(_('uncommitted merge'))
5887 5891 bheads = repo.branchheads()
5888 5892 if not opts.get('force') and bheads and p1 not in bheads:
5889 5893 raise error.Abort(_('working directory is not at a branch head '
5890 5894 '(use -f to force)'))
5891 5895 node = scmutil.revsingle(repo, rev_).node()
5892 5896
5893 5897 if not message:
5894 5898 # we don't translate commit messages
5895 5899 message = ('Added tag %s for changeset %s' %
5896 5900 (', '.join(names), short(node)))
5897 5901
5898 5902 date = opts.get('date')
5899 5903 if date:
5900 5904 date = dateutil.parsedate(date)
5901 5905
5902 5906 if opts.get('remove'):
5903 5907 editform = 'tag.remove'
5904 5908 else:
5905 5909 editform = 'tag.add'
5906 5910 editor = cmdutil.getcommiteditor(editform=editform,
5907 5911 **pycompat.strkwargs(opts))
5908 5912
5909 5913 # don't allow tagging the null rev
5910 5914 if (not opts.get('remove') and
5911 5915 scmutil.revsingle(repo, rev_).rev() == nullrev):
5912 5916 raise error.Abort(_("cannot tag null revision"))
5913 5917
5914 5918 tagsmod.tag(repo, names, node, message, opts.get('local'),
5915 5919 opts.get('user'), date, editor=editor)
5916 5920
5917 5921 @command(
5918 5922 'tags', formatteropts, '',
5919 5923 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5920 5924 intents={INTENT_READONLY})
5921 5925 def tags(ui, repo, **opts):
5922 5926 """list repository tags
5923 5927
5924 5928 This lists both regular and local tags. When the -v/--verbose
5925 5929 switch is used, a third column "local" is printed for local tags.
5926 5930 When the -q/--quiet switch is used, only the tag name is printed.
5927 5931
5928 5932 .. container:: verbose
5929 5933
5930 5934 Template:
5931 5935
5932 5936 The following keywords are supported in addition to the common template
5933 5937 keywords and functions such as ``{tag}``. See also
5934 5938 :hg:`help templates`.
5935 5939
5936 5940 :type: String. ``local`` for local tags.
5937 5941
5938 5942 Returns 0 on success.
5939 5943 """
5940 5944
5941 5945 opts = pycompat.byteskwargs(opts)
5942 5946 ui.pager('tags')
5943 5947 fm = ui.formatter('tags', opts)
5944 5948 hexfunc = fm.hexfunc
5945 5949
5946 5950 for t, n in reversed(repo.tagslist()):
5947 5951 hn = hexfunc(n)
5948 5952 label = 'tags.normal'
5949 5953 tagtype = ''
5950 5954 if repo.tagtype(t) == 'local':
5951 5955 label = 'tags.local'
5952 5956 tagtype = 'local'
5953 5957
5954 5958 fm.startitem()
5955 5959 fm.context(repo=repo)
5956 5960 fm.write('tag', '%s', t, label=label)
5957 5961 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5958 5962 fm.condwrite(not ui.quiet, 'rev node', fmt,
5959 5963 repo.changelog.rev(n), hn, label=label)
5960 5964 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5961 5965 tagtype, label=label)
5962 5966 fm.plain('\n')
5963 5967 fm.end()
5964 5968
5965 5969 @command('tip',
5966 5970 [('p', 'patch', None, _('show patch')),
5967 5971 ('g', 'git', None, _('use git extended diff format')),
5968 5972 ] + templateopts,
5969 5973 _('[-p] [-g]'),
5970 5974 helpcategory=command.CATEGORY_CHANGE_NAVIGATION)
5971 5975 def tip(ui, repo, **opts):
5972 5976 """show the tip revision (DEPRECATED)
5973 5977
5974 5978 The tip revision (usually just called the tip) is the changeset
5975 5979 most recently added to the repository (and therefore the most
5976 5980 recently changed head).
5977 5981
5978 5982 If you have just made a commit, that commit will be the tip. If
5979 5983 you have just pulled changes from another repository, the tip of
5980 5984 that repository becomes the current tip. The "tip" tag is special
5981 5985 and cannot be renamed or assigned to a different changeset.
5982 5986
5983 5987 This command is deprecated, please use :hg:`heads` instead.
5984 5988
5985 5989 Returns 0 on success.
5986 5990 """
5987 5991 opts = pycompat.byteskwargs(opts)
5988 5992 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5989 5993 displayer.show(repo['tip'])
5990 5994 displayer.close()
5991 5995
5992 5996 @command('unbundle',
5993 5997 [('u', 'update', None,
5994 5998 _('update to new branch head if changesets were unbundled'))],
5995 5999 _('[-u] FILE...'),
5996 6000 helpcategory=command.CATEGORY_IMPORT_EXPORT)
5997 6001 def unbundle(ui, repo, fname1, *fnames, **opts):
5998 6002 """apply one or more bundle files
5999 6003
6000 6004 Apply one or more bundle files generated by :hg:`bundle`.
6001 6005
6002 6006 Returns 0 on success, 1 if an update has unresolved files.
6003 6007 """
6004 6008 fnames = (fname1,) + fnames
6005 6009
6006 6010 with repo.lock():
6007 6011 for fname in fnames:
6008 6012 f = hg.openpath(ui, fname)
6009 6013 gen = exchange.readbundle(ui, f, fname)
6010 6014 if isinstance(gen, streamclone.streamcloneapplier):
6011 6015 raise error.Abort(
6012 6016 _('packed bundles cannot be applied with '
6013 6017 '"hg unbundle"'),
6014 6018 hint=_('use "hg debugapplystreamclonebundle"'))
6015 6019 url = 'bundle:' + fname
6016 6020 try:
6017 6021 txnname = 'unbundle'
6018 6022 if not isinstance(gen, bundle2.unbundle20):
6019 6023 txnname = 'unbundle\n%s' % util.hidepassword(url)
6020 6024 with repo.transaction(txnname) as tr:
6021 6025 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6022 6026 url=url)
6023 6027 except error.BundleUnknownFeatureError as exc:
6024 6028 raise error.Abort(
6025 6029 _('%s: unknown bundle feature, %s') % (fname, exc),
6026 6030 hint=_("see https://mercurial-scm.org/"
6027 6031 "wiki/BundleFeature for more "
6028 6032 "information"))
6029 6033 modheads = bundle2.combinechangegroupresults(op)
6030 6034
6031 6035 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
6032 6036
6033 6037 @command('update|up|checkout|co',
6034 6038 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6035 6039 ('c', 'check', None, _('require clean working directory')),
6036 6040 ('m', 'merge', None, _('merge uncommitted changes')),
6037 6041 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6038 6042 ('r', 'rev', '', _('revision'), _('REV'))
6039 6043 ] + mergetoolopts,
6040 6044 _('[-C|-c|-m] [-d DATE] [[-r] REV]'),
6041 6045 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6042 6046 helpbasic=True)
6043 6047 def update(ui, repo, node=None, **opts):
6044 6048 """update working directory (or switch revisions)
6045 6049
6046 6050 Update the repository's working directory to the specified
6047 6051 changeset. If no changeset is specified, update to the tip of the
6048 6052 current named branch and move the active bookmark (see :hg:`help
6049 6053 bookmarks`).
6050 6054
6051 6055 Update sets the working directory's parent revision to the specified
6052 6056 changeset (see :hg:`help parents`).
6053 6057
6054 6058 If the changeset is not a descendant or ancestor of the working
6055 6059 directory's parent and there are uncommitted changes, the update is
6056 6060 aborted. With the -c/--check option, the working directory is checked
6057 6061 for uncommitted changes; if none are found, the working directory is
6058 6062 updated to the specified changeset.
6059 6063
6060 6064 .. container:: verbose
6061 6065
6062 6066 The -C/--clean, -c/--check, and -m/--merge options control what
6063 6067 happens if the working directory contains uncommitted changes.
6064 6068 At most of one of them can be specified.
6065 6069
6066 6070 1. If no option is specified, and if
6067 6071 the requested changeset is an ancestor or descendant of
6068 6072 the working directory's parent, the uncommitted changes
6069 6073 are merged into the requested changeset and the merged
6070 6074 result is left uncommitted. If the requested changeset is
6071 6075 not an ancestor or descendant (that is, it is on another
6072 6076 branch), the update is aborted and the uncommitted changes
6073 6077 are preserved.
6074 6078
6075 6079 2. With the -m/--merge option, the update is allowed even if the
6076 6080 requested changeset is not an ancestor or descendant of
6077 6081 the working directory's parent.
6078 6082
6079 6083 3. With the -c/--check option, the update is aborted and the
6080 6084 uncommitted changes are preserved.
6081 6085
6082 6086 4. With the -C/--clean option, uncommitted changes are discarded and
6083 6087 the working directory is updated to the requested changeset.
6084 6088
6085 6089 To cancel an uncommitted merge (and lose your changes), use
6086 6090 :hg:`merge --abort`.
6087 6091
6088 6092 Use null as the changeset to remove the working directory (like
6089 6093 :hg:`clone -U`).
6090 6094
6091 6095 If you want to revert just one file to an older revision, use
6092 6096 :hg:`revert [-r REV] NAME`.
6093 6097
6094 6098 See :hg:`help dates` for a list of formats valid for -d/--date.
6095 6099
6096 6100 Returns 0 on success, 1 if there are unresolved files.
6097 6101 """
6098 6102 rev = opts.get(r'rev')
6099 6103 date = opts.get(r'date')
6100 6104 clean = opts.get(r'clean')
6101 6105 check = opts.get(r'check')
6102 6106 merge = opts.get(r'merge')
6103 6107 if rev and node:
6104 6108 raise error.Abort(_("please specify just one revision"))
6105 6109
6106 6110 if ui.configbool('commands', 'update.requiredest'):
6107 6111 if not node and not rev and not date:
6108 6112 raise error.Abort(_('you must specify a destination'),
6109 6113 hint=_('for example: hg update ".::"'))
6110 6114
6111 6115 if rev is None or rev == '':
6112 6116 rev = node
6113 6117
6114 6118 if date and rev is not None:
6115 6119 raise error.Abort(_("you can't specify a revision and a date"))
6116 6120
6117 6121 if len([x for x in (clean, check, merge) if x]) > 1:
6118 6122 raise error.Abort(_("can only specify one of -C/--clean, -c/--check, "
6119 6123 "or -m/--merge"))
6120 6124
6121 6125 updatecheck = None
6122 6126 if check:
6123 6127 updatecheck = 'abort'
6124 6128 elif merge:
6125 6129 updatecheck = 'none'
6126 6130
6127 6131 with repo.wlock():
6128 6132 cmdutil.clearunfinished(repo)
6129 6133
6130 6134 if date:
6131 6135 rev = cmdutil.finddate(ui, repo, date)
6132 6136
6133 6137 # if we defined a bookmark, we have to remember the original name
6134 6138 brev = rev
6135 6139 if rev:
6136 6140 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
6137 6141 ctx = scmutil.revsingle(repo, rev, default=None)
6138 6142 rev = ctx.rev()
6139 6143 hidden = ctx.hidden()
6140 6144 overrides = {('ui', 'forcemerge'): opts.get(r'tool', '')}
6141 6145 with ui.configoverride(overrides, 'update'):
6142 6146 ret = hg.updatetotally(ui, repo, rev, brev, clean=clean,
6143 6147 updatecheck=updatecheck)
6144 6148 if hidden:
6145 6149 ctxstr = ctx.hex()[:12]
6146 6150 ui.warn(_("updated to hidden changeset %s\n") % ctxstr)
6147 6151
6148 6152 if ctx.obsolete():
6149 6153 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
6150 6154 ui.warn("(%s)\n" % obsfatemsg)
6151 6155 return ret
6152 6156
6153 6157 @command('verify',
6154 6158 [('', 'full', False, 'perform more checks (EXPERIMENTAL)')],
6155 6159 helpcategory=command.CATEGORY_MAINTENANCE)
6156 6160 def verify(ui, repo, **opts):
6157 6161 """verify the integrity of the repository
6158 6162
6159 6163 Verify the integrity of the current repository.
6160 6164
6161 6165 This will perform an extensive check of the repository's
6162 6166 integrity, validating the hashes and checksums of each entry in
6163 6167 the changelog, manifest, and tracked files, as well as the
6164 6168 integrity of their crosslinks and indices.
6165 6169
6166 6170 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6167 6171 for more information about recovery from corruption of the
6168 6172 repository.
6169 6173
6170 6174 Returns 0 on success, 1 if errors are encountered.
6171 6175 """
6172 6176 opts = pycompat.byteskwargs(opts)
6173 6177
6174 6178 level = None
6175 6179 if opts['full']:
6176 6180 level = verifymod.VERIFY_FULL
6177 6181 return hg.verify(repo, level)
6178 6182
6179 6183 @command(
6180 6184 'version', [] + formatteropts, helpcategory=command.CATEGORY_HELP,
6181 6185 norepo=True, intents={INTENT_READONLY})
6182 6186 def version_(ui, **opts):
6183 6187 """output version and copyright information
6184 6188
6185 6189 .. container:: verbose
6186 6190
6187 6191 Template:
6188 6192
6189 6193 The following keywords are supported. See also :hg:`help templates`.
6190 6194
6191 6195 :extensions: List of extensions.
6192 6196 :ver: String. Version number.
6193 6197
6194 6198 And each entry of ``{extensions}`` provides the following sub-keywords
6195 6199 in addition to ``{ver}``.
6196 6200
6197 6201 :bundled: Boolean. True if included in the release.
6198 6202 :name: String. Extension name.
6199 6203 """
6200 6204 opts = pycompat.byteskwargs(opts)
6201 6205 if ui.verbose:
6202 6206 ui.pager('version')
6203 6207 fm = ui.formatter("version", opts)
6204 6208 fm.startitem()
6205 6209 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
6206 6210 util.version())
6207 6211 license = _(
6208 6212 "(see https://mercurial-scm.org for more information)\n"
6209 6213 "\nCopyright (C) 2005-2019 Matt Mackall and others\n"
6210 6214 "This is free software; see the source for copying conditions. "
6211 6215 "There is NO\nwarranty; "
6212 6216 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6213 6217 )
6214 6218 if not ui.quiet:
6215 6219 fm.plain(license)
6216 6220
6217 6221 if ui.verbose:
6218 6222 fm.plain(_("\nEnabled extensions:\n\n"))
6219 6223 # format names and versions into columns
6220 6224 names = []
6221 6225 vers = []
6222 6226 isinternals = []
6223 6227 for name, module in extensions.extensions():
6224 6228 names.append(name)
6225 6229 vers.append(extensions.moduleversion(module) or None)
6226 6230 isinternals.append(extensions.ismoduleinternal(module))
6227 6231 fn = fm.nested("extensions", tmpl='{name}\n')
6228 6232 if names:
6229 6233 namefmt = " %%-%ds " % max(len(n) for n in names)
6230 6234 places = [_("external"), _("internal")]
6231 6235 for n, v, p in zip(names, vers, isinternals):
6232 6236 fn.startitem()
6233 6237 fn.condwrite(ui.verbose, "name", namefmt, n)
6234 6238 if ui.verbose:
6235 6239 fn.plain("%s " % places[p])
6236 6240 fn.data(bundled=p)
6237 6241 fn.condwrite(ui.verbose and v, "ver", "%s", v)
6238 6242 if ui.verbose:
6239 6243 fn.plain("\n")
6240 6244 fn.end()
6241 6245 fm.end()
6242 6246
6243 6247 def loadcmdtable(ui, name, cmdtable):
6244 6248 """Load command functions from specified cmdtable
6245 6249 """
6246 6250 cmdtable = cmdtable.copy()
6247 6251 for cmd in list(cmdtable):
6248 6252 if not cmd.startswith('^'):
6249 6253 continue
6250 6254 ui.deprecwarn("old-style command registration '%s' in extension '%s'"
6251 6255 % (cmd, name), '4.8')
6252 6256 entry = cmdtable.pop(cmd)
6253 6257 entry[0].helpbasic = True
6254 6258 cmdtable[cmd[1:]] = entry
6255 6259
6256 6260 overrides = [cmd for cmd in cmdtable if cmd in table]
6257 6261 if overrides:
6258 6262 ui.warn(_("extension '%s' overrides commands: %s\n")
6259 6263 % (name, " ".join(overrides)))
6260 6264 table.update(cmdtable)
@@ -1,1484 +1,1487 b''
1 1 # configitems.py - centralized declaration of configuration option
2 2 #
3 3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import functools
11 11 import re
12 12
13 13 from . import (
14 14 encoding,
15 15 error,
16 16 )
17 17
18 18 def loadconfigtable(ui, extname, configtable):
19 19 """update config item known to the ui with the extension ones"""
20 20 for section, items in sorted(configtable.items()):
21 21 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 22 knownkeys = set(knownitems)
23 23 newkeys = set(items)
24 24 for key in sorted(knownkeys & newkeys):
25 25 msg = "extension '%s' overwrite config item '%s.%s'"
26 26 msg %= (extname, section, key)
27 27 ui.develwarn(msg, config='warn-config')
28 28
29 29 knownitems.update(items)
30 30
31 31 class configitem(object):
32 32 """represent a known config item
33 33
34 34 :section: the official config section where to find this item,
35 35 :name: the official name within the section,
36 36 :default: default value for this item,
37 37 :alias: optional list of tuples as alternatives,
38 38 :generic: this is a generic definition, match name using regular expression.
39 39 """
40 40
41 41 def __init__(self, section, name, default=None, alias=(),
42 42 generic=False, priority=0):
43 43 self.section = section
44 44 self.name = name
45 45 self.default = default
46 46 self.alias = list(alias)
47 47 self.generic = generic
48 48 self.priority = priority
49 49 self._re = None
50 50 if generic:
51 51 self._re = re.compile(self.name)
52 52
53 53 class itemregister(dict):
54 54 """A specialized dictionary that can handle wild-card selection"""
55 55
56 56 def __init__(self):
57 57 super(itemregister, self).__init__()
58 58 self._generics = set()
59 59
60 60 def update(self, other):
61 61 super(itemregister, self).update(other)
62 62 self._generics.update(other._generics)
63 63
64 64 def __setitem__(self, key, item):
65 65 super(itemregister, self).__setitem__(key, item)
66 66 if item.generic:
67 67 self._generics.add(item)
68 68
69 69 def get(self, key):
70 70 baseitem = super(itemregister, self).get(key)
71 71 if baseitem is not None and not baseitem.generic:
72 72 return baseitem
73 73
74 74 # search for a matching generic item
75 75 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
76 76 for item in generics:
77 77 # we use 'match' instead of 'search' to make the matching simpler
78 78 # for people unfamiliar with regular expression. Having the match
79 79 # rooted to the start of the string will produce less surprising
80 80 # result for user writing simple regex for sub-attribute.
81 81 #
82 82 # For example using "color\..*" match produces an unsurprising
83 83 # result, while using search could suddenly match apparently
84 84 # unrelated configuration that happens to contains "color."
85 85 # anywhere. This is a tradeoff where we favor requiring ".*" on
86 86 # some match to avoid the need to prefix most pattern with "^".
87 87 # The "^" seems more error prone.
88 88 if item._re.match(key):
89 89 return item
90 90
91 91 return None
92 92
93 93 coreitems = {}
94 94
95 95 def _register(configtable, *args, **kwargs):
96 96 item = configitem(*args, **kwargs)
97 97 section = configtable.setdefault(item.section, itemregister())
98 98 if item.name in section:
99 99 msg = "duplicated config item registration for '%s.%s'"
100 100 raise error.ProgrammingError(msg % (item.section, item.name))
101 101 section[item.name] = item
102 102
103 103 # special value for case where the default is derived from other values
104 104 dynamicdefault = object()
105 105
106 106 # Registering actual config items
107 107
108 108 def getitemregister(configtable):
109 109 f = functools.partial(_register, configtable)
110 110 # export pseudo enum as configitem.*
111 111 f.dynamicdefault = dynamicdefault
112 112 return f
113 113
114 114 coreconfigitem = getitemregister(coreitems)
115 115
116 116 def _registerdiffopts(section, configprefix=''):
117 117 coreconfigitem(section, configprefix + 'nodates',
118 118 default=False,
119 119 )
120 120 coreconfigitem(section, configprefix + 'showfunc',
121 121 default=False,
122 122 )
123 123 coreconfigitem(section, configprefix + 'unified',
124 124 default=None,
125 125 )
126 126 coreconfigitem(section, configprefix + 'git',
127 127 default=False,
128 128 )
129 129 coreconfigitem(section, configprefix + 'ignorews',
130 130 default=False,
131 131 )
132 132 coreconfigitem(section, configprefix + 'ignorewsamount',
133 133 default=False,
134 134 )
135 135 coreconfigitem(section, configprefix + 'ignoreblanklines',
136 136 default=False,
137 137 )
138 138 coreconfigitem(section, configprefix + 'ignorewseol',
139 139 default=False,
140 140 )
141 141 coreconfigitem(section, configprefix + 'nobinary',
142 142 default=False,
143 143 )
144 144 coreconfigitem(section, configprefix + 'noprefix',
145 145 default=False,
146 146 )
147 147 coreconfigitem(section, configprefix + 'word-diff',
148 148 default=False,
149 149 )
150 150
151 151 coreconfigitem('alias', '.*',
152 152 default=dynamicdefault,
153 153 generic=True,
154 154 )
155 155 coreconfigitem('auth', 'cookiefile',
156 156 default=None,
157 157 )
158 158 _registerdiffopts(section='annotate')
159 159 # bookmarks.pushing: internal hack for discovery
160 160 coreconfigitem('bookmarks', 'pushing',
161 161 default=list,
162 162 )
163 163 # bundle.mainreporoot: internal hack for bundlerepo
164 164 coreconfigitem('bundle', 'mainreporoot',
165 165 default='',
166 166 )
167 167 coreconfigitem('censor', 'policy',
168 168 default='abort',
169 169 )
170 170 coreconfigitem('chgserver', 'idletimeout',
171 171 default=3600,
172 172 )
173 173 coreconfigitem('chgserver', 'skiphash',
174 174 default=False,
175 175 )
176 176 coreconfigitem('cmdserver', 'log',
177 177 default=None,
178 178 )
179 179 coreconfigitem('cmdserver', 'max-log-files',
180 180 default=7,
181 181 )
182 182 coreconfigitem('cmdserver', 'max-log-size',
183 183 default='1 MB',
184 184 )
185 185 coreconfigitem('cmdserver', 'max-repo-cache',
186 186 default=0,
187 187 )
188 188 coreconfigitem('cmdserver', 'message-encodings',
189 189 default=list,
190 190 )
191 191 coreconfigitem('cmdserver', 'track-log',
192 192 default=lambda: ['chgserver', 'cmdserver', 'repocache'],
193 193 )
194 194 coreconfigitem('color', '.*',
195 195 default=None,
196 196 generic=True,
197 197 )
198 198 coreconfigitem('color', 'mode',
199 199 default='auto',
200 200 )
201 201 coreconfigitem('color', 'pagermode',
202 202 default=dynamicdefault,
203 203 )
204 204 _registerdiffopts(section='commands', configprefix='commit.interactive.')
205 coreconfigitem('commands', 'commit.post-status',
206 default=False,
207 )
205 208 coreconfigitem('commands', 'grep.all-files',
206 209 default=False,
207 210 )
208 211 coreconfigitem('commands', 'resolve.confirm',
209 212 default=False,
210 213 )
211 214 coreconfigitem('commands', 'resolve.explicit-re-merge',
212 215 default=False,
213 216 )
214 217 coreconfigitem('commands', 'resolve.mark-check',
215 218 default='none',
216 219 )
217 220 _registerdiffopts(section='commands', configprefix='revert.interactive.')
218 221 coreconfigitem('commands', 'show.aliasprefix',
219 222 default=list,
220 223 )
221 224 coreconfigitem('commands', 'status.relative',
222 225 default=False,
223 226 )
224 227 coreconfigitem('commands', 'status.skipstates',
225 228 default=[],
226 229 )
227 230 coreconfigitem('commands', 'status.terse',
228 231 default='',
229 232 )
230 233 coreconfigitem('commands', 'status.verbose',
231 234 default=False,
232 235 )
233 236 coreconfigitem('commands', 'update.check',
234 237 default=None,
235 238 )
236 239 coreconfigitem('commands', 'update.requiredest',
237 240 default=False,
238 241 )
239 242 coreconfigitem('committemplate', '.*',
240 243 default=None,
241 244 generic=True,
242 245 )
243 246 coreconfigitem('convert', 'bzr.saverev',
244 247 default=True,
245 248 )
246 249 coreconfigitem('convert', 'cvsps.cache',
247 250 default=True,
248 251 )
249 252 coreconfigitem('convert', 'cvsps.fuzz',
250 253 default=60,
251 254 )
252 255 coreconfigitem('convert', 'cvsps.logencoding',
253 256 default=None,
254 257 )
255 258 coreconfigitem('convert', 'cvsps.mergefrom',
256 259 default=None,
257 260 )
258 261 coreconfigitem('convert', 'cvsps.mergeto',
259 262 default=None,
260 263 )
261 264 coreconfigitem('convert', 'git.committeractions',
262 265 default=lambda: ['messagedifferent'],
263 266 )
264 267 coreconfigitem('convert', 'git.extrakeys',
265 268 default=list,
266 269 )
267 270 coreconfigitem('convert', 'git.findcopiesharder',
268 271 default=False,
269 272 )
270 273 coreconfigitem('convert', 'git.remoteprefix',
271 274 default='remote',
272 275 )
273 276 coreconfigitem('convert', 'git.renamelimit',
274 277 default=400,
275 278 )
276 279 coreconfigitem('convert', 'git.saverev',
277 280 default=True,
278 281 )
279 282 coreconfigitem('convert', 'git.similarity',
280 283 default=50,
281 284 )
282 285 coreconfigitem('convert', 'git.skipsubmodules',
283 286 default=False,
284 287 )
285 288 coreconfigitem('convert', 'hg.clonebranches',
286 289 default=False,
287 290 )
288 291 coreconfigitem('convert', 'hg.ignoreerrors',
289 292 default=False,
290 293 )
291 294 coreconfigitem('convert', 'hg.revs',
292 295 default=None,
293 296 )
294 297 coreconfigitem('convert', 'hg.saverev',
295 298 default=False,
296 299 )
297 300 coreconfigitem('convert', 'hg.sourcename',
298 301 default=None,
299 302 )
300 303 coreconfigitem('convert', 'hg.startrev',
301 304 default=None,
302 305 )
303 306 coreconfigitem('convert', 'hg.tagsbranch',
304 307 default='default',
305 308 )
306 309 coreconfigitem('convert', 'hg.usebranchnames',
307 310 default=True,
308 311 )
309 312 coreconfigitem('convert', 'ignoreancestorcheck',
310 313 default=False,
311 314 )
312 315 coreconfigitem('convert', 'localtimezone',
313 316 default=False,
314 317 )
315 318 coreconfigitem('convert', 'p4.encoding',
316 319 default=dynamicdefault,
317 320 )
318 321 coreconfigitem('convert', 'p4.startrev',
319 322 default=0,
320 323 )
321 324 coreconfigitem('convert', 'skiptags',
322 325 default=False,
323 326 )
324 327 coreconfigitem('convert', 'svn.debugsvnlog',
325 328 default=True,
326 329 )
327 330 coreconfigitem('convert', 'svn.trunk',
328 331 default=None,
329 332 )
330 333 coreconfigitem('convert', 'svn.tags',
331 334 default=None,
332 335 )
333 336 coreconfigitem('convert', 'svn.branches',
334 337 default=None,
335 338 )
336 339 coreconfigitem('convert', 'svn.startrev',
337 340 default=0,
338 341 )
339 342 coreconfigitem('debug', 'dirstate.delaywrite',
340 343 default=0,
341 344 )
342 345 coreconfigitem('defaults', '.*',
343 346 default=None,
344 347 generic=True,
345 348 )
346 349 coreconfigitem('devel', 'all-warnings',
347 350 default=False,
348 351 )
349 352 coreconfigitem('devel', 'bundle2.debug',
350 353 default=False,
351 354 )
352 355 coreconfigitem('devel', 'bundle.delta',
353 356 default='',
354 357 )
355 358 coreconfigitem('devel', 'cache-vfs',
356 359 default=None,
357 360 )
358 361 coreconfigitem('devel', 'check-locks',
359 362 default=False,
360 363 )
361 364 coreconfigitem('devel', 'check-relroot',
362 365 default=False,
363 366 )
364 367 coreconfigitem('devel', 'default-date',
365 368 default=None,
366 369 )
367 370 coreconfigitem('devel', 'deprec-warn',
368 371 default=False,
369 372 )
370 373 coreconfigitem('devel', 'disableloaddefaultcerts',
371 374 default=False,
372 375 )
373 376 coreconfigitem('devel', 'warn-empty-changegroup',
374 377 default=False,
375 378 )
376 379 coreconfigitem('devel', 'legacy.exchange',
377 380 default=list,
378 381 )
379 382 coreconfigitem('devel', 'servercafile',
380 383 default='',
381 384 )
382 385 coreconfigitem('devel', 'serverexactprotocol',
383 386 default='',
384 387 )
385 388 coreconfigitem('devel', 'serverrequirecert',
386 389 default=False,
387 390 )
388 391 coreconfigitem('devel', 'strip-obsmarkers',
389 392 default=True,
390 393 )
391 394 coreconfigitem('devel', 'warn-config',
392 395 default=None,
393 396 )
394 397 coreconfigitem('devel', 'warn-config-default',
395 398 default=None,
396 399 )
397 400 coreconfigitem('devel', 'user.obsmarker',
398 401 default=None,
399 402 )
400 403 coreconfigitem('devel', 'warn-config-unknown',
401 404 default=None,
402 405 )
403 406 coreconfigitem('devel', 'debug.copies',
404 407 default=False,
405 408 )
406 409 coreconfigitem('devel', 'debug.extensions',
407 410 default=False,
408 411 )
409 412 coreconfigitem('devel', 'debug.peer-request',
410 413 default=False,
411 414 )
412 415 _registerdiffopts(section='diff')
413 416 coreconfigitem('email', 'bcc',
414 417 default=None,
415 418 )
416 419 coreconfigitem('email', 'cc',
417 420 default=None,
418 421 )
419 422 coreconfigitem('email', 'charsets',
420 423 default=list,
421 424 )
422 425 coreconfigitem('email', 'from',
423 426 default=None,
424 427 )
425 428 coreconfigitem('email', 'method',
426 429 default='smtp',
427 430 )
428 431 coreconfigitem('email', 'reply-to',
429 432 default=None,
430 433 )
431 434 coreconfigitem('email', 'to',
432 435 default=None,
433 436 )
434 437 coreconfigitem('experimental', 'archivemetatemplate',
435 438 default=dynamicdefault,
436 439 )
437 440 coreconfigitem('experimental', 'auto-publish',
438 441 default='publish',
439 442 )
440 443 coreconfigitem('experimental', 'bundle-phases',
441 444 default=False,
442 445 )
443 446 coreconfigitem('experimental', 'bundle2-advertise',
444 447 default=True,
445 448 )
446 449 coreconfigitem('experimental', 'bundle2-output-capture',
447 450 default=False,
448 451 )
449 452 coreconfigitem('experimental', 'bundle2.pushback',
450 453 default=False,
451 454 )
452 455 coreconfigitem('experimental', 'bundle2lazylocking',
453 456 default=False,
454 457 )
455 458 coreconfigitem('experimental', 'bundlecomplevel',
456 459 default=None,
457 460 )
458 461 coreconfigitem('experimental', 'bundlecomplevel.bzip2',
459 462 default=None,
460 463 )
461 464 coreconfigitem('experimental', 'bundlecomplevel.gzip',
462 465 default=None,
463 466 )
464 467 coreconfigitem('experimental', 'bundlecomplevel.none',
465 468 default=None,
466 469 )
467 470 coreconfigitem('experimental', 'bundlecomplevel.zstd',
468 471 default=None,
469 472 )
470 473 coreconfigitem('experimental', 'changegroup3',
471 474 default=False,
472 475 )
473 476 coreconfigitem('experimental', 'cleanup-as-archived',
474 477 default=False,
475 478 )
476 479 coreconfigitem('experimental', 'clientcompressionengines',
477 480 default=list,
478 481 )
479 482 coreconfigitem('experimental', 'copytrace',
480 483 default='on',
481 484 )
482 485 coreconfigitem('experimental', 'copytrace.movecandidateslimit',
483 486 default=100,
484 487 )
485 488 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
486 489 default=100,
487 490 )
488 491 coreconfigitem('experimental', 'copies.read-from',
489 492 default="filelog-only",
490 493 )
491 494 coreconfigitem('experimental', 'copies.write-to',
492 495 default='filelog-only',
493 496 )
494 497 coreconfigitem('experimental', 'crecordtest',
495 498 default=None,
496 499 )
497 500 coreconfigitem('experimental', 'directaccess',
498 501 default=False,
499 502 )
500 503 coreconfigitem('experimental', 'directaccess.revnums',
501 504 default=False,
502 505 )
503 506 coreconfigitem('experimental', 'editortmpinhg',
504 507 default=False,
505 508 )
506 509 coreconfigitem('experimental', 'evolution',
507 510 default=list,
508 511 )
509 512 coreconfigitem('experimental', 'evolution.allowdivergence',
510 513 default=False,
511 514 alias=[('experimental', 'allowdivergence')]
512 515 )
513 516 coreconfigitem('experimental', 'evolution.allowunstable',
514 517 default=None,
515 518 )
516 519 coreconfigitem('experimental', 'evolution.createmarkers',
517 520 default=None,
518 521 )
519 522 coreconfigitem('experimental', 'evolution.effect-flags',
520 523 default=True,
521 524 alias=[('experimental', 'effect-flags')]
522 525 )
523 526 coreconfigitem('experimental', 'evolution.exchange',
524 527 default=None,
525 528 )
526 529 coreconfigitem('experimental', 'evolution.bundle-obsmarker',
527 530 default=False,
528 531 )
529 532 coreconfigitem('experimental', 'evolution.report-instabilities',
530 533 default=True,
531 534 )
532 535 coreconfigitem('experimental', 'evolution.track-operation',
533 536 default=True,
534 537 )
535 538 # repo-level config to exclude a revset visibility
536 539 #
537 540 # The target use case is to use `share` to expose different subset of the same
538 541 # repository, especially server side. See also `server.view`.
539 542 coreconfigitem('experimental', 'extra-filter-revs',
540 543 default=None,
541 544 )
542 545 coreconfigitem('experimental', 'maxdeltachainspan',
543 546 default=-1,
544 547 )
545 548 coreconfigitem('experimental', 'mergetempdirprefix',
546 549 default=None,
547 550 )
548 551 coreconfigitem('experimental', 'mmapindexthreshold',
549 552 default=None,
550 553 )
551 554 coreconfigitem('experimental', 'narrow',
552 555 default=False,
553 556 )
554 557 coreconfigitem('experimental', 'nonnormalparanoidcheck',
555 558 default=False,
556 559 )
557 560 coreconfigitem('experimental', 'exportableenviron',
558 561 default=list,
559 562 )
560 563 coreconfigitem('experimental', 'extendedheader.index',
561 564 default=None,
562 565 )
563 566 coreconfigitem('experimental', 'extendedheader.similarity',
564 567 default=False,
565 568 )
566 569 coreconfigitem('experimental', 'graphshorten',
567 570 default=False,
568 571 )
569 572 coreconfigitem('experimental', 'graphstyle.parent',
570 573 default=dynamicdefault,
571 574 )
572 575 coreconfigitem('experimental', 'graphstyle.missing',
573 576 default=dynamicdefault,
574 577 )
575 578 coreconfigitem('experimental', 'graphstyle.grandparent',
576 579 default=dynamicdefault,
577 580 )
578 581 coreconfigitem('experimental', 'hook-track-tags',
579 582 default=False,
580 583 )
581 584 coreconfigitem('experimental', 'httppeer.advertise-v2',
582 585 default=False,
583 586 )
584 587 coreconfigitem('experimental', 'httppeer.v2-encoder-order',
585 588 default=None,
586 589 )
587 590 coreconfigitem('experimental', 'httppostargs',
588 591 default=False,
589 592 )
590 593 coreconfigitem('experimental', 'mergedriver',
591 594 default=None,
592 595 )
593 596 coreconfigitem('experimental', 'nointerrupt', default=False)
594 597 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
595 598
596 599 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
597 600 default=False,
598 601 )
599 602 coreconfigitem('experimental', 'remotenames',
600 603 default=False,
601 604 )
602 605 coreconfigitem('experimental', 'removeemptydirs',
603 606 default=True,
604 607 )
605 608 coreconfigitem('experimental', 'revert.interactive.select-to-keep',
606 609 default=False,
607 610 )
608 611 coreconfigitem('experimental', 'revisions.prefixhexnode',
609 612 default=False,
610 613 )
611 614 coreconfigitem('experimental', 'revlogv2',
612 615 default=None,
613 616 )
614 617 coreconfigitem('experimental', 'revisions.disambiguatewithin',
615 618 default=None,
616 619 )
617 620 coreconfigitem('experimental', 'server.filesdata.recommended-batch-size',
618 621 default=50000,
619 622 )
620 623 coreconfigitem('experimental', 'server.manifestdata.recommended-batch-size',
621 624 default=100000,
622 625 )
623 626 coreconfigitem('experimental', 'server.stream-narrow-clones',
624 627 default=False,
625 628 )
626 629 coreconfigitem('experimental', 'single-head-per-branch',
627 630 default=False,
628 631 )
629 632 coreconfigitem('experimental', 'sshserver.support-v2',
630 633 default=False,
631 634 )
632 635 coreconfigitem('experimental', 'sparse-read',
633 636 default=False,
634 637 )
635 638 coreconfigitem('experimental', 'sparse-read.density-threshold',
636 639 default=0.50,
637 640 )
638 641 coreconfigitem('experimental', 'sparse-read.min-gap-size',
639 642 default='65K',
640 643 )
641 644 coreconfigitem('experimental', 'treemanifest',
642 645 default=False,
643 646 )
644 647 coreconfigitem('experimental', 'update.atomic-file',
645 648 default=False,
646 649 )
647 650 coreconfigitem('experimental', 'sshpeer.advertise-v2',
648 651 default=False,
649 652 )
650 653 coreconfigitem('experimental', 'web.apiserver',
651 654 default=False,
652 655 )
653 656 coreconfigitem('experimental', 'web.api.http-v2',
654 657 default=False,
655 658 )
656 659 coreconfigitem('experimental', 'web.api.debugreflect',
657 660 default=False,
658 661 )
659 662 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
660 663 default=False,
661 664 )
662 665 coreconfigitem('experimental', 'xdiff',
663 666 default=False,
664 667 )
665 668 coreconfigitem('extensions', '.*',
666 669 default=None,
667 670 generic=True,
668 671 )
669 672 coreconfigitem('extdata', '.*',
670 673 default=None,
671 674 generic=True,
672 675 )
673 676 coreconfigitem('format', 'chunkcachesize',
674 677 default=None,
675 678 )
676 679 coreconfigitem('format', 'dotencode',
677 680 default=True,
678 681 )
679 682 coreconfigitem('format', 'generaldelta',
680 683 default=False,
681 684 )
682 685 coreconfigitem('format', 'manifestcachesize',
683 686 default=None,
684 687 )
685 688 coreconfigitem('format', 'maxchainlen',
686 689 default=dynamicdefault,
687 690 )
688 691 coreconfigitem('format', 'obsstore-version',
689 692 default=None,
690 693 )
691 694 coreconfigitem('format', 'sparse-revlog',
692 695 default=True,
693 696 )
694 697 coreconfigitem('format', 'revlog-compression',
695 698 default='zlib',
696 699 alias=[('experimental', 'format.compression')]
697 700 )
698 701 coreconfigitem('format', 'usefncache',
699 702 default=True,
700 703 )
701 704 coreconfigitem('format', 'usegeneraldelta',
702 705 default=True,
703 706 )
704 707 coreconfigitem('format', 'usestore',
705 708 default=True,
706 709 )
707 710 coreconfigitem('format', 'internal-phase',
708 711 default=False,
709 712 )
710 713 coreconfigitem('fsmonitor', 'warn_when_unused',
711 714 default=True,
712 715 )
713 716 coreconfigitem('fsmonitor', 'warn_update_file_count',
714 717 default=50000,
715 718 )
716 719 coreconfigitem('help', br'hidden-command\..*',
717 720 default=False,
718 721 generic=True,
719 722 )
720 723 coreconfigitem('help', br'hidden-topic\..*',
721 724 default=False,
722 725 generic=True,
723 726 )
724 727 coreconfigitem('hooks', '.*',
725 728 default=dynamicdefault,
726 729 generic=True,
727 730 )
728 731 coreconfigitem('hgweb-paths', '.*',
729 732 default=list,
730 733 generic=True,
731 734 )
732 735 coreconfigitem('hostfingerprints', '.*',
733 736 default=list,
734 737 generic=True,
735 738 )
736 739 coreconfigitem('hostsecurity', 'ciphers',
737 740 default=None,
738 741 )
739 742 coreconfigitem('hostsecurity', 'disabletls10warning',
740 743 default=False,
741 744 )
742 745 coreconfigitem('hostsecurity', 'minimumprotocol',
743 746 default=dynamicdefault,
744 747 )
745 748 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
746 749 default=dynamicdefault,
747 750 generic=True,
748 751 )
749 752 coreconfigitem('hostsecurity', '.*:ciphers$',
750 753 default=dynamicdefault,
751 754 generic=True,
752 755 )
753 756 coreconfigitem('hostsecurity', '.*:fingerprints$',
754 757 default=list,
755 758 generic=True,
756 759 )
757 760 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
758 761 default=None,
759 762 generic=True,
760 763 )
761 764
762 765 coreconfigitem('http_proxy', 'always',
763 766 default=False,
764 767 )
765 768 coreconfigitem('http_proxy', 'host',
766 769 default=None,
767 770 )
768 771 coreconfigitem('http_proxy', 'no',
769 772 default=list,
770 773 )
771 774 coreconfigitem('http_proxy', 'passwd',
772 775 default=None,
773 776 )
774 777 coreconfigitem('http_proxy', 'user',
775 778 default=None,
776 779 )
777 780
778 781 coreconfigitem('http', 'timeout',
779 782 default=None,
780 783 )
781 784
782 785 coreconfigitem('logtoprocess', 'commandexception',
783 786 default=None,
784 787 )
785 788 coreconfigitem('logtoprocess', 'commandfinish',
786 789 default=None,
787 790 )
788 791 coreconfigitem('logtoprocess', 'command',
789 792 default=None,
790 793 )
791 794 coreconfigitem('logtoprocess', 'develwarn',
792 795 default=None,
793 796 )
794 797 coreconfigitem('logtoprocess', 'uiblocked',
795 798 default=None,
796 799 )
797 800 coreconfigitem('merge', 'checkunknown',
798 801 default='abort',
799 802 )
800 803 coreconfigitem('merge', 'checkignored',
801 804 default='abort',
802 805 )
803 806 coreconfigitem('experimental', 'merge.checkpathconflicts',
804 807 default=False,
805 808 )
806 809 coreconfigitem('merge', 'followcopies',
807 810 default=True,
808 811 )
809 812 coreconfigitem('merge', 'on-failure',
810 813 default='continue',
811 814 )
812 815 coreconfigitem('merge', 'preferancestor',
813 816 default=lambda: ['*'],
814 817 )
815 818 coreconfigitem('merge', 'strict-capability-check',
816 819 default=False,
817 820 )
818 821 coreconfigitem('merge-tools', '.*',
819 822 default=None,
820 823 generic=True,
821 824 )
822 825 coreconfigitem('merge-tools', br'.*\.args$',
823 826 default="$local $base $other",
824 827 generic=True,
825 828 priority=-1,
826 829 )
827 830 coreconfigitem('merge-tools', br'.*\.binary$',
828 831 default=False,
829 832 generic=True,
830 833 priority=-1,
831 834 )
832 835 coreconfigitem('merge-tools', br'.*\.check$',
833 836 default=list,
834 837 generic=True,
835 838 priority=-1,
836 839 )
837 840 coreconfigitem('merge-tools', br'.*\.checkchanged$',
838 841 default=False,
839 842 generic=True,
840 843 priority=-1,
841 844 )
842 845 coreconfigitem('merge-tools', br'.*\.executable$',
843 846 default=dynamicdefault,
844 847 generic=True,
845 848 priority=-1,
846 849 )
847 850 coreconfigitem('merge-tools', br'.*\.fixeol$',
848 851 default=False,
849 852 generic=True,
850 853 priority=-1,
851 854 )
852 855 coreconfigitem('merge-tools', br'.*\.gui$',
853 856 default=False,
854 857 generic=True,
855 858 priority=-1,
856 859 )
857 860 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
858 861 default='basic',
859 862 generic=True,
860 863 priority=-1,
861 864 )
862 865 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
863 866 default=dynamicdefault, # take from ui.mergemarkertemplate
864 867 generic=True,
865 868 priority=-1,
866 869 )
867 870 coreconfigitem('merge-tools', br'.*\.priority$',
868 871 default=0,
869 872 generic=True,
870 873 priority=-1,
871 874 )
872 875 coreconfigitem('merge-tools', br'.*\.premerge$',
873 876 default=dynamicdefault,
874 877 generic=True,
875 878 priority=-1,
876 879 )
877 880 coreconfigitem('merge-tools', br'.*\.symlink$',
878 881 default=False,
879 882 generic=True,
880 883 priority=-1,
881 884 )
882 885 coreconfigitem('pager', 'attend-.*',
883 886 default=dynamicdefault,
884 887 generic=True,
885 888 )
886 889 coreconfigitem('pager', 'ignore',
887 890 default=list,
888 891 )
889 892 coreconfigitem('pager', 'pager',
890 893 default=dynamicdefault,
891 894 )
892 895 coreconfigitem('patch', 'eol',
893 896 default='strict',
894 897 )
895 898 coreconfigitem('patch', 'fuzz',
896 899 default=2,
897 900 )
898 901 coreconfigitem('paths', 'default',
899 902 default=None,
900 903 )
901 904 coreconfigitem('paths', 'default-push',
902 905 default=None,
903 906 )
904 907 coreconfigitem('paths', '.*',
905 908 default=None,
906 909 generic=True,
907 910 )
908 911 coreconfigitem('phases', 'checksubrepos',
909 912 default='follow',
910 913 )
911 914 coreconfigitem('phases', 'new-commit',
912 915 default='draft',
913 916 )
914 917 coreconfigitem('phases', 'publish',
915 918 default=True,
916 919 )
917 920 coreconfigitem('profiling', 'enabled',
918 921 default=False,
919 922 )
920 923 coreconfigitem('profiling', 'format',
921 924 default='text',
922 925 )
923 926 coreconfigitem('profiling', 'freq',
924 927 default=1000,
925 928 )
926 929 coreconfigitem('profiling', 'limit',
927 930 default=30,
928 931 )
929 932 coreconfigitem('profiling', 'nested',
930 933 default=0,
931 934 )
932 935 coreconfigitem('profiling', 'output',
933 936 default=None,
934 937 )
935 938 coreconfigitem('profiling', 'showmax',
936 939 default=0.999,
937 940 )
938 941 coreconfigitem('profiling', 'showmin',
939 942 default=dynamicdefault,
940 943 )
941 944 coreconfigitem('profiling', 'sort',
942 945 default='inlinetime',
943 946 )
944 947 coreconfigitem('profiling', 'statformat',
945 948 default='hotpath',
946 949 )
947 950 coreconfigitem('profiling', 'time-track',
948 951 default=dynamicdefault,
949 952 )
950 953 coreconfigitem('profiling', 'type',
951 954 default='stat',
952 955 )
953 956 coreconfigitem('progress', 'assume-tty',
954 957 default=False,
955 958 )
956 959 coreconfigitem('progress', 'changedelay',
957 960 default=1,
958 961 )
959 962 coreconfigitem('progress', 'clear-complete',
960 963 default=True,
961 964 )
962 965 coreconfigitem('progress', 'debug',
963 966 default=False,
964 967 )
965 968 coreconfigitem('progress', 'delay',
966 969 default=3,
967 970 )
968 971 coreconfigitem('progress', 'disable',
969 972 default=False,
970 973 )
971 974 coreconfigitem('progress', 'estimateinterval',
972 975 default=60.0,
973 976 )
974 977 coreconfigitem('progress', 'format',
975 978 default=lambda: ['topic', 'bar', 'number', 'estimate'],
976 979 )
977 980 coreconfigitem('progress', 'refresh',
978 981 default=0.1,
979 982 )
980 983 coreconfigitem('progress', 'width',
981 984 default=dynamicdefault,
982 985 )
983 986 coreconfigitem('push', 'pushvars.server',
984 987 default=False,
985 988 )
986 989 coreconfigitem('rewrite', 'backup-bundle',
987 990 default=True,
988 991 alias=[('ui', 'history-editing-backup')],
989 992 )
990 993 coreconfigitem('rewrite', 'update-timestamp',
991 994 default=False,
992 995 )
993 996 coreconfigitem('storage', 'new-repo-backend',
994 997 default='revlogv1',
995 998 )
996 999 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
997 1000 default=True,
998 1001 alias=[('format', 'aggressivemergedeltas')],
999 1002 )
1000 1003 coreconfigitem('storage', 'revlog.reuse-external-delta',
1001 1004 default=True,
1002 1005 )
1003 1006 coreconfigitem('storage', 'revlog.reuse-external-delta-parent',
1004 1007 default=None,
1005 1008 )
1006 1009 coreconfigitem('storage', 'revlog.zlib.level',
1007 1010 default=None,
1008 1011 )
1009 1012 coreconfigitem('storage', 'revlog.zstd.level',
1010 1013 default=None,
1011 1014 )
1012 1015 coreconfigitem('server', 'bookmarks-pushkey-compat',
1013 1016 default=True,
1014 1017 )
1015 1018 coreconfigitem('server', 'bundle1',
1016 1019 default=True,
1017 1020 )
1018 1021 coreconfigitem('server', 'bundle1gd',
1019 1022 default=None,
1020 1023 )
1021 1024 coreconfigitem('server', 'bundle1.pull',
1022 1025 default=None,
1023 1026 )
1024 1027 coreconfigitem('server', 'bundle1gd.pull',
1025 1028 default=None,
1026 1029 )
1027 1030 coreconfigitem('server', 'bundle1.push',
1028 1031 default=None,
1029 1032 )
1030 1033 coreconfigitem('server', 'bundle1gd.push',
1031 1034 default=None,
1032 1035 )
1033 1036 coreconfigitem('server', 'bundle2.stream',
1034 1037 default=True,
1035 1038 alias=[('experimental', 'bundle2.stream')]
1036 1039 )
1037 1040 coreconfigitem('server', 'compressionengines',
1038 1041 default=list,
1039 1042 )
1040 1043 coreconfigitem('server', 'concurrent-push-mode',
1041 1044 default='strict',
1042 1045 )
1043 1046 coreconfigitem('server', 'disablefullbundle',
1044 1047 default=False,
1045 1048 )
1046 1049 coreconfigitem('server', 'maxhttpheaderlen',
1047 1050 default=1024,
1048 1051 )
1049 1052 coreconfigitem('server', 'pullbundle',
1050 1053 default=False,
1051 1054 )
1052 1055 coreconfigitem('server', 'preferuncompressed',
1053 1056 default=False,
1054 1057 )
1055 1058 coreconfigitem('server', 'streamunbundle',
1056 1059 default=False,
1057 1060 )
1058 1061 coreconfigitem('server', 'uncompressed',
1059 1062 default=True,
1060 1063 )
1061 1064 coreconfigitem('server', 'uncompressedallowsecret',
1062 1065 default=False,
1063 1066 )
1064 1067 coreconfigitem('server', 'view',
1065 1068 default='served',
1066 1069 )
1067 1070 coreconfigitem('server', 'validate',
1068 1071 default=False,
1069 1072 )
1070 1073 coreconfigitem('server', 'zliblevel',
1071 1074 default=-1,
1072 1075 )
1073 1076 coreconfigitem('server', 'zstdlevel',
1074 1077 default=3,
1075 1078 )
1076 1079 coreconfigitem('share', 'pool',
1077 1080 default=None,
1078 1081 )
1079 1082 coreconfigitem('share', 'poolnaming',
1080 1083 default='identity',
1081 1084 )
1082 1085 coreconfigitem('smtp', 'host',
1083 1086 default=None,
1084 1087 )
1085 1088 coreconfigitem('smtp', 'local_hostname',
1086 1089 default=None,
1087 1090 )
1088 1091 coreconfigitem('smtp', 'password',
1089 1092 default=None,
1090 1093 )
1091 1094 coreconfigitem('smtp', 'port',
1092 1095 default=dynamicdefault,
1093 1096 )
1094 1097 coreconfigitem('smtp', 'tls',
1095 1098 default='none',
1096 1099 )
1097 1100 coreconfigitem('smtp', 'username',
1098 1101 default=None,
1099 1102 )
1100 1103 coreconfigitem('sparse', 'missingwarning',
1101 1104 default=True,
1102 1105 )
1103 1106 coreconfigitem('subrepos', 'allowed',
1104 1107 default=dynamicdefault, # to make backporting simpler
1105 1108 )
1106 1109 coreconfigitem('subrepos', 'hg:allowed',
1107 1110 default=dynamicdefault,
1108 1111 )
1109 1112 coreconfigitem('subrepos', 'git:allowed',
1110 1113 default=dynamicdefault,
1111 1114 )
1112 1115 coreconfigitem('subrepos', 'svn:allowed',
1113 1116 default=dynamicdefault,
1114 1117 )
1115 1118 coreconfigitem('templates', '.*',
1116 1119 default=None,
1117 1120 generic=True,
1118 1121 )
1119 1122 coreconfigitem('templateconfig', '.*',
1120 1123 default=dynamicdefault,
1121 1124 generic=True,
1122 1125 )
1123 1126 coreconfigitem('trusted', 'groups',
1124 1127 default=list,
1125 1128 )
1126 1129 coreconfigitem('trusted', 'users',
1127 1130 default=list,
1128 1131 )
1129 1132 coreconfigitem('ui', '_usedassubrepo',
1130 1133 default=False,
1131 1134 )
1132 1135 coreconfigitem('ui', 'allowemptycommit',
1133 1136 default=False,
1134 1137 )
1135 1138 coreconfigitem('ui', 'archivemeta',
1136 1139 default=True,
1137 1140 )
1138 1141 coreconfigitem('ui', 'askusername',
1139 1142 default=False,
1140 1143 )
1141 1144 coreconfigitem('ui', 'clonebundlefallback',
1142 1145 default=False,
1143 1146 )
1144 1147 coreconfigitem('ui', 'clonebundleprefers',
1145 1148 default=list,
1146 1149 )
1147 1150 coreconfigitem('ui', 'clonebundles',
1148 1151 default=True,
1149 1152 )
1150 1153 coreconfigitem('ui', 'color',
1151 1154 default='auto',
1152 1155 )
1153 1156 coreconfigitem('ui', 'commitsubrepos',
1154 1157 default=False,
1155 1158 )
1156 1159 coreconfigitem('ui', 'debug',
1157 1160 default=False,
1158 1161 )
1159 1162 coreconfigitem('ui', 'debugger',
1160 1163 default=None,
1161 1164 )
1162 1165 coreconfigitem('ui', 'editor',
1163 1166 default=dynamicdefault,
1164 1167 )
1165 1168 coreconfigitem('ui', 'fallbackencoding',
1166 1169 default=None,
1167 1170 )
1168 1171 coreconfigitem('ui', 'forcecwd',
1169 1172 default=None,
1170 1173 )
1171 1174 coreconfigitem('ui', 'forcemerge',
1172 1175 default=None,
1173 1176 )
1174 1177 coreconfigitem('ui', 'formatdebug',
1175 1178 default=False,
1176 1179 )
1177 1180 coreconfigitem('ui', 'formatjson',
1178 1181 default=False,
1179 1182 )
1180 1183 coreconfigitem('ui', 'formatted',
1181 1184 default=None,
1182 1185 )
1183 1186 coreconfigitem('ui', 'graphnodetemplate',
1184 1187 default=None,
1185 1188 )
1186 1189 coreconfigitem('ui', 'interactive',
1187 1190 default=None,
1188 1191 )
1189 1192 coreconfigitem('ui', 'interface',
1190 1193 default=None,
1191 1194 )
1192 1195 coreconfigitem('ui', 'interface.chunkselector',
1193 1196 default=None,
1194 1197 )
1195 1198 coreconfigitem('ui', 'large-file-limit',
1196 1199 default=10000000,
1197 1200 )
1198 1201 coreconfigitem('ui', 'logblockedtimes',
1199 1202 default=False,
1200 1203 )
1201 1204 coreconfigitem('ui', 'logtemplate',
1202 1205 default=None,
1203 1206 )
1204 1207 coreconfigitem('ui', 'merge',
1205 1208 default=None,
1206 1209 )
1207 1210 coreconfigitem('ui', 'mergemarkers',
1208 1211 default='basic',
1209 1212 )
1210 1213 coreconfigitem('ui', 'mergemarkertemplate',
1211 1214 default=('{node|short} '
1212 1215 '{ifeq(tags, "tip", "", '
1213 1216 'ifeq(tags, "", "", "{tags} "))}'
1214 1217 '{if(bookmarks, "{bookmarks} ")}'
1215 1218 '{ifeq(branch, "default", "", "{branch} ")}'
1216 1219 '- {author|user}: {desc|firstline}')
1217 1220 )
1218 1221 coreconfigitem('ui', 'message-output',
1219 1222 default='stdio',
1220 1223 )
1221 1224 coreconfigitem('ui', 'nontty',
1222 1225 default=False,
1223 1226 )
1224 1227 coreconfigitem('ui', 'origbackuppath',
1225 1228 default=None,
1226 1229 )
1227 1230 coreconfigitem('ui', 'paginate',
1228 1231 default=True,
1229 1232 )
1230 1233 coreconfigitem('ui', 'patch',
1231 1234 default=None,
1232 1235 )
1233 1236 coreconfigitem('ui', 'pre-merge-tool-output-template',
1234 1237 default=None,
1235 1238 )
1236 1239 coreconfigitem('ui', 'portablefilenames',
1237 1240 default='warn',
1238 1241 )
1239 1242 coreconfigitem('ui', 'promptecho',
1240 1243 default=False,
1241 1244 )
1242 1245 coreconfigitem('ui', 'quiet',
1243 1246 default=False,
1244 1247 )
1245 1248 coreconfigitem('ui', 'quietbookmarkmove',
1246 1249 default=False,
1247 1250 )
1248 1251 coreconfigitem('ui', 'relative-paths',
1249 1252 default='legacy',
1250 1253 )
1251 1254 coreconfigitem('ui', 'remotecmd',
1252 1255 default='hg',
1253 1256 )
1254 1257 coreconfigitem('ui', 'report_untrusted',
1255 1258 default=True,
1256 1259 )
1257 1260 coreconfigitem('ui', 'rollback',
1258 1261 default=True,
1259 1262 )
1260 1263 coreconfigitem('ui', 'signal-safe-lock',
1261 1264 default=True,
1262 1265 )
1263 1266 coreconfigitem('ui', 'slash',
1264 1267 default=False,
1265 1268 )
1266 1269 coreconfigitem('ui', 'ssh',
1267 1270 default='ssh',
1268 1271 )
1269 1272 coreconfigitem('ui', 'ssherrorhint',
1270 1273 default=None,
1271 1274 )
1272 1275 coreconfigitem('ui', 'statuscopies',
1273 1276 default=False,
1274 1277 )
1275 1278 coreconfigitem('ui', 'strict',
1276 1279 default=False,
1277 1280 )
1278 1281 coreconfigitem('ui', 'style',
1279 1282 default='',
1280 1283 )
1281 1284 coreconfigitem('ui', 'supportcontact',
1282 1285 default=None,
1283 1286 )
1284 1287 coreconfigitem('ui', 'textwidth',
1285 1288 default=78,
1286 1289 )
1287 1290 coreconfigitem('ui', 'timeout',
1288 1291 default='600',
1289 1292 )
1290 1293 coreconfigitem('ui', 'timeout.warn',
1291 1294 default=0,
1292 1295 )
1293 1296 coreconfigitem('ui', 'traceback',
1294 1297 default=False,
1295 1298 )
1296 1299 coreconfigitem('ui', 'tweakdefaults',
1297 1300 default=False,
1298 1301 )
1299 1302 coreconfigitem('ui', 'username',
1300 1303 alias=[('ui', 'user')]
1301 1304 )
1302 1305 coreconfigitem('ui', 'verbose',
1303 1306 default=False,
1304 1307 )
1305 1308 coreconfigitem('verify', 'skipflags',
1306 1309 default=None,
1307 1310 )
1308 1311 coreconfigitem('web', 'allowbz2',
1309 1312 default=False,
1310 1313 )
1311 1314 coreconfigitem('web', 'allowgz',
1312 1315 default=False,
1313 1316 )
1314 1317 coreconfigitem('web', 'allow-pull',
1315 1318 alias=[('web', 'allowpull')],
1316 1319 default=True,
1317 1320 )
1318 1321 coreconfigitem('web', 'allow-push',
1319 1322 alias=[('web', 'allow_push')],
1320 1323 default=list,
1321 1324 )
1322 1325 coreconfigitem('web', 'allowzip',
1323 1326 default=False,
1324 1327 )
1325 1328 coreconfigitem('web', 'archivesubrepos',
1326 1329 default=False,
1327 1330 )
1328 1331 coreconfigitem('web', 'cache',
1329 1332 default=True,
1330 1333 )
1331 1334 coreconfigitem('web', 'comparisoncontext',
1332 1335 default=5,
1333 1336 )
1334 1337 coreconfigitem('web', 'contact',
1335 1338 default=None,
1336 1339 )
1337 1340 coreconfigitem('web', 'deny_push',
1338 1341 default=list,
1339 1342 )
1340 1343 coreconfigitem('web', 'guessmime',
1341 1344 default=False,
1342 1345 )
1343 1346 coreconfigitem('web', 'hidden',
1344 1347 default=False,
1345 1348 )
1346 1349 coreconfigitem('web', 'labels',
1347 1350 default=list,
1348 1351 )
1349 1352 coreconfigitem('web', 'logoimg',
1350 1353 default='hglogo.png',
1351 1354 )
1352 1355 coreconfigitem('web', 'logourl',
1353 1356 default='https://mercurial-scm.org/',
1354 1357 )
1355 1358 coreconfigitem('web', 'accesslog',
1356 1359 default='-',
1357 1360 )
1358 1361 coreconfigitem('web', 'address',
1359 1362 default='',
1360 1363 )
1361 1364 coreconfigitem('web', 'allow-archive',
1362 1365 alias=[('web', 'allow_archive')],
1363 1366 default=list,
1364 1367 )
1365 1368 coreconfigitem('web', 'allow_read',
1366 1369 default=list,
1367 1370 )
1368 1371 coreconfigitem('web', 'baseurl',
1369 1372 default=None,
1370 1373 )
1371 1374 coreconfigitem('web', 'cacerts',
1372 1375 default=None,
1373 1376 )
1374 1377 coreconfigitem('web', 'certificate',
1375 1378 default=None,
1376 1379 )
1377 1380 coreconfigitem('web', 'collapse',
1378 1381 default=False,
1379 1382 )
1380 1383 coreconfigitem('web', 'csp',
1381 1384 default=None,
1382 1385 )
1383 1386 coreconfigitem('web', 'deny_read',
1384 1387 default=list,
1385 1388 )
1386 1389 coreconfigitem('web', 'descend',
1387 1390 default=True,
1388 1391 )
1389 1392 coreconfigitem('web', 'description',
1390 1393 default="",
1391 1394 )
1392 1395 coreconfigitem('web', 'encoding',
1393 1396 default=lambda: encoding.encoding,
1394 1397 )
1395 1398 coreconfigitem('web', 'errorlog',
1396 1399 default='-',
1397 1400 )
1398 1401 coreconfigitem('web', 'ipv6',
1399 1402 default=False,
1400 1403 )
1401 1404 coreconfigitem('web', 'maxchanges',
1402 1405 default=10,
1403 1406 )
1404 1407 coreconfigitem('web', 'maxfiles',
1405 1408 default=10,
1406 1409 )
1407 1410 coreconfigitem('web', 'maxshortchanges',
1408 1411 default=60,
1409 1412 )
1410 1413 coreconfigitem('web', 'motd',
1411 1414 default='',
1412 1415 )
1413 1416 coreconfigitem('web', 'name',
1414 1417 default=dynamicdefault,
1415 1418 )
1416 1419 coreconfigitem('web', 'port',
1417 1420 default=8000,
1418 1421 )
1419 1422 coreconfigitem('web', 'prefix',
1420 1423 default='',
1421 1424 )
1422 1425 coreconfigitem('web', 'push_ssl',
1423 1426 default=True,
1424 1427 )
1425 1428 coreconfigitem('web', 'refreshinterval',
1426 1429 default=20,
1427 1430 )
1428 1431 coreconfigitem('web', 'server-header',
1429 1432 default=None,
1430 1433 )
1431 1434 coreconfigitem('web', 'static',
1432 1435 default=None,
1433 1436 )
1434 1437 coreconfigitem('web', 'staticurl',
1435 1438 default=None,
1436 1439 )
1437 1440 coreconfigitem('web', 'stripes',
1438 1441 default=1,
1439 1442 )
1440 1443 coreconfigitem('web', 'style',
1441 1444 default='paper',
1442 1445 )
1443 1446 coreconfigitem('web', 'templates',
1444 1447 default=None,
1445 1448 )
1446 1449 coreconfigitem('web', 'view',
1447 1450 default='served',
1448 1451 )
1449 1452 coreconfigitem('worker', 'backgroundclose',
1450 1453 default=dynamicdefault,
1451 1454 )
1452 1455 # Windows defaults to a limit of 512 open files. A buffer of 128
1453 1456 # should give us enough headway.
1454 1457 coreconfigitem('worker', 'backgroundclosemaxqueue',
1455 1458 default=384,
1456 1459 )
1457 1460 coreconfigitem('worker', 'backgroundcloseminfilecount',
1458 1461 default=2048,
1459 1462 )
1460 1463 coreconfigitem('worker', 'backgroundclosethreadcount',
1461 1464 default=4,
1462 1465 )
1463 1466 coreconfigitem('worker', 'enabled',
1464 1467 default=True,
1465 1468 )
1466 1469 coreconfigitem('worker', 'numcpus',
1467 1470 default=None,
1468 1471 )
1469 1472
1470 1473 # Rebase related configuration moved to core because other extension are doing
1471 1474 # strange things. For example, shelve import the extensions to reuse some bit
1472 1475 # without formally loading it.
1473 1476 coreconfigitem('commands', 'rebase.requiredest',
1474 1477 default=False,
1475 1478 )
1476 1479 coreconfigitem('experimental', 'rebaseskipobsolete',
1477 1480 default=True,
1478 1481 )
1479 1482 coreconfigitem('rebase', 'singletransaction',
1480 1483 default=False,
1481 1484 )
1482 1485 coreconfigitem('rebase', 'experimental.inmemory',
1483 1486 default=False,
1484 1487 )
@@ -1,2842 +1,2846 b''
1 1 The Mercurial system uses a set of configuration files to control
2 2 aspects of its behavior.
3 3
4 4 Troubleshooting
5 5 ===============
6 6
7 7 If you're having problems with your configuration,
8 8 :hg:`config --debug` can help you understand what is introducing
9 9 a setting into your environment.
10 10
11 11 See :hg:`help config.syntax` and :hg:`help config.files`
12 12 for information about how and where to override things.
13 13
14 14 Structure
15 15 =========
16 16
17 17 The configuration files use a simple ini-file format. A configuration
18 18 file consists of sections, led by a ``[section]`` header and followed
19 19 by ``name = value`` entries::
20 20
21 21 [ui]
22 22 username = Firstname Lastname <firstname.lastname@example.net>
23 23 verbose = True
24 24
25 25 The above entries will be referred to as ``ui.username`` and
26 26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
27 27
28 28 Files
29 29 =====
30 30
31 31 Mercurial reads configuration data from several files, if they exist.
32 32 These files do not exist by default and you will have to create the
33 33 appropriate configuration files yourself:
34 34
35 35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
36 36
37 37 Global configuration like the username setting is typically put into:
38 38
39 39 .. container:: windows
40 40
41 41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
42 42
43 43 .. container:: unix.plan9
44 44
45 45 - ``$HOME/.hgrc`` (on Unix, Plan9)
46 46
47 47 The names of these files depend on the system on which Mercurial is
48 48 installed. ``*.rc`` files from a single directory are read in
49 49 alphabetical order, later ones overriding earlier ones. Where multiple
50 50 paths are given below, settings from earlier paths override later
51 51 ones.
52 52
53 53 .. container:: verbose.unix
54 54
55 55 On Unix, the following files are consulted:
56 56
57 57 - ``<repo>/.hg/hgrc`` (per-repository)
58 58 - ``$HOME/.hgrc`` (per-user)
59 59 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
60 60 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
61 61 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
62 62 - ``/etc/mercurial/hgrc`` (per-system)
63 63 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
64 64 - ``<internal>/default.d/*.rc`` (defaults)
65 65
66 66 .. container:: verbose.windows
67 67
68 68 On Windows, the following files are consulted:
69 69
70 70 - ``<repo>/.hg/hgrc`` (per-repository)
71 71 - ``%USERPROFILE%\.hgrc`` (per-user)
72 72 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
73 73 - ``%HOME%\.hgrc`` (per-user)
74 74 - ``%HOME%\Mercurial.ini`` (per-user)
75 75 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-installation)
76 76 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
77 77 - ``<install-dir>\Mercurial.ini`` (per-installation)
78 78 - ``<internal>/default.d/*.rc`` (defaults)
79 79
80 80 .. note::
81 81
82 82 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
83 83 is used when running 32-bit Python on 64-bit Windows.
84 84
85 85 .. container:: windows
86 86
87 87 On Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``.
88 88
89 89 .. container:: verbose.plan9
90 90
91 91 On Plan9, the following files are consulted:
92 92
93 93 - ``<repo>/.hg/hgrc`` (per-repository)
94 94 - ``$home/lib/hgrc`` (per-user)
95 95 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
96 96 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
97 97 - ``/lib/mercurial/hgrc`` (per-system)
98 98 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
99 99 - ``<internal>/default.d/*.rc`` (defaults)
100 100
101 101 Per-repository configuration options only apply in a
102 102 particular repository. This file is not version-controlled, and
103 103 will not get transferred during a "clone" operation. Options in
104 104 this file override options in all other configuration files.
105 105
106 106 .. container:: unix.plan9
107 107
108 108 On Plan 9 and Unix, most of this file will be ignored if it doesn't
109 109 belong to a trusted user or to a trusted group. See
110 110 :hg:`help config.trusted` for more details.
111 111
112 112 Per-user configuration file(s) are for the user running Mercurial. Options
113 113 in these files apply to all Mercurial commands executed by this user in any
114 114 directory. Options in these files override per-system and per-installation
115 115 options.
116 116
117 117 Per-installation configuration files are searched for in the
118 118 directory where Mercurial is installed. ``<install-root>`` is the
119 119 parent directory of the **hg** executable (or symlink) being run.
120 120
121 121 .. container:: unix.plan9
122 122
123 123 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
124 124 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
125 125 files apply to all Mercurial commands executed by any user in any
126 126 directory.
127 127
128 128 Per-installation configuration files are for the system on
129 129 which Mercurial is running. Options in these files apply to all
130 130 Mercurial commands executed by any user in any directory. Registry
131 131 keys contain PATH-like strings, every part of which must reference
132 132 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
133 133 be read. Mercurial checks each of these locations in the specified
134 134 order until one or more configuration files are detected.
135 135
136 136 Per-system configuration files are for the system on which Mercurial
137 137 is running. Options in these files apply to all Mercurial commands
138 138 executed by any user in any directory. Options in these files
139 139 override per-installation options.
140 140
141 141 Mercurial comes with some default configuration. The default configuration
142 142 files are installed with Mercurial and will be overwritten on upgrades. Default
143 143 configuration files should never be edited by users or administrators but can
144 144 be overridden in other configuration files. So far the directory only contains
145 145 merge tool configuration but packagers can also put other default configuration
146 146 there.
147 147
148 148 Syntax
149 149 ======
150 150
151 151 A configuration file consists of sections, led by a ``[section]`` header
152 152 and followed by ``name = value`` entries (sometimes called
153 153 ``configuration keys``)::
154 154
155 155 [spam]
156 156 eggs=ham
157 157 green=
158 158 eggs
159 159
160 160 Each line contains one entry. If the lines that follow are indented,
161 161 they are treated as continuations of that entry. Leading whitespace is
162 162 removed from values. Empty lines are skipped. Lines beginning with
163 163 ``#`` or ``;`` are ignored and may be used to provide comments.
164 164
165 165 Configuration keys can be set multiple times, in which case Mercurial
166 166 will use the value that was configured last. As an example::
167 167
168 168 [spam]
169 169 eggs=large
170 170 ham=serrano
171 171 eggs=small
172 172
173 173 This would set the configuration key named ``eggs`` to ``small``.
174 174
175 175 It is also possible to define a section multiple times. A section can
176 176 be redefined on the same and/or on different configuration files. For
177 177 example::
178 178
179 179 [foo]
180 180 eggs=large
181 181 ham=serrano
182 182 eggs=small
183 183
184 184 [bar]
185 185 eggs=ham
186 186 green=
187 187 eggs
188 188
189 189 [foo]
190 190 ham=prosciutto
191 191 eggs=medium
192 192 bread=toasted
193 193
194 194 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
195 195 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
196 196 respectively. As you can see there only thing that matters is the last
197 197 value that was set for each of the configuration keys.
198 198
199 199 If a configuration key is set multiple times in different
200 200 configuration files the final value will depend on the order in which
201 201 the different configuration files are read, with settings from earlier
202 202 paths overriding later ones as described on the ``Files`` section
203 203 above.
204 204
205 205 A line of the form ``%include file`` will include ``file`` into the
206 206 current configuration file. The inclusion is recursive, which means
207 207 that included files can include other files. Filenames are relative to
208 208 the configuration file in which the ``%include`` directive is found.
209 209 Environment variables and ``~user`` constructs are expanded in
210 210 ``file``. This lets you do something like::
211 211
212 212 %include ~/.hgrc.d/$HOST.rc
213 213
214 214 to include a different configuration file on each computer you use.
215 215
216 216 A line with ``%unset name`` will remove ``name`` from the current
217 217 section, if it has been set previously.
218 218
219 219 The values are either free-form text strings, lists of text strings,
220 220 or Boolean values. Boolean values can be set to true using any of "1",
221 221 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
222 222 (all case insensitive).
223 223
224 224 List values are separated by whitespace or comma, except when values are
225 225 placed in double quotation marks::
226 226
227 227 allow_read = "John Doe, PhD", brian, betty
228 228
229 229 Quotation marks can be escaped by prefixing them with a backslash. Only
230 230 quotation marks at the beginning of a word is counted as a quotation
231 231 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
232 232
233 233 Sections
234 234 ========
235 235
236 236 This section describes the different sections that may appear in a
237 237 Mercurial configuration file, the purpose of each section, its possible
238 238 keys, and their possible values.
239 239
240 240 ``alias``
241 241 ---------
242 242
243 243 Defines command aliases.
244 244
245 245 Aliases allow you to define your own commands in terms of other
246 246 commands (or aliases), optionally including arguments. Positional
247 247 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
248 248 are expanded by Mercurial before execution. Positional arguments not
249 249 already used by ``$N`` in the definition are put at the end of the
250 250 command to be executed.
251 251
252 252 Alias definitions consist of lines of the form::
253 253
254 254 <alias> = <command> [<argument>]...
255 255
256 256 For example, this definition::
257 257
258 258 latest = log --limit 5
259 259
260 260 creates a new command ``latest`` that shows only the five most recent
261 261 changesets. You can define subsequent aliases using earlier ones::
262 262
263 263 stable5 = latest -b stable
264 264
265 265 .. note::
266 266
267 267 It is possible to create aliases with the same names as
268 268 existing commands, which will then override the original
269 269 definitions. This is almost always a bad idea!
270 270
271 271 An alias can start with an exclamation point (``!``) to make it a
272 272 shell alias. A shell alias is executed with the shell and will let you
273 273 run arbitrary commands. As an example, ::
274 274
275 275 echo = !echo $@
276 276
277 277 will let you do ``hg echo foo`` to have ``foo`` printed in your
278 278 terminal. A better example might be::
279 279
280 280 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
281 281
282 282 which will make ``hg purge`` delete all unknown files in the
283 283 repository in the same manner as the purge extension.
284 284
285 285 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
286 286 expand to the command arguments. Unmatched arguments are
287 287 removed. ``$0`` expands to the alias name and ``$@`` expands to all
288 288 arguments separated by a space. ``"$@"`` (with quotes) expands to all
289 289 arguments quoted individually and separated by a space. These expansions
290 290 happen before the command is passed to the shell.
291 291
292 292 Shell aliases are executed in an environment where ``$HG`` expands to
293 293 the path of the Mercurial that was used to execute the alias. This is
294 294 useful when you want to call further Mercurial commands in a shell
295 295 alias, as was done above for the purge alias. In addition,
296 296 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
297 297 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
298 298
299 299 .. note::
300 300
301 301 Some global configuration options such as ``-R`` are
302 302 processed before shell aliases and will thus not be passed to
303 303 aliases.
304 304
305 305
306 306 ``annotate``
307 307 ------------
308 308
309 309 Settings used when displaying file annotations. All values are
310 310 Booleans and default to False. See :hg:`help config.diff` for
311 311 related options for the diff command.
312 312
313 313 ``ignorews``
314 314 Ignore white space when comparing lines.
315 315
316 316 ``ignorewseol``
317 317 Ignore white space at the end of a line when comparing lines.
318 318
319 319 ``ignorewsamount``
320 320 Ignore changes in the amount of white space.
321 321
322 322 ``ignoreblanklines``
323 323 Ignore changes whose lines are all blank.
324 324
325 325
326 326 ``auth``
327 327 --------
328 328
329 329 Authentication credentials and other authentication-like configuration
330 330 for HTTP connections. This section allows you to store usernames and
331 331 passwords for use when logging *into* HTTP servers. See
332 332 :hg:`help config.web` if you want to configure *who* can login to
333 333 your HTTP server.
334 334
335 335 The following options apply to all hosts.
336 336
337 337 ``cookiefile``
338 338 Path to a file containing HTTP cookie lines. Cookies matching a
339 339 host will be sent automatically.
340 340
341 341 The file format uses the Mozilla cookies.txt format, which defines cookies
342 342 on their own lines. Each line contains 7 fields delimited by the tab
343 343 character (domain, is_domain_cookie, path, is_secure, expires, name,
344 344 value). For more info, do an Internet search for "Netscape cookies.txt
345 345 format."
346 346
347 347 Note: the cookies parser does not handle port numbers on domains. You
348 348 will need to remove ports from the domain for the cookie to be recognized.
349 349 This could result in a cookie being disclosed to an unwanted server.
350 350
351 351 The cookies file is read-only.
352 352
353 353 Other options in this section are grouped by name and have the following
354 354 format::
355 355
356 356 <name>.<argument> = <value>
357 357
358 358 where ``<name>`` is used to group arguments into authentication
359 359 entries. Example::
360 360
361 361 foo.prefix = hg.intevation.de/mercurial
362 362 foo.username = foo
363 363 foo.password = bar
364 364 foo.schemes = http https
365 365
366 366 bar.prefix = secure.example.org
367 367 bar.key = path/to/file.key
368 368 bar.cert = path/to/file.cert
369 369 bar.schemes = https
370 370
371 371 Supported arguments:
372 372
373 373 ``prefix``
374 374 Either ``*`` or a URI prefix with or without the scheme part.
375 375 The authentication entry with the longest matching prefix is used
376 376 (where ``*`` matches everything and counts as a match of length
377 377 1). If the prefix doesn't include a scheme, the match is performed
378 378 against the URI with its scheme stripped as well, and the schemes
379 379 argument, q.v., is then subsequently consulted.
380 380
381 381 ``username``
382 382 Optional. Username to authenticate with. If not given, and the
383 383 remote site requires basic or digest authentication, the user will
384 384 be prompted for it. Environment variables are expanded in the
385 385 username letting you do ``foo.username = $USER``. If the URI
386 386 includes a username, only ``[auth]`` entries with a matching
387 387 username or without a username will be considered.
388 388
389 389 ``password``
390 390 Optional. Password to authenticate with. If not given, and the
391 391 remote site requires basic or digest authentication, the user
392 392 will be prompted for it.
393 393
394 394 ``key``
395 395 Optional. PEM encoded client certificate key file. Environment
396 396 variables are expanded in the filename.
397 397
398 398 ``cert``
399 399 Optional. PEM encoded client certificate chain file. Environment
400 400 variables are expanded in the filename.
401 401
402 402 ``schemes``
403 403 Optional. Space separated list of URI schemes to use this
404 404 authentication entry with. Only used if the prefix doesn't include
405 405 a scheme. Supported schemes are http and https. They will match
406 406 static-http and static-https respectively, as well.
407 407 (default: https)
408 408
409 409 If no suitable authentication entry is found, the user is prompted
410 410 for credentials as usual if required by the remote.
411 411
412 412 ``color``
413 413 ---------
414 414
415 415 Configure the Mercurial color mode. For details about how to define your custom
416 416 effect and style see :hg:`help color`.
417 417
418 418 ``mode``
419 419 String: control the method used to output color. One of ``auto``, ``ansi``,
420 420 ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
421 421 use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
422 422 terminal. Any invalid value will disable color.
423 423
424 424 ``pagermode``
425 425 String: optional override of ``color.mode`` used with pager.
426 426
427 427 On some systems, terminfo mode may cause problems when using
428 428 color with ``less -R`` as a pager program. less with the -R option
429 429 will only display ECMA-48 color codes, and terminfo mode may sometimes
430 430 emit codes that less doesn't understand. You can work around this by
431 431 either using ansi mode (or auto mode), or by using less -r (which will
432 432 pass through all terminal control codes, not just color control
433 433 codes).
434 434
435 435 On some systems (such as MSYS in Windows), the terminal may support
436 436 a different color mode than the pager program.
437 437
438 438 ``commands``
439 439 ------------
440 440
441 ``commit.post-status``
442 Show status of files in the working directory after successful commit.
443 (default: False)
444
441 445 ``resolve.confirm``
442 446 Confirm before performing action if no filename is passed.
443 447 (default: False)
444 448
445 449 ``resolve.explicit-re-merge``
446 450 Require uses of ``hg resolve`` to specify which action it should perform,
447 451 instead of re-merging files by default.
448 452 (default: False)
449 453
450 454 ``resolve.mark-check``
451 455 Determines what level of checking :hg:`resolve --mark` will perform before
452 456 marking files as resolved. Valid values are ``none`, ``warn``, and
453 457 ``abort``. ``warn`` will output a warning listing the file(s) that still
454 458 have conflict markers in them, but will still mark everything resolved.
455 459 ``abort`` will output the same warning but will not mark things as resolved.
456 460 If --all is passed and this is set to ``abort``, only a warning will be
457 461 shown (an error will not be raised).
458 462 (default: ``none``)
459 463
460 464 ``status.relative``
461 465 Make paths in :hg:`status` output relative to the current directory.
462 466 (default: False)
463 467
464 468 ``status.terse``
465 469 Default value for the --terse flag, which condenses status output.
466 470 (default: empty)
467 471
468 472 ``update.check``
469 473 Determines what level of checking :hg:`update` will perform before moving
470 474 to a destination revision. Valid values are ``abort``, ``none``,
471 475 ``linear``, and ``noconflict``. ``abort`` always fails if the working
472 476 directory has uncommitted changes. ``none`` performs no checking, and may
473 477 result in a merge with uncommitted changes. ``linear`` allows any update
474 478 as long as it follows a straight line in the revision history, and may
475 479 trigger a merge with uncommitted changes. ``noconflict`` will allow any
476 480 update which would not trigger a merge with uncommitted changes, if any
477 481 are present.
478 482 (default: ``linear``)
479 483
480 484 ``update.requiredest``
481 485 Require that the user pass a destination when running :hg:`update`.
482 486 For example, :hg:`update .::` will be allowed, but a plain :hg:`update`
483 487 will be disallowed.
484 488 (default: False)
485 489
486 490 ``committemplate``
487 491 ------------------
488 492
489 493 ``changeset``
490 494 String: configuration in this section is used as the template to
491 495 customize the text shown in the editor when committing.
492 496
493 497 In addition to pre-defined template keywords, commit log specific one
494 498 below can be used for customization:
495 499
496 500 ``extramsg``
497 501 String: Extra message (typically 'Leave message empty to abort
498 502 commit.'). This may be changed by some commands or extensions.
499 503
500 504 For example, the template configuration below shows as same text as
501 505 one shown by default::
502 506
503 507 [committemplate]
504 508 changeset = {desc}\n\n
505 509 HG: Enter commit message. Lines beginning with 'HG:' are removed.
506 510 HG: {extramsg}
507 511 HG: --
508 512 HG: user: {author}\n{ifeq(p2rev, "-1", "",
509 513 "HG: branch merge\n")
510 514 }HG: branch '{branch}'\n{if(activebookmark,
511 515 "HG: bookmark '{activebookmark}'\n") }{subrepos %
512 516 "HG: subrepo {subrepo}\n" }{file_adds %
513 517 "HG: added {file}\n" }{file_mods %
514 518 "HG: changed {file}\n" }{file_dels %
515 519 "HG: removed {file}\n" }{if(files, "",
516 520 "HG: no files changed\n")}
517 521
518 522 ``diff()``
519 523 String: show the diff (see :hg:`help templates` for detail)
520 524
521 525 Sometimes it is helpful to show the diff of the changeset in the editor without
522 526 having to prefix 'HG: ' to each line so that highlighting works correctly. For
523 527 this, Mercurial provides a special string which will ignore everything below
524 528 it::
525 529
526 530 HG: ------------------------ >8 ------------------------
527 531
528 532 For example, the template configuration below will show the diff below the
529 533 extra message::
530 534
531 535 [committemplate]
532 536 changeset = {desc}\n\n
533 537 HG: Enter commit message. Lines beginning with 'HG:' are removed.
534 538 HG: {extramsg}
535 539 HG: ------------------------ >8 ------------------------
536 540 HG: Do not touch the line above.
537 541 HG: Everything below will be removed.
538 542 {diff()}
539 543
540 544 .. note::
541 545
542 546 For some problematic encodings (see :hg:`help win32mbcs` for
543 547 detail), this customization should be configured carefully, to
544 548 avoid showing broken characters.
545 549
546 550 For example, if a multibyte character ending with backslash (0x5c) is
547 551 followed by the ASCII character 'n' in the customized template,
548 552 the sequence of backslash and 'n' is treated as line-feed unexpectedly
549 553 (and the multibyte character is broken, too).
550 554
551 555 Customized template is used for commands below (``--edit`` may be
552 556 required):
553 557
554 558 - :hg:`backout`
555 559 - :hg:`commit`
556 560 - :hg:`fetch` (for merge commit only)
557 561 - :hg:`graft`
558 562 - :hg:`histedit`
559 563 - :hg:`import`
560 564 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
561 565 - :hg:`rebase`
562 566 - :hg:`shelve`
563 567 - :hg:`sign`
564 568 - :hg:`tag`
565 569 - :hg:`transplant`
566 570
567 571 Configuring items below instead of ``changeset`` allows showing
568 572 customized message only for specific actions, or showing different
569 573 messages for each action.
570 574
571 575 - ``changeset.backout`` for :hg:`backout`
572 576 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
573 577 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
574 578 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
575 579 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
576 580 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
577 581 - ``changeset.gpg.sign`` for :hg:`sign`
578 582 - ``changeset.graft`` for :hg:`graft`
579 583 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
580 584 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
581 585 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
582 586 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
583 587 - ``changeset.import.bypass`` for :hg:`import --bypass`
584 588 - ``changeset.import.normal.merge`` for :hg:`import` on merges
585 589 - ``changeset.import.normal.normal`` for :hg:`import` on other
586 590 - ``changeset.mq.qnew`` for :hg:`qnew`
587 591 - ``changeset.mq.qfold`` for :hg:`qfold`
588 592 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
589 593 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
590 594 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
591 595 - ``changeset.rebase.normal`` for :hg:`rebase` on other
592 596 - ``changeset.shelve.shelve`` for :hg:`shelve`
593 597 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
594 598 - ``changeset.tag.remove`` for :hg:`tag --remove`
595 599 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
596 600 - ``changeset.transplant.normal`` for :hg:`transplant` on other
597 601
598 602 These dot-separated lists of names are treated as hierarchical ones.
599 603 For example, ``changeset.tag.remove`` customizes the commit message
600 604 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
601 605 commit message for :hg:`tag` regardless of ``--remove`` option.
602 606
603 607 When the external editor is invoked for a commit, the corresponding
604 608 dot-separated list of names without the ``changeset.`` prefix
605 609 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
606 610 variable.
607 611
608 612 In this section, items other than ``changeset`` can be referred from
609 613 others. For example, the configuration to list committed files up
610 614 below can be referred as ``{listupfiles}``::
611 615
612 616 [committemplate]
613 617 listupfiles = {file_adds %
614 618 "HG: added {file}\n" }{file_mods %
615 619 "HG: changed {file}\n" }{file_dels %
616 620 "HG: removed {file}\n" }{if(files, "",
617 621 "HG: no files changed\n")}
618 622
619 623 ``decode/encode``
620 624 -----------------
621 625
622 626 Filters for transforming files on checkout/checkin. This would
623 627 typically be used for newline processing or other
624 628 localization/canonicalization of files.
625 629
626 630 Filters consist of a filter pattern followed by a filter command.
627 631 Filter patterns are globs by default, rooted at the repository root.
628 632 For example, to match any file ending in ``.txt`` in the root
629 633 directory only, use the pattern ``*.txt``. To match any file ending
630 634 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
631 635 For each file only the first matching filter applies.
632 636
633 637 The filter command can start with a specifier, either ``pipe:`` or
634 638 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
635 639
636 640 A ``pipe:`` command must accept data on stdin and return the transformed
637 641 data on stdout.
638 642
639 643 Pipe example::
640 644
641 645 [encode]
642 646 # uncompress gzip files on checkin to improve delta compression
643 647 # note: not necessarily a good idea, just an example
644 648 *.gz = pipe: gunzip
645 649
646 650 [decode]
647 651 # recompress gzip files when writing them to the working dir (we
648 652 # can safely omit "pipe:", because it's the default)
649 653 *.gz = gzip
650 654
651 655 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
652 656 with the name of a temporary file that contains the data to be
653 657 filtered by the command. The string ``OUTFILE`` is replaced with the name
654 658 of an empty temporary file, where the filtered data must be written by
655 659 the command.
656 660
657 661 .. container:: windows
658 662
659 663 .. note::
660 664
661 665 The tempfile mechanism is recommended for Windows systems,
662 666 where the standard shell I/O redirection operators often have
663 667 strange effects and may corrupt the contents of your files.
664 668
665 669 This filter mechanism is used internally by the ``eol`` extension to
666 670 translate line ending characters between Windows (CRLF) and Unix (LF)
667 671 format. We suggest you use the ``eol`` extension for convenience.
668 672
669 673
670 674 ``defaults``
671 675 ------------
672 676
673 677 (defaults are deprecated. Don't use them. Use aliases instead.)
674 678
675 679 Use the ``[defaults]`` section to define command defaults, i.e. the
676 680 default options/arguments to pass to the specified commands.
677 681
678 682 The following example makes :hg:`log` run in verbose mode, and
679 683 :hg:`status` show only the modified files, by default::
680 684
681 685 [defaults]
682 686 log = -v
683 687 status = -m
684 688
685 689 The actual commands, instead of their aliases, must be used when
686 690 defining command defaults. The command defaults will also be applied
687 691 to the aliases of the commands defined.
688 692
689 693
690 694 ``diff``
691 695 --------
692 696
693 697 Settings used when displaying diffs. Everything except for ``unified``
694 698 is a Boolean and defaults to False. See :hg:`help config.annotate`
695 699 for related options for the annotate command.
696 700
697 701 ``git``
698 702 Use git extended diff format.
699 703
700 704 ``nobinary``
701 705 Omit git binary patches.
702 706
703 707 ``nodates``
704 708 Don't include dates in diff headers.
705 709
706 710 ``noprefix``
707 711 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
708 712
709 713 ``showfunc``
710 714 Show which function each change is in.
711 715
712 716 ``ignorews``
713 717 Ignore white space when comparing lines.
714 718
715 719 ``ignorewsamount``
716 720 Ignore changes in the amount of white space.
717 721
718 722 ``ignoreblanklines``
719 723 Ignore changes whose lines are all blank.
720 724
721 725 ``unified``
722 726 Number of lines of context to show.
723 727
724 728 ``word-diff``
725 729 Highlight changed words.
726 730
727 731 ``email``
728 732 ---------
729 733
730 734 Settings for extensions that send email messages.
731 735
732 736 ``from``
733 737 Optional. Email address to use in "From" header and SMTP envelope
734 738 of outgoing messages.
735 739
736 740 ``to``
737 741 Optional. Comma-separated list of recipients' email addresses.
738 742
739 743 ``cc``
740 744 Optional. Comma-separated list of carbon copy recipients'
741 745 email addresses.
742 746
743 747 ``bcc``
744 748 Optional. Comma-separated list of blind carbon copy recipients'
745 749 email addresses.
746 750
747 751 ``method``
748 752 Optional. Method to use to send email messages. If value is ``smtp``
749 753 (default), use SMTP (see the ``[smtp]`` section for configuration).
750 754 Otherwise, use as name of program to run that acts like sendmail
751 755 (takes ``-f`` option for sender, list of recipients on command line,
752 756 message on stdin). Normally, setting this to ``sendmail`` or
753 757 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
754 758
755 759 ``charsets``
756 760 Optional. Comma-separated list of character sets considered
757 761 convenient for recipients. Addresses, headers, and parts not
758 762 containing patches of outgoing messages will be encoded in the
759 763 first character set to which conversion from local encoding
760 764 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
761 765 conversion fails, the text in question is sent as is.
762 766 (default: '')
763 767
764 768 Order of outgoing email character sets:
765 769
766 770 1. ``us-ascii``: always first, regardless of settings
767 771 2. ``email.charsets``: in order given by user
768 772 3. ``ui.fallbackencoding``: if not in email.charsets
769 773 4. ``$HGENCODING``: if not in email.charsets
770 774 5. ``utf-8``: always last, regardless of settings
771 775
772 776 Email example::
773 777
774 778 [email]
775 779 from = Joseph User <joe.user@example.com>
776 780 method = /usr/sbin/sendmail
777 781 # charsets for western Europeans
778 782 # us-ascii, utf-8 omitted, as they are tried first and last
779 783 charsets = iso-8859-1, iso-8859-15, windows-1252
780 784
781 785
782 786 ``extensions``
783 787 --------------
784 788
785 789 Mercurial has an extension mechanism for adding new features. To
786 790 enable an extension, create an entry for it in this section.
787 791
788 792 If you know that the extension is already in Python's search path,
789 793 you can give the name of the module, followed by ``=``, with nothing
790 794 after the ``=``.
791 795
792 796 Otherwise, give a name that you choose, followed by ``=``, followed by
793 797 the path to the ``.py`` file (including the file name extension) that
794 798 defines the extension.
795 799
796 800 To explicitly disable an extension that is enabled in an hgrc of
797 801 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
798 802 or ``foo = !`` when path is not supplied.
799 803
800 804 Example for ``~/.hgrc``::
801 805
802 806 [extensions]
803 807 # (the churn extension will get loaded from Mercurial's path)
804 808 churn =
805 809 # (this extension will get loaded from the file specified)
806 810 myfeature = ~/.hgext/myfeature.py
807 811
808 812
809 813 ``format``
810 814 ----------
811 815
812 816 Configuration that controls the repository format. Newer format options are more
813 817 powerful but incompatible with some older versions of Mercurial. Format options
814 818 are considered at repository initialization only. You need to make a new clone
815 819 for config change to be taken into account.
816 820
817 821 For more details about repository format and version compatibility, see
818 822 https://www.mercurial-scm.org/wiki/MissingRequirement
819 823
820 824 ``usegeneraldelta``
821 825 Enable or disable the "generaldelta" repository format which improves
822 826 repository compression by allowing "revlog" to store delta against arbitrary
823 827 revision instead of the previous stored one. This provides significant
824 828 improvement for repositories with branches.
825 829
826 830 Repositories with this on-disk format require Mercurial version 1.9.
827 831
828 832 Enabled by default.
829 833
830 834 ``dotencode``
831 835 Enable or disable the "dotencode" repository format which enhances
832 836 the "fncache" repository format (which has to be enabled to use
833 837 dotencode) to avoid issues with filenames starting with ._ on
834 838 Mac OS X and spaces on Windows.
835 839
836 840 Repositories with this on-disk format require Mercurial version 1.7.
837 841
838 842 Enabled by default.
839 843
840 844 ``usefncache``
841 845 Enable or disable the "fncache" repository format which enhances
842 846 the "store" repository format (which has to be enabled to use
843 847 fncache) to allow longer filenames and avoids using Windows
844 848 reserved names, e.g. "nul".
845 849
846 850 Repositories with this on-disk format require Mercurial version 1.1.
847 851
848 852 Enabled by default.
849 853
850 854 ``usestore``
851 855 Enable or disable the "store" repository format which improves
852 856 compatibility with systems that fold case or otherwise mangle
853 857 filenames. Disabling this option will allow you to store longer filenames
854 858 in some situations at the expense of compatibility.
855 859
856 860 Repositories with this on-disk format require Mercurial version 0.9.4.
857 861
858 862 Enabled by default.
859 863
860 864 ``sparse-revlog``
861 865 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
862 866 delta re-use inside revlog. For very branchy repositories, it results in a
863 867 smaller store. For repositories with many revisions, it also helps
864 868 performance (by using shortened delta chains.)
865 869
866 870 Repositories with this on-disk format require Mercurial version 4.7
867 871
868 872 Enabled by default.
869 873 ``revlog-compression``
870 874 Compression algorithm used by revlog. Supported value are `zlib` and `zstd`.
871 875 The `zlib` engine is the historical default of Mercurial. `zstd` is a newer
872 876 format that is usually a net win over `zlib` operating faster at better
873 877 compression rate. Use `zstd` to reduce CPU usage.
874 878
875 879 On some system, Mercurial installation may lack `zstd` supports. Default is `zlib`.
876 880
877 881 ``graph``
878 882 ---------
879 883
880 884 Web graph view configuration. This section let you change graph
881 885 elements display properties by branches, for instance to make the
882 886 ``default`` branch stand out.
883 887
884 888 Each line has the following format::
885 889
886 890 <branch>.<argument> = <value>
887 891
888 892 where ``<branch>`` is the name of the branch being
889 893 customized. Example::
890 894
891 895 [graph]
892 896 # 2px width
893 897 default.width = 2
894 898 # red color
895 899 default.color = FF0000
896 900
897 901 Supported arguments:
898 902
899 903 ``width``
900 904 Set branch edges width in pixels.
901 905
902 906 ``color``
903 907 Set branch edges color in hexadecimal RGB notation.
904 908
905 909 ``hooks``
906 910 ---------
907 911
908 912 Commands or Python functions that get automatically executed by
909 913 various actions such as starting or finishing a commit. Multiple
910 914 hooks can be run for the same action by appending a suffix to the
911 915 action. Overriding a site-wide hook can be done by changing its
912 916 value or setting it to an empty string. Hooks can be prioritized
913 917 by adding a prefix of ``priority.`` to the hook name on a new line
914 918 and setting the priority. The default priority is 0.
915 919
916 920 Example ``.hg/hgrc``::
917 921
918 922 [hooks]
919 923 # update working directory after adding changesets
920 924 changegroup.update = hg update
921 925 # do not use the site-wide hook
922 926 incoming =
923 927 incoming.email = /my/email/hook
924 928 incoming.autobuild = /my/build/hook
925 929 # force autobuild hook to run before other incoming hooks
926 930 priority.incoming.autobuild = 1
927 931
928 932 Most hooks are run with environment variables set that give useful
929 933 additional information. For each hook below, the environment variables
930 934 it is passed are listed with names in the form ``$HG_foo``. The
931 935 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
932 936 They contain the type of hook which triggered the run and the full name
933 937 of the hook in the config, respectively. In the example above, this will
934 938 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
935 939
936 940 .. container:: windows
937 941
938 942 Some basic Unix syntax can be enabled for portability, including ``$VAR``
939 943 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
940 944 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
941 945 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
942 946 slash or inside of a strong quote. Strong quotes will be replaced by
943 947 double quotes after processing.
944 948
945 949 This feature is enabled by adding a prefix of ``tonative.`` to the hook
946 950 name on a new line, and setting it to ``True``. For example::
947 951
948 952 [hooks]
949 953 incoming.autobuild = /my/build/hook
950 954 # enable translation to cmd.exe syntax for autobuild hook
951 955 tonative.incoming.autobuild = True
952 956
953 957 ``changegroup``
954 958 Run after a changegroup has been added via push, pull or unbundle. The ID of
955 959 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
956 960 The URL from which changes came is in ``$HG_URL``.
957 961
958 962 ``commit``
959 963 Run after a changeset has been created in the local repository. The ID
960 964 of the newly created changeset is in ``$HG_NODE``. Parent changeset
961 965 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
962 966
963 967 ``incoming``
964 968 Run after a changeset has been pulled, pushed, or unbundled into
965 969 the local repository. The ID of the newly arrived changeset is in
966 970 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
967 971
968 972 ``outgoing``
969 973 Run after sending changes from the local repository to another. The ID of
970 974 first changeset sent is in ``$HG_NODE``. The source of operation is in
971 975 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
972 976
973 977 ``post-<command>``
974 978 Run after successful invocations of the associated command. The
975 979 contents of the command line are passed as ``$HG_ARGS`` and the result
976 980 code in ``$HG_RESULT``. Parsed command line arguments are passed as
977 981 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
978 982 the python data internally passed to <command>. ``$HG_OPTS`` is a
979 983 dictionary of options (with unspecified options set to their defaults).
980 984 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
981 985
982 986 ``fail-<command>``
983 987 Run after a failed invocation of an associated command. The contents
984 988 of the command line are passed as ``$HG_ARGS``. Parsed command line
985 989 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
986 990 string representations of the python data internally passed to
987 991 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
988 992 options set to their defaults). ``$HG_PATS`` is a list of arguments.
989 993 Hook failure is ignored.
990 994
991 995 ``pre-<command>``
992 996 Run before executing the associated command. The contents of the
993 997 command line are passed as ``$HG_ARGS``. Parsed command line arguments
994 998 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
995 999 representations of the data internally passed to <command>. ``$HG_OPTS``
996 1000 is a dictionary of options (with unspecified options set to their
997 1001 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
998 1002 failure, the command doesn't execute and Mercurial returns the failure
999 1003 code.
1000 1004
1001 1005 ``prechangegroup``
1002 1006 Run before a changegroup is added via push, pull or unbundle. Exit
1003 1007 status 0 allows the changegroup to proceed. A non-zero status will
1004 1008 cause the push, pull or unbundle to fail. The URL from which changes
1005 1009 will come is in ``$HG_URL``.
1006 1010
1007 1011 ``precommit``
1008 1012 Run before starting a local commit. Exit status 0 allows the
1009 1013 commit to proceed. A non-zero status will cause the commit to fail.
1010 1014 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1011 1015
1012 1016 ``prelistkeys``
1013 1017 Run before listing pushkeys (like bookmarks) in the
1014 1018 repository. A non-zero status will cause failure. The key namespace is
1015 1019 in ``$HG_NAMESPACE``.
1016 1020
1017 1021 ``preoutgoing``
1018 1022 Run before collecting changes to send from the local repository to
1019 1023 another. A non-zero status will cause failure. This lets you prevent
1020 1024 pull over HTTP or SSH. It can also prevent propagating commits (via
1021 1025 local pull, push (outbound) or bundle commands), but not completely,
1022 1026 since you can just copy files instead. The source of operation is in
1023 1027 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1024 1028 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1025 1029 is happening on behalf of a repository on same system.
1026 1030
1027 1031 ``prepushkey``
1028 1032 Run before a pushkey (like a bookmark) is added to the
1029 1033 repository. A non-zero status will cause the key to be rejected. The
1030 1034 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1031 1035 the old value (if any) is in ``$HG_OLD``, and the new value is in
1032 1036 ``$HG_NEW``.
1033 1037
1034 1038 ``pretag``
1035 1039 Run before creating a tag. Exit status 0 allows the tag to be
1036 1040 created. A non-zero status will cause the tag to fail. The ID of the
1037 1041 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1038 1042 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1039 1043
1040 1044 ``pretxnopen``
1041 1045 Run before any new repository transaction is open. The reason for the
1042 1046 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1043 1047 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
1044 1048 transaction from being opened.
1045 1049
1046 1050 ``pretxnclose``
1047 1051 Run right before the transaction is actually finalized. Any repository change
1048 1052 will be visible to the hook program. This lets you validate the transaction
1049 1053 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1050 1054 status will cause the transaction to be rolled back. The reason for the
1051 1055 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1052 1056 the transaction will be in ``HG_TXNID``. The rest of the available data will
1053 1057 vary according the transaction type. New changesets will add ``$HG_NODE``
1054 1058 (the ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last
1055 1059 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1056 1060 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1057 1061 respectively, etc.
1058 1062
1059 1063 ``pretxnclose-bookmark``
1060 1064 Run right before a bookmark change is actually finalized. Any repository
1061 1065 change will be visible to the hook program. This lets you validate the
1062 1066 transaction content or change it. Exit status 0 allows the commit to
1063 1067 proceed. A non-zero status will cause the transaction to be rolled back.
1064 1068 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1065 1069 bookmark location will be available in ``$HG_NODE`` while the previous
1066 1070 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1067 1071 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1068 1072 will be empty.
1069 1073 In addition, the reason for the transaction opening will be in
1070 1074 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1071 1075 ``HG_TXNID``.
1072 1076
1073 1077 ``pretxnclose-phase``
1074 1078 Run right before a phase change is actually finalized. Any repository change
1075 1079 will be visible to the hook program. This lets you validate the transaction
1076 1080 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1077 1081 status will cause the transaction to be rolled back. The hook is called
1078 1082 multiple times, once for each revision affected by a phase change.
1079 1083 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1080 1084 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1081 1085 will be empty. In addition, the reason for the transaction opening will be in
1082 1086 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1083 1087 ``HG_TXNID``. The hook is also run for newly added revisions. In this case
1084 1088 the ``$HG_OLDPHASE`` entry will be empty.
1085 1089
1086 1090 ``txnclose``
1087 1091 Run after any repository transaction has been committed. At this
1088 1092 point, the transaction can no longer be rolled back. The hook will run
1089 1093 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1090 1094 details about available variables.
1091 1095
1092 1096 ``txnclose-bookmark``
1093 1097 Run after any bookmark change has been committed. At this point, the
1094 1098 transaction can no longer be rolled back. The hook will run after the lock
1095 1099 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1096 1100 about available variables.
1097 1101
1098 1102 ``txnclose-phase``
1099 1103 Run after any phase change has been committed. At this point, the
1100 1104 transaction can no longer be rolled back. The hook will run after the lock
1101 1105 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1102 1106 available variables.
1103 1107
1104 1108 ``txnabort``
1105 1109 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1106 1110 for details about available variables.
1107 1111
1108 1112 ``pretxnchangegroup``
1109 1113 Run after a changegroup has been added via push, pull or unbundle, but before
1110 1114 the transaction has been committed. The changegroup is visible to the hook
1111 1115 program. This allows validation of incoming changes before accepting them.
1112 1116 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1113 1117 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1114 1118 status will cause the transaction to be rolled back, and the push, pull or
1115 1119 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1116 1120
1117 1121 ``pretxncommit``
1118 1122 Run after a changeset has been created, but before the transaction is
1119 1123 committed. The changeset is visible to the hook program. This allows
1120 1124 validation of the commit message and changes. Exit status 0 allows the
1121 1125 commit to proceed. A non-zero status will cause the transaction to
1122 1126 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1123 1127 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1124 1128
1125 1129 ``preupdate``
1126 1130 Run before updating the working directory. Exit status 0 allows
1127 1131 the update to proceed. A non-zero status will prevent the update.
1128 1132 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1129 1133 merge, the ID of second new parent is in ``$HG_PARENT2``.
1130 1134
1131 1135 ``listkeys``
1132 1136 Run after listing pushkeys (like bookmarks) in the repository. The
1133 1137 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1134 1138 dictionary containing the keys and values.
1135 1139
1136 1140 ``pushkey``
1137 1141 Run after a pushkey (like a bookmark) is added to the
1138 1142 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1139 1143 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1140 1144 value is in ``$HG_NEW``.
1141 1145
1142 1146 ``tag``
1143 1147 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1144 1148 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1145 1149 the repository if ``$HG_LOCAL=0``.
1146 1150
1147 1151 ``update``
1148 1152 Run after updating the working directory. The changeset ID of first
1149 1153 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1150 1154 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1151 1155 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1152 1156
1153 1157 .. note::
1154 1158
1155 1159 It is generally better to use standard hooks rather than the
1156 1160 generic pre- and post- command hooks, as they are guaranteed to be
1157 1161 called in the appropriate contexts for influencing transactions.
1158 1162 Also, hooks like "commit" will be called in all contexts that
1159 1163 generate a commit (e.g. tag) and not just the commit command.
1160 1164
1161 1165 .. note::
1162 1166
1163 1167 Environment variables with empty values may not be passed to
1164 1168 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1165 1169 will have an empty value under Unix-like platforms for non-merge
1166 1170 changesets, while it will not be available at all under Windows.
1167 1171
1168 1172 The syntax for Python hooks is as follows::
1169 1173
1170 1174 hookname = python:modulename.submodule.callable
1171 1175 hookname = python:/path/to/python/module.py:callable
1172 1176
1173 1177 Python hooks are run within the Mercurial process. Each hook is
1174 1178 called with at least three keyword arguments: a ui object (keyword
1175 1179 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1176 1180 keyword that tells what kind of hook is used. Arguments listed as
1177 1181 environment variables above are passed as keyword arguments, with no
1178 1182 ``HG_`` prefix, and names in lower case.
1179 1183
1180 1184 If a Python hook returns a "true" value or raises an exception, this
1181 1185 is treated as a failure.
1182 1186
1183 1187
1184 1188 ``hostfingerprints``
1185 1189 --------------------
1186 1190
1187 1191 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1188 1192
1189 1193 Fingerprints of the certificates of known HTTPS servers.
1190 1194
1191 1195 A HTTPS connection to a server with a fingerprint configured here will
1192 1196 only succeed if the servers certificate matches the fingerprint.
1193 1197 This is very similar to how ssh known hosts works.
1194 1198
1195 1199 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1196 1200 Multiple values can be specified (separated by spaces or commas). This can
1197 1201 be used to define both old and new fingerprints while a host transitions
1198 1202 to a new certificate.
1199 1203
1200 1204 The CA chain and web.cacerts is not used for servers with a fingerprint.
1201 1205
1202 1206 For example::
1203 1207
1204 1208 [hostfingerprints]
1205 1209 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1206 1210 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1207 1211
1208 1212 ``hostsecurity``
1209 1213 ----------------
1210 1214
1211 1215 Used to specify global and per-host security settings for connecting to
1212 1216 other machines.
1213 1217
1214 1218 The following options control default behavior for all hosts.
1215 1219
1216 1220 ``ciphers``
1217 1221 Defines the cryptographic ciphers to use for connections.
1218 1222
1219 1223 Value must be a valid OpenSSL Cipher List Format as documented at
1220 1224 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1221 1225
1222 1226 This setting is for advanced users only. Setting to incorrect values
1223 1227 can significantly lower connection security or decrease performance.
1224 1228 You have been warned.
1225 1229
1226 1230 This option requires Python 2.7.
1227 1231
1228 1232 ``minimumprotocol``
1229 1233 Defines the minimum channel encryption protocol to use.
1230 1234
1231 1235 By default, the highest version of TLS supported by both client and server
1232 1236 is used.
1233 1237
1234 1238 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1235 1239
1236 1240 When running on an old Python version, only ``tls1.0`` is allowed since
1237 1241 old versions of Python only support up to TLS 1.0.
1238 1242
1239 1243 When running a Python that supports modern TLS versions, the default is
1240 1244 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1241 1245 weakens security and should only be used as a feature of last resort if
1242 1246 a server does not support TLS 1.1+.
1243 1247
1244 1248 Options in the ``[hostsecurity]`` section can have the form
1245 1249 ``hostname``:``setting``. This allows multiple settings to be defined on a
1246 1250 per-host basis.
1247 1251
1248 1252 The following per-host settings can be defined.
1249 1253
1250 1254 ``ciphers``
1251 1255 This behaves like ``ciphers`` as described above except it only applies
1252 1256 to the host on which it is defined.
1253 1257
1254 1258 ``fingerprints``
1255 1259 A list of hashes of the DER encoded peer/remote certificate. Values have
1256 1260 the form ``algorithm``:``fingerprint``. e.g.
1257 1261 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1258 1262 In addition, colons (``:``) can appear in the fingerprint part.
1259 1263
1260 1264 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1261 1265 ``sha512``.
1262 1266
1263 1267 Use of ``sha256`` or ``sha512`` is preferred.
1264 1268
1265 1269 If a fingerprint is specified, the CA chain is not validated for this
1266 1270 host and Mercurial will require the remote certificate to match one
1267 1271 of the fingerprints specified. This means if the server updates its
1268 1272 certificate, Mercurial will abort until a new fingerprint is defined.
1269 1273 This can provide stronger security than traditional CA-based validation
1270 1274 at the expense of convenience.
1271 1275
1272 1276 This option takes precedence over ``verifycertsfile``.
1273 1277
1274 1278 ``minimumprotocol``
1275 1279 This behaves like ``minimumprotocol`` as described above except it
1276 1280 only applies to the host on which it is defined.
1277 1281
1278 1282 ``verifycertsfile``
1279 1283 Path to file a containing a list of PEM encoded certificates used to
1280 1284 verify the server certificate. Environment variables and ``~user``
1281 1285 constructs are expanded in the filename.
1282 1286
1283 1287 The server certificate or the certificate's certificate authority (CA)
1284 1288 must match a certificate from this file or certificate verification
1285 1289 will fail and connections to the server will be refused.
1286 1290
1287 1291 If defined, only certificates provided by this file will be used:
1288 1292 ``web.cacerts`` and any system/default certificates will not be
1289 1293 used.
1290 1294
1291 1295 This option has no effect if the per-host ``fingerprints`` option
1292 1296 is set.
1293 1297
1294 1298 The format of the file is as follows::
1295 1299
1296 1300 -----BEGIN CERTIFICATE-----
1297 1301 ... (certificate in base64 PEM encoding) ...
1298 1302 -----END CERTIFICATE-----
1299 1303 -----BEGIN CERTIFICATE-----
1300 1304 ... (certificate in base64 PEM encoding) ...
1301 1305 -----END CERTIFICATE-----
1302 1306
1303 1307 For example::
1304 1308
1305 1309 [hostsecurity]
1306 1310 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1307 1311 hg2.example.com:fingerprints = sha1:914f1aff87249c09b6859b88b1906d30756491ca, sha1:fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1308 1312 hg3.example.com:fingerprints = sha256:9a:b0:dc:e2:75:ad:8a:b7:84:58:e5:1f:07:32:f1:87:e6:bd:24:22:af:b7:ce:8e:9c:b4:10:cf:b9:f4:0e:d2
1309 1313 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1310 1314
1311 1315 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1312 1316 when connecting to ``hg.example.com``::
1313 1317
1314 1318 [hostsecurity]
1315 1319 minimumprotocol = tls1.2
1316 1320 hg.example.com:minimumprotocol = tls1.1
1317 1321
1318 1322 ``http_proxy``
1319 1323 --------------
1320 1324
1321 1325 Used to access web-based Mercurial repositories through a HTTP
1322 1326 proxy.
1323 1327
1324 1328 ``host``
1325 1329 Host name and (optional) port of the proxy server, for example
1326 1330 "myproxy:8000".
1327 1331
1328 1332 ``no``
1329 1333 Optional. Comma-separated list of host names that should bypass
1330 1334 the proxy.
1331 1335
1332 1336 ``passwd``
1333 1337 Optional. Password to authenticate with at the proxy server.
1334 1338
1335 1339 ``user``
1336 1340 Optional. User name to authenticate with at the proxy server.
1337 1341
1338 1342 ``always``
1339 1343 Optional. Always use the proxy, even for localhost and any entries
1340 1344 in ``http_proxy.no``. (default: False)
1341 1345
1342 1346 ``http``
1343 1347 ----------
1344 1348
1345 1349 Used to configure access to Mercurial repositories via HTTP.
1346 1350
1347 1351 ``timeout``
1348 1352 If set, blocking operations will timeout after that many seconds.
1349 1353 (default: None)
1350 1354
1351 1355 ``merge``
1352 1356 ---------
1353 1357
1354 1358 This section specifies behavior during merges and updates.
1355 1359
1356 1360 ``checkignored``
1357 1361 Controls behavior when an ignored file on disk has the same name as a tracked
1358 1362 file in the changeset being merged or updated to, and has different
1359 1363 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1360 1364 abort on such files. With ``warn``, warn on such files and back them up as
1361 1365 ``.orig``. With ``ignore``, don't print a warning and back them up as
1362 1366 ``.orig``. (default: ``abort``)
1363 1367
1364 1368 ``checkunknown``
1365 1369 Controls behavior when an unknown file that isn't ignored has the same name
1366 1370 as a tracked file in the changeset being merged or updated to, and has
1367 1371 different contents. Similar to ``merge.checkignored``, except for files that
1368 1372 are not ignored. (default: ``abort``)
1369 1373
1370 1374 ``on-failure``
1371 1375 When set to ``continue`` (the default), the merge process attempts to
1372 1376 merge all unresolved files using the merge chosen tool, regardless of
1373 1377 whether previous file merge attempts during the process succeeded or not.
1374 1378 Setting this to ``prompt`` will prompt after any merge failure continue
1375 1379 or halt the merge process. Setting this to ``halt`` will automatically
1376 1380 halt the merge process on any merge tool failure. The merge process
1377 1381 can be restarted by using the ``resolve`` command. When a merge is
1378 1382 halted, the repository is left in a normal ``unresolved`` merge state.
1379 1383 (default: ``continue``)
1380 1384
1381 1385 ``strict-capability-check``
1382 1386 Whether capabilities of internal merge tools are checked strictly
1383 1387 or not, while examining rules to decide merge tool to be used.
1384 1388 (default: False)
1385 1389
1386 1390 ``merge-patterns``
1387 1391 ------------------
1388 1392
1389 1393 This section specifies merge tools to associate with particular file
1390 1394 patterns. Tools matched here will take precedence over the default
1391 1395 merge tool. Patterns are globs by default, rooted at the repository
1392 1396 root.
1393 1397
1394 1398 Example::
1395 1399
1396 1400 [merge-patterns]
1397 1401 **.c = kdiff3
1398 1402 **.jpg = myimgmerge
1399 1403
1400 1404 ``merge-tools``
1401 1405 ---------------
1402 1406
1403 1407 This section configures external merge tools to use for file-level
1404 1408 merges. This section has likely been preconfigured at install time.
1405 1409 Use :hg:`config merge-tools` to check the existing configuration.
1406 1410 Also see :hg:`help merge-tools` for more details.
1407 1411
1408 1412 Example ``~/.hgrc``::
1409 1413
1410 1414 [merge-tools]
1411 1415 # Override stock tool location
1412 1416 kdiff3.executable = ~/bin/kdiff3
1413 1417 # Specify command line
1414 1418 kdiff3.args = $base $local $other -o $output
1415 1419 # Give higher priority
1416 1420 kdiff3.priority = 1
1417 1421
1418 1422 # Changing the priority of preconfigured tool
1419 1423 meld.priority = 0
1420 1424
1421 1425 # Disable a preconfigured tool
1422 1426 vimdiff.disabled = yes
1423 1427
1424 1428 # Define new tool
1425 1429 myHtmlTool.args = -m $local $other $base $output
1426 1430 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1427 1431 myHtmlTool.priority = 1
1428 1432
1429 1433 Supported arguments:
1430 1434
1431 1435 ``priority``
1432 1436 The priority in which to evaluate this tool.
1433 1437 (default: 0)
1434 1438
1435 1439 ``executable``
1436 1440 Either just the name of the executable or its pathname.
1437 1441
1438 1442 .. container:: windows
1439 1443
1440 1444 On Windows, the path can use environment variables with ${ProgramFiles}
1441 1445 syntax.
1442 1446
1443 1447 (default: the tool name)
1444 1448
1445 1449 ``args``
1446 1450 The arguments to pass to the tool executable. You can refer to the
1447 1451 files being merged as well as the output file through these
1448 1452 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1449 1453
1450 1454 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1451 1455 being performed. During an update or merge, ``$local`` represents the original
1452 1456 state of the file, while ``$other`` represents the commit you are updating to or
1453 1457 the commit you are merging with. During a rebase, ``$local`` represents the
1454 1458 destination of the rebase, and ``$other`` represents the commit being rebased.
1455 1459
1456 1460 Some operations define custom labels to assist with identifying the revisions,
1457 1461 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1458 1462 labels are not available, these will be ``local``, ``other``, and ``base``,
1459 1463 respectively.
1460 1464 (default: ``$local $base $other``)
1461 1465
1462 1466 ``premerge``
1463 1467 Attempt to run internal non-interactive 3-way merge tool before
1464 1468 launching external tool. Options are ``true``, ``false``, ``keep`` or
1465 1469 ``keep-merge3``. The ``keep`` option will leave markers in the file if the
1466 1470 premerge fails. The ``keep-merge3`` will do the same but include information
1467 1471 about the base of the merge in the marker (see internal :merge3 in
1468 1472 :hg:`help merge-tools`).
1469 1473 (default: True)
1470 1474
1471 1475 ``binary``
1472 1476 This tool can merge binary files. (default: False, unless tool
1473 1477 was selected by file pattern match)
1474 1478
1475 1479 ``symlink``
1476 1480 This tool can merge symlinks. (default: False)
1477 1481
1478 1482 ``check``
1479 1483 A list of merge success-checking options:
1480 1484
1481 1485 ``changed``
1482 1486 Ask whether merge was successful when the merged file shows no changes.
1483 1487 ``conflicts``
1484 1488 Check whether there are conflicts even though the tool reported success.
1485 1489 ``prompt``
1486 1490 Always prompt for merge success, regardless of success reported by tool.
1487 1491
1488 1492 ``fixeol``
1489 1493 Attempt to fix up EOL changes caused by the merge tool.
1490 1494 (default: False)
1491 1495
1492 1496 ``gui``
1493 1497 This tool requires a graphical interface to run. (default: False)
1494 1498
1495 1499 ``mergemarkers``
1496 1500 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1497 1501 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1498 1502 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1499 1503 markers generated during premerge will be ``detailed`` if either this option or
1500 1504 the corresponding option in the ``[ui]`` section is ``detailed``.
1501 1505 (default: ``basic``)
1502 1506
1503 1507 ``mergemarkertemplate``
1504 1508 This setting can be used to override ``mergemarkertemplate`` from the ``[ui]``
1505 1509 section on a per-tool basis; this applies to the ``$label``-prefixed variables
1506 1510 and to the conflict markers that are generated if ``premerge`` is ``keep` or
1507 1511 ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
1508 1512 information.
1509 1513
1510 1514 .. container:: windows
1511 1515
1512 1516 ``regkey``
1513 1517 Windows registry key which describes install location of this
1514 1518 tool. Mercurial will search for this key first under
1515 1519 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1516 1520 (default: None)
1517 1521
1518 1522 ``regkeyalt``
1519 1523 An alternate Windows registry key to try if the first key is not
1520 1524 found. The alternate key uses the same ``regname`` and ``regappend``
1521 1525 semantics of the primary key. The most common use for this key
1522 1526 is to search for 32bit applications on 64bit operating systems.
1523 1527 (default: None)
1524 1528
1525 1529 ``regname``
1526 1530 Name of value to read from specified registry key.
1527 1531 (default: the unnamed (default) value)
1528 1532
1529 1533 ``regappend``
1530 1534 String to append to the value read from the registry, typically
1531 1535 the executable name of the tool.
1532 1536 (default: None)
1533 1537
1534 1538 ``pager``
1535 1539 ---------
1536 1540
1537 1541 Setting used to control when to paginate and with what external tool. See
1538 1542 :hg:`help pager` for details.
1539 1543
1540 1544 ``pager``
1541 1545 Define the external tool used as pager.
1542 1546
1543 1547 If no pager is set, Mercurial uses the environment variable $PAGER.
1544 1548 If neither pager.pager, nor $PAGER is set, a default pager will be
1545 1549 used, typically `less` on Unix and `more` on Windows. Example::
1546 1550
1547 1551 [pager]
1548 1552 pager = less -FRX
1549 1553
1550 1554 ``ignore``
1551 1555 List of commands to disable the pager for. Example::
1552 1556
1553 1557 [pager]
1554 1558 ignore = version, help, update
1555 1559
1556 1560 ``patch``
1557 1561 ---------
1558 1562
1559 1563 Settings used when applying patches, for instance through the 'import'
1560 1564 command or with Mercurial Queues extension.
1561 1565
1562 1566 ``eol``
1563 1567 When set to 'strict' patch content and patched files end of lines
1564 1568 are preserved. When set to ``lf`` or ``crlf``, both files end of
1565 1569 lines are ignored when patching and the result line endings are
1566 1570 normalized to either LF (Unix) or CRLF (Windows). When set to
1567 1571 ``auto``, end of lines are again ignored while patching but line
1568 1572 endings in patched files are normalized to their original setting
1569 1573 on a per-file basis. If target file does not exist or has no end
1570 1574 of line, patch line endings are preserved.
1571 1575 (default: strict)
1572 1576
1573 1577 ``fuzz``
1574 1578 The number of lines of 'fuzz' to allow when applying patches. This
1575 1579 controls how much context the patcher is allowed to ignore when
1576 1580 trying to apply a patch.
1577 1581 (default: 2)
1578 1582
1579 1583 ``paths``
1580 1584 ---------
1581 1585
1582 1586 Assigns symbolic names and behavior to repositories.
1583 1587
1584 1588 Options are symbolic names defining the URL or directory that is the
1585 1589 location of the repository. Example::
1586 1590
1587 1591 [paths]
1588 1592 my_server = https://example.com/my_repo
1589 1593 local_path = /home/me/repo
1590 1594
1591 1595 These symbolic names can be used from the command line. To pull
1592 1596 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1593 1597 :hg:`push local_path`.
1594 1598
1595 1599 Options containing colons (``:``) denote sub-options that can influence
1596 1600 behavior for that specific path. Example::
1597 1601
1598 1602 [paths]
1599 1603 my_server = https://example.com/my_path
1600 1604 my_server:pushurl = ssh://example.com/my_path
1601 1605
1602 1606 The following sub-options can be defined:
1603 1607
1604 1608 ``pushurl``
1605 1609 The URL to use for push operations. If not defined, the location
1606 1610 defined by the path's main entry is used.
1607 1611
1608 1612 ``pushrev``
1609 1613 A revset defining which revisions to push by default.
1610 1614
1611 1615 When :hg:`push` is executed without a ``-r`` argument, the revset
1612 1616 defined by this sub-option is evaluated to determine what to push.
1613 1617
1614 1618 For example, a value of ``.`` will push the working directory's
1615 1619 revision by default.
1616 1620
1617 1621 Revsets specifying bookmarks will not result in the bookmark being
1618 1622 pushed.
1619 1623
1620 1624 The following special named paths exist:
1621 1625
1622 1626 ``default``
1623 1627 The URL or directory to use when no source or remote is specified.
1624 1628
1625 1629 :hg:`clone` will automatically define this path to the location the
1626 1630 repository was cloned from.
1627 1631
1628 1632 ``default-push``
1629 1633 (deprecated) The URL or directory for the default :hg:`push` location.
1630 1634 ``default:pushurl`` should be used instead.
1631 1635
1632 1636 ``phases``
1633 1637 ----------
1634 1638
1635 1639 Specifies default handling of phases. See :hg:`help phases` for more
1636 1640 information about working with phases.
1637 1641
1638 1642 ``publish``
1639 1643 Controls draft phase behavior when working as a server. When true,
1640 1644 pushed changesets are set to public in both client and server and
1641 1645 pulled or cloned changesets are set to public in the client.
1642 1646 (default: True)
1643 1647
1644 1648 ``new-commit``
1645 1649 Phase of newly-created commits.
1646 1650 (default: draft)
1647 1651
1648 1652 ``checksubrepos``
1649 1653 Check the phase of the current revision of each subrepository. Allowed
1650 1654 values are "ignore", "follow" and "abort". For settings other than
1651 1655 "ignore", the phase of the current revision of each subrepository is
1652 1656 checked before committing the parent repository. If any of those phases is
1653 1657 greater than the phase of the parent repository (e.g. if a subrepo is in a
1654 1658 "secret" phase while the parent repo is in "draft" phase), the commit is
1655 1659 either aborted (if checksubrepos is set to "abort") or the higher phase is
1656 1660 used for the parent repository commit (if set to "follow").
1657 1661 (default: follow)
1658 1662
1659 1663
1660 1664 ``profiling``
1661 1665 -------------
1662 1666
1663 1667 Specifies profiling type, format, and file output. Two profilers are
1664 1668 supported: an instrumenting profiler (named ``ls``), and a sampling
1665 1669 profiler (named ``stat``).
1666 1670
1667 1671 In this section description, 'profiling data' stands for the raw data
1668 1672 collected during profiling, while 'profiling report' stands for a
1669 1673 statistical text report generated from the profiling data.
1670 1674
1671 1675 ``enabled``
1672 1676 Enable the profiler.
1673 1677 (default: false)
1674 1678
1675 1679 This is equivalent to passing ``--profile`` on the command line.
1676 1680
1677 1681 ``type``
1678 1682 The type of profiler to use.
1679 1683 (default: stat)
1680 1684
1681 1685 ``ls``
1682 1686 Use Python's built-in instrumenting profiler. This profiler
1683 1687 works on all platforms, but each line number it reports is the
1684 1688 first line of a function. This restriction makes it difficult to
1685 1689 identify the expensive parts of a non-trivial function.
1686 1690 ``stat``
1687 1691 Use a statistical profiler, statprof. This profiler is most
1688 1692 useful for profiling commands that run for longer than about 0.1
1689 1693 seconds.
1690 1694
1691 1695 ``format``
1692 1696 Profiling format. Specific to the ``ls`` instrumenting profiler.
1693 1697 (default: text)
1694 1698
1695 1699 ``text``
1696 1700 Generate a profiling report. When saving to a file, it should be
1697 1701 noted that only the report is saved, and the profiling data is
1698 1702 not kept.
1699 1703 ``kcachegrind``
1700 1704 Format profiling data for kcachegrind use: when saving to a
1701 1705 file, the generated file can directly be loaded into
1702 1706 kcachegrind.
1703 1707
1704 1708 ``statformat``
1705 1709 Profiling format for the ``stat`` profiler.
1706 1710 (default: hotpath)
1707 1711
1708 1712 ``hotpath``
1709 1713 Show a tree-based display containing the hot path of execution (where
1710 1714 most time was spent).
1711 1715 ``bymethod``
1712 1716 Show a table of methods ordered by how frequently they are active.
1713 1717 ``byline``
1714 1718 Show a table of lines in files ordered by how frequently they are active.
1715 1719 ``json``
1716 1720 Render profiling data as JSON.
1717 1721
1718 1722 ``frequency``
1719 1723 Sampling frequency. Specific to the ``stat`` sampling profiler.
1720 1724 (default: 1000)
1721 1725
1722 1726 ``output``
1723 1727 File path where profiling data or report should be saved. If the
1724 1728 file exists, it is replaced. (default: None, data is printed on
1725 1729 stderr)
1726 1730
1727 1731 ``sort``
1728 1732 Sort field. Specific to the ``ls`` instrumenting profiler.
1729 1733 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1730 1734 ``inlinetime``.
1731 1735 (default: inlinetime)
1732 1736
1733 1737 ``time-track``
1734 1738 Control if the stat profiler track ``cpu`` or ``real`` time.
1735 1739 (default: ``cpu`` on Windows, otherwise ``real``)
1736 1740
1737 1741 ``limit``
1738 1742 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1739 1743 (default: 30)
1740 1744
1741 1745 ``nested``
1742 1746 Show at most this number of lines of drill-down info after each main entry.
1743 1747 This can help explain the difference between Total and Inline.
1744 1748 Specific to the ``ls`` instrumenting profiler.
1745 1749 (default: 0)
1746 1750
1747 1751 ``showmin``
1748 1752 Minimum fraction of samples an entry must have for it to be displayed.
1749 1753 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
1750 1754 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1751 1755
1752 1756 Only used by the ``stat`` profiler.
1753 1757
1754 1758 For the ``hotpath`` format, default is ``0.05``.
1755 1759 For the ``chrome`` format, default is ``0.005``.
1756 1760
1757 1761 The option is unused on other formats.
1758 1762
1759 1763 ``showmax``
1760 1764 Maximum fraction of samples an entry can have before it is ignored in
1761 1765 display. Values format is the same as ``showmin``.
1762 1766
1763 1767 Only used by the ``stat`` profiler.
1764 1768
1765 1769 For the ``chrome`` format, default is ``0.999``.
1766 1770
1767 1771 The option is unused on other formats.
1768 1772
1769 1773 ``progress``
1770 1774 ------------
1771 1775
1772 1776 Mercurial commands can draw progress bars that are as informative as
1773 1777 possible. Some progress bars only offer indeterminate information, while others
1774 1778 have a definite end point.
1775 1779
1776 1780 ``debug``
1777 1781 Whether to print debug info when updating the progress bar. (default: False)
1778 1782
1779 1783 ``delay``
1780 1784 Number of seconds (float) before showing the progress bar. (default: 3)
1781 1785
1782 1786 ``changedelay``
1783 1787 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1784 1788 that value will be used instead. (default: 1)
1785 1789
1786 1790 ``estimateinterval``
1787 1791 Maximum sampling interval in seconds for speed and estimated time
1788 1792 calculation. (default: 60)
1789 1793
1790 1794 ``refresh``
1791 1795 Time in seconds between refreshes of the progress bar. (default: 0.1)
1792 1796
1793 1797 ``format``
1794 1798 Format of the progress bar.
1795 1799
1796 1800 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1797 1801 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1798 1802 last 20 characters of the item, but this can be changed by adding either
1799 1803 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1800 1804 first num characters.
1801 1805
1802 1806 (default: topic bar number estimate)
1803 1807
1804 1808 ``width``
1805 1809 If set, the maximum width of the progress information (that is, min(width,
1806 1810 term width) will be used).
1807 1811
1808 1812 ``clear-complete``
1809 1813 Clear the progress bar after it's done. (default: True)
1810 1814
1811 1815 ``disable``
1812 1816 If true, don't show a progress bar.
1813 1817
1814 1818 ``assume-tty``
1815 1819 If true, ALWAYS show a progress bar, unless disable is given.
1816 1820
1817 1821 ``rebase``
1818 1822 ----------
1819 1823
1820 1824 ``evolution.allowdivergence``
1821 1825 Default to False, when True allow creating divergence when performing
1822 1826 rebase of obsolete changesets.
1823 1827
1824 1828 ``revsetalias``
1825 1829 ---------------
1826 1830
1827 1831 Alias definitions for revsets. See :hg:`help revsets` for details.
1828 1832
1829 1833 ``rewrite``
1830 1834 -----------
1831 1835
1832 1836 ``backup-bundle``
1833 1837 Whether to save stripped changesets to a bundle file. (default: True)
1834 1838
1835 1839 ``update-timestamp``
1836 1840 If true, updates the date and time of the changeset to current. It is only
1837 1841 applicable for hg amend in current version.
1838 1842
1839 1843 ``storage``
1840 1844 -----------
1841 1845
1842 1846 Control the strategy Mercurial uses internally to store history. Options in this
1843 1847 category impact performance and repository size.
1844 1848
1845 1849 ``revlog.optimize-delta-parent-choice``
1846 1850 When storing a merge revision, both parents will be equally considered as
1847 1851 a possible delta base. This results in better delta selection and improved
1848 1852 revlog compression. This option is enabled by default.
1849 1853
1850 1854 Turning this option off can result in large increase of repository size for
1851 1855 repository with many merges.
1852 1856
1853 1857 ``revlog.reuse-external-delta-parent``
1854 1858 Control the order in which delta parents are considered when adding new
1855 1859 revisions from an external source.
1856 1860 (typically: apply bundle from `hg pull` or `hg push`).
1857 1861
1858 1862 New revisions are usually provided as a delta against other revisions. By
1859 1863 default, Mercurial will try to reuse this delta first, therefore using the
1860 1864 same "delta parent" as the source. Directly using delta's from the source
1861 1865 reduces CPU usage and usually speeds up operation. However, in some case,
1862 1866 the source might have sub-optimal delta bases and forcing their reevaluation
1863 1867 is useful. For example, pushes from an old client could have sub-optimal
1864 1868 delta's parent that the server want to optimize. (lack of general delta, bad
1865 1869 parents, choice, lack of sparse-revlog, etc).
1866 1870
1867 1871 This option is enabled by default. Turning it off will ensure bad delta
1868 1872 parent choices from older client do not propagate to this repository, at
1869 1873 the cost of a small increase in CPU consumption.
1870 1874
1871 1875 Note: this option only control the order in which delta parents are
1872 1876 considered. Even when disabled, the existing delta from the source will be
1873 1877 reused if the same delta parent is selected.
1874 1878
1875 1879 ``revlog.reuse-external-delta``
1876 1880 Control the reuse of delta from external source.
1877 1881 (typically: apply bundle from `hg pull` or `hg push`).
1878 1882
1879 1883 New revisions are usually provided as a delta against another revision. By
1880 1884 default, Mercurial will not recompute the same delta again, trusting
1881 1885 externally provided deltas. There have been rare cases of small adjustment
1882 1886 to the diffing algorithm in the past. So in some rare case, recomputing
1883 1887 delta provided by ancient clients can provides better results. Disabling
1884 1888 this option means going through a full delta recomputation for all incoming
1885 1889 revisions. It means a large increase in CPU usage and will slow operations
1886 1890 down.
1887 1891
1888 1892 This option is enabled by default. When disabled, it also disables the
1889 1893 related ``storage.revlog.reuse-external-delta-parent`` option.
1890 1894
1891 1895 ``revlog.zlib.level``
1892 1896 Zlib compression level used when storing data into the repository. Accepted
1893 1897 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
1894 1898 default value is 6.
1895 1899
1896 1900
1897 1901 ``revlog.zstd.level``
1898 1902 zstd compression level used when storing data into the repository. Accepted
1899 1903 Value range from 1 (lowest compression) to 22 (highest compression).
1900 1904 (default 3)
1901 1905
1902 1906 ``server``
1903 1907 ----------
1904 1908
1905 1909 Controls generic server settings.
1906 1910
1907 1911 ``bookmarks-pushkey-compat``
1908 1912 Trigger pushkey hook when being pushed bookmark updates. This config exist
1909 1913 for compatibility purpose (default to True)
1910 1914
1911 1915 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
1912 1916 movement we recommend you migrate them to ``txnclose-bookmark`` and
1913 1917 ``pretxnclose-bookmark``.
1914 1918
1915 1919 ``compressionengines``
1916 1920 List of compression engines and their relative priority to advertise
1917 1921 to clients.
1918 1922
1919 1923 The order of compression engines determines their priority, the first
1920 1924 having the highest priority. If a compression engine is not listed
1921 1925 here, it won't be advertised to clients.
1922 1926
1923 1927 If not set (the default), built-in defaults are used. Run
1924 1928 :hg:`debuginstall` to list available compression engines and their
1925 1929 default wire protocol priority.
1926 1930
1927 1931 Older Mercurial clients only support zlib compression and this setting
1928 1932 has no effect for legacy clients.
1929 1933
1930 1934 ``uncompressed``
1931 1935 Whether to allow clients to clone a repository using the
1932 1936 uncompressed streaming protocol. This transfers about 40% more
1933 1937 data than a regular clone, but uses less memory and CPU on both
1934 1938 server and client. Over a LAN (100 Mbps or better) or a very fast
1935 1939 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1936 1940 regular clone. Over most WAN connections (anything slower than
1937 1941 about 6 Mbps), uncompressed streaming is slower, because of the
1938 1942 extra data transfer overhead. This mode will also temporarily hold
1939 1943 the write lock while determining what data to transfer.
1940 1944 (default: True)
1941 1945
1942 1946 ``uncompressedallowsecret``
1943 1947 Whether to allow stream clones when the repository contains secret
1944 1948 changesets. (default: False)
1945 1949
1946 1950 ``preferuncompressed``
1947 1951 When set, clients will try to use the uncompressed streaming
1948 1952 protocol. (default: False)
1949 1953
1950 1954 ``disablefullbundle``
1951 1955 When set, servers will refuse attempts to do pull-based clones.
1952 1956 If this option is set, ``preferuncompressed`` and/or clone bundles
1953 1957 are highly recommended. Partial clones will still be allowed.
1954 1958 (default: False)
1955 1959
1956 1960 ``streamunbundle``
1957 1961 When set, servers will apply data sent from the client directly,
1958 1962 otherwise it will be written to a temporary file first. This option
1959 1963 effectively prevents concurrent pushes.
1960 1964
1961 1965 ``pullbundle``
1962 1966 When set, the server will check pullbundle.manifest for bundles
1963 1967 covering the requested heads and common nodes. The first matching
1964 1968 entry will be streamed to the client.
1965 1969
1966 1970 For HTTP transport, the stream will still use zlib compression
1967 1971 for older clients.
1968 1972
1969 1973 ``concurrent-push-mode``
1970 1974 Level of allowed race condition between two pushing clients.
1971 1975
1972 1976 - 'strict': push is abort if another client touched the repository
1973 1977 while the push was preparing. (default)
1974 1978 - 'check-related': push is only aborted if it affects head that got also
1975 1979 affected while the push was preparing.
1976 1980
1977 1981 This requires compatible client (version 4.3 and later). Old client will
1978 1982 use 'strict'.
1979 1983
1980 1984 ``validate``
1981 1985 Whether to validate the completeness of pushed changesets by
1982 1986 checking that all new file revisions specified in manifests are
1983 1987 present. (default: False)
1984 1988
1985 1989 ``maxhttpheaderlen``
1986 1990 Instruct HTTP clients not to send request headers longer than this
1987 1991 many bytes. (default: 1024)
1988 1992
1989 1993 ``bundle1``
1990 1994 Whether to allow clients to push and pull using the legacy bundle1
1991 1995 exchange format. (default: True)
1992 1996
1993 1997 ``bundle1gd``
1994 1998 Like ``bundle1`` but only used if the repository is using the
1995 1999 *generaldelta* storage format. (default: True)
1996 2000
1997 2001 ``bundle1.push``
1998 2002 Whether to allow clients to push using the legacy bundle1 exchange
1999 2003 format. (default: True)
2000 2004
2001 2005 ``bundle1gd.push``
2002 2006 Like ``bundle1.push`` but only used if the repository is using the
2003 2007 *generaldelta* storage format. (default: True)
2004 2008
2005 2009 ``bundle1.pull``
2006 2010 Whether to allow clients to pull using the legacy bundle1 exchange
2007 2011 format. (default: True)
2008 2012
2009 2013 ``bundle1gd.pull``
2010 2014 Like ``bundle1.pull`` but only used if the repository is using the
2011 2015 *generaldelta* storage format. (default: True)
2012 2016
2013 2017 Large repositories using the *generaldelta* storage format should
2014 2018 consider setting this option because converting *generaldelta*
2015 2019 repositories to the exchange format required by the bundle1 data
2016 2020 format can consume a lot of CPU.
2017 2021
2018 2022 ``bundle2.stream``
2019 2023 Whether to allow clients to pull using the bundle2 streaming protocol.
2020 2024 (default: True)
2021 2025
2022 2026 ``zliblevel``
2023 2027 Integer between ``-1`` and ``9`` that controls the zlib compression level
2024 2028 for wire protocol commands that send zlib compressed output (notably the
2025 2029 commands that send repository history data).
2026 2030
2027 2031 The default (``-1``) uses the default zlib compression level, which is
2028 2032 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2029 2033 maximum compression.
2030 2034
2031 2035 Setting this option allows server operators to make trade-offs between
2032 2036 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2033 2037 but sends more bytes to clients.
2034 2038
2035 2039 This option only impacts the HTTP server.
2036 2040
2037 2041 ``zstdlevel``
2038 2042 Integer between ``1`` and ``22`` that controls the zstd compression level
2039 2043 for wire protocol commands. ``1`` is the minimal amount of compression and
2040 2044 ``22`` is the highest amount of compression.
2041 2045
2042 2046 The default (``3``) should be significantly faster than zlib while likely
2043 2047 delivering better compression ratios.
2044 2048
2045 2049 This option only impacts the HTTP server.
2046 2050
2047 2051 See also ``server.zliblevel``.
2048 2052
2049 2053 ``view``
2050 2054 Repository filter used when exchanging revisions with the peer.
2051 2055
2052 2056 The default view (``served``) excludes secret and hidden changesets.
2053 2057 Another useful value is ``immutable`` (no draft, secret or hidden
2054 2058 changesets). (EXPERIMENTAL)
2055 2059
2056 2060 ``smtp``
2057 2061 --------
2058 2062
2059 2063 Configuration for extensions that need to send email messages.
2060 2064
2061 2065 ``host``
2062 2066 Host name of mail server, e.g. "mail.example.com".
2063 2067
2064 2068 ``port``
2065 2069 Optional. Port to connect to on mail server. (default: 465 if
2066 2070 ``tls`` is smtps; 25 otherwise)
2067 2071
2068 2072 ``tls``
2069 2073 Optional. Method to enable TLS when connecting to mail server: starttls,
2070 2074 smtps or none. (default: none)
2071 2075
2072 2076 ``username``
2073 2077 Optional. User name for authenticating with the SMTP server.
2074 2078 (default: None)
2075 2079
2076 2080 ``password``
2077 2081 Optional. Password for authenticating with the SMTP server. If not
2078 2082 specified, interactive sessions will prompt the user for a
2079 2083 password; non-interactive sessions will fail. (default: None)
2080 2084
2081 2085 ``local_hostname``
2082 2086 Optional. The hostname that the sender can use to identify
2083 2087 itself to the MTA.
2084 2088
2085 2089
2086 2090 ``subpaths``
2087 2091 ------------
2088 2092
2089 2093 Subrepository source URLs can go stale if a remote server changes name
2090 2094 or becomes temporarily unavailable. This section lets you define
2091 2095 rewrite rules of the form::
2092 2096
2093 2097 <pattern> = <replacement>
2094 2098
2095 2099 where ``pattern`` is a regular expression matching a subrepository
2096 2100 source URL and ``replacement`` is the replacement string used to
2097 2101 rewrite it. Groups can be matched in ``pattern`` and referenced in
2098 2102 ``replacements``. For instance::
2099 2103
2100 2104 http://server/(.*)-hg/ = http://hg.server/\1/
2101 2105
2102 2106 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2103 2107
2104 2108 Relative subrepository paths are first made absolute, and the
2105 2109 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2106 2110 doesn't match the full path, an attempt is made to apply it on the
2107 2111 relative path alone. The rules are applied in definition order.
2108 2112
2109 2113 ``subrepos``
2110 2114 ------------
2111 2115
2112 2116 This section contains options that control the behavior of the
2113 2117 subrepositories feature. See also :hg:`help subrepos`.
2114 2118
2115 2119 Security note: auditing in Mercurial is known to be insufficient to
2116 2120 prevent clone-time code execution with carefully constructed Git
2117 2121 subrepos. It is unknown if a similar detect is present in Subversion
2118 2122 subrepos. Both Git and Subversion subrepos are disabled by default
2119 2123 out of security concerns. These subrepo types can be enabled using
2120 2124 the respective options below.
2121 2125
2122 2126 ``allowed``
2123 2127 Whether subrepositories are allowed in the working directory.
2124 2128
2125 2129 When false, commands involving subrepositories (like :hg:`update`)
2126 2130 will fail for all subrepository types.
2127 2131 (default: true)
2128 2132
2129 2133 ``hg:allowed``
2130 2134 Whether Mercurial subrepositories are allowed in the working
2131 2135 directory. This option only has an effect if ``subrepos.allowed``
2132 2136 is true.
2133 2137 (default: true)
2134 2138
2135 2139 ``git:allowed``
2136 2140 Whether Git subrepositories are allowed in the working directory.
2137 2141 This option only has an effect if ``subrepos.allowed`` is true.
2138 2142
2139 2143 See the security note above before enabling Git subrepos.
2140 2144 (default: false)
2141 2145
2142 2146 ``svn:allowed``
2143 2147 Whether Subversion subrepositories are allowed in the working
2144 2148 directory. This option only has an effect if ``subrepos.allowed``
2145 2149 is true.
2146 2150
2147 2151 See the security note above before enabling Subversion subrepos.
2148 2152 (default: false)
2149 2153
2150 2154 ``templatealias``
2151 2155 -----------------
2152 2156
2153 2157 Alias definitions for templates. See :hg:`help templates` for details.
2154 2158
2155 2159 ``templates``
2156 2160 -------------
2157 2161
2158 2162 Use the ``[templates]`` section to define template strings.
2159 2163 See :hg:`help templates` for details.
2160 2164
2161 2165 ``trusted``
2162 2166 -----------
2163 2167
2164 2168 Mercurial will not use the settings in the
2165 2169 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2166 2170 user or to a trusted group, as various hgrc features allow arbitrary
2167 2171 commands to be run. This issue is often encountered when configuring
2168 2172 hooks or extensions for shared repositories or servers. However,
2169 2173 the web interface will use some safe settings from the ``[web]``
2170 2174 section.
2171 2175
2172 2176 This section specifies what users and groups are trusted. The
2173 2177 current user is always trusted. To trust everybody, list a user or a
2174 2178 group with name ``*``. These settings must be placed in an
2175 2179 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2176 2180 user or service running Mercurial.
2177 2181
2178 2182 ``users``
2179 2183 Comma-separated list of trusted users.
2180 2184
2181 2185 ``groups``
2182 2186 Comma-separated list of trusted groups.
2183 2187
2184 2188
2185 2189 ``ui``
2186 2190 ------
2187 2191
2188 2192 User interface controls.
2189 2193
2190 2194 ``archivemeta``
2191 2195 Whether to include the .hg_archival.txt file containing meta data
2192 2196 (hashes for the repository base and for tip) in archives created
2193 2197 by the :hg:`archive` command or downloaded via hgweb.
2194 2198 (default: True)
2195 2199
2196 2200 ``askusername``
2197 2201 Whether to prompt for a username when committing. If True, and
2198 2202 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2199 2203 be prompted to enter a username. If no username is entered, the
2200 2204 default ``USER@HOST`` is used instead.
2201 2205 (default: False)
2202 2206
2203 2207 ``clonebundles``
2204 2208 Whether the "clone bundles" feature is enabled.
2205 2209
2206 2210 When enabled, :hg:`clone` may download and apply a server-advertised
2207 2211 bundle file from a URL instead of using the normal exchange mechanism.
2208 2212
2209 2213 This can likely result in faster and more reliable clones.
2210 2214
2211 2215 (default: True)
2212 2216
2213 2217 ``clonebundlefallback``
2214 2218 Whether failure to apply an advertised "clone bundle" from a server
2215 2219 should result in fallback to a regular clone.
2216 2220
2217 2221 This is disabled by default because servers advertising "clone
2218 2222 bundles" often do so to reduce server load. If advertised bundles
2219 2223 start mass failing and clients automatically fall back to a regular
2220 2224 clone, this would add significant and unexpected load to the server
2221 2225 since the server is expecting clone operations to be offloaded to
2222 2226 pre-generated bundles. Failing fast (the default behavior) ensures
2223 2227 clients don't overwhelm the server when "clone bundle" application
2224 2228 fails.
2225 2229
2226 2230 (default: False)
2227 2231
2228 2232 ``clonebundleprefers``
2229 2233 Defines preferences for which "clone bundles" to use.
2230 2234
2231 2235 Servers advertising "clone bundles" may advertise multiple available
2232 2236 bundles. Each bundle may have different attributes, such as the bundle
2233 2237 type and compression format. This option is used to prefer a particular
2234 2238 bundle over another.
2235 2239
2236 2240 The following keys are defined by Mercurial:
2237 2241
2238 2242 BUNDLESPEC
2239 2243 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2240 2244 e.g. ``gzip-v2`` or ``bzip2-v1``.
2241 2245
2242 2246 COMPRESSION
2243 2247 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2244 2248
2245 2249 Server operators may define custom keys.
2246 2250
2247 2251 Example values: ``COMPRESSION=bzip2``,
2248 2252 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2249 2253
2250 2254 By default, the first bundle advertised by the server is used.
2251 2255
2252 2256 ``color``
2253 2257 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2254 2258 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2255 2259 seems possible. See :hg:`help color` for details.
2256 2260
2257 2261 ``commitsubrepos``
2258 2262 Whether to commit modified subrepositories when committing the
2259 2263 parent repository. If False and one subrepository has uncommitted
2260 2264 changes, abort the commit.
2261 2265 (default: False)
2262 2266
2263 2267 ``debug``
2264 2268 Print debugging information. (default: False)
2265 2269
2266 2270 ``editor``
2267 2271 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2268 2272
2269 2273 ``fallbackencoding``
2270 2274 Encoding to try if it's not possible to decode the changelog using
2271 2275 UTF-8. (default: ISO-8859-1)
2272 2276
2273 2277 ``graphnodetemplate``
2274 2278 The template used to print changeset nodes in an ASCII revision graph.
2275 2279 (default: ``{graphnode}``)
2276 2280
2277 2281 ``ignore``
2278 2282 A file to read per-user ignore patterns from. This file should be
2279 2283 in the same format as a repository-wide .hgignore file. Filenames
2280 2284 are relative to the repository root. This option supports hook syntax,
2281 2285 so if you want to specify multiple ignore files, you can do so by
2282 2286 setting something like ``ignore.other = ~/.hgignore2``. For details
2283 2287 of the ignore file format, see the ``hgignore(5)`` man page.
2284 2288
2285 2289 ``interactive``
2286 2290 Allow to prompt the user. (default: True)
2287 2291
2288 2292 ``interface``
2289 2293 Select the default interface for interactive features (default: text).
2290 2294 Possible values are 'text' and 'curses'.
2291 2295
2292 2296 ``interface.chunkselector``
2293 2297 Select the interface for change recording (e.g. :hg:`commit -i`).
2294 2298 Possible values are 'text' and 'curses'.
2295 2299 This config overrides the interface specified by ui.interface.
2296 2300
2297 2301 ``large-file-limit``
2298 2302 Largest file size that gives no memory use warning.
2299 2303 Possible values are integers or 0 to disable the check.
2300 2304 (default: 10000000)
2301 2305
2302 2306 ``logtemplate``
2303 2307 Template string for commands that print changesets.
2304 2308
2305 2309 ``merge``
2306 2310 The conflict resolution program to use during a manual merge.
2307 2311 For more information on merge tools see :hg:`help merge-tools`.
2308 2312 For configuring merge tools see the ``[merge-tools]`` section.
2309 2313
2310 2314 ``mergemarkers``
2311 2315 Sets the merge conflict marker label styling. The ``detailed``
2312 2316 style uses the ``mergemarkertemplate`` setting to style the labels.
2313 2317 The ``basic`` style just uses 'local' and 'other' as the marker label.
2314 2318 One of ``basic`` or ``detailed``.
2315 2319 (default: ``basic``)
2316 2320
2317 2321 ``mergemarkertemplate``
2318 2322 The template used to print the commit description next to each conflict
2319 2323 marker during merge conflicts. See :hg:`help templates` for the template
2320 2324 format.
2321 2325
2322 2326 Defaults to showing the hash, tags, branches, bookmarks, author, and
2323 2327 the first line of the commit description.
2324 2328
2325 2329 If you use non-ASCII characters in names for tags, branches, bookmarks,
2326 2330 authors, and/or commit descriptions, you must pay attention to encodings of
2327 2331 managed files. At template expansion, non-ASCII characters use the encoding
2328 2332 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2329 2333 environment variables that govern your locale. If the encoding of the merge
2330 2334 markers is different from the encoding of the merged files,
2331 2335 serious problems may occur.
2332 2336
2333 2337 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2334 2338
2335 2339 ``message-output``
2336 2340 Where to write status and error messages. (default: ``stdio``)
2337 2341
2338 2342 ``stderr``
2339 2343 Everything to stderr.
2340 2344 ``stdio``
2341 2345 Status to stdout, and error to stderr.
2342 2346
2343 2347 ``origbackuppath``
2344 2348 The path to a directory used to store generated .orig files. If the path is
2345 2349 not a directory, one will be created. If set, files stored in this
2346 2350 directory have the same name as the original file and do not have a .orig
2347 2351 suffix.
2348 2352
2349 2353 ``paginate``
2350 2354 Control the pagination of command output (default: True). See :hg:`help pager`
2351 2355 for details.
2352 2356
2353 2357 ``patch``
2354 2358 An optional external tool that ``hg import`` and some extensions
2355 2359 will use for applying patches. By default Mercurial uses an
2356 2360 internal patch utility. The external tool must work as the common
2357 2361 Unix ``patch`` program. In particular, it must accept a ``-p``
2358 2362 argument to strip patch headers, a ``-d`` argument to specify the
2359 2363 current directory, a file name to patch, and a patch file to take
2360 2364 from stdin.
2361 2365
2362 2366 It is possible to specify a patch tool together with extra
2363 2367 arguments. For example, setting this option to ``patch --merge``
2364 2368 will use the ``patch`` program with its 2-way merge option.
2365 2369
2366 2370 ``portablefilenames``
2367 2371 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2368 2372 (default: ``warn``)
2369 2373
2370 2374 ``warn``
2371 2375 Print a warning message on POSIX platforms, if a file with a non-portable
2372 2376 filename is added (e.g. a file with a name that can't be created on
2373 2377 Windows because it contains reserved parts like ``AUX``, reserved
2374 2378 characters like ``:``, or would cause a case collision with an existing
2375 2379 file).
2376 2380
2377 2381 ``ignore``
2378 2382 Don't print a warning.
2379 2383
2380 2384 ``abort``
2381 2385 The command is aborted.
2382 2386
2383 2387 ``true``
2384 2388 Alias for ``warn``.
2385 2389
2386 2390 ``false``
2387 2391 Alias for ``ignore``.
2388 2392
2389 2393 .. container:: windows
2390 2394
2391 2395 On Windows, this configuration option is ignored and the command aborted.
2392 2396
2393 2397 ``pre-merge-tool-output-template``
2394 2398 A template that is printed before executing an external merge tool. This can
2395 2399 be used to print out additional context that might be useful to have during
2396 2400 the conflict resolution, such as the description of the various commits
2397 2401 involved or bookmarks/tags.
2398 2402
2399 2403 Additional information is available in the ``local`, ``base``, and ``other``
2400 2404 dicts. For example: ``{local.label}``, ``{base.name}``, or
2401 2405 ``{other.islink}``.
2402 2406
2403 2407 ``quiet``
2404 2408 Reduce the amount of output printed.
2405 2409 (default: False)
2406 2410
2407 2411 ``relative-paths``
2408 2412 Prefer relative paths in the UI.
2409 2413
2410 2414 ``remotecmd``
2411 2415 Remote command to use for clone/push/pull operations.
2412 2416 (default: ``hg``)
2413 2417
2414 2418 ``report_untrusted``
2415 2419 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2416 2420 trusted user or group.
2417 2421 (default: True)
2418 2422
2419 2423 ``slash``
2420 2424 (Deprecated. Use ``slashpath`` template filter instead.)
2421 2425
2422 2426 Display paths using a slash (``/``) as the path separator. This
2423 2427 only makes a difference on systems where the default path
2424 2428 separator is not the slash character (e.g. Windows uses the
2425 2429 backslash character (``\``)).
2426 2430 (default: False)
2427 2431
2428 2432 ``statuscopies``
2429 2433 Display copies in the status command.
2430 2434
2431 2435 ``ssh``
2432 2436 Command to use for SSH connections. (default: ``ssh``)
2433 2437
2434 2438 ``ssherrorhint``
2435 2439 A hint shown to the user in the case of SSH error (e.g.
2436 2440 ``Please see http://company/internalwiki/ssh.html``)
2437 2441
2438 2442 ``strict``
2439 2443 Require exact command names, instead of allowing unambiguous
2440 2444 abbreviations. (default: False)
2441 2445
2442 2446 ``style``
2443 2447 Name of style to use for command output.
2444 2448
2445 2449 ``supportcontact``
2446 2450 A URL where users should report a Mercurial traceback. Use this if you are a
2447 2451 large organisation with its own Mercurial deployment process and crash
2448 2452 reports should be addressed to your internal support.
2449 2453
2450 2454 ``textwidth``
2451 2455 Maximum width of help text. A longer line generated by ``hg help`` or
2452 2456 ``hg subcommand --help`` will be broken after white space to get this
2453 2457 width or the terminal width, whichever comes first.
2454 2458 A non-positive value will disable this and the terminal width will be
2455 2459 used. (default: 78)
2456 2460
2457 2461 ``timeout``
2458 2462 The timeout used when a lock is held (in seconds), a negative value
2459 2463 means no timeout. (default: 600)
2460 2464
2461 2465 ``timeout.warn``
2462 2466 Time (in seconds) before a warning is printed about held lock. A negative
2463 2467 value means no warning. (default: 0)
2464 2468
2465 2469 ``traceback``
2466 2470 Mercurial always prints a traceback when an unknown exception
2467 2471 occurs. Setting this to True will make Mercurial print a traceback
2468 2472 on all exceptions, even those recognized by Mercurial (such as
2469 2473 IOError or MemoryError). (default: False)
2470 2474
2471 2475 ``tweakdefaults``
2472 2476
2473 2477 By default Mercurial's behavior changes very little from release
2474 2478 to release, but over time the recommended config settings
2475 2479 shift. Enable this config to opt in to get automatic tweaks to
2476 2480 Mercurial's behavior over time. This config setting will have no
2477 2481 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2478 2482 not include ``tweakdefaults``. (default: False)
2479 2483
2480 2484 It currently means::
2481 2485
2482 2486 .. tweakdefaultsmarker
2483 2487
2484 2488 ``username``
2485 2489 The committer of a changeset created when running "commit".
2486 2490 Typically a person's name and email address, e.g. ``Fred Widget
2487 2491 <fred@example.com>``. Environment variables in the
2488 2492 username are expanded.
2489 2493
2490 2494 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2491 2495 hgrc is empty, e.g. if the system admin set ``username =`` in the
2492 2496 system hgrc, it has to be specified manually or in a different
2493 2497 hgrc file)
2494 2498
2495 2499 ``verbose``
2496 2500 Increase the amount of output printed. (default: False)
2497 2501
2498 2502
2499 2503 ``web``
2500 2504 -------
2501 2505
2502 2506 Web interface configuration. The settings in this section apply to
2503 2507 both the builtin webserver (started by :hg:`serve`) and the script you
2504 2508 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2505 2509 and WSGI).
2506 2510
2507 2511 The Mercurial webserver does no authentication (it does not prompt for
2508 2512 usernames and passwords to validate *who* users are), but it does do
2509 2513 authorization (it grants or denies access for *authenticated users*
2510 2514 based on settings in this section). You must either configure your
2511 2515 webserver to do authentication for you, or disable the authorization
2512 2516 checks.
2513 2517
2514 2518 For a quick setup in a trusted environment, e.g., a private LAN, where
2515 2519 you want it to accept pushes from anybody, you can use the following
2516 2520 command line::
2517 2521
2518 2522 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2519 2523
2520 2524 Note that this will allow anybody to push anything to the server and
2521 2525 that this should not be used for public servers.
2522 2526
2523 2527 The full set of options is:
2524 2528
2525 2529 ``accesslog``
2526 2530 Where to output the access log. (default: stdout)
2527 2531
2528 2532 ``address``
2529 2533 Interface address to bind to. (default: all)
2530 2534
2531 2535 ``allow-archive``
2532 2536 List of archive format (bz2, gz, zip) allowed for downloading.
2533 2537 (default: empty)
2534 2538
2535 2539 ``allowbz2``
2536 2540 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2537 2541 revisions.
2538 2542 (default: False)
2539 2543
2540 2544 ``allowgz``
2541 2545 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2542 2546 revisions.
2543 2547 (default: False)
2544 2548
2545 2549 ``allow-pull``
2546 2550 Whether to allow pulling from the repository. (default: True)
2547 2551
2548 2552 ``allow-push``
2549 2553 Whether to allow pushing to the repository. If empty or not set,
2550 2554 pushing is not allowed. If the special value ``*``, any remote
2551 2555 user can push, including unauthenticated users. Otherwise, the
2552 2556 remote user must have been authenticated, and the authenticated
2553 2557 user name must be present in this list. The contents of the
2554 2558 allow-push list are examined after the deny_push list.
2555 2559
2556 2560 ``allow_read``
2557 2561 If the user has not already been denied repository access due to
2558 2562 the contents of deny_read, this list determines whether to grant
2559 2563 repository access to the user. If this list is not empty, and the
2560 2564 user is unauthenticated or not present in the list, then access is
2561 2565 denied for the user. If the list is empty or not set, then access
2562 2566 is permitted to all users by default. Setting allow_read to the
2563 2567 special value ``*`` is equivalent to it not being set (i.e. access
2564 2568 is permitted to all users). The contents of the allow_read list are
2565 2569 examined after the deny_read list.
2566 2570
2567 2571 ``allowzip``
2568 2572 (DEPRECATED) Whether to allow .zip downloading of repository
2569 2573 revisions. This feature creates temporary files.
2570 2574 (default: False)
2571 2575
2572 2576 ``archivesubrepos``
2573 2577 Whether to recurse into subrepositories when archiving.
2574 2578 (default: False)
2575 2579
2576 2580 ``baseurl``
2577 2581 Base URL to use when publishing URLs in other locations, so
2578 2582 third-party tools like email notification hooks can construct
2579 2583 URLs. Example: ``http://hgserver/repos/``.
2580 2584
2581 2585 ``cacerts``
2582 2586 Path to file containing a list of PEM encoded certificate
2583 2587 authority certificates. Environment variables and ``~user``
2584 2588 constructs are expanded in the filename. If specified on the
2585 2589 client, then it will verify the identity of remote HTTPS servers
2586 2590 with these certificates.
2587 2591
2588 2592 To disable SSL verification temporarily, specify ``--insecure`` from
2589 2593 command line.
2590 2594
2591 2595 You can use OpenSSL's CA certificate file if your platform has
2592 2596 one. On most Linux systems this will be
2593 2597 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2594 2598 generate this file manually. The form must be as follows::
2595 2599
2596 2600 -----BEGIN CERTIFICATE-----
2597 2601 ... (certificate in base64 PEM encoding) ...
2598 2602 -----END CERTIFICATE-----
2599 2603 -----BEGIN CERTIFICATE-----
2600 2604 ... (certificate in base64 PEM encoding) ...
2601 2605 -----END CERTIFICATE-----
2602 2606
2603 2607 ``cache``
2604 2608 Whether to support caching in hgweb. (default: True)
2605 2609
2606 2610 ``certificate``
2607 2611 Certificate to use when running :hg:`serve`.
2608 2612
2609 2613 ``collapse``
2610 2614 With ``descend`` enabled, repositories in subdirectories are shown at
2611 2615 a single level alongside repositories in the current path. With
2612 2616 ``collapse`` also enabled, repositories residing at a deeper level than
2613 2617 the current path are grouped behind navigable directory entries that
2614 2618 lead to the locations of these repositories. In effect, this setting
2615 2619 collapses each collection of repositories found within a subdirectory
2616 2620 into a single entry for that subdirectory. (default: False)
2617 2621
2618 2622 ``comparisoncontext``
2619 2623 Number of lines of context to show in side-by-side file comparison. If
2620 2624 negative or the value ``full``, whole files are shown. (default: 5)
2621 2625
2622 2626 This setting can be overridden by a ``context`` request parameter to the
2623 2627 ``comparison`` command, taking the same values.
2624 2628
2625 2629 ``contact``
2626 2630 Name or email address of the person in charge of the repository.
2627 2631 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2628 2632
2629 2633 ``csp``
2630 2634 Send a ``Content-Security-Policy`` HTTP header with this value.
2631 2635
2632 2636 The value may contain a special string ``%nonce%``, which will be replaced
2633 2637 by a randomly-generated one-time use value. If the value contains
2634 2638 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2635 2639 one-time property of the nonce. This nonce will also be inserted into
2636 2640 ``<script>`` elements containing inline JavaScript.
2637 2641
2638 2642 Note: lots of HTML content sent by the server is derived from repository
2639 2643 data. Please consider the potential for malicious repository data to
2640 2644 "inject" itself into generated HTML content as part of your security
2641 2645 threat model.
2642 2646
2643 2647 ``deny_push``
2644 2648 Whether to deny pushing to the repository. If empty or not set,
2645 2649 push is not denied. If the special value ``*``, all remote users are
2646 2650 denied push. Otherwise, unauthenticated users are all denied, and
2647 2651 any authenticated user name present in this list is also denied. The
2648 2652 contents of the deny_push list are examined before the allow-push list.
2649 2653
2650 2654 ``deny_read``
2651 2655 Whether to deny reading/viewing of the repository. If this list is
2652 2656 not empty, unauthenticated users are all denied, and any
2653 2657 authenticated user name present in this list is also denied access to
2654 2658 the repository. If set to the special value ``*``, all remote users
2655 2659 are denied access (rarely needed ;). If deny_read is empty or not set,
2656 2660 the determination of repository access depends on the presence and
2657 2661 content of the allow_read list (see description). If both
2658 2662 deny_read and allow_read are empty or not set, then access is
2659 2663 permitted to all users by default. If the repository is being
2660 2664 served via hgwebdir, denied users will not be able to see it in
2661 2665 the list of repositories. The contents of the deny_read list have
2662 2666 priority over (are examined before) the contents of the allow_read
2663 2667 list.
2664 2668
2665 2669 ``descend``
2666 2670 hgwebdir indexes will not descend into subdirectories. Only repositories
2667 2671 directly in the current path will be shown (other repositories are still
2668 2672 available from the index corresponding to their containing path).
2669 2673
2670 2674 ``description``
2671 2675 Textual description of the repository's purpose or contents.
2672 2676 (default: "unknown")
2673 2677
2674 2678 ``encoding``
2675 2679 Character encoding name. (default: the current locale charset)
2676 2680 Example: "UTF-8".
2677 2681
2678 2682 ``errorlog``
2679 2683 Where to output the error log. (default: stderr)
2680 2684
2681 2685 ``guessmime``
2682 2686 Control MIME types for raw download of file content.
2683 2687 Set to True to let hgweb guess the content type from the file
2684 2688 extension. This will serve HTML files as ``text/html`` and might
2685 2689 allow cross-site scripting attacks when serving untrusted
2686 2690 repositories. (default: False)
2687 2691
2688 2692 ``hidden``
2689 2693 Whether to hide the repository in the hgwebdir index.
2690 2694 (default: False)
2691 2695
2692 2696 ``ipv6``
2693 2697 Whether to use IPv6. (default: False)
2694 2698
2695 2699 ``labels``
2696 2700 List of string *labels* associated with the repository.
2697 2701
2698 2702 Labels are exposed as a template keyword and can be used to customize
2699 2703 output. e.g. the ``index`` template can group or filter repositories
2700 2704 by labels and the ``summary`` template can display additional content
2701 2705 if a specific label is present.
2702 2706
2703 2707 ``logoimg``
2704 2708 File name of the logo image that some templates display on each page.
2705 2709 The file name is relative to ``staticurl``. That is, the full path to
2706 2710 the logo image is "staticurl/logoimg".
2707 2711 If unset, ``hglogo.png`` will be used.
2708 2712
2709 2713 ``logourl``
2710 2714 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2711 2715 will be used.
2712 2716
2713 2717 ``maxchanges``
2714 2718 Maximum number of changes to list on the changelog. (default: 10)
2715 2719
2716 2720 ``maxfiles``
2717 2721 Maximum number of files to list per changeset. (default: 10)
2718 2722
2719 2723 ``maxshortchanges``
2720 2724 Maximum number of changes to list on the shortlog, graph or filelog
2721 2725 pages. (default: 60)
2722 2726
2723 2727 ``name``
2724 2728 Repository name to use in the web interface.
2725 2729 (default: current working directory)
2726 2730
2727 2731 ``port``
2728 2732 Port to listen on. (default: 8000)
2729 2733
2730 2734 ``prefix``
2731 2735 Prefix path to serve from. (default: '' (server root))
2732 2736
2733 2737 ``push_ssl``
2734 2738 Whether to require that inbound pushes be transported over SSL to
2735 2739 prevent password sniffing. (default: True)
2736 2740
2737 2741 ``refreshinterval``
2738 2742 How frequently directory listings re-scan the filesystem for new
2739 2743 repositories, in seconds. This is relevant when wildcards are used
2740 2744 to define paths. Depending on how much filesystem traversal is
2741 2745 required, refreshing may negatively impact performance.
2742 2746
2743 2747 Values less than or equal to 0 always refresh.
2744 2748 (default: 20)
2745 2749
2746 2750 ``server-header``
2747 2751 Value for HTTP ``Server`` response header.
2748 2752
2749 2753 ``static``
2750 2754 Directory where static files are served from.
2751 2755
2752 2756 ``staticurl``
2753 2757 Base URL to use for static files. If unset, static files (e.g. the
2754 2758 hgicon.png favicon) will be served by the CGI script itself. Use
2755 2759 this setting to serve them directly with the HTTP server.
2756 2760 Example: ``http://hgserver/static/``.
2757 2761
2758 2762 ``stripes``
2759 2763 How many lines a "zebra stripe" should span in multi-line output.
2760 2764 Set to 0 to disable. (default: 1)
2761 2765
2762 2766 ``style``
2763 2767 Which template map style to use. The available options are the names of
2764 2768 subdirectories in the HTML templates path. (default: ``paper``)
2765 2769 Example: ``monoblue``.
2766 2770
2767 2771 ``templates``
2768 2772 Where to find the HTML templates. The default path to the HTML templates
2769 2773 can be obtained from ``hg debuginstall``.
2770 2774
2771 2775 ``websub``
2772 2776 ----------
2773 2777
2774 2778 Web substitution filter definition. You can use this section to
2775 2779 define a set of regular expression substitution patterns which
2776 2780 let you automatically modify the hgweb server output.
2777 2781
2778 2782 The default hgweb templates only apply these substitution patterns
2779 2783 on the revision description fields. You can apply them anywhere
2780 2784 you want when you create your own templates by adding calls to the
2781 2785 "websub" filter (usually after calling the "escape" filter).
2782 2786
2783 2787 This can be used, for example, to convert issue references to links
2784 2788 to your issue tracker, or to convert "markdown-like" syntax into
2785 2789 HTML (see the examples below).
2786 2790
2787 2791 Each entry in this section names a substitution filter.
2788 2792 The value of each entry defines the substitution expression itself.
2789 2793 The websub expressions follow the old interhg extension syntax,
2790 2794 which in turn imitates the Unix sed replacement syntax::
2791 2795
2792 2796 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2793 2797
2794 2798 You can use any separator other than "/". The final "i" is optional
2795 2799 and indicates that the search must be case insensitive.
2796 2800
2797 2801 Examples::
2798 2802
2799 2803 [websub]
2800 2804 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2801 2805 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2802 2806 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2803 2807
2804 2808 ``worker``
2805 2809 ----------
2806 2810
2807 2811 Parallel master/worker configuration. We currently perform working
2808 2812 directory updates in parallel on Unix-like systems, which greatly
2809 2813 helps performance.
2810 2814
2811 2815 ``enabled``
2812 2816 Whether to enable workers code to be used.
2813 2817 (default: true)
2814 2818
2815 2819 ``numcpus``
2816 2820 Number of CPUs to use for parallel operations. A zero or
2817 2821 negative value is treated as ``use the default``.
2818 2822 (default: 4 or the number of CPUs on the system, whichever is larger)
2819 2823
2820 2824 ``backgroundclose``
2821 2825 Whether to enable closing file handles on background threads during certain
2822 2826 operations. Some platforms aren't very efficient at closing file
2823 2827 handles that have been written or appended to. By performing file closing
2824 2828 on background threads, file write rate can increase substantially.
2825 2829 (default: true on Windows, false elsewhere)
2826 2830
2827 2831 ``backgroundcloseminfilecount``
2828 2832 Minimum number of files required to trigger background file closing.
2829 2833 Operations not writing this many files won't start background close
2830 2834 threads.
2831 2835 (default: 2048)
2832 2836
2833 2837 ``backgroundclosemaxqueue``
2834 2838 The maximum number of opened file handles waiting to be closed in the
2835 2839 background. This option only has an effect if ``backgroundclose`` is
2836 2840 enabled.
2837 2841 (default: 384)
2838 2842
2839 2843 ``backgroundclosethreadcount``
2840 2844 Number of threads to process background file closes. Only relevant if
2841 2845 ``backgroundclose`` is enabled.
2842 2846 (default: 4)
@@ -1,840 +1,879 b''
1 1 commit date test
2 2
3 3 $ hg init test
4 4 $ cd test
5 5 $ echo foo > foo
6 6 $ hg add foo
7 7 $ cat > $TESTTMP/checkeditform.sh <<EOF
8 8 > env | grep HGEDITFORM
9 9 > true
10 10 > EOF
11 11 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg commit -m ""
12 12 HGEDITFORM=commit.normal.normal
13 13 abort: empty commit message
14 14 [255]
15 15 $ hg commit -d '0 0' -m commit-1
16 16 $ echo foo >> foo
17 17 $ hg commit -d '1 4444444' -m commit-3
18 18 hg: parse error: impossible time zone offset: 4444444
19 19 [255]
20 20 $ hg commit -d '1 15.1' -m commit-4
21 21 hg: parse error: invalid date: '1\t15.1'
22 22 [255]
23 23 $ hg commit -d 'foo bar' -m commit-5
24 24 hg: parse error: invalid date: 'foo bar'
25 25 [255]
26 26 $ hg commit -d ' 1 4444' -m commit-6
27 27 $ hg commit -d '111111111111 0' -m commit-7
28 28 hg: parse error: date exceeds 32 bits: 111111111111
29 29 [255]
30 30 $ hg commit -d '-111111111111 0' -m commit-7
31 31 hg: parse error: date exceeds 32 bits: -111111111111
32 32 [255]
33 33 $ echo foo >> foo
34 34 $ hg commit -d '1901-12-13 20:45:52 +0000' -m commit-7-2
35 35 $ echo foo >> foo
36 36 $ hg commit -d '-2147483648 0' -m commit-7-3
37 37 $ hg log -T '{rev} {date|isodatesec}\n' -l2
38 38 3 1901-12-13 20:45:52 +0000
39 39 2 1901-12-13 20:45:52 +0000
40 40 $ hg commit -d '1901-12-13 20:45:51 +0000' -m commit-7
41 41 hg: parse error: date exceeds 32 bits: -2147483649
42 42 [255]
43 43 $ hg commit -d '-2147483649 0' -m commit-7
44 44 hg: parse error: date exceeds 32 bits: -2147483649
45 45 [255]
46 46
47 47 commit added file that has been deleted
48 48
49 49 $ echo bar > bar
50 50 $ hg add bar
51 51 $ rm bar
52 52 $ hg commit -m commit-8
53 53 nothing changed (1 missing files, see 'hg status')
54 54 [1]
55 55 $ hg commit -m commit-8-2 bar
56 56 abort: bar: file not found!
57 57 [255]
58 58
59 59 $ hg -q revert -a --no-backup
60 60
61 61 $ mkdir dir
62 62 $ echo boo > dir/file
63 63 $ hg add
64 64 adding dir/file
65 65 $ hg -v commit -m commit-9 dir
66 66 committing files:
67 67 dir/file
68 68 committing manifest
69 69 committing changelog
70 70 committed changeset 4:1957363f1ced
71 71
72 72 $ echo > dir.file
73 73 $ hg add
74 74 adding dir.file
75 75 $ hg commit -m commit-10 dir dir.file
76 76 abort: dir: no match under directory!
77 77 [255]
78 78
79 79 $ echo >> dir/file
80 80 $ mkdir bleh
81 81 $ mkdir dir2
82 82 $ cd bleh
83 83 $ hg commit -m commit-11 .
84 84 abort: bleh: no match under directory!
85 85 [255]
86 86 $ hg commit -m commit-12 ../dir ../dir2
87 87 abort: dir2: no match under directory!
88 88 [255]
89 89 $ hg -v commit -m commit-13 ../dir
90 90 committing files:
91 91 dir/file
92 92 committing manifest
93 93 committing changelog
94 94 committed changeset 5:a31d8f87544a
95 95 $ cd ..
96 96
97 97 $ hg commit -m commit-14 does-not-exist
98 98 abort: does-not-exist: * (glob)
99 99 [255]
100 100
101 101 #if symlink
102 102 $ ln -s foo baz
103 103 $ hg commit -m commit-15 baz
104 104 abort: baz: file not tracked!
105 105 [255]
106 106 $ rm baz
107 107 #endif
108 108
109 109 $ touch quux
110 110 $ hg commit -m commit-16 quux
111 111 abort: quux: file not tracked!
112 112 [255]
113 113 $ echo >> dir/file
114 114 $ hg -v commit -m commit-17 dir/file
115 115 committing files:
116 116 dir/file
117 117 committing manifest
118 118 committing changelog
119 119 committed changeset 6:32d054c9d085
120 120
121 121 An empty date was interpreted as epoch origin
122 122
123 123 $ echo foo >> foo
124 124 $ hg commit -d '' -m commit-no-date --config devel.default-date=
125 125 $ hg tip --template '{date|isodate}\n' | grep '1970'
126 126 [1]
127 127
128 128 Using the advanced --extra flag
129 129
130 130 $ echo "[extensions]" >> $HGRCPATH
131 131 $ echo "commitextras=" >> $HGRCPATH
132 132 $ hg status
133 133 ? quux
134 134 $ hg add quux
135 135 $ hg commit -m "adding internal used extras" --extra amend_source=hash
136 136 abort: key 'amend_source' is used internally, can't be set manually
137 137 [255]
138 138 $ hg commit -m "special chars in extra" --extra id@phab=214
139 139 abort: keys can only contain ascii letters, digits, '_' and '-'
140 140 [255]
141 141 $ hg commit -m "empty key" --extra =value
142 142 abort: unable to parse '=value', keys can't be empty
143 143 [255]
144 144 $ hg commit -m "adding extras" --extra sourcehash=foo --extra oldhash=bar
145 145 $ hg log -r . -T '{extras % "{extra}\n"}'
146 146 branch=default
147 147 oldhash=bar
148 148 sourcehash=foo
149 149
150 150 Failed commit with --addremove should not update dirstate
151 151
152 152 $ echo foo > newfile
153 153 $ hg status
154 154 ? newfile
155 155 $ HGEDITOR=false hg ci --addremove
156 156 adding newfile
157 157 abort: edit failed: false exited with status 1
158 158 [255]
159 159 $ hg status
160 160 ? newfile
161 161
162 162 Make sure we do not obscure unknown requires file entries (issue2649)
163 163
164 164 $ echo foo >> foo
165 165 $ echo fake >> .hg/requires
166 166 $ hg commit -m bla
167 167 abort: repository requires features unknown to this Mercurial: fake!
168 168 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
169 169 [255]
170 170
171 171 $ cd ..
172 172
173 173
174 174 partial subdir commit test
175 175
176 176 $ hg init test2
177 177 $ cd test2
178 178 $ mkdir foo
179 179 $ echo foo > foo/foo
180 180 $ mkdir bar
181 181 $ echo bar > bar/bar
182 182 $ hg add
183 183 adding bar/bar
184 184 adding foo/foo
185 185 $ HGEDITOR=cat hg ci -e -m commit-subdir-1 foo
186 186 commit-subdir-1
187 187
188 188
189 189 HG: Enter commit message. Lines beginning with 'HG:' are removed.
190 190 HG: Leave message empty to abort commit.
191 191 HG: --
192 192 HG: user: test
193 193 HG: branch 'default'
194 194 HG: added foo/foo
195 195
196 196
197 197 $ hg ci -m commit-subdir-2 bar
198 198
199 199 subdir log 1
200 200
201 201 $ hg log -v foo
202 202 changeset: 0:f97e73a25882
203 203 user: test
204 204 date: Thu Jan 01 00:00:00 1970 +0000
205 205 files: foo/foo
206 206 description:
207 207 commit-subdir-1
208 208
209 209
210 210
211 211 subdir log 2
212 212
213 213 $ hg log -v bar
214 214 changeset: 1:aa809156d50d
215 215 tag: tip
216 216 user: test
217 217 date: Thu Jan 01 00:00:00 1970 +0000
218 218 files: bar/bar
219 219 description:
220 220 commit-subdir-2
221 221
222 222
223 223
224 224 full log
225 225
226 226 $ hg log -v
227 227 changeset: 1:aa809156d50d
228 228 tag: tip
229 229 user: test
230 230 date: Thu Jan 01 00:00:00 1970 +0000
231 231 files: bar/bar
232 232 description:
233 233 commit-subdir-2
234 234
235 235
236 236 changeset: 0:f97e73a25882
237 237 user: test
238 238 date: Thu Jan 01 00:00:00 1970 +0000
239 239 files: foo/foo
240 240 description:
241 241 commit-subdir-1
242 242
243 243
244 244 $ cd ..
245 245
246 246
247 247 dot and subdir commit test
248 248
249 249 $ hg init test3
250 250 $ echo commit-foo-subdir > commit-log-test
251 251 $ cd test3
252 252 $ mkdir foo
253 253 $ echo foo content > foo/plain-file
254 254 $ hg add foo/plain-file
255 255 $ HGEDITOR=cat hg ci --edit -l ../commit-log-test foo
256 256 commit-foo-subdir
257 257
258 258
259 259 HG: Enter commit message. Lines beginning with 'HG:' are removed.
260 260 HG: Leave message empty to abort commit.
261 261 HG: --
262 262 HG: user: test
263 263 HG: branch 'default'
264 264 HG: added foo/plain-file
265 265
266 266
267 267 $ echo modified foo content > foo/plain-file
268 268 $ hg ci -m commit-foo-dot .
269 269
270 270 full log
271 271
272 272 $ hg log -v
273 273 changeset: 1:95b38e3a5b2e
274 274 tag: tip
275 275 user: test
276 276 date: Thu Jan 01 00:00:00 1970 +0000
277 277 files: foo/plain-file
278 278 description:
279 279 commit-foo-dot
280 280
281 281
282 282 changeset: 0:65d4e9386227
283 283 user: test
284 284 date: Thu Jan 01 00:00:00 1970 +0000
285 285 files: foo/plain-file
286 286 description:
287 287 commit-foo-subdir
288 288
289 289
290 290
291 291 subdir log
292 292
293 293 $ cd foo
294 294 $ hg log .
295 295 changeset: 1:95b38e3a5b2e
296 296 tag: tip
297 297 user: test
298 298 date: Thu Jan 01 00:00:00 1970 +0000
299 299 summary: commit-foo-dot
300 300
301 301 changeset: 0:65d4e9386227
302 302 user: test
303 303 date: Thu Jan 01 00:00:00 1970 +0000
304 304 summary: commit-foo-subdir
305 305
306 306 $ cd ..
307 307 $ cd ..
308 308
309 309 Issue1049: Hg permits partial commit of merge without warning
310 310
311 311 $ hg init issue1049
312 312 $ cd issue1049
313 313 $ echo a > a
314 314 $ hg ci -Ama
315 315 adding a
316 316 $ echo a >> a
317 317 $ hg ci -mb
318 318 $ hg up 0
319 319 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
320 320 $ echo b >> a
321 321 $ hg ci -mc
322 322 created new head
323 323 $ HGMERGE=true hg merge
324 324 merging a
325 325 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
326 326 (branch merge, don't forget to commit)
327 327
328 328 should fail because we are specifying a file name
329 329
330 330 $ hg ci -mmerge a
331 331 abort: cannot partially commit a merge (do not specify files or patterns)
332 332 [255]
333 333
334 334 should fail because we are specifying a pattern
335 335
336 336 $ hg ci -mmerge -I a
337 337 abort: cannot partially commit a merge (do not specify files or patterns)
338 338 [255]
339 339
340 340 should succeed
341 341
342 342 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg ci -mmerge --edit
343 343 HGEDITFORM=commit.normal.merge
344 344 $ cd ..
345 345
346 346
347 347 test commit message content
348 348
349 349 $ hg init commitmsg
350 350 $ cd commitmsg
351 351 $ echo changed > changed
352 352 $ echo removed > removed
353 353 $ hg book activebookmark
354 354 $ hg ci -qAm init
355 355
356 356 $ hg rm removed
357 357 $ echo changed >> changed
358 358 $ echo added > added
359 359 $ hg add added
360 360 $ HGEDITOR=cat hg ci -A
361 361
362 362
363 363 HG: Enter commit message. Lines beginning with 'HG:' are removed.
364 364 HG: Leave message empty to abort commit.
365 365 HG: --
366 366 HG: user: test
367 367 HG: branch 'default'
368 368 HG: bookmark 'activebookmark'
369 369 HG: added added
370 370 HG: changed changed
371 371 HG: removed removed
372 372 abort: empty commit message
373 373 [255]
374 374
375 375 test saving last-message.txt
376 376
377 377 $ hg init sub
378 378 $ echo a > sub/a
379 379 $ hg -R sub add sub/a
380 380 $ cat > sub/.hg/hgrc <<EOF
381 381 > [hooks]
382 382 > precommit.test-saving-last-message = false
383 383 > EOF
384 384
385 385 $ echo 'sub = sub' > .hgsub
386 386 $ hg add .hgsub
387 387
388 388 $ cat > $TESTTMP/editor.sh <<EOF
389 389 > echo "==== before editing:"
390 390 > cat \$1
391 391 > echo "===="
392 392 > echo "test saving last-message.txt" >> \$1
393 393 > EOF
394 394
395 395 $ rm -f .hg/last-message.txt
396 396 $ HGEDITOR="sh $TESTTMP/editor.sh" hg commit -S -q
397 397 ==== before editing:
398 398
399 399
400 400 HG: Enter commit message. Lines beginning with 'HG:' are removed.
401 401 HG: Leave message empty to abort commit.
402 402 HG: --
403 403 HG: user: test
404 404 HG: branch 'default'
405 405 HG: bookmark 'activebookmark'
406 406 HG: subrepo sub
407 407 HG: added .hgsub
408 408 HG: added added
409 409 HG: changed .hgsubstate
410 410 HG: changed changed
411 411 HG: removed removed
412 412 ====
413 413 abort: precommit.test-saving-last-message hook exited with status 1 (in subrepository "sub")
414 414 [255]
415 415 $ cat .hg/last-message.txt
416 416
417 417
418 418 test saving last-message.txt
419 419
420 420 test that '[committemplate] changeset' definition and commit log
421 421 specific template keywords work well
422 422
423 423 $ cat >> .hg/hgrc <<EOF
424 424 > [committemplate]
425 425 > changeset.commit.normal = 'HG: this is "commit.normal" template
426 426 > HG: {extramsg}
427 427 > {if(activebookmark,
428 428 > "HG: bookmark '{activebookmark}' is activated\n",
429 429 > "HG: no bookmark is activated\n")}{subrepos %
430 430 > "HG: subrepo '{subrepo}' is changed\n"}'
431 431 >
432 432 > changeset.commit = HG: this is "commit" template
433 433 > HG: {extramsg}
434 434 > {if(activebookmark,
435 435 > "HG: bookmark '{activebookmark}' is activated\n",
436 436 > "HG: no bookmark is activated\n")}{subrepos %
437 437 > "HG: subrepo '{subrepo}' is changed\n"}
438 438 >
439 439 > changeset = HG: this is customized commit template
440 440 > HG: {extramsg}
441 441 > {if(activebookmark,
442 442 > "HG: bookmark '{activebookmark}' is activated\n",
443 443 > "HG: no bookmark is activated\n")}{subrepos %
444 444 > "HG: subrepo '{subrepo}' is changed\n"}
445 445 > EOF
446 446
447 447 $ hg init sub2
448 448 $ echo a > sub2/a
449 449 $ hg -R sub2 add sub2/a
450 450 $ echo 'sub2 = sub2' >> .hgsub
451 451
452 452 $ HGEDITOR=cat hg commit -S -q
453 453 HG: this is "commit.normal" template
454 454 HG: Leave message empty to abort commit.
455 455 HG: bookmark 'activebookmark' is activated
456 456 HG: subrepo 'sub' is changed
457 457 HG: subrepo 'sub2' is changed
458 458 abort: empty commit message
459 459 [255]
460 460
461 461 $ cat >> .hg/hgrc <<EOF
462 462 > [committemplate]
463 463 > changeset.commit.normal =
464 464 > # now, "changeset.commit" should be chosen for "hg commit"
465 465 > EOF
466 466
467 467 $ hg bookmark --inactive activebookmark
468 468 $ hg forget .hgsub
469 469 $ HGEDITOR=cat hg commit -q
470 470 HG: this is "commit" template
471 471 HG: Leave message empty to abort commit.
472 472 HG: no bookmark is activated
473 473 abort: empty commit message
474 474 [255]
475 475
476 476 $ cat >> .hg/hgrc <<EOF
477 477 > [committemplate]
478 478 > changeset.commit =
479 479 > # now, "changeset" should be chosen for "hg commit"
480 480 > EOF
481 481
482 482 $ HGEDITOR=cat hg commit -q
483 483 HG: this is customized commit template
484 484 HG: Leave message empty to abort commit.
485 485 HG: no bookmark is activated
486 486 abort: empty commit message
487 487 [255]
488 488
489 489 $ cat >> .hg/hgrc <<EOF
490 490 > [committemplate]
491 491 > changeset = {desc}
492 492 > HG: mods={file_mods}
493 493 > HG: adds={file_adds}
494 494 > HG: dels={file_dels}
495 495 > HG: files={files}
496 496 > HG:
497 497 > {splitlines(diff()) % 'HG: {line}\n'
498 498 > }HG:
499 499 > HG: mods={file_mods}
500 500 > HG: adds={file_adds}
501 501 > HG: dels={file_dels}
502 502 > HG: files={files}\n
503 503 > EOF
504 504 $ hg status -amr
505 505 M changed
506 506 A added
507 507 R removed
508 508 $ HGEDITOR=cat hg commit -q -e -m "foo bar" changed
509 509 foo bar
510 510 HG: mods=changed
511 511 HG: adds=
512 512 HG: dels=
513 513 HG: files=changed
514 514 HG:
515 515 HG: diff -r d2313f97106f changed
516 516 HG: --- a/changed Thu Jan 01 00:00:00 1970 +0000
517 517 HG: +++ b/changed Thu Jan 01 00:00:00 1970 +0000
518 518 HG: @@ -1,1 +1,2 @@
519 519 HG: changed
520 520 HG: +changed
521 521 HG:
522 522 HG: mods=changed
523 523 HG: adds=
524 524 HG: dels=
525 525 HG: files=changed
526 526 $ hg status -amr
527 527 A added
528 528 R removed
529 529 $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n"
530 530 M changed
531 531 A
532 532 R
533 533 $ hg rollback -q
534 534
535 535 $ cat >> .hg/hgrc <<EOF
536 536 > [committemplate]
537 537 > changeset = {desc}
538 538 > HG: mods={file_mods}
539 539 > HG: adds={file_adds}
540 540 > HG: dels={file_dels}
541 541 > HG: files={files}
542 542 > HG:
543 543 > {splitlines(diff("changed")) % 'HG: {line}\n'
544 544 > }HG:
545 545 > HG: mods={file_mods}
546 546 > HG: adds={file_adds}
547 547 > HG: dels={file_dels}
548 548 > HG: files={files}
549 549 > HG:
550 550 > {splitlines(diff("added")) % 'HG: {line}\n'
551 551 > }HG:
552 552 > HG: mods={file_mods}
553 553 > HG: adds={file_adds}
554 554 > HG: dels={file_dels}
555 555 > HG: files={files}
556 556 > HG:
557 557 > {splitlines(diff("removed")) % 'HG: {line}\n'
558 558 > }HG:
559 559 > HG: mods={file_mods}
560 560 > HG: adds={file_adds}
561 561 > HG: dels={file_dels}
562 562 > HG: files={files}\n
563 563 > EOF
564 564 $ HGEDITOR=cat hg commit -q -e -m "foo bar" added removed
565 565 foo bar
566 566 HG: mods=
567 567 HG: adds=added
568 568 HG: dels=removed
569 569 HG: files=added removed
570 570 HG:
571 571 HG:
572 572 HG: mods=
573 573 HG: adds=added
574 574 HG: dels=removed
575 575 HG: files=added removed
576 576 HG:
577 577 HG: diff -r d2313f97106f added
578 578 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
579 579 HG: +++ b/added Thu Jan 01 00:00:00 1970 +0000
580 580 HG: @@ -0,0 +1,1 @@
581 581 HG: +added
582 582 HG:
583 583 HG: mods=
584 584 HG: adds=added
585 585 HG: dels=removed
586 586 HG: files=added removed
587 587 HG:
588 588 HG: diff -r d2313f97106f removed
589 589 HG: --- a/removed Thu Jan 01 00:00:00 1970 +0000
590 590 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
591 591 HG: @@ -1,1 +0,0 @@
592 592 HG: -removed
593 593 HG:
594 594 HG: mods=
595 595 HG: adds=added
596 596 HG: dels=removed
597 597 HG: files=added removed
598 598 $ hg status -amr
599 599 M changed
600 600 $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n"
601 601 M
602 602 A added
603 603 R removed
604 604 $ hg rollback -q
605 605
606 606 $ cat >> .hg/hgrc <<EOF
607 607 > # disable customizing for subsequent tests
608 608 > [committemplate]
609 609 > changeset =
610 610 > EOF
611 611
612 612 $ cd ..
613 613
614 614
615 615 commit copy
616 616
617 617 $ hg init dir2
618 618 $ cd dir2
619 619 $ echo bleh > bar
620 620 $ hg add bar
621 621 $ hg ci -m 'add bar'
622 622
623 623 $ hg cp bar foo
624 624 $ echo >> bar
625 625 $ hg ci -m 'cp bar foo; change bar'
626 626
627 627 $ hg debugrename foo
628 628 foo renamed from bar:26d3ca0dfd18e44d796b564e38dd173c9668d3a9
629 629 $ hg debugindex bar
630 630 rev linkrev nodeid p1 p2
631 631 0 0 26d3ca0dfd18 000000000000 000000000000
632 632 1 1 d267bddd54f7 26d3ca0dfd18 000000000000
633 633
634 634 Test making empty commits
635 635 $ hg commit --config ui.allowemptycommit=True -m "empty commit"
636 636 $ hg log -r . -v --stat
637 637 changeset: 2:d809f3644287
638 638 tag: tip
639 639 user: test
640 640 date: Thu Jan 01 00:00:00 1970 +0000
641 641 description:
642 642 empty commit
643 643
644 644
645 645
646 646 verify pathauditor blocks evil filepaths
647 647 $ cat > evil-commit.py <<EOF
648 648 > from __future__ import absolute_import
649 649 > from mercurial import context, hg, node, ui as uimod
650 650 > notrc = u".h\u200cg".encode('utf-8') + b'/hgrc'
651 651 > u = uimod.ui.load()
652 652 > r = hg.repository(u, b'.')
653 653 > def filectxfn(repo, memctx, path):
654 654 > return context.memfilectx(repo, memctx, path,
655 655 > b'[hooks]\nupdate = echo owned')
656 656 > c = context.memctx(r, [r.changelog.tip(), node.nullid],
657 657 > b'evil', [notrc], filectxfn, 0)
658 658 > r.commitctx(c)
659 659 > EOF
660 660 $ "$PYTHON" evil-commit.py
661 661 #if windows
662 662 $ hg co --clean tip
663 663 abort: path contains illegal component: .h\xe2\x80\x8cg\\hgrc (esc)
664 664 [255]
665 665 #else
666 666 $ hg co --clean tip
667 667 abort: path contains illegal component: .h\xe2\x80\x8cg/hgrc (esc)
668 668 [255]
669 669 #endif
670 670
671 671 $ hg rollback -f
672 672 repository tip rolled back to revision 2 (undo commit)
673 673 $ cat > evil-commit.py <<EOF
674 674 > from __future__ import absolute_import
675 675 > from mercurial import context, hg, node, ui as uimod
676 676 > notrc = b"HG~1/hgrc"
677 677 > u = uimod.ui.load()
678 678 > r = hg.repository(u, b'.')
679 679 > def filectxfn(repo, memctx, path):
680 680 > return context.memfilectx(repo, memctx, path,
681 681 > b'[hooks]\nupdate = echo owned')
682 682 > c = context.memctx(r, [r[b'tip'].node(), node.nullid],
683 683 > b'evil', [notrc], filectxfn, 0)
684 684 > r.commitctx(c)
685 685 > EOF
686 686 $ "$PYTHON" evil-commit.py
687 687 $ hg co --clean tip
688 688 abort: path contains illegal component: HG~1/hgrc
689 689 [255]
690 690
691 691 $ hg rollback -f
692 692 repository tip rolled back to revision 2 (undo commit)
693 693 $ cat > evil-commit.py <<EOF
694 694 > from __future__ import absolute_import
695 695 > from mercurial import context, hg, node, ui as uimod
696 696 > notrc = b"HG8B6C~2/hgrc"
697 697 > u = uimod.ui.load()
698 698 > r = hg.repository(u, b'.')
699 699 > def filectxfn(repo, memctx, path):
700 700 > return context.memfilectx(repo, memctx, path,
701 701 > b'[hooks]\nupdate = echo owned')
702 702 > c = context.memctx(r, [r[b'tip'].node(), node.nullid],
703 703 > b'evil', [notrc], filectxfn, 0)
704 704 > r.commitctx(c)
705 705 > EOF
706 706 $ "$PYTHON" evil-commit.py
707 707 $ hg co --clean tip
708 708 abort: path contains illegal component: HG8B6C~2/hgrc
709 709 [255]
710 710
711 711 $ cd ..
712 712
713 713 # test that an unmodified commit template message aborts
714 714
715 715 $ hg init unmodified_commit_template
716 716 $ cd unmodified_commit_template
717 717 $ echo foo > foo
718 718 $ hg add foo
719 719 $ hg commit -m "foo"
720 720 $ cat >> .hg/hgrc <<EOF
721 721 > [committemplate]
722 722 > changeset.commit = HI THIS IS NOT STRIPPED
723 723 > HG: this is customized commit template
724 724 > HG: {extramsg}
725 725 > {if(activebookmark,
726 726 > "HG: bookmark '{activebookmark}' is activated\n",
727 727 > "HG: no bookmark is activated\n")}{subrepos %
728 728 > "HG: subrepo '{subrepo}' is changed\n"}
729 729 > EOF
730 730 $ cat > $TESTTMP/notouching.sh <<EOF
731 731 > true
732 732 > EOF
733 733 $ echo foo2 > foo2
734 734 $ hg add foo2
735 735 $ HGEDITOR="sh $TESTTMP/notouching.sh" hg commit
736 736 abort: commit message unchanged
737 737 [255]
738 738
739 739 $ cd ..
740 740
741 741 test that text below the --- >8 --- special string is ignored
742 742
743 743 $ cat <<'EOF' > $TESTTMP/lowercaseline.sh
744 744 > cat $1 | sed s/LINE/line/ | tee $1.new
745 745 > mv $1.new $1
746 746 > EOF
747 747
748 748 $ hg init ignore_below_special_string
749 749 $ cd ignore_below_special_string
750 750 $ echo foo > foo
751 751 $ hg add foo
752 752 $ hg commit -m "foo"
753 753 $ cat >> .hg/hgrc <<EOF
754 754 > [committemplate]
755 755 > changeset.commit = first LINE
756 756 > HG: this is customized commit template
757 757 > HG: {extramsg}
758 758 > HG: ------------------------ >8 ------------------------
759 759 > {diff()}
760 760 > EOF
761 761 $ echo foo2 > foo2
762 762 $ hg add foo2
763 763 $ HGEDITOR="sh $TESTTMP/notouching.sh" hg ci
764 764 abort: commit message unchanged
765 765 [255]
766 766 $ HGEDITOR="sh $TESTTMP/lowercaseline.sh" hg ci
767 767 first line
768 768 HG: this is customized commit template
769 769 HG: Leave message empty to abort commit.
770 770 HG: ------------------------ >8 ------------------------
771 771 diff -r e63c23eaa88a foo2
772 772 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
773 773 +++ b/foo2 Thu Jan 01 00:00:00 1970 +0000
774 774 @@ -0,0 +1,1 @@
775 775 +foo2
776 776 $ hg log -T '{desc}\n' -r .
777 777 first line
778 778
779 779 test that the special string --- >8 --- isn't used when not at the beginning of
780 780 a line
781 781
782 782 $ cat >> .hg/hgrc <<EOF
783 783 > [committemplate]
784 784 > changeset.commit = first LINE2
785 785 > another line HG: ------------------------ >8 ------------------------
786 786 > HG: this is customized commit template
787 787 > HG: {extramsg}
788 788 > HG: ------------------------ >8 ------------------------
789 789 > {diff()}
790 790 > EOF
791 791 $ echo foo >> foo
792 792 $ HGEDITOR="sh $TESTTMP/lowercaseline.sh" hg ci
793 793 first line2
794 794 another line HG: ------------------------ >8 ------------------------
795 795 HG: this is customized commit template
796 796 HG: Leave message empty to abort commit.
797 797 HG: ------------------------ >8 ------------------------
798 798 diff -r 3661b22b0702 foo
799 799 --- a/foo Thu Jan 01 00:00:00 1970 +0000
800 800 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
801 801 @@ -1,1 +1,2 @@
802 802 foo
803 803 +foo
804 804 $ hg log -T '{desc}\n' -r .
805 805 first line2
806 806 another line HG: ------------------------ >8 ------------------------
807 807
808 808 also test that this special string isn't accepted when there is some extra text
809 809 at the end
810 810
811 811 $ cat >> .hg/hgrc <<EOF
812 812 > [committemplate]
813 813 > changeset.commit = first LINE3
814 814 > HG: ------------------------ >8 ------------------------foobar
815 815 > second line
816 816 > HG: this is customized commit template
817 817 > HG: {extramsg}
818 818 > HG: ------------------------ >8 ------------------------
819 819 > {diff()}
820 820 > EOF
821 821 $ echo foo >> foo
822 822 $ HGEDITOR="sh $TESTTMP/lowercaseline.sh" hg ci
823 823 first line3
824 824 HG: ------------------------ >8 ------------------------foobar
825 825 second line
826 826 HG: this is customized commit template
827 827 HG: Leave message empty to abort commit.
828 828 HG: ------------------------ >8 ------------------------
829 829 diff -r ce648f5f066f foo
830 830 --- a/foo Thu Jan 01 00:00:00 1970 +0000
831 831 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
832 832 @@ -1,2 +1,3 @@
833 833 foo
834 834 foo
835 835 +foo
836 836 $ hg log -T '{desc}\n' -r .
837 837 first line3
838 838 second line
839 839
840 840 $ cd ..
841
842 testing commands.commit.post-status config option
843
844 $ hg init ci-post-st
845 $ cd ci-post-st
846 $ echo '[commands]' > .hg/hgrc
847 $ echo 'commit.post-status = 1' >> .hg/hgrc
848
849 $ echo 'ignored-file' > .hgignore
850 $ hg ci -qAm 0
851
852 $ echo 'c' > clean-file
853 $ echo 'a' > added-file
854 $ echo '?' > unknown-file
855 $ echo 'i' > ignored-file
856 $ hg add clean-file added-file
857 $ hg ci -m 1 clean-file
858 A added-file
859 ? unknown-file
860 $ hg st -mardu
861 A added-file
862 ? unknown-file
863
864 $ touch modified-file
865 $ hg add modified-file
866 $ hg ci -m 2 modified-file -q
867
868 $ echo 'm' > modified-file
869 $ hg ci --amend -m 'reworded' -X 're:'
870 saved backup bundle to $TESTTMP/ci-post-st/.hg/strip-backup/*-amend.hg (glob)
871 M modified-file
872 A added-file
873 ? unknown-file
874 $ hg st -mardu
875 M modified-file
876 A added-file
877 ? unknown-file
878
879 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now