comparison mercurial/commands.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents c04e0836f039
children 687b865b95ad
comparison
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
78 INTENT_READONLY = registrar.INTENT_READONLY 78 INTENT_READONLY = registrar.INTENT_READONLY
79 79
80 # common command options 80 # common command options
81 81
82 globalopts = [ 82 globalopts = [
83 ('R', 'repository', '', 83 (
84 _('repository root directory or name of overlay bundle file'), 84 'R',
85 _('REPO')), 85 'repository',
86 ('', 'cwd', '', 86 '',
87 _('change working directory'), _('DIR')), 87 _('repository root directory or name of overlay bundle file'),
88 ('y', 'noninteractive', None, 88 _('REPO'),
89 _('do not prompt, automatically pick the first choice for all prompts')), 89 ),
90 ('', 'cwd', '', _('change working directory'), _('DIR')),
91 (
92 'y',
93 'noninteractive',
94 None,
95 _('do not prompt, automatically pick the first choice for all prompts'),
96 ),
90 ('q', 'quiet', None, _('suppress output')), 97 ('q', 'quiet', None, _('suppress output')),
91 ('v', 'verbose', None, _('enable additional output')), 98 ('v', 'verbose', None, _('enable additional output')),
92 ('', 'color', '', 99 (
93 # i18n: 'always', 'auto', 'never', and 'debug' are keywords 100 '',
94 # and should not be translated 101 'color',
95 _("when to colorize (boolean, always, auto, never, or debug)"), 102 '',
96 _('TYPE')), 103 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
97 ('', 'config', [], 104 # and should not be translated
98 _('set/override config option (use \'section.name=value\')'), 105 _("when to colorize (boolean, always, auto, never, or debug)"),
99 _('CONFIG')), 106 _('TYPE'),
107 ),
108 (
109 '',
110 'config',
111 [],
112 _('set/override config option (use \'section.name=value\')'),
113 _('CONFIG'),
114 ),
100 ('', 'debug', None, _('enable debugging output')), 115 ('', 'debug', None, _('enable debugging output')),
101 ('', 'debugger', None, _('start debugger')), 116 ('', 'debugger', None, _('start debugger')),
102 ('', 'encoding', encoding.encoding, _('set the charset encoding'), 117 (
103 _('ENCODE')), 118 '',
104 ('', 'encodingmode', encoding.encodingmode, 119 'encoding',
105 _('set the charset encoding mode'), _('MODE')), 120 encoding.encoding,
121 _('set the charset encoding'),
122 _('ENCODE'),
123 ),
124 (
125 '',
126 'encodingmode',
127 encoding.encodingmode,
128 _('set the charset encoding mode'),
129 _('MODE'),
130 ),
106 ('', 'traceback', None, _('always print a traceback on exception')), 131 ('', 'traceback', None, _('always print a traceback on exception')),
107 ('', 'time', None, _('time how long the command takes')), 132 ('', 'time', None, _('time how long the command takes')),
108 ('', 'profile', None, _('print command execution profile')), 133 ('', 'profile', None, _('print command execution profile')),
109 ('', 'version', None, _('output version information and exit')), 134 ('', 'version', None, _('output version information and exit')),
110 ('h', 'help', None, _('display help and exit')), 135 ('h', 'help', None, _('display help and exit')),
111 ('', 'hidden', False, _('consider hidden changesets')), 136 ('', 'hidden', False, _('consider hidden changesets')),
112 ('', 'pager', 'auto', 137 (
113 _("when to paginate (boolean, always, auto, or never)"), _('TYPE')), 138 '',
139 'pager',
140 'auto',
141 _("when to paginate (boolean, always, auto, or never)"),
142 _('TYPE'),
143 ),
114 ] 144 ]
115 145
116 dryrunopts = cmdutil.dryrunopts 146 dryrunopts = cmdutil.dryrunopts
117 remoteopts = cmdutil.remoteopts 147 remoteopts = cmdutil.remoteopts
118 walkopts = cmdutil.walkopts 148 walkopts = cmdutil.walkopts
130 subrepoopts = cmdutil.subrepoopts 160 subrepoopts = cmdutil.subrepoopts
131 debugrevlogopts = cmdutil.debugrevlogopts 161 debugrevlogopts = cmdutil.debugrevlogopts
132 162
133 # Commands start here, listed alphabetically 163 # Commands start here, listed alphabetically
134 164
135 @command('abort', 165
136 dryrunopts, helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, 166 @command(
137 helpbasic=True) 167 'abort',
168 dryrunopts,
169 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
170 helpbasic=True,
171 )
138 def abort(ui, repo, **opts): 172 def abort(ui, repo, **opts):
139 """abort an unfinished operation (EXPERIMENTAL) 173 """abort an unfinished operation (EXPERIMENTAL)
140 174
141 Aborts a multistep operation like graft, histedit, rebase, merge, 175 Aborts a multistep operation like graft, histedit, rebase, merge,
142 and unshelve if they are in an unfinished state. 176 and unshelve if they are in an unfinished state.
146 dryrun = opts.get(r'dry_run') 180 dryrun = opts.get(r'dry_run')
147 abortstate = cmdutil.getunfinishedstate(repo) 181 abortstate = cmdutil.getunfinishedstate(repo)
148 if not abortstate: 182 if not abortstate:
149 raise error.Abort(_('no operation in progress')) 183 raise error.Abort(_('no operation in progress'))
150 if not abortstate.abortfunc: 184 if not abortstate.abortfunc:
151 raise error.Abort((_("%s in progress but does not support 'hg abort'") % 185 raise error.Abort(
152 (abortstate._opname)), hint=abortstate.hint()) 186 (
187 _("%s in progress but does not support 'hg abort'")
188 % (abortstate._opname)
189 ),
190 hint=abortstate.hint(),
191 )
153 if dryrun: 192 if dryrun:
154 ui.status(_('%s in progress, will be aborted\n') % (abortstate._opname)) 193 ui.status(_('%s in progress, will be aborted\n') % (abortstate._opname))
155 return 194 return
156 return abortstate.abortfunc(ui, repo) 195 return abortstate.abortfunc(ui, repo)
157 196
158 @command('add', 197
198 @command(
199 'add',
159 walkopts + subrepoopts + dryrunopts, 200 walkopts + subrepoopts + dryrunopts,
160 _('[OPTION]... [FILE]...'), 201 _('[OPTION]... [FILE]...'),
161 helpcategory=command.CATEGORY_WORKING_DIRECTORY, 202 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
162 helpbasic=True, inferrepo=True) 203 helpbasic=True,
204 inferrepo=True,
205 )
163 def add(ui, repo, *pats, **opts): 206 def add(ui, repo, *pats, **opts):
164 """add the specified files on the next commit 207 """add the specified files on the next commit
165 208
166 Schedule files to be version controlled and added to the 209 Schedule files to be version controlled and added to the
167 repository. 210 repository.
206 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts)) 249 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
207 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) 250 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
208 rejected = cmdutil.add(ui, repo, m, "", uipathfn, False, **opts) 251 rejected = cmdutil.add(ui, repo, m, "", uipathfn, False, **opts)
209 return rejected and 1 or 0 252 return rejected and 1 or 0
210 253
211 @command('addremove', 254
255 @command(
256 'addremove',
212 similarityopts + subrepoopts + walkopts + dryrunopts, 257 similarityopts + subrepoopts + walkopts + dryrunopts,
213 _('[OPTION]... [FILE]...'), 258 _('[OPTION]... [FILE]...'),
214 helpcategory=command.CATEGORY_WORKING_DIRECTORY, 259 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
215 inferrepo=True) 260 inferrepo=True,
261 )
216 def addremove(ui, repo, *pats, **opts): 262 def addremove(ui, repo, *pats, **opts):
217 """add all new files, delete all missing files 263 """add all new files, delete all missing files
218 264
219 Add all new files and remove all missing files from the 265 Add all new files and remove all missing files from the
220 repository. 266 repository.
281 matcher = scmutil.match(repo[None], pats, opts) 327 matcher = scmutil.match(repo[None], pats, opts)
282 relative = scmutil.anypats(pats, opts) 328 relative = scmutil.anypats(pats, opts)
283 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative) 329 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
284 return scmutil.addremove(repo, matcher, "", uipathfn, opts) 330 return scmutil.addremove(repo, matcher, "", uipathfn, opts)
285 331
286 @command('annotate|blame', 332
287 [('r', 'rev', '', _('annotate the specified revision'), _('REV')), 333 @command(
288 ('', 'follow', None, 334 'annotate|blame',
289 _('follow copies/renames and list the filename (DEPRECATED)')), 335 [
290 ('', 'no-follow', None, _("don't follow copies and renames")), 336 ('r', 'rev', '', _('annotate the specified revision'), _('REV')),
291 ('a', 'text', None, _('treat all files as text')), 337 (
292 ('u', 'user', None, _('list the author (long with -v)')), 338 '',
293 ('f', 'file', None, _('list the filename')), 339 'follow',
294 ('d', 'date', None, _('list the date (short with -q)')), 340 None,
295 ('n', 'number', None, _('list the revision number (default)')), 341 _('follow copies/renames and list the filename (DEPRECATED)'),
296 ('c', 'changeset', None, _('list the changeset')), 342 ),
297 ('l', 'line-number', None, _('show line number at the first appearance')), 343 ('', 'no-follow', None, _("don't follow copies and renames")),
298 ('', 'skip', [], _('revision to not display (EXPERIMENTAL)'), _('REV')), 344 ('a', 'text', None, _('treat all files as text')),
299 ] + diffwsopts + walkopts + formatteropts, 345 ('u', 'user', None, _('list the author (long with -v)')),
346 ('f', 'file', None, _('list the filename')),
347 ('d', 'date', None, _('list the date (short with -q)')),
348 ('n', 'number', None, _('list the revision number (default)')),
349 ('c', 'changeset', None, _('list the changeset')),
350 (
351 'l',
352 'line-number',
353 None,
354 _('show line number at the first appearance'),
355 ),
356 ('', 'skip', [], _('revision to not display (EXPERIMENTAL)'), _('REV')),
357 ]
358 + diffwsopts
359 + walkopts
360 + formatteropts,
300 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'), 361 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
301 helpcategory=command.CATEGORY_FILE_CONTENTS, 362 helpcategory=command.CATEGORY_FILE_CONTENTS,
302 helpbasic=True, inferrepo=True) 363 helpbasic=True,
364 inferrepo=True,
365 )
303 def annotate(ui, repo, *pats, **opts): 366 def annotate(ui, repo, *pats, **opts):
304 """show changeset information by line for each file 367 """show changeset information by line for each file
305 368
306 List changes in files, showing the revision id responsible for 369 List changes in files, showing the revision id responsible for
307 each line. 370 each line.
345 if opts.get('follow'): 408 if opts.get('follow'):
346 # --follow is deprecated and now just an alias for -f/--file 409 # --follow is deprecated and now just an alias for -f/--file
347 # to mimic the behavior of Mercurial before version 1.5 410 # to mimic the behavior of Mercurial before version 1.5
348 opts['file'] = True 411 opts['file'] = True
349 412
350 if (not opts.get('user') and not opts.get('changeset') 413 if (
351 and not opts.get('date') and not opts.get('file')): 414 not opts.get('user')
415 and not opts.get('changeset')
416 and not opts.get('date')
417 and not opts.get('file')
418 ):
352 opts['number'] = True 419 opts['number'] = True
353 420
354 linenumber = opts.get('line_number') is not None 421 linenumber = opts.get('line_number') is not None
355 if linenumber and (not opts.get('changeset')) and (not opts.get('number')): 422 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
356 raise error.Abort(_('at least one of -n/-c is required for -l')) 423 raise error.Abort(_('at least one of -n/-c is required for -l'))
363 ui.pager('annotate') 430 ui.pager('annotate')
364 rootfm = ui.formatter('annotate', opts) 431 rootfm = ui.formatter('annotate', opts)
365 if ui.debugflag: 432 if ui.debugflag:
366 shorthex = pycompat.identity 433 shorthex = pycompat.identity
367 else: 434 else:
435
368 def shorthex(h): 436 def shorthex(h):
369 return h[:12] 437 return h[:12]
438
370 if ui.quiet: 439 if ui.quiet:
371 datefunc = dateutil.shortdate 440 datefunc = dateutil.shortdate
372 else: 441 else:
373 datefunc = dateutil.datestr 442 datefunc = dateutil.datestr
374 if ctx.rev() is None: 443 if ctx.rev() is None:
377 def formatrev(rev): 446 def formatrev(rev):
378 if rev == wdirrev: 447 if rev == wdirrev:
379 return '%d' % ctx.p1().rev() 448 return '%d' % ctx.p1().rev()
380 else: 449 else:
381 return '%d' % rev 450 return '%d' % rev
451
382 else: 452 else:
453
383 def formatrev(rev): 454 def formatrev(rev):
384 if rev == wdirrev: 455 if rev == wdirrev:
385 return '%d+' % ctx.p1().rev() 456 return '%d+' % ctx.p1().rev()
386 else: 457 else:
387 return '%d ' % rev 458 return '%d ' % rev
459
388 def formathex(h): 460 def formathex(h):
389 if h == wdirhex: 461 if h == wdirhex:
390 return '%s+' % shorthex(hex(ctx.p1().node())) 462 return '%s+' % shorthex(hex(ctx.p1().node()))
391 else: 463 else:
392 return '%s ' % shorthex(h) 464 return '%s ' % shorthex(h)
465
393 else: 466 else:
394 formatrev = b'%d'.__mod__ 467 formatrev = b'%d'.__mod__
395 formathex = shorthex 468 formathex = shorthex
396 469
397 opmap = [ 470 opmap = [
408 'path': 'file', 481 'path': 'file',
409 'lineno': 'line_number', 482 'lineno': 'line_number',
410 } 483 }
411 484
412 if rootfm.isplain(): 485 if rootfm.isplain():
486
413 def makefunc(get, fmt): 487 def makefunc(get, fmt):
414 return lambda x: fmt(get(x)) 488 return lambda x: fmt(get(x))
489
415 else: 490 else:
491
416 def makefunc(get, fmt): 492 def makefunc(get, fmt):
417 return get 493 return get
494
418 datahint = rootfm.datahint() 495 datahint = rootfm.datahint()
419 funcmap = [(makefunc(get, fmt), sep) for fn, sep, get, fmt in opmap 496 funcmap = [
420 if opts.get(opnamemap.get(fn, fn)) or fn in datahint] 497 (makefunc(get, fmt), sep)
421 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column 498 for fn, sep, get, fmt in opmap
422 fields = ' '.join(fn for fn, sep, get, fmt in opmap 499 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
423 if opts.get(opnamemap.get(fn, fn)) or fn in datahint) 500 ]
501 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
502 fields = ' '.join(
503 fn
504 for fn, sep, get, fmt in opmap
505 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
506 )
424 507
425 def bad(x, y): 508 def bad(x, y):
426 raise error.Abort("%s: %s" % (x, y)) 509 raise error.Abort("%s: %s" % (x, y))
427 510
428 m = scmutil.match(ctx, pats, opts, badfn=bad) 511 m = scmutil.match(ctx, pats, opts, badfn=bad)
429 512
430 follow = not opts.get('no_follow') 513 follow = not opts.get('no_follow')
431 diffopts = patch.difffeatureopts(ui, opts, section='annotate', 514 diffopts = patch.difffeatureopts(
432 whitespace=True) 515 ui, opts, section='annotate', whitespace=True
516 )
433 skiprevs = opts.get('skip') 517 skiprevs = opts.get('skip')
434 if skiprevs: 518 if skiprevs:
435 skiprevs = scmutil.revrange(repo, skiprevs) 519 skiprevs = scmutil.revrange(repo, skiprevs)
436 520
437 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) 521 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
442 if not opts.get('text') and fctx.isbinary(): 526 if not opts.get('text') and fctx.isbinary():
443 rootfm.plain(_("%s: binary file\n") % uipathfn(abs)) 527 rootfm.plain(_("%s: binary file\n") % uipathfn(abs))
444 continue 528 continue
445 529
446 fm = rootfm.nested('lines', tmpl='{rev}: {line}') 530 fm = rootfm.nested('lines', tmpl='{rev}: {line}')
447 lines = fctx.annotate(follow=follow, skiprevs=skiprevs, 531 lines = fctx.annotate(
448 diffopts=diffopts) 532 follow=follow, skiprevs=skiprevs, diffopts=diffopts
533 )
449 if not lines: 534 if not lines:
450 fm.end() 535 fm.end()
451 continue 536 continue
452 formats = [] 537 formats = []
453 pieces = [] 538 pieces = []
476 fm.plain('\n') 561 fm.plain('\n')
477 fm.end() 562 fm.end()
478 563
479 rootfm.end() 564 rootfm.end()
480 565
481 @command('archive', 566
482 [('', 'no-decode', None, _('do not pass files through decoders')), 567 @command(
483 ('p', 'prefix', '', _('directory prefix for files in archive'), 568 'archive',
484 _('PREFIX')), 569 [
485 ('r', 'rev', '', _('revision to distribute'), _('REV')), 570 ('', 'no-decode', None, _('do not pass files through decoders')),
486 ('t', 'type', '', _('type of distribution to create'), _('TYPE')), 571 (
487 ] + subrepoopts + walkopts, 572 'p',
573 'prefix',
574 '',
575 _('directory prefix for files in archive'),
576 _('PREFIX'),
577 ),
578 ('r', 'rev', '', _('revision to distribute'), _('REV')),
579 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
580 ]
581 + subrepoopts
582 + walkopts,
488 _('[OPTION]... DEST'), 583 _('[OPTION]... DEST'),
489 helpcategory=command.CATEGORY_IMPORT_EXPORT) 584 helpcategory=command.CATEGORY_IMPORT_EXPORT,
585 )
490 def archive(ui, repo, dest, **opts): 586 def archive(ui, repo, dest, **opts):
491 '''create an unversioned archive of a repository revision 587 '''create an unversioned archive of a repository revision
492 588
493 By default, the revision used is the parent of the working 589 By default, the revision used is the parent of the working
494 directory; use -r/--rev to specify a different revision. 590 directory; use -r/--rev to specify a different revision.
551 if not prefix: 647 if not prefix:
552 prefix = os.path.basename(repo.root) + '-%h' 648 prefix = os.path.basename(repo.root) + '-%h'
553 649
554 prefix = cmdutil.makefilename(ctx, prefix) 650 prefix = cmdutil.makefilename(ctx, prefix)
555 match = scmutil.match(ctx, [], opts) 651 match = scmutil.match(ctx, [], opts)
556 archival.archive(repo, dest, node, kind, not opts.get('no_decode'), 652 archival.archive(
557 match, prefix, subrepos=opts.get('subrepos')) 653 repo,
558 654 dest,
559 @command('backout', 655 node,
560 [('', 'merge', None, _('merge with old dirstate parent after backout')), 656 kind,
561 ('', 'commit', None, 657 not opts.get('no_decode'),
562 _('commit if no conflicts were encountered (DEPRECATED)')), 658 match,
563 ('', 'no-commit', None, _('do not commit')), 659 prefix,
564 ('', 'parent', '', 660 subrepos=opts.get('subrepos'),
565 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')), 661 )
566 ('r', 'rev', '', _('revision to backout'), _('REV')), 662
567 ('e', 'edit', False, _('invoke editor on commit messages')), 663
568 ] + mergetoolopts + walkopts + commitopts + commitopts2, 664 @command(
665 'backout',
666 [
667 ('', 'merge', None, _('merge with old dirstate parent after backout')),
668 (
669 '',
670 'commit',
671 None,
672 _('commit if no conflicts were encountered (DEPRECATED)'),
673 ),
674 ('', 'no-commit', None, _('do not commit')),
675 (
676 '',
677 'parent',
678 '',
679 _('parent to choose when backing out merge (DEPRECATED)'),
680 _('REV'),
681 ),
682 ('r', 'rev', '', _('revision to backout'), _('REV')),
683 ('e', 'edit', False, _('invoke editor on commit messages')),
684 ]
685 + mergetoolopts
686 + walkopts
687 + commitopts
688 + commitopts2,
569 _('[OPTION]... [-r] REV'), 689 _('[OPTION]... [-r] REV'),
570 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT) 690 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
691 )
571 def backout(ui, repo, node=None, rev=None, **opts): 692 def backout(ui, repo, node=None, rev=None, **opts):
572 '''reverse effect of earlier changeset 693 '''reverse effect of earlier changeset
573 694
574 Prepare a new changeset with the effect of REV undone in the 695 Prepare a new changeset with the effect of REV undone in the
575 current working directory. If no conflicts were encountered, 696 current working directory. If no conflicts were encountered,
620 Returns 0 on success, 1 if nothing to backout or there are unresolved 741 Returns 0 on success, 1 if nothing to backout or there are unresolved
621 files. 742 files.
622 ''' 743 '''
623 with repo.wlock(), repo.lock(): 744 with repo.wlock(), repo.lock():
624 return _dobackout(ui, repo, node, rev, **opts) 745 return _dobackout(ui, repo, node, rev, **opts)
746
625 747
626 def _dobackout(ui, repo, node=None, rev=None, **opts): 748 def _dobackout(ui, repo, node=None, rev=None, **opts):
627 opts = pycompat.byteskwargs(opts) 749 opts = pycompat.byteskwargs(opts)
628 if opts.get('commit') and opts.get('no_commit'): 750 if opts.get('commit') and opts.get('no_commit'):
629 raise error.Abort(_("cannot use --commit with --no-commit")) 751 raise error.Abort(_("cannot use --commit with --no-commit"))
657 if p2 != nullid: 779 if p2 != nullid:
658 if not opts.get('parent'): 780 if not opts.get('parent'):
659 raise error.Abort(_('cannot backout a merge changeset')) 781 raise error.Abort(_('cannot backout a merge changeset'))
660 p = repo.lookup(opts['parent']) 782 p = repo.lookup(opts['parent'])
661 if p not in (p1, p2): 783 if p not in (p1, p2):
662 raise error.Abort(_('%s is not a parent of %s') % 784 raise error.Abort(
663 (short(p), short(node))) 785 _('%s is not a parent of %s') % (short(p), short(node))
786 )
664 parent = p 787 parent = p
665 else: 788 else:
666 if opts.get('parent'): 789 if opts.get('parent'):
667 raise error.Abort(_('cannot use --parent on non-merge changeset')) 790 raise error.Abort(_('cannot use --parent on non-merge changeset'))
668 parent = p1 791 parent = p1
673 rctx = scmutil.revsingle(repo, hex(parent)) 796 rctx = scmutil.revsingle(repo, hex(parent))
674 if not opts.get('merge') and op1 != node: 797 if not opts.get('merge') and op1 != node:
675 with dirstateguard.dirstateguard(repo, 'backout'): 798 with dirstateguard.dirstateguard(repo, 'backout'):
676 overrides = {('ui', 'forcemerge'): opts.get('tool', '')} 799 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
677 with ui.configoverride(overrides, 'backout'): 800 with ui.configoverride(overrides, 'backout'):
678 stats = mergemod.update(repo, parent, branchmerge=True, 801 stats = mergemod.update(
679 force=True, ancestor=node, 802 repo,
680 mergeancestor=False) 803 parent,
804 branchmerge=True,
805 force=True,
806 ancestor=node,
807 mergeancestor=False,
808 )
681 repo.setparents(op1, op2) 809 repo.setparents(op1, op2)
682 hg._showstats(repo, stats) 810 hg._showstats(repo, stats)
683 if stats.unresolvedcount: 811 if stats.unresolvedcount:
684 repo.ui.status(_("use 'hg resolve' to retry unresolved " 812 repo.ui.status(
685 "file merges\n")) 813 _("use 'hg resolve' to retry unresolved " "file merges\n")
814 )
686 return 1 815 return 1
687 else: 816 else:
688 hg.clean(repo, node, show_stats=False) 817 hg.clean(repo, node, show_stats=False)
689 repo.dirstate.setbranch(branch) 818 repo.dirstate.setbranch(branch)
690 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents()) 819 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
691 820
692 if opts.get('no_commit'): 821 if opts.get('no_commit'):
693 msg = _("changeset %s backed out, " 822 msg = _("changeset %s backed out, " "don't forget to commit.\n")
694 "don't forget to commit.\n")
695 ui.status(msg % short(node)) 823 ui.status(msg % short(node))
696 return 0 824 return 0
697 825
698 def commitfunc(ui, repo, message, match, opts): 826 def commitfunc(ui, repo, message, match, opts):
699 editform = 'backout' 827 editform = 'backout'
700 e = cmdutil.getcommiteditor(editform=editform, 828 e = cmdutil.getcommiteditor(
701 **pycompat.strkwargs(opts)) 829 editform=editform, **pycompat.strkwargs(opts)
830 )
702 if not message: 831 if not message:
703 # we don't translate commit messages 832 # we don't translate commit messages
704 message = "Backed out changeset %s" % short(node) 833 message = "Backed out changeset %s" % short(node)
705 e = cmdutil.getcommiteditor(edit=True, editform=editform) 834 e = cmdutil.getcommiteditor(edit=True, editform=editform)
706 return repo.commit(message, opts.get('user'), opts.get('date'), 835 return repo.commit(
707 match, editor=e) 836 message, opts.get('user'), opts.get('date'), match, editor=e
837 )
838
708 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts) 839 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
709 if not newnode: 840 if not newnode:
710 ui.status(_("nothing changed\n")) 841 ui.status(_("nothing changed\n"))
711 return 1 842 return 1
712 cmdutil.commitstatus(repo, newnode, branch, bheads) 843 cmdutil.commitstatus(repo, newnode, branch, bheads)
713 844
714 def nice(node): 845 def nice(node):
715 return '%d:%s' % (repo.changelog.rev(node), short(node)) 846 return '%d:%s' % (repo.changelog.rev(node), short(node))
716 ui.status(_('changeset %s backs out changeset %s\n') % 847
717 (nice(repo.changelog.tip()), nice(node))) 848 ui.status(
849 _('changeset %s backs out changeset %s\n')
850 % (nice(repo.changelog.tip()), nice(node))
851 )
718 if opts.get('merge') and op1 != node: 852 if opts.get('merge') and op1 != node:
719 hg.clean(repo, op1, show_stats=False) 853 hg.clean(repo, op1, show_stats=False)
720 ui.status(_('merging with changeset %s\n') 854 ui.status(_('merging with changeset %s\n') % nice(repo.changelog.tip()))
721 % nice(repo.changelog.tip()))
722 overrides = {('ui', 'forcemerge'): opts.get('tool', '')} 855 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
723 with ui.configoverride(overrides, 'backout'): 856 with ui.configoverride(overrides, 'backout'):
724 return hg.merge(repo, hex(repo.changelog.tip())) 857 return hg.merge(repo, hex(repo.changelog.tip()))
725 return 0 858 return 0
726 859
727 @command('bisect', 860
728 [('r', 'reset', False, _('reset bisect state')), 861 @command(
729 ('g', 'good', False, _('mark changeset good')), 862 'bisect',
730 ('b', 'bad', False, _('mark changeset bad')), 863 [
731 ('s', 'skip', False, _('skip testing changeset')), 864 ('r', 'reset', False, _('reset bisect state')),
732 ('e', 'extend', False, _('extend the bisect range')), 865 ('g', 'good', False, _('mark changeset good')),
733 ('c', 'command', '', _('use command to check changeset state'), _('CMD')), 866 ('b', 'bad', False, _('mark changeset bad')),
734 ('U', 'noupdate', False, _('do not update to target'))], 867 ('s', 'skip', False, _('skip testing changeset')),
868 ('e', 'extend', False, _('extend the bisect range')),
869 (
870 'c',
871 'command',
872 '',
873 _('use command to check changeset state'),
874 _('CMD'),
875 ),
876 ('U', 'noupdate', False, _('do not update to target')),
877 ],
735 _("[-gbsr] [-U] [-c CMD] [REV]"), 878 _("[-gbsr] [-U] [-c CMD] [REV]"),
736 helpcategory=command.CATEGORY_CHANGE_NAVIGATION) 879 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
737 def bisect(ui, repo, rev=None, extra=None, command=None, 880 )
738 reset=None, good=None, bad=None, skip=None, extend=None, 881 def bisect(
739 noupdate=None): 882 ui,
883 repo,
884 rev=None,
885 extra=None,
886 command=None,
887 reset=None,
888 good=None,
889 bad=None,
890 skip=None,
891 extend=None,
892 noupdate=None,
893 ):
740 """subdivision search of changesets 894 """subdivision search of changesets
741 895
742 This command helps to find changesets which introduce problems. To 896 This command helps to find changesets which introduce problems. To
743 use, mark the earliest changeset you know exhibits the problem as 897 use, mark the earliest changeset you know exhibits the problem as
744 bad, then mark the latest changeset which is free from the problem 898 bad, then mark the latest changeset which is free from the problem
841 } 995 }
842 996
843 enabled = [x for x in incompatibles if incompatibles[x]] 997 enabled = [x for x in incompatibles if incompatibles[x]]
844 998
845 if len(enabled) > 1: 999 if len(enabled) > 1:
846 raise error.Abort(_('%s and %s are incompatible') % 1000 raise error.Abort(
847 tuple(sorted(enabled)[0:2])) 1001 _('%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
1002 )
848 1003
849 if reset: 1004 if reset:
850 hbisect.resetstate(repo) 1005 hbisect.resetstate(repo)
851 return 1006 return
852 1007
882 changesets = 1 1037 changesets = 1
883 if noupdate: 1038 if noupdate:
884 try: 1039 try:
885 node = state['current'][0] 1040 node = state['current'][0]
886 except LookupError: 1041 except LookupError:
887 raise error.Abort(_('current bisect revision is unknown - ' 1042 raise error.Abort(
888 'start a new bisect to fix')) 1043 _(
1044 'current bisect revision is unknown - '
1045 'start a new bisect to fix'
1046 )
1047 )
889 else: 1048 else:
890 node, p2 = repo.dirstate.parents() 1049 node, p2 = repo.dirstate.parents()
891 if p2 != nullid: 1050 if p2 != nullid:
892 raise error.Abort(_('current bisect revision is a merge')) 1051 raise error.Abort(_('current bisect revision is a merge'))
893 if rev: 1052 if rev:
895 try: 1054 try:
896 while changesets: 1055 while changesets:
897 # update state 1056 # update state
898 state['current'] = [node] 1057 state['current'] = [node]
899 hbisect.save_state(repo, state) 1058 hbisect.save_state(repo, state)
900 status = ui.system(command, environ={'HG_NODE': hex(node)}, 1059 status = ui.system(
901 blockedtag='bisect_check') 1060 command,
1061 environ={'HG_NODE': hex(node)},
1062 blockedtag='bisect_check',
1063 )
902 if status == 125: 1064 if status == 125:
903 transition = "skip" 1065 transition = "skip"
904 elif status == 0: 1066 elif status == 0:
905 transition = "good" 1067 transition = "good"
906 # status < 0 means process was killed 1068 # status < 0 means process was killed
910 raise error.Abort(_("%s killed") % command) 1072 raise error.Abort(_("%s killed") % command)
911 else: 1073 else:
912 transition = "bad" 1074 transition = "bad"
913 state[transition].append(node) 1075 state[transition].append(node)
914 ctx = repo[node] 1076 ctx = repo[node]
915 ui.status(_('changeset %d:%s: %s\n') % (ctx.rev(), ctx, 1077 ui.status(
916 transition)) 1078 _('changeset %d:%s: %s\n') % (ctx.rev(), ctx, transition)
1079 )
917 hbisect.checkstate(state) 1080 hbisect.checkstate(state)
918 # bisect 1081 # bisect
919 nodes, changesets, bgood = hbisect.bisect(repo, state) 1082 nodes, changesets, bgood = hbisect.bisect(repo, state)
920 # update to next check 1083 # update to next check
921 node = nodes[0] 1084 node = nodes[0]
932 nodes, changesets, good = hbisect.bisect(repo, state) 1095 nodes, changesets, good = hbisect.bisect(repo, state)
933 if extend: 1096 if extend:
934 if not changesets: 1097 if not changesets:
935 extendnode = hbisect.extendrange(repo, state, nodes, good) 1098 extendnode = hbisect.extendrange(repo, state, nodes, good)
936 if extendnode is not None: 1099 if extendnode is not None:
937 ui.write(_("Extending search to changeset %d:%s\n") 1100 ui.write(
938 % (extendnode.rev(), extendnode)) 1101 _("Extending search to changeset %d:%s\n")
1102 % (extendnode.rev(), extendnode)
1103 )
939 state['current'] = [extendnode.node()] 1104 state['current'] = [extendnode.node()]
940 hbisect.save_state(repo, state) 1105 hbisect.save_state(repo, state)
941 return mayupdate(repo, extendnode.node()) 1106 return mayupdate(repo, extendnode.node())
942 raise error.Abort(_("nothing to extend")) 1107 raise error.Abort(_("nothing to extend"))
943 1108
944 if changesets == 0: 1109 if changesets == 0:
945 hbisect.printresult(ui, repo, state, displayer, nodes, good) 1110 hbisect.printresult(ui, repo, state, displayer, nodes, good)
946 else: 1111 else:
947 assert len(nodes) == 1 # only a single node can be tested next 1112 assert len(nodes) == 1 # only a single node can be tested next
948 node = nodes[0] 1113 node = nodes[0]
949 # compute the approximate number of remaining tests 1114 # compute the approximate number of remaining tests
950 tests, size = 0, 2 1115 tests, size = 0, 2
951 while size <= changesets: 1116 while size <= changesets:
952 tests, size = tests + 1, size * 2 1117 tests, size = tests + 1, size * 2
953 rev = repo.changelog.rev(node) 1118 rev = repo.changelog.rev(node)
954 ui.write(_("Testing changeset %d:%s " 1119 ui.write(
955 "(%d changesets remaining, ~%d tests)\n") 1120 _(
956 % (rev, short(node), changesets, tests)) 1121 "Testing changeset %d:%s "
1122 "(%d changesets remaining, ~%d tests)\n"
1123 )
1124 % (rev, short(node), changesets, tests)
1125 )
957 state['current'] = [node] 1126 state['current'] = [node]
958 hbisect.save_state(repo, state) 1127 hbisect.save_state(repo, state)
959 return mayupdate(repo, node) 1128 return mayupdate(repo, node)
960 1129
961 @command('bookmarks|bookmark', 1130
962 [('f', 'force', False, _('force')), 1131 @command(
963 ('r', 'rev', '', _('revision for bookmark action'), _('REV')), 1132 'bookmarks|bookmark',
964 ('d', 'delete', False, _('delete a given bookmark')), 1133 [
965 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')), 1134 ('f', 'force', False, _('force')),
966 ('i', 'inactive', False, _('mark a bookmark inactive')), 1135 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
967 ('l', 'list', False, _('list existing bookmarks')), 1136 ('d', 'delete', False, _('delete a given bookmark')),
968 ] + formatteropts, 1137 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
1138 ('i', 'inactive', False, _('mark a bookmark inactive')),
1139 ('l', 'list', False, _('list existing bookmarks')),
1140 ]
1141 + formatteropts,
969 _('hg bookmarks [OPTIONS]... [NAME]...'), 1142 _('hg bookmarks [OPTIONS]... [NAME]...'),
970 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) 1143 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1144 )
971 def bookmark(ui, repo, *names, **opts): 1145 def bookmark(ui, repo, *names, **opts):
972 '''create a new bookmark or list existing bookmarks 1146 '''create a new bookmark or list existing bookmarks
973 1147
974 Bookmarks are labels on changesets to help track lines of development. 1148 Bookmarks are labels on changesets to help track lines of development.
975 Bookmarks are unversioned and can be moved, renamed and deleted. 1149 Bookmarks are unversioned and can be moved, renamed and deleted.
1033 rev = opts.get('rev') 1207 rev = opts.get('rev')
1034 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark 1208 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark
1035 1209
1036 selactions = [k for k in ['delete', 'rename', 'list'] if opts.get(k)] 1210 selactions = [k for k in ['delete', 'rename', 'list'] if opts.get(k)]
1037 if len(selactions) > 1: 1211 if len(selactions) > 1:
1038 raise error.Abort(_('--%s and --%s are incompatible') 1212 raise error.Abort(
1039 % tuple(selactions[:2])) 1213 _('--%s and --%s are incompatible') % tuple(selactions[:2])
1214 )
1040 if selactions: 1215 if selactions:
1041 action = selactions[0] 1216 action = selactions[0]
1042 elif names or rev: 1217 elif names or rev:
1043 action = 'add' 1218 action = 'add'
1044 elif inactive: 1219 elif inactive:
1079 with ui.formatter('bookmarks', opts) as fm: 1254 with ui.formatter('bookmarks', opts) as fm:
1080 bookmarks.printbookmarks(ui, repo, fm, names) 1255 bookmarks.printbookmarks(ui, repo, fm, names)
1081 else: 1256 else:
1082 raise error.ProgrammingError('invalid action: %s' % action) 1257 raise error.ProgrammingError('invalid action: %s' % action)
1083 1258
1084 @command('branch', 1259
1085 [('f', 'force', None, 1260 @command(
1086 _('set branch name even if it shadows an existing branch')), 1261 'branch',
1087 ('C', 'clean', None, _('reset branch name to parent branch name')), 1262 [
1088 ('r', 'rev', [], _('change branches of the given revs (EXPERIMENTAL)')), 1263 (
1264 'f',
1265 'force',
1266 None,
1267 _('set branch name even if it shadows an existing branch'),
1268 ),
1269 ('C', 'clean', None, _('reset branch name to parent branch name')),
1270 ('r', 'rev', [], _('change branches of the given revs (EXPERIMENTAL)')),
1089 ], 1271 ],
1090 _('[-fC] [NAME]'), 1272 _('[-fC] [NAME]'),
1091 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) 1273 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1274 )
1092 def branch(ui, repo, label=None, **opts): 1275 def branch(ui, repo, label=None, **opts):
1093 """set or show the current branch name 1276 """set or show the current branch name
1094 1277
1095 .. note:: 1278 .. note::
1096 1279
1140 if revs: 1323 if revs:
1141 return cmdutil.changebranch(ui, repo, revs, label) 1324 return cmdutil.changebranch(ui, repo, revs, label)
1142 1325
1143 if not opts.get('force') and label in repo.branchmap(): 1326 if not opts.get('force') and label in repo.branchmap():
1144 if label not in [p.branch() for p in repo[None].parents()]: 1327 if label not in [p.branch() for p in repo[None].parents()]:
1145 raise error.Abort(_('a branch of the same name already' 1328 raise error.Abort(
1146 ' exists'), 1329 _('a branch of the same name already' ' exists'),
1147 # i18n: "it" refers to an existing branch 1330 # i18n: "it" refers to an existing branch
1148 hint=_("use 'hg update' to switch to it")) 1331 hint=_("use 'hg update' to switch to it"),
1332 )
1149 1333
1150 repo.dirstate.setbranch(label) 1334 repo.dirstate.setbranch(label)
1151 ui.status(_('marked working directory as branch %s\n') % label) 1335 ui.status(_('marked working directory as branch %s\n') % label)
1152 1336
1153 # find any open named branches aside from default 1337 # find any open named branches aside from default
1154 for n, h, t, c in repo.branchmap().iterbranches(): 1338 for n, h, t, c in repo.branchmap().iterbranches():
1155 if n != "default" and not c: 1339 if n != "default" and not c:
1156 return 0 1340 return 0
1157 ui.status(_('(branches are permanent and global, ' 1341 ui.status(
1158 'did you want a bookmark?)\n')) 1342 _(
1159 1343 '(branches are permanent and global, '
1160 @command('branches', 1344 'did you want a bookmark?)\n'
1161 [('a', 'active', False, 1345 )
1162 _('show only branches that have unmerged heads (DEPRECATED)')), 1346 )
1163 ('c', 'closed', False, _('show normal and closed branches')), 1347
1164 ('r', 'rev', [], _('show branch name(s) of the given rev')) 1348
1165 ] + formatteropts, 1349 @command(
1350 'branches',
1351 [
1352 (
1353 'a',
1354 'active',
1355 False,
1356 _('show only branches that have unmerged heads (DEPRECATED)'),
1357 ),
1358 ('c', 'closed', False, _('show normal and closed branches')),
1359 ('r', 'rev', [], _('show branch name(s) of the given rev')),
1360 ]
1361 + formatteropts,
1166 _('[-c]'), 1362 _('[-c]'),
1167 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, 1363 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1168 intents={INTENT_READONLY}) 1364 intents={INTENT_READONLY},
1365 )
1169 def branches(ui, repo, active=False, closed=False, **opts): 1366 def branches(ui, repo, active=False, closed=False, **opts):
1170 """list repository named branches 1367 """list repository named branches
1171 1368
1172 List the repository's named branches, indicating which ones are 1369 List the repository's named branches, indicating which ones are
1173 inactive. If -c/--closed is specified, also list branches which have 1370 inactive. If -c/--closed is specified, also list branches which have
1210 isactive = False 1407 isactive = False
1211 if not isclosed: 1408 if not isclosed:
1212 openheads = set(repo.branchmap().iteropen(heads)) 1409 openheads = set(repo.branchmap().iteropen(heads))
1213 isactive = bool(openheads & allheads) 1410 isactive = bool(openheads & allheads)
1214 branches.append((tag, repo[tip], isactive, not isclosed)) 1411 branches.append((tag, repo[tip], isactive, not isclosed))
1215 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]), 1412 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]), reverse=True)
1216 reverse=True)
1217 1413
1218 for tag, ctx, isactive, isopen in branches: 1414 for tag, ctx, isactive, isopen in branches:
1219 if active and not isactive: 1415 if active and not isactive:
1220 continue 1416 continue
1221 if isactive: 1417 if isactive:
1227 label = 'branches.closed' 1423 label = 'branches.closed'
1228 notice = _(' (closed)') 1424 notice = _(' (closed)')
1229 else: 1425 else:
1230 label = 'branches.inactive' 1426 label = 'branches.inactive'
1231 notice = _(' (inactive)') 1427 notice = _(' (inactive)')
1232 current = (tag == repo.dirstate.branch()) 1428 current = tag == repo.dirstate.branch()
1233 if current: 1429 if current:
1234 label = 'branches.current' 1430 label = 'branches.current'
1235 1431
1236 fm.startitem() 1432 fm.startitem()
1237 fm.write('branch', '%s', tag, label=label) 1433 fm.write('branch', '%s', tag, label=label)
1238 rev = ctx.rev() 1434 rev = ctx.rev()
1239 padsize = max(31 - len("%d" % rev) - encoding.colwidth(tag), 0) 1435 padsize = max(31 - len("%d" % rev) - encoding.colwidth(tag), 0)
1240 fmt = ' ' * padsize + ' %d:%s' 1436 fmt = ' ' * padsize + ' %d:%s'
1241 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()), 1437 fm.condwrite(
1242 label='log.changeset changeset.%s' % ctx.phasestr()) 1438 not ui.quiet,
1439 'rev node',
1440 fmt,
1441 rev,
1442 hexfunc(ctx.node()),
1443 label='log.changeset changeset.%s' % ctx.phasestr(),
1444 )
1243 fm.context(ctx=ctx) 1445 fm.context(ctx=ctx)
1244 fm.data(active=isactive, closed=not isopen, current=current) 1446 fm.data(active=isactive, closed=not isopen, current=current)
1245 if not ui.quiet: 1447 if not ui.quiet:
1246 fm.plain(notice) 1448 fm.plain(notice)
1247 fm.plain('\n') 1449 fm.plain('\n')
1248 fm.end() 1450 fm.end()
1249 1451
1250 @command('bundle', 1452
1251 [('f', 'force', None, _('run even when the destination is unrelated')), 1453 @command(
1252 ('r', 'rev', [], _('a changeset intended to be added to the destination'), 1454 'bundle',
1253 _('REV')), 1455 [
1254 ('b', 'branch', [], _('a specific branch you would like to bundle'), 1456 ('f', 'force', None, _('run even when the destination is unrelated')),
1255 _('BRANCH')), 1457 (
1256 ('', 'base', [], 1458 'r',
1257 _('a base changeset assumed to be available at the destination'), 1459 'rev',
1258 _('REV')), 1460 [],
1259 ('a', 'all', None, _('bundle all changesets in the repository')), 1461 _('a changeset intended to be added to the destination'),
1260 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')), 1462 _('REV'),
1261 ] + remoteopts, 1463 ),
1464 (
1465 'b',
1466 'branch',
1467 [],
1468 _('a specific branch you would like to bundle'),
1469 _('BRANCH'),
1470 ),
1471 (
1472 '',
1473 'base',
1474 [],
1475 _('a base changeset assumed to be available at the destination'),
1476 _('REV'),
1477 ),
1478 ('a', 'all', None, _('bundle all changesets in the repository')),
1479 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1480 ]
1481 + remoteopts,
1262 _('[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'), 1482 _('[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
1263 helpcategory=command.CATEGORY_IMPORT_EXPORT) 1483 helpcategory=command.CATEGORY_IMPORT_EXPORT,
1484 )
1264 def bundle(ui, repo, fname, dest=None, **opts): 1485 def bundle(ui, repo, fname, dest=None, **opts):
1265 """create a bundle file 1486 """create a bundle file
1266 1487
1267 Generate a bundle file containing data to be transferred to another 1488 Generate a bundle file containing data to be transferred to another
1268 repository. 1489 repository.
1299 1520
1300 bundletype = opts.get('type', 'bzip2').lower() 1521 bundletype = opts.get('type', 'bzip2').lower()
1301 try: 1522 try:
1302 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False) 1523 bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
1303 except error.UnsupportedBundleSpecification as e: 1524 except error.UnsupportedBundleSpecification as e:
1304 raise error.Abort(pycompat.bytestr(e), 1525 raise error.Abort(
1305 hint=_("see 'hg help bundlespec' for supported " 1526 pycompat.bytestr(e),
1306 "values for --type")) 1527 hint=_(
1528 "see 'hg help bundlespec' for supported " "values for --type"
1529 ),
1530 )
1307 cgversion = bundlespec.contentopts["cg.version"] 1531 cgversion = bundlespec.contentopts["cg.version"]
1308 1532
1309 # Packed bundles are a pseudo bundle format for now. 1533 # Packed bundles are a pseudo bundle format for now.
1310 if cgversion == 's1': 1534 if cgversion == 's1':
1311 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'), 1535 raise error.Abort(
1312 hint=_("use 'hg debugcreatestreamclonebundle'")) 1536 _('packed bundles cannot be produced by "hg bundle"'),
1537 hint=_("use 'hg debugcreatestreamclonebundle'"),
1538 )
1313 1539
1314 if opts.get('all'): 1540 if opts.get('all'):
1315 if dest: 1541 if dest:
1316 raise error.Abort(_("--all is incompatible with specifying " 1542 raise error.Abort(
1317 "a destination")) 1543 _("--all is incompatible with specifying " "a destination")
1544 )
1318 if opts.get('base'): 1545 if opts.get('base'):
1319 ui.warn(_("ignoring --base because --all was specified\n")) 1546 ui.warn(_("ignoring --base because --all was specified\n"))
1320 base = [nullrev] 1547 base = [nullrev]
1321 else: 1548 else:
1322 base = scmutil.revrange(repo, opts.get('base')) 1549 base = scmutil.revrange(repo, opts.get('base'))
1323 if cgversion not in changegroup.supportedoutgoingversions(repo): 1550 if cgversion not in changegroup.supportedoutgoingversions(repo):
1324 raise error.Abort(_("repository does not support bundle version %s") % 1551 raise error.Abort(
1325 cgversion) 1552 _("repository does not support bundle version %s") % cgversion
1553 )
1326 1554
1327 if base: 1555 if base:
1328 if dest: 1556 if dest:
1329 raise error.Abort(_("--base is incompatible with specifying " 1557 raise error.Abort(
1330 "a destination")) 1558 _("--base is incompatible with specifying " "a destination")
1559 )
1331 common = [repo[rev].node() for rev in base] 1560 common = [repo[rev].node() for rev in base]
1332 heads = [repo[r].node() for r in revs] if revs else None 1561 heads = [repo[r].node() for r in revs] if revs else None
1333 outgoing = discovery.outgoing(repo, common, heads) 1562 outgoing = discovery.outgoing(repo, common, heads)
1334 else: 1563 else:
1335 dest = ui.expandpath(dest or 'default-push', dest or 'default') 1564 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1336 dest, branches = hg.parseurl(dest, opts.get('branch')) 1565 dest, branches = hg.parseurl(dest, opts.get('branch'))
1337 other = hg.peer(repo, opts, dest) 1566 other = hg.peer(repo, opts, dest)
1338 revs = [repo[r].hex() for r in revs] 1567 revs = [repo[r].hex() for r in revs]
1339 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs) 1568 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1340 heads = revs and pycompat.maplist(repo.lookup, revs) or revs 1569 heads = revs and pycompat.maplist(repo.lookup, revs) or revs
1341 outgoing = discovery.findcommonoutgoing(repo, other, 1570 outgoing = discovery.findcommonoutgoing(
1342 onlyheads=heads, 1571 repo, other, onlyheads=heads, force=opts.get('force'), portable=True
1343 force=opts.get('force'), 1572 )
1344 portable=True)
1345 1573
1346 if not outgoing.missing: 1574 if not outgoing.missing:
1347 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded) 1575 scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
1348 return 1 1576 return 1
1349 1577
1350 if cgversion == '01': #bundle1 1578 if cgversion == '01': # bundle1
1351 bversion = 'HG10' + bundlespec.wirecompression 1579 bversion = 'HG10' + bundlespec.wirecompression
1352 bcompression = None 1580 bcompression = None
1353 elif cgversion in ('02', '03'): 1581 elif cgversion in ('02', '03'):
1354 bversion = 'HG20' 1582 bversion = 'HG20'
1355 bcompression = bundlespec.wirecompression 1583 bcompression = bundlespec.wirecompression
1356 else: 1584 else:
1357 raise error.ProgrammingError( 1585 raise error.ProgrammingError(
1358 'bundle: unexpected changegroup version %s' % cgversion) 1586 'bundle: unexpected changegroup version %s' % cgversion
1587 )
1359 1588
1360 # TODO compression options should be derived from bundlespec parsing. 1589 # TODO compression options should be derived from bundlespec parsing.
1361 # This is a temporary hack to allow adjusting bundle compression 1590 # This is a temporary hack to allow adjusting bundle compression
1362 # level without a) formalizing the bundlespec changes to declare it 1591 # level without a) formalizing the bundlespec changes to declare it
1363 # b) introducing a command flag. 1592 # b) introducing a command flag.
1364 compopts = {} 1593 compopts = {}
1365 complevel = ui.configint('experimental', 1594 complevel = ui.configint(
1366 'bundlecomplevel.' + bundlespec.compression) 1595 'experimental', 'bundlecomplevel.' + bundlespec.compression
1596 )
1367 if complevel is None: 1597 if complevel is None:
1368 complevel = ui.configint('experimental', 'bundlecomplevel') 1598 complevel = ui.configint('experimental', 'bundlecomplevel')
1369 if complevel is not None: 1599 if complevel is not None:
1370 compopts['level'] = complevel 1600 compopts['level'] = complevel
1371 1601
1374 if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'): 1604 if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'):
1375 bundlespec.contentopts['obsolescence'] = True 1605 bundlespec.contentopts['obsolescence'] = True
1376 if repo.ui.configbool('experimental', 'bundle-phases'): 1606 if repo.ui.configbool('experimental', 'bundle-phases'):
1377 bundlespec.contentopts['phases'] = True 1607 bundlespec.contentopts['phases'] = True
1378 1608
1379 bundle2.writenewbundle(ui, repo, 'bundle', fname, bversion, outgoing, 1609 bundle2.writenewbundle(
1380 bundlespec.contentopts, compression=bcompression, 1610 ui,
1381 compopts=compopts) 1611 repo,
1382 1612 'bundle',
1383 @command('cat', 1613 fname,
1384 [('o', 'output', '', 1614 bversion,
1385 _('print output to file with formatted name'), _('FORMAT')), 1615 outgoing,
1386 ('r', 'rev', '', _('print the given revision'), _('REV')), 1616 bundlespec.contentopts,
1387 ('', 'decode', None, _('apply any matching decode filter')), 1617 compression=bcompression,
1388 ] + walkopts + formatteropts, 1618 compopts=compopts,
1619 )
1620
1621
1622 @command(
1623 'cat',
1624 [
1625 (
1626 'o',
1627 'output',
1628 '',
1629 _('print output to file with formatted name'),
1630 _('FORMAT'),
1631 ),
1632 ('r', 'rev', '', _('print the given revision'), _('REV')),
1633 ('', 'decode', None, _('apply any matching decode filter')),
1634 ]
1635 + walkopts
1636 + formatteropts,
1389 _('[OPTION]... FILE...'), 1637 _('[OPTION]... FILE...'),
1390 helpcategory=command.CATEGORY_FILE_CONTENTS, 1638 helpcategory=command.CATEGORY_FILE_CONTENTS,
1391 inferrepo=True, 1639 inferrepo=True,
1392 intents={INTENT_READONLY}) 1640 intents={INTENT_READONLY},
1641 )
1393 def cat(ui, repo, file1, *pats, **opts): 1642 def cat(ui, repo, file1, *pats, **opts):
1394 """output the current or given revision of files 1643 """output the current or given revision of files
1395 1644
1396 Print the specified files as they were at the given revision. If 1645 Print the specified files as they were at the given revision. If
1397 no revision is given, the parent of the working directory is used. 1646 no revision is given, the parent of the working directory is used.
1438 fm = formatter.nullformatter(ui, 'cat', opts) 1687 fm = formatter.nullformatter(ui, 'cat', opts)
1439 else: 1688 else:
1440 ui.pager('cat') 1689 ui.pager('cat')
1441 fm = ui.formatter('cat', opts) 1690 fm = ui.formatter('cat', opts)
1442 with fm: 1691 with fm:
1443 return cmdutil.cat(ui, repo, ctx, m, fm, fntemplate, '', 1692 return cmdutil.cat(
1444 **pycompat.strkwargs(opts)) 1693 ui, repo, ctx, m, fm, fntemplate, '', **pycompat.strkwargs(opts)
1445 1694 )
1446 @command('clone', 1695
1447 [('U', 'noupdate', None, _('the clone will include an empty working ' 1696
1448 'directory (only a repository)')), 1697 @command(
1449 ('u', 'updaterev', '', _('revision, tag, or branch to check out'), 1698 'clone',
1450 _('REV')), 1699 [
1451 ('r', 'rev', [], _('do not clone everything, but include this changeset' 1700 (
1452 ' and its ancestors'), _('REV')), 1701 'U',
1453 ('b', 'branch', [], _('do not clone everything, but include this branch\'s' 1702 'noupdate',
1454 ' changesets and their ancestors'), _('BRANCH')), 1703 None,
1455 ('', 'pull', None, _('use pull protocol to copy metadata')), 1704 _(
1456 ('', 'uncompressed', None, 1705 'the clone will include an empty working '
1457 _('an alias to --stream (DEPRECATED)')), 1706 'directory (only a repository)'
1458 ('', 'stream', None, 1707 ),
1459 _('clone with minimal data processing')), 1708 ),
1460 ] + remoteopts, 1709 (
1710 'u',
1711 'updaterev',
1712 '',
1713 _('revision, tag, or branch to check out'),
1714 _('REV'),
1715 ),
1716 (
1717 'r',
1718 'rev',
1719 [],
1720 _(
1721 'do not clone everything, but include this changeset'
1722 ' and its ancestors'
1723 ),
1724 _('REV'),
1725 ),
1726 (
1727 'b',
1728 'branch',
1729 [],
1730 _(
1731 'do not clone everything, but include this branch\'s'
1732 ' changesets and their ancestors'
1733 ),
1734 _('BRANCH'),
1735 ),
1736 ('', 'pull', None, _('use pull protocol to copy metadata')),
1737 ('', 'uncompressed', None, _('an alias to --stream (DEPRECATED)')),
1738 ('', 'stream', None, _('clone with minimal data processing')),
1739 ]
1740 + remoteopts,
1461 _('[OPTION]... SOURCE [DEST]'), 1741 _('[OPTION]... SOURCE [DEST]'),
1462 helpcategory=command.CATEGORY_REPO_CREATION, 1742 helpcategory=command.CATEGORY_REPO_CREATION,
1463 helpbasic=True, norepo=True) 1743 helpbasic=True,
1744 norepo=True,
1745 )
1464 def clone(ui, source, dest=None, **opts): 1746 def clone(ui, source, dest=None, **opts):
1465 """make a copy of an existing repository 1747 """make a copy of an existing repository
1466 1748
1467 Create a copy of an existing repository in a new directory. 1749 Create a copy of an existing repository in a new directory.
1468 1750
1585 if opts.get('include'): 1867 if opts.get('include'):
1586 includepats = narrowspec.parsepatterns(opts.get('include')) 1868 includepats = narrowspec.parsepatterns(opts.get('include'))
1587 if opts.get('exclude'): 1869 if opts.get('exclude'):
1588 excludepats = narrowspec.parsepatterns(opts.get('exclude')) 1870 excludepats = narrowspec.parsepatterns(opts.get('exclude'))
1589 1871
1590 r = hg.clone(ui, opts, source, dest, 1872 r = hg.clone(
1591 pull=opts.get('pull'), 1873 ui,
1592 stream=opts.get('stream') or opts.get('uncompressed'), 1874 opts,
1593 revs=opts.get('rev'), 1875 source,
1594 update=opts.get('updaterev') or not opts.get('noupdate'), 1876 dest,
1595 branch=opts.get('branch'), 1877 pull=opts.get('pull'),
1596 shareopts=opts.get('shareopts'), 1878 stream=opts.get('stream') or opts.get('uncompressed'),
1597 storeincludepats=includepats, 1879 revs=opts.get('rev'),
1598 storeexcludepats=excludepats, 1880 update=opts.get('updaterev') or not opts.get('noupdate'),
1599 depth=opts.get('depth') or None) 1881 branch=opts.get('branch'),
1882 shareopts=opts.get('shareopts'),
1883 storeincludepats=includepats,
1884 storeexcludepats=excludepats,
1885 depth=opts.get('depth') or None,
1886 )
1600 1887
1601 return r is None 1888 return r is None
1602 1889
1603 @command('commit|ci', 1890
1604 [('A', 'addremove', None, 1891 @command(
1605 _('mark new/missing files as added/removed before committing')), 1892 'commit|ci',
1606 ('', 'close-branch', None, 1893 [
1607 _('mark a branch head as closed')), 1894 (
1608 ('', 'amend', None, _('amend the parent of the working directory')), 1895 'A',
1609 ('s', 'secret', None, _('use the secret phase for committing')), 1896 'addremove',
1610 ('e', 'edit', None, _('invoke editor on commit messages')), 1897 None,
1611 ('', 'force-close-branch', None, 1898 _('mark new/missing files as added/removed before committing'),
1612 _('forcibly close branch from a non-head changeset (ADVANCED)')), 1899 ),
1613 ('i', 'interactive', None, _('use interactive mode')), 1900 ('', 'close-branch', None, _('mark a branch head as closed')),
1614 ] + walkopts + commitopts + commitopts2 + subrepoopts, 1901 ('', 'amend', None, _('amend the parent of the working directory')),
1902 ('s', 'secret', None, _('use the secret phase for committing')),
1903 ('e', 'edit', None, _('invoke editor on commit messages')),
1904 (
1905 '',
1906 'force-close-branch',
1907 None,
1908 _('forcibly close branch from a non-head changeset (ADVANCED)'),
1909 ),
1910 ('i', 'interactive', None, _('use interactive mode')),
1911 ]
1912 + walkopts
1913 + commitopts
1914 + commitopts2
1915 + subrepoopts,
1615 _('[OPTION]... [FILE]...'), 1916 _('[OPTION]... [FILE]...'),
1616 helpcategory=command.CATEGORY_COMMITTING, helpbasic=True, 1917 helpcategory=command.CATEGORY_COMMITTING,
1617 inferrepo=True) 1918 helpbasic=True,
1919 inferrepo=True,
1920 )
1618 def commit(ui, repo, *pats, **opts): 1921 def commit(ui, repo, *pats, **opts):
1619 """commit the specified files or all outstanding changes 1922 """commit the specified files or all outstanding changes
1620 1923
1621 Commit changes to the given files into the repository. Unlike a 1924 Commit changes to the given files into the repository. Unlike a
1622 centralized SCM, this operation is a local operation. See 1925 centralized SCM, this operation is a local operation. See
1672 hg commit --amend --date now 1975 hg commit --amend --date now
1673 """ 1976 """
1674 with repo.wlock(), repo.lock(): 1977 with repo.wlock(), repo.lock():
1675 return _docommit(ui, repo, *pats, **opts) 1978 return _docommit(ui, repo, *pats, **opts)
1676 1979
1980
1677 def _docommit(ui, repo, *pats, **opts): 1981 def _docommit(ui, repo, *pats, **opts):
1678 if opts.get(r'interactive'): 1982 if opts.get(r'interactive'):
1679 opts.pop(r'interactive') 1983 opts.pop(r'interactive')
1680 ret = cmdutil.dorecord(ui, repo, commit, None, False, 1984 ret = cmdutil.dorecord(
1681 cmdutil.recordfilter, *pats, 1985 ui, repo, commit, None, False, cmdutil.recordfilter, *pats, **opts
1682 **opts) 1986 )
1683 # ret can be 0 (no changes to record) or the value returned by 1987 # ret can be 0 (no changes to record) or the value returned by
1684 # commit(), 1 if nothing changed or None on success. 1988 # commit(), 1 if nothing changed or None on success.
1685 return 1 if ret == 0 else ret 1989 return 1 if ret == 0 else ret
1686 1990
1687 opts = pycompat.byteskwargs(opts) 1991 opts = pycompat.byteskwargs(opts)
1699 extra = {} 2003 extra = {}
1700 if opts.get('close_branch') or opts.get('force_close_branch'): 2004 if opts.get('close_branch') or opts.get('force_close_branch'):
1701 extra['close'] = '1' 2005 extra['close'] = '1'
1702 2006
1703 if repo['.'].closesbranch(): 2007 if repo['.'].closesbranch():
1704 raise error.Abort(_('current revision is already a branch closing' 2008 raise error.Abort(
1705 ' head')) 2009 _('current revision is already a branch closing' ' head')
2010 )
1706 elif not bheads: 2011 elif not bheads:
1707 raise error.Abort(_('branch "%s" has no heads to close') % branch) 2012 raise error.Abort(_('branch "%s" has no heads to close') % branch)
1708 elif (branch == repo['.'].branch() and repo['.'].node() not in bheads 2013 elif (
1709 and not opts.get('force_close_branch')): 2014 branch == repo['.'].branch()
1710 hint = _('use --force-close-branch to close branch from a non-head' 2015 and repo['.'].node() not in bheads
1711 ' changeset') 2016 and not opts.get('force_close_branch')
2017 ):
2018 hint = _(
2019 'use --force-close-branch to close branch from a non-head'
2020 ' changeset'
2021 )
1712 raise error.Abort(_('can only close branch heads'), hint=hint) 2022 raise error.Abort(_('can only close branch heads'), hint=hint)
1713 elif opts.get('amend'): 2023 elif opts.get('amend'):
1714 if (repo['.'].p1().branch() != branch and 2024 if (
1715 repo['.'].p2().branch() != branch): 2025 repo['.'].p1().branch() != branch
2026 and repo['.'].p2().branch() != branch
2027 ):
1716 raise error.Abort(_('can only close branch heads')) 2028 raise error.Abort(_('can only close branch heads'))
1717 2029
1718 if opts.get('amend'): 2030 if opts.get('amend'):
1719 if ui.configbool('ui', 'commitsubrepos'): 2031 if ui.configbool('ui', 'commitsubrepos'):
1720 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled')) 2032 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1734 node = cmdutil.amend(ui, repo, old, extra, pats, opts) 2046 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
1735 if node == old.node(): 2047 if node == old.node():
1736 ui.status(_("nothing changed\n")) 2048 ui.status(_("nothing changed\n"))
1737 return 1 2049 return 1
1738 else: 2050 else:
2051
1739 def commitfunc(ui, repo, message, match, opts): 2052 def commitfunc(ui, repo, message, match, opts):
1740 overrides = {} 2053 overrides = {}
1741 if opts.get('secret'): 2054 if opts.get('secret'):
1742 overrides[('phases', 'new-commit')] = 'secret' 2055 overrides[('phases', 'new-commit')] = 'secret'
1743 2056
1744 baseui = repo.baseui 2057 baseui = repo.baseui
1745 with baseui.configoverride(overrides, 'commit'): 2058 with baseui.configoverride(overrides, 'commit'):
1746 with ui.configoverride(overrides, 'commit'): 2059 with ui.configoverride(overrides, 'commit'):
1747 editform = cmdutil.mergeeditform(repo[None], 2060 editform = cmdutil.mergeeditform(
1748 'commit.normal') 2061 repo[None], 'commit.normal'
2062 )
1749 editor = cmdutil.getcommiteditor( 2063 editor = cmdutil.getcommiteditor(
1750 editform=editform, **pycompat.strkwargs(opts)) 2064 editform=editform, **pycompat.strkwargs(opts)
1751 return repo.commit(message, 2065 )
1752 opts.get('user'), 2066 return repo.commit(
1753 opts.get('date'), 2067 message,
1754 match, 2068 opts.get('user'),
1755 editor=editor, 2069 opts.get('date'),
1756 extra=extra) 2070 match,
2071 editor=editor,
2072 extra=extra,
2073 )
1757 2074
1758 node = cmdutil.commit(ui, repo, commitfunc, pats, opts) 2075 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1759 2076
1760 if not node: 2077 if not node:
1761 stat = cmdutil.postcommitstatus(repo, pats, opts) 2078 stat = cmdutil.postcommitstatus(repo, pats, opts)
1762 if stat[3]: 2079 if stat[3]:
1763 ui.status(_("nothing changed (%d missing files, see " 2080 ui.status(
1764 "'hg status')\n") % len(stat[3])) 2081 _(
2082 "nothing changed (%d missing files, see "
2083 "'hg status')\n"
2084 )
2085 % len(stat[3])
2086 )
1765 else: 2087 else:
1766 ui.status(_("nothing changed\n")) 2088 ui.status(_("nothing changed\n"))
1767 return 1 2089 return 1
1768 2090
1769 cmdutil.commitstatus(repo, node, branch, bheads, opts) 2091 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1770 2092
1771 if not ui.quiet and ui.configbool('commands', 'commit.post-status'): 2093 if not ui.quiet and ui.configbool('commands', 'commit.post-status'):
1772 status(ui, repo, modified=True, added=True, removed=True, deleted=True, 2094 status(
1773 unknown=True, subrepos=opts.get('subrepos')) 2095 ui,
1774 2096 repo,
1775 @command('config|showconfig|debugconfig', 2097 modified=True,
1776 [('u', 'untrusted', None, _('show untrusted configuration options')), 2098 added=True,
1777 ('e', 'edit', None, _('edit user config')), 2099 removed=True,
1778 ('l', 'local', None, _('edit repository config')), 2100 deleted=True,
1779 ('g', 'global', None, _('edit global config'))] + formatteropts, 2101 unknown=True,
2102 subrepos=opts.get('subrepos'),
2103 )
2104
2105
2106 @command(
2107 'config|showconfig|debugconfig',
2108 [
2109 ('u', 'untrusted', None, _('show untrusted configuration options')),
2110 ('e', 'edit', None, _('edit user config')),
2111 ('l', 'local', None, _('edit repository config')),
2112 ('g', 'global', None, _('edit global config')),
2113 ]
2114 + formatteropts,
1780 _('[-u] [NAME]...'), 2115 _('[-u] [NAME]...'),
1781 helpcategory=command.CATEGORY_HELP, 2116 helpcategory=command.CATEGORY_HELP,
1782 optionalrepo=True, 2117 optionalrepo=True,
1783 intents={INTENT_READONLY}) 2118 intents={INTENT_READONLY},
2119 )
1784 def config(ui, repo, *values, **opts): 2120 def config(ui, repo, *values, **opts):
1785 """show combined config settings from all hgrc files 2121 """show combined config settings from all hgrc files
1786 2122
1787 With no arguments, print names and values of all config items. 2123 With no arguments, print names and values of all config items.
1788 2124
1844 fp = open(f, "wb") 2180 fp = open(f, "wb")
1845 fp.write(util.tonativeeol(samplehgrc)) 2181 fp.write(util.tonativeeol(samplehgrc))
1846 fp.close() 2182 fp.close()
1847 2183
1848 editor = ui.geteditor() 2184 editor = ui.geteditor()
1849 ui.system("%s \"%s\"" % (editor, f), 2185 ui.system(
1850 onerr=error.Abort, errprefix=_("edit failed"), 2186 "%s \"%s\"" % (editor, f),
1851 blockedtag='config_edit') 2187 onerr=error.Abort,
2188 errprefix=_("edit failed"),
2189 blockedtag='config_edit',
2190 )
1852 return 2191 return
1853 ui.pager('config') 2192 ui.pager('config')
1854 fm = ui.formatter('config', opts) 2193 fm = ui.formatter('config', opts)
1855 for t, f in rcutil.rccomponents(): 2194 for t, f in rcutil.rccomponents():
1856 if t == 'path': 2195 if t == 'path':
1864 2203
1865 selsections = selentries = [] 2204 selsections = selentries = []
1866 if values: 2205 if values:
1867 selsections = [v for v in values if '.' not in v] 2206 selsections = [v for v in values if '.' not in v]
1868 selentries = [v for v in values if '.' in v] 2207 selentries = [v for v in values if '.' in v]
1869 uniquesel = (len(selentries) == 1 and not selsections) 2208 uniquesel = len(selentries) == 1 and not selsections
1870 selsections = set(selsections) 2209 selsections = set(selsections)
1871 selentries = set(selentries) 2210 selentries = set(selentries)
1872 2211
1873 matched = False 2212 matched = False
1874 for section, name, value in ui.walkconfig(untrusted=untrusted): 2213 for section, name, value in ui.walkconfig(untrusted=untrusted):
1893 fm.end() 2232 fm.end()
1894 if matched: 2233 if matched:
1895 return 0 2234 return 0
1896 return 1 2235 return 1
1897 2236
1898 @command('continue', 2237
1899 dryrunopts, helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, 2238 @command(
1900 helpbasic=True) 2239 'continue',
2240 dryrunopts,
2241 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2242 helpbasic=True,
2243 )
1901 def continuecmd(ui, repo, **opts): 2244 def continuecmd(ui, repo, **opts):
1902 """resumes an interrupted operation (EXPERIMENTAL) 2245 """resumes an interrupted operation (EXPERIMENTAL)
1903 2246
1904 Finishes a multistep operation like graft, histedit, rebase, merge, 2247 Finishes a multistep operation like graft, histedit, rebase, merge,
1905 and unshelve if they are in an interrupted state. 2248 and unshelve if they are in an interrupted state.
1909 dryrun = opts.get(r'dry_run') 2252 dryrun = opts.get(r'dry_run')
1910 contstate = cmdutil.getunfinishedstate(repo) 2253 contstate = cmdutil.getunfinishedstate(repo)
1911 if not contstate: 2254 if not contstate:
1912 raise error.Abort(_('no operation in progress')) 2255 raise error.Abort(_('no operation in progress'))
1913 if not contstate.continuefunc: 2256 if not contstate.continuefunc:
1914 raise error.Abort((_("%s in progress but does not support " 2257 raise error.Abort(
1915 "'hg continue'") % (contstate._opname)), 2258 (
1916 hint=contstate.continuemsg()) 2259 _("%s in progress but does not support " "'hg continue'")
2260 % (contstate._opname)
2261 ),
2262 hint=contstate.continuemsg(),
2263 )
1917 if dryrun: 2264 if dryrun:
1918 ui.status(_('%s in progress, will be resumed\n') % (contstate._opname)) 2265 ui.status(_('%s in progress, will be resumed\n') % (contstate._opname))
1919 return 2266 return
1920 return contstate.continuefunc(ui, repo) 2267 return contstate.continuefunc(ui, repo)
1921 2268
1922 @command('copy|cp', 2269
1923 [('A', 'after', None, _('record a copy that has already occurred')), 2270 @command(
1924 ('f', 'force', None, _('forcibly copy over an existing managed file')), 2271 'copy|cp',
1925 ] + walkopts + dryrunopts, 2272 [
2273 ('A', 'after', None, _('record a copy that has already occurred')),
2274 ('f', 'force', None, _('forcibly copy over an existing managed file')),
2275 ]
2276 + walkopts
2277 + dryrunopts,
1926 _('[OPTION]... SOURCE... DEST'), 2278 _('[OPTION]... SOURCE... DEST'),
1927 helpcategory=command.CATEGORY_FILE_CONTENTS) 2279 helpcategory=command.CATEGORY_FILE_CONTENTS,
2280 )
1928 def copy(ui, repo, *pats, **opts): 2281 def copy(ui, repo, *pats, **opts):
1929 """mark files as copied for the next commit 2282 """mark files as copied for the next commit
1930 2283
1931 Mark dest as having copies of source files. If dest is a 2284 Mark dest as having copies of source files. If dest is a
1932 directory, copies are put in that directory. If dest is a file, 2285 directory, copies are put in that directory. If dest is a file,
1943 """ 2296 """
1944 opts = pycompat.byteskwargs(opts) 2297 opts = pycompat.byteskwargs(opts)
1945 with repo.wlock(False): 2298 with repo.wlock(False):
1946 return cmdutil.copy(ui, repo, pats, opts) 2299 return cmdutil.copy(ui, repo, pats, opts)
1947 2300
2301
1948 @command( 2302 @command(
1949 'debugcommands', [], _('[COMMAND]'), 2303 'debugcommands',
2304 [],
2305 _('[COMMAND]'),
1950 helpcategory=command.CATEGORY_HELP, 2306 helpcategory=command.CATEGORY_HELP,
1951 norepo=True) 2307 norepo=True,
2308 )
1952 def debugcommands(ui, cmd='', *args): 2309 def debugcommands(ui, cmd='', *args):
1953 """list all available commands and options""" 2310 """list all available commands and options"""
1954 for cmd, vals in sorted(table.iteritems()): 2311 for cmd, vals in sorted(table.iteritems()):
1955 cmd = cmd.split('|')[0] 2312 cmd = cmd.split('|')[0]
1956 opts = ', '.join([i[1] for i in vals[1]]) 2313 opts = ', '.join([i[1] for i in vals[1]])
1957 ui.write('%s: %s\n' % (cmd, opts)) 2314 ui.write('%s: %s\n' % (cmd, opts))
1958 2315
1959 @command('debugcomplete', 2316
2317 @command(
2318 'debugcomplete',
1960 [('o', 'options', None, _('show the command options'))], 2319 [('o', 'options', None, _('show the command options'))],
1961 _('[-o] CMD'), 2320 _('[-o] CMD'),
1962 helpcategory=command.CATEGORY_HELP, 2321 helpcategory=command.CATEGORY_HELP,
1963 norepo=True) 2322 norepo=True,
2323 )
1964 def debugcomplete(ui, cmd='', **opts): 2324 def debugcomplete(ui, cmd='', **opts):
1965 """returns the completion list associated with the given command""" 2325 """returns the completion list associated with the given command"""
1966 2326
1967 if opts.get(r'options'): 2327 if opts.get(r'options'):
1968 options = [] 2328 options = []
1983 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table) 2343 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
1984 if ui.verbose: 2344 if ui.verbose:
1985 cmdlist = [' '.join(c[0]) for c in cmdlist.values()] 2345 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1986 ui.write("%s\n" % "\n".join(sorted(cmdlist))) 2346 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1987 2347
1988 @command('diff', 2348
1989 [('r', 'rev', [], _('revision'), _('REV')), 2349 @command(
1990 ('c', 'change', '', _('change made by revision'), _('REV')) 2350 'diff',
1991 ] + diffopts + diffopts2 + walkopts + subrepoopts, 2351 [
2352 ('r', 'rev', [], _('revision'), _('REV')),
2353 ('c', 'change', '', _('change made by revision'), _('REV')),
2354 ]
2355 + diffopts
2356 + diffopts2
2357 + walkopts
2358 + subrepoopts,
1992 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'), 2359 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1993 helpcategory=command.CATEGORY_FILE_CONTENTS, 2360 helpcategory=command.CATEGORY_FILE_CONTENTS,
1994 helpbasic=True, inferrepo=True, intents={INTENT_READONLY}) 2361 helpbasic=True,
2362 inferrepo=True,
2363 intents={INTENT_READONLY},
2364 )
1995 def diff(ui, repo, *pats, **opts): 2365 def diff(ui, repo, *pats, **opts):
1996 """diff repository (or selected files) 2366 """diff repository (or selected files)
1997 2367
1998 Show differences between revisions for the specified files. 2368 Show differences between revisions for the specified files.
1999 2369
2073 2443
2074 diffopts = patch.diffallopts(ui, opts) 2444 diffopts = patch.diffallopts(ui, opts)
2075 m = scmutil.match(ctx2, pats, opts) 2445 m = scmutil.match(ctx2, pats, opts)
2076 m = repo.narrowmatch(m) 2446 m = repo.narrowmatch(m)
2077 ui.pager('diff') 2447 ui.pager('diff')
2078 logcmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat, 2448 logcmdutil.diffordiffstat(
2079 listsubrepos=opts.get('subrepos'), 2449 ui,
2080 root=opts.get('root')) 2450 repo,
2081 2451 diffopts,
2082 @command('export', 2452 node1,
2083 [('B', 'bookmark', '', 2453 node2,
2084 _('export changes only reachable by given bookmark'), _('BOOKMARK')), 2454 m,
2085 ('o', 'output', '', 2455 stat=stat,
2086 _('print output to file with formatted name'), _('FORMAT')), 2456 listsubrepos=opts.get('subrepos'),
2087 ('', 'switch-parent', None, _('diff against the second parent')), 2457 root=opts.get('root'),
2088 ('r', 'rev', [], _('revisions to export'), _('REV')), 2458 )
2089 ] + diffopts + formatteropts, 2459
2460
2461 @command(
2462 'export',
2463 [
2464 (
2465 'B',
2466 'bookmark',
2467 '',
2468 _('export changes only reachable by given bookmark'),
2469 _('BOOKMARK'),
2470 ),
2471 (
2472 'o',
2473 'output',
2474 '',
2475 _('print output to file with formatted name'),
2476 _('FORMAT'),
2477 ),
2478 ('', 'switch-parent', None, _('diff against the second parent')),
2479 ('r', 'rev', [], _('revisions to export'), _('REV')),
2480 ]
2481 + diffopts
2482 + formatteropts,
2090 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'), 2483 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2091 helpcategory=command.CATEGORY_IMPORT_EXPORT, 2484 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2092 helpbasic=True, intents={INTENT_READONLY}) 2485 helpbasic=True,
2486 intents={INTENT_READONLY},
2487 )
2093 def export(ui, repo, *changesets, **opts): 2488 def export(ui, repo, *changesets, **opts):
2094 """dump the header and diffs for one or more changesets 2489 """dump the header and diffs for one or more changesets
2095 2490
2096 Print the changeset header and diffs for one or more revisions. 2491 Print the changeset header and diffs for one or more revisions.
2097 If no revision is given, the parent of the working directory is used. 2492 If no revision is given, the parent of the working directory is used.
2198 fm = formatter.nullformatter(ui, 'export', opts) 2593 fm = formatter.nullformatter(ui, 'export', opts)
2199 else: 2594 else:
2200 ui.pager('export') 2595 ui.pager('export')
2201 fm = ui.formatter('export', opts) 2596 fm = ui.formatter('export', opts)
2202 with fm: 2597 with fm:
2203 cmdutil.export(repo, revs, fm, fntemplate=fntemplate, 2598 cmdutil.export(
2204 switch_parent=opts.get('switch_parent'), 2599 repo,
2205 opts=patch.diffallopts(ui, opts)) 2600 revs,
2206 2601 fm,
2207 @command('files', 2602 fntemplate=fntemplate,
2208 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')), 2603 switch_parent=opts.get('switch_parent'),
2209 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')), 2604 opts=patch.diffallopts(ui, opts),
2210 ] + walkopts + formatteropts + subrepoopts, 2605 )
2606
2607
2608 @command(
2609 'files',
2610 [
2611 ('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2612 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2613 ]
2614 + walkopts
2615 + formatteropts
2616 + subrepoopts,
2211 _('[OPTION]... [FILE]...'), 2617 _('[OPTION]... [FILE]...'),
2212 helpcategory=command.CATEGORY_WORKING_DIRECTORY, 2618 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2213 intents={INTENT_READONLY}) 2619 intents={INTENT_READONLY},
2620 )
2214 def files(ui, repo, *pats, **opts): 2621 def files(ui, repo, *pats, **opts):
2215 """list tracked files 2622 """list tracked files
2216 2623
2217 Print files under Mercurial control in the working directory or 2624 Print files under Mercurial control in the working directory or
2218 specified revision for given files (excluding removed files). 2625 specified revision for given files (excluding removed files).
2278 2685
2279 m = scmutil.match(ctx, pats, opts) 2686 m = scmutil.match(ctx, pats, opts)
2280 ui.pager('files') 2687 ui.pager('files')
2281 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True) 2688 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2282 with ui.formatter('files', opts) as fm: 2689 with ui.formatter('files', opts) as fm:
2283 return cmdutil.files(ui, ctx, m, uipathfn, fm, fmt, 2690 return cmdutil.files(
2284 opts.get('subrepos')) 2691 ui, ctx, m, uipathfn, fm, fmt, opts.get('subrepos')
2692 )
2693
2285 2694
2286 @command( 2695 @command(
2287 'forget', 2696 'forget',
2288 [('i', 'interactive', None, _('use interactive mode')), 2697 [('i', 'interactive', None, _('use interactive mode')),]
2289 ] + walkopts + dryrunopts, 2698 + walkopts
2699 + dryrunopts,
2290 _('[OPTION]... FILE...'), 2700 _('[OPTION]... FILE...'),
2291 helpcategory=command.CATEGORY_WORKING_DIRECTORY, 2701 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2292 helpbasic=True, inferrepo=True) 2702 helpbasic=True,
2703 inferrepo=True,
2704 )
2293 def forget(ui, repo, *pats, **opts): 2705 def forget(ui, repo, *pats, **opts):
2294 """forget the specified files on the next commit 2706 """forget the specified files on the next commit
2295 2707
2296 Mark the specified files so they will no longer be tracked 2708 Mark the specified files so they will no longer be tracked
2297 after the next commit. 2709 after the next commit.
2324 raise error.Abort(_('no files specified')) 2736 raise error.Abort(_('no files specified'))
2325 2737
2326 m = scmutil.match(repo[None], pats, opts) 2738 m = scmutil.match(repo[None], pats, opts)
2327 dryrun, interactive = opts.get('dry_run'), opts.get('interactive') 2739 dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
2328 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) 2740 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2329 rejected = cmdutil.forget(ui, repo, m, prefix="", uipathfn=uipathfn, 2741 rejected = cmdutil.forget(
2330 explicitonly=False, dryrun=dryrun, 2742 ui,
2331 interactive=interactive)[0] 2743 repo,
2744 m,
2745 prefix="",
2746 uipathfn=uipathfn,
2747 explicitonly=False,
2748 dryrun=dryrun,
2749 interactive=interactive,
2750 )[0]
2332 return rejected and 1 or 0 2751 return rejected and 1 or 0
2752
2333 2753
2334 @command( 2754 @command(
2335 'graft', 2755 'graft',
2336 [('r', 'rev', [], _('revisions to graft'), _('REV')), 2756 [
2337 ('', 'base', '', 2757 ('r', 'rev', [], _('revisions to graft'), _('REV')),
2338 _('base revision when doing the graft merge (ADVANCED)'), _('REV')), 2758 (
2339 ('c', 'continue', False, _('resume interrupted graft')), 2759 '',
2340 ('', 'stop', False, _('stop interrupted graft')), 2760 'base',
2341 ('', 'abort', False, _('abort interrupted graft')), 2761 '',
2342 ('e', 'edit', False, _('invoke editor on commit messages')), 2762 _('base revision when doing the graft merge (ADVANCED)'),
2343 ('', 'log', None, _('append graft info to log message')), 2763 _('REV'),
2344 ('', 'no-commit', None, 2764 ),
2345 _("don't commit, just apply the changes in working directory")), 2765 ('c', 'continue', False, _('resume interrupted graft')),
2346 ('f', 'force', False, _('force graft')), 2766 ('', 'stop', False, _('stop interrupted graft')),
2347 ('D', 'currentdate', False, 2767 ('', 'abort', False, _('abort interrupted graft')),
2348 _('record the current date as commit date')), 2768 ('e', 'edit', False, _('invoke editor on commit messages')),
2349 ('U', 'currentuser', False, 2769 ('', 'log', None, _('append graft info to log message')),
2350 _('record the current user as committer'))] 2770 (
2351 + commitopts2 + mergetoolopts + dryrunopts, 2771 '',
2772 'no-commit',
2773 None,
2774 _("don't commit, just apply the changes in working directory"),
2775 ),
2776 ('f', 'force', False, _('force graft')),
2777 (
2778 'D',
2779 'currentdate',
2780 False,
2781 _('record the current date as commit date'),
2782 ),
2783 ('U', 'currentuser', False, _('record the current user as committer')),
2784 ]
2785 + commitopts2
2786 + mergetoolopts
2787 + dryrunopts,
2352 _('[OPTION]... [-r REV]... REV...'), 2788 _('[OPTION]... [-r REV]... REV...'),
2353 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT) 2789 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2790 )
2354 def graft(ui, repo, *revs, **opts): 2791 def graft(ui, repo, *revs, **opts):
2355 '''copy changes from other branches onto the current branch 2792 '''copy changes from other branches onto the current branch
2356 2793
2357 This command uses Mercurial's merge logic to copy individual 2794 This command uses Mercurial's merge logic to copy individual
2358 changes from other branches without merging branches in the 2795 changes from other branches without merging branches in the
2447 Returns 0 on successful completion. 2884 Returns 0 on successful completion.
2448 ''' 2885 '''
2449 with repo.wlock(): 2886 with repo.wlock():
2450 return _dograft(ui, repo, *revs, **opts) 2887 return _dograft(ui, repo, *revs, **opts)
2451 2888
2889
2452 def _dograft(ui, repo, *revs, **opts): 2890 def _dograft(ui, repo, *revs, **opts):
2453 opts = pycompat.byteskwargs(opts) 2891 opts = pycompat.byteskwargs(opts)
2454 if revs and opts.get('rev'): 2892 if revs and opts.get('rev'):
2455 ui.warn(_('warning: inconsistent use of --rev might give unexpected ' 2893 ui.warn(
2456 'revision ordering!\n')) 2894 _(
2895 'warning: inconsistent use of --rev might give unexpected '
2896 'revision ordering!\n'
2897 )
2898 )
2457 2899
2458 revs = list(revs) 2900 revs = list(revs)
2459 revs.extend(opts.get('rev')) 2901 revs.extend(opts.get('rev'))
2460 basectx = None 2902 basectx = None
2461 if opts.get('base'): 2903 if opts.get('base'):
2472 if not opts.get('user') and opts.get('currentuser'): 2914 if not opts.get('user') and opts.get('currentuser'):
2473 opts['user'] = ui.username() 2915 opts['user'] = ui.username()
2474 if not opts.get('date') and opts.get('currentdate'): 2916 if not opts.get('date') and opts.get('currentdate'):
2475 opts['date'] = "%d %d" % dateutil.makedate() 2917 opts['date'] = "%d %d" % dateutil.makedate()
2476 2918
2477 editor = cmdutil.getcommiteditor(editform='graft', 2919 editor = cmdutil.getcommiteditor(
2478 **pycompat.strkwargs(opts)) 2920 editform='graft', **pycompat.strkwargs(opts)
2921 )
2479 2922
2480 cont = False 2923 cont = False
2481 if opts.get('no_commit'): 2924 if opts.get('no_commit'):
2482 if opts.get('edit'): 2925 if opts.get('edit'):
2483 raise error.Abort(_("cannot specify --no-commit and " 2926 raise error.Abort(
2484 "--edit together")) 2927 _("cannot specify --no-commit and " "--edit together")
2928 )
2485 if opts.get('currentuser'): 2929 if opts.get('currentuser'):
2486 raise error.Abort(_("cannot specify --no-commit and " 2930 raise error.Abort(
2487 "--currentuser together")) 2931 _("cannot specify --no-commit and " "--currentuser together")
2932 )
2488 if opts.get('currentdate'): 2933 if opts.get('currentdate'):
2489 raise error.Abort(_("cannot specify --no-commit and " 2934 raise error.Abort(
2490 "--currentdate together")) 2935 _("cannot specify --no-commit and " "--currentdate together")
2936 )
2491 if opts.get('log'): 2937 if opts.get('log'):
2492 raise error.Abort(_("cannot specify --no-commit and " 2938 raise error.Abort(
2493 "--log together")) 2939 _("cannot specify --no-commit and " "--log together")
2940 )
2494 2941
2495 graftstate = statemod.cmdstate(repo, 'graftstate') 2942 graftstate = statemod.cmdstate(repo, 'graftstate')
2496 2943
2497 if opts.get('stop'): 2944 if opts.get('stop'):
2498 if opts.get('continue'): 2945 if opts.get('continue'):
2499 raise error.Abort(_("cannot use '--continue' and " 2946 raise error.Abort(
2500 "'--stop' together")) 2947 _("cannot use '--continue' and " "'--stop' together")
2948 )
2501 if opts.get('abort'): 2949 if opts.get('abort'):
2502 raise error.Abort(_("cannot use '--abort' and '--stop' together")) 2950 raise error.Abort(_("cannot use '--abort' and '--stop' together"))
2503 2951
2504 if any((opts.get('edit'), opts.get('log'), opts.get('user'), 2952 if any(
2505 opts.get('date'), opts.get('currentdate'), 2953 (
2506 opts.get('currentuser'), opts.get('rev'))): 2954 opts.get('edit'),
2955 opts.get('log'),
2956 opts.get('user'),
2957 opts.get('date'),
2958 opts.get('currentdate'),
2959 opts.get('currentuser'),
2960 opts.get('rev'),
2961 )
2962 ):
2507 raise error.Abort(_("cannot specify any other flag with '--stop'")) 2963 raise error.Abort(_("cannot specify any other flag with '--stop'"))
2508 return _stopgraft(ui, repo, graftstate) 2964 return _stopgraft(ui, repo, graftstate)
2509 elif opts.get('abort'): 2965 elif opts.get('abort'):
2510 if opts.get('continue'): 2966 if opts.get('continue'):
2511 raise error.Abort(_("cannot use '--continue' and " 2967 raise error.Abort(
2512 "'--abort' together")) 2968 _("cannot use '--continue' and " "'--abort' together")
2513 if any((opts.get('edit'), opts.get('log'), opts.get('user'), 2969 )
2514 opts.get('date'), opts.get('currentdate'), 2970 if any(
2515 opts.get('currentuser'), opts.get('rev'))): 2971 (
2972 opts.get('edit'),
2973 opts.get('log'),
2974 opts.get('user'),
2975 opts.get('date'),
2976 opts.get('currentdate'),
2977 opts.get('currentuser'),
2978 opts.get('rev'),
2979 )
2980 ):
2516 raise error.Abort(_("cannot specify any other flag with '--abort'")) 2981 raise error.Abort(_("cannot specify any other flag with '--abort'"))
2517 2982
2518 return cmdutil.abortgraft(ui, repo, graftstate) 2983 return cmdutil.abortgraft(ui, repo, graftstate)
2519 elif opts.get('continue'): 2984 elif opts.get('continue'):
2520 cont = True 2985 cont = True
2566 ancestors = repo.changelog.ancestors([crev], inclusive=True) 3031 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2567 # XXX make this lazy in the future 3032 # XXX make this lazy in the future
2568 # don't mutate while iterating, create a copy 3033 # don't mutate while iterating, create a copy
2569 for rev in list(revs): 3034 for rev in list(revs):
2570 if rev in ancestors: 3035 if rev in ancestors:
2571 ui.warn(_('skipping ancestor revision %d:%s\n') % 3036 ui.warn(
2572 (rev, repo[rev])) 3037 _('skipping ancestor revision %d:%s\n') % (rev, repo[rev])
3038 )
2573 # XXX remove on list is slow 3039 # XXX remove on list is slow
2574 revs.remove(rev) 3040 revs.remove(rev)
2575 if not revs: 3041 if not revs:
2576 return -1 3042 return -1
2577 3043
2595 try: 3061 try:
2596 r = repo[n].rev() 3062 r = repo[n].rev()
2597 except error.RepoLookupError: 3063 except error.RepoLookupError:
2598 r = None 3064 r = None
2599 if r in revs: 3065 if r in revs:
2600 ui.warn(_('skipping revision %d:%s ' 3066 ui.warn(
2601 '(already grafted to %d:%s)\n') 3067 _(
2602 % (r, repo[r], rev, ctx)) 3068 'skipping revision %d:%s '
3069 '(already grafted to %d:%s)\n'
3070 )
3071 % (r, repo[r], rev, ctx)
3072 )
2603 revs.remove(r) 3073 revs.remove(r)
2604 elif ids[n] in revs: 3074 elif ids[n] in revs:
2605 if r is None: 3075 if r is None:
2606 ui.warn(_('skipping already grafted revision %d:%s ' 3076 ui.warn(
2607 '(%d:%s also has unknown origin %s)\n') 3077 _(
2608 % (ids[n], repo[ids[n]], rev, ctx, n[:12])) 3078 'skipping already grafted revision %d:%s '
3079 '(%d:%s also has unknown origin %s)\n'
3080 )
3081 % (ids[n], repo[ids[n]], rev, ctx, n[:12])
3082 )
2609 else: 3083 else:
2610 ui.warn(_('skipping already grafted revision %d:%s ' 3084 ui.warn(
2611 '(%d:%s also has origin %d:%s)\n') 3085 _(
2612 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])) 3086 'skipping already grafted revision %d:%s '
3087 '(%d:%s also has origin %d:%s)\n'
3088 )
3089 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
3090 )
2613 revs.remove(ids[n]) 3091 revs.remove(ids[n])
2614 elif ctx.hex() in ids: 3092 elif ctx.hex() in ids:
2615 r = ids[ctx.hex()] 3093 r = ids[ctx.hex()]
2616 if r in revs: 3094 if r in revs:
2617 ui.warn(_('skipping already grafted revision %d:%s ' 3095 ui.warn(
2618 '(was grafted from %d:%s)\n') % 3096 _(
2619 (r, repo[r], rev, ctx)) 3097 'skipping already grafted revision %d:%s '
3098 '(was grafted from %d:%s)\n'
3099 )
3100 % (r, repo[r], rev, ctx)
3101 )
2620 revs.remove(r) 3102 revs.remove(r)
2621 if not revs: 3103 if not revs:
2622 return -1 3104 return -1
2623 3105
2624 if opts.get('no_commit'): 3106 if opts.get('no_commit'):
2625 statedata['no_commit'] = True 3107 statedata['no_commit'] = True
2626 for pos, ctx in enumerate(repo.set("%ld", revs)): 3108 for pos, ctx in enumerate(repo.set("%ld", revs)):
2627 desc = '%d:%s "%s"' % (ctx.rev(), ctx, 3109 desc = '%d:%s "%s"' % (
2628 ctx.description().split('\n', 1)[0]) 3110 ctx.rev(),
3111 ctx,
3112 ctx.description().split('\n', 1)[0],
3113 )
2629 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node()) 3114 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2630 if names: 3115 if names:
2631 desc += ' (%s)' % ' '.join(names) 3116 desc += ' (%s)' % ' '.join(names)
2632 ui.status(_('grafting %s\n') % desc) 3117 ui.status(_('grafting %s\n') % desc)
2633 if opts.get('dry_run'): 3118 if opts.get('dry_run'):
2667 statedata['nodes'] = nodes 3152 statedata['nodes'] = nodes
2668 stateversion = 1 3153 stateversion = 1
2669 graftstate.save(stateversion, statedata) 3154 graftstate.save(stateversion, statedata)
2670 hint = _("use 'hg resolve' and 'hg graft --continue'") 3155 hint = _("use 'hg resolve' and 'hg graft --continue'")
2671 raise error.Abort( 3156 raise error.Abort(
2672 _("unresolved conflicts, can't continue"), 3157 _("unresolved conflicts, can't continue"), hint=hint
2673 hint=hint) 3158 )
2674 else: 3159 else:
2675 cont = False 3160 cont = False
2676 3161
2677 # commit if --no-commit is false 3162 # commit if --no-commit is false
2678 if not opts.get('no_commit'): 3163 if not opts.get('no_commit'):
2679 node = repo.commit(text=message, user=user, date=date, extra=extra, 3164 node = repo.commit(
2680 editor=editor) 3165 text=message, user=user, date=date, extra=extra, editor=editor
3166 )
2681 if node is None: 3167 if node is None:
2682 ui.warn( 3168 ui.warn(
2683 _('note: graft of %d:%s created no changes to commit\n') % 3169 _('note: graft of %d:%s created no changes to commit\n')
2684 (ctx.rev(), ctx)) 3170 % (ctx.rev(), ctx)
3171 )
2685 # checking that newnodes exist because old state files won't have it 3172 # checking that newnodes exist because old state files won't have it
2686 elif statedata.get('newnodes') is not None: 3173 elif statedata.get('newnodes') is not None:
2687 statedata['newnodes'].append(node) 3174 statedata['newnodes'].append(node)
2688 3175
2689 # remove state when we complete successfully 3176 # remove state when we complete successfully
2690 if not opts.get('dry_run'): 3177 if not opts.get('dry_run'):
2691 graftstate.delete() 3178 graftstate.delete()
2692 3179
2693 return 0 3180 return 0
3181
2694 3182
2695 def _stopgraft(ui, repo, graftstate): 3183 def _stopgraft(ui, repo, graftstate):
2696 """stop the interrupted graft""" 3184 """stop the interrupted graft"""
2697 if not graftstate.exists(): 3185 if not graftstate.exists():
2698 raise error.Abort(_("no interrupted graft found")) 3186 raise error.Abort(_("no interrupted graft found"))
2701 graftstate.delete() 3189 graftstate.delete()
2702 ui.status(_("stopped the interrupted graft\n")) 3190 ui.status(_("stopped the interrupted graft\n"))
2703 ui.status(_("working directory is now at %s\n") % pctx.hex()[:12]) 3191 ui.status(_("working directory is now at %s\n") % pctx.hex()[:12])
2704 return 0 3192 return 0
2705 3193
3194
2706 statemod.addunfinished( 3195 statemod.addunfinished(
2707 'graft', fname='graftstate', clearable=True, stopflag=True, 3196 'graft',
2708 continueflag=True, abortfunc=cmdutil.hgabortgraft, 3197 fname='graftstate',
2709 cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop") 3198 clearable=True,
3199 stopflag=True,
3200 continueflag=True,
3201 abortfunc=cmdutil.hgabortgraft,
3202 cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop"),
2710 ) 3203 )
2711 3204
2712 @command('grep', 3205
2713 [('0', 'print0', None, _('end fields with NUL')), 3206 @command(
2714 ('', 'all', None, _('print all revisions that match (DEPRECATED) ')), 3207 'grep',
2715 ('', 'diff', None, _('print all revisions when the term was introduced ' 3208 [
2716 'or removed')), 3209 ('0', 'print0', None, _('end fields with NUL')),
2717 ('a', 'text', None, _('treat all files as text')), 3210 ('', 'all', None, _('print all revisions that match (DEPRECATED) ')),
2718 ('f', 'follow', None, 3211 (
2719 _('follow changeset history,' 3212 '',
2720 ' or file history across copies and renames')), 3213 'diff',
2721 ('i', 'ignore-case', None, _('ignore case when matching')), 3214 None,
2722 ('l', 'files-with-matches', None, 3215 _('print all revisions when the term was introduced ' 'or removed'),
2723 _('print only filenames and revisions that match')), 3216 ),
2724 ('n', 'line-number', None, _('print matching line numbers')), 3217 ('a', 'text', None, _('treat all files as text')),
2725 ('r', 'rev', [], 3218 (
2726 _('only search files changed within revision range'), _('REV')), 3219 'f',
2727 ('', 'all-files', None, 3220 'follow',
2728 _('include all files in the changeset while grepping (EXPERIMENTAL)')), 3221 None,
2729 ('u', 'user', None, _('list the author (long with -v)')), 3222 _(
2730 ('d', 'date', None, _('list the date (short with -q)')), 3223 'follow changeset history,'
2731 ] + formatteropts + walkopts, 3224 ' or file history across copies and renames'
3225 ),
3226 ),
3227 ('i', 'ignore-case', None, _('ignore case when matching')),
3228 (
3229 'l',
3230 'files-with-matches',
3231 None,
3232 _('print only filenames and revisions that match'),
3233 ),
3234 ('n', 'line-number', None, _('print matching line numbers')),
3235 (
3236 'r',
3237 'rev',
3238 [],
3239 _('only search files changed within revision range'),
3240 _('REV'),
3241 ),
3242 (
3243 '',
3244 'all-files',
3245 None,
3246 _(
3247 'include all files in the changeset while grepping (EXPERIMENTAL)'
3248 ),
3249 ),
3250 ('u', 'user', None, _('list the author (long with -v)')),
3251 ('d', 'date', None, _('list the date (short with -q)')),
3252 ]
3253 + formatteropts
3254 + walkopts,
2732 _('[OPTION]... PATTERN [FILE]...'), 3255 _('[OPTION]... PATTERN [FILE]...'),
2733 helpcategory=command.CATEGORY_FILE_CONTENTS, 3256 helpcategory=command.CATEGORY_FILE_CONTENTS,
2734 inferrepo=True, 3257 inferrepo=True,
2735 intents={INTENT_READONLY}) 3258 intents={INTENT_READONLY},
3259 )
2736 def grep(ui, repo, pattern, *pats, **opts): 3260 def grep(ui, repo, pattern, *pats, **opts):
2737 """search revision history for a pattern in specified files 3261 """search revision history for a pattern in specified files
2738 3262
2739 Search revision history for a regular expression in the specified 3263 Search revision history for a regular expression in the specified
2740 files or the entire project. 3264 files or the entire project.
2839 yield m.span() 3363 yield m.span()
2840 p = m.end() 3364 p = m.end()
2841 3365
2842 matches = {} 3366 matches = {}
2843 copies = {} 3367 copies = {}
3368
2844 def grepbody(fn, rev, body): 3369 def grepbody(fn, rev, body):
2845 matches[rev].setdefault(fn, []) 3370 matches[rev].setdefault(fn, [])
2846 m = matches[rev][fn] 3371 m = matches[rev][fn]
2847 for lnum, cstart, cend, line in matchlines(body): 3372 for lnum, cstart, cend, line in matchlines(body):
2848 s = linestate(line, lnum, cstart, cend) 3373 s = linestate(line, lnum, cstart, cend)
2862 yield ('-', a[i]) 3387 yield ('-', a[i])
2863 for i in pycompat.xrange(blo, bhi): 3388 for i in pycompat.xrange(blo, bhi):
2864 yield ('+', b[i]) 3389 yield ('+', b[i])
2865 3390
2866 uipathfn = scmutil.getuipathfn(repo) 3391 uipathfn = scmutil.getuipathfn(repo)
3392
2867 def display(fm, fn, ctx, pstates, states): 3393 def display(fm, fn, ctx, pstates, states):
2868 rev = scmutil.intrev(ctx) 3394 rev = scmutil.intrev(ctx)
2869 if fm.isplain(): 3395 if fm.isplain():
2870 formatuser = ui.shortuser 3396 formatuser = ui.shortuser
2871 else: 3397 else:
2873 if ui.quiet: 3399 if ui.quiet:
2874 datefmt = '%Y-%m-%d' 3400 datefmt = '%Y-%m-%d'
2875 else: 3401 else:
2876 datefmt = '%a %b %d %H:%M:%S %Y %1%2' 3402 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2877 found = False 3403 found = False
3404
2878 @util.cachefunc 3405 @util.cachefunc
2879 def binary(): 3406 def binary():
2880 flog = getfile(fn) 3407 flog = getfile(fn)
2881 try: 3408 try:
2882 return stringutil.binary(flog.read(ctx.filenode(fn))) 3409 return stringutil.binary(flog.read(ctx.filenode(fn)))
2898 ('rev', '%d', rev, not plaingrep, ''), 3425 ('rev', '%d', rev, not plaingrep, ''),
2899 ('linenumber', '%d', l.linenum, opts.get('line_number'), ''), 3426 ('linenumber', '%d', l.linenum, opts.get('line_number'), ''),
2900 ] 3427 ]
2901 if diff: 3428 if diff:
2902 cols.append( 3429 cols.append(
2903 ('change', '%s', change, True, 3430 (
2904 'grep.inserted ' if change == '+' else 'grep.deleted ') 3431 'change',
3432 '%s',
3433 change,
3434 True,
3435 'grep.inserted ' if change == '+' else 'grep.deleted ',
3436 )
2905 ) 3437 )
2906 cols.extend([ 3438 cols.extend(
2907 ('user', '%s', formatuser(ctx.user()), opts.get('user'), ''), 3439 [
2908 ('date', '%s', fm.formatdate(ctx.date(), datefmt), 3440 (
2909 opts.get('date'), ''), 3441 'user',
2910 ]) 3442 '%s',
3443 formatuser(ctx.user()),
3444 opts.get('user'),
3445 '',
3446 ),
3447 (
3448 'date',
3449 '%s',
3450 fm.formatdate(ctx.date(), datefmt),
3451 opts.get('date'),
3452 '',
3453 ),
3454 ]
3455 )
2911 for name, fmt, data, cond, extra_label in cols: 3456 for name, fmt, data, cond, extra_label in cols:
2912 if cond: 3457 if cond:
2913 fm.plain(sep, label='grep.sep') 3458 fm.plain(sep, label='grep.sep')
2914 field = fieldnamemap.get(name, name) 3459 field = fieldnamemap.get(name, name)
2915 label = extra_label + ('grep.%s' % name) 3460 label = extra_label + ('grep.%s' % name)
2948 match = scmutil.match(repo[None], pats, opts) 3493 match = scmutil.match(repo[None], pats, opts)
2949 found = False 3494 found = False
2950 follow = opts.get('follow') 3495 follow = opts.get('follow')
2951 3496
2952 getrenamed = scmutil.getrenamedfn(repo) 3497 getrenamed = scmutil.getrenamedfn(repo)
3498
2953 def prep(ctx, fns): 3499 def prep(ctx, fns):
2954 rev = ctx.rev() 3500 rev = ctx.rev()
2955 pctx = ctx.p1() 3501 pctx = ctx.p1()
2956 parent = pctx.rev() 3502 parent = pctx.rev()
2957 matches.setdefault(rev, {}) 3503 matches.setdefault(rev, {})
3017 matches.clear() 3563 matches.clear()
3018 fm.end() 3564 fm.end()
3019 3565
3020 return not found 3566 return not found
3021 3567
3022 @command('heads', 3568
3023 [('r', 'rev', '', 3569 @command(
3024 _('show only heads which are descendants of STARTREV'), _('STARTREV')), 3570 'heads',
3025 ('t', 'topo', False, _('show topological heads only')), 3571 [
3026 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')), 3572 (
3027 ('c', 'closed', False, _('show normal and closed branch heads')), 3573 'r',
3028 ] + templateopts, 3574 'rev',
3575 '',
3576 _('show only heads which are descendants of STARTREV'),
3577 _('STARTREV'),
3578 ),
3579 ('t', 'topo', False, _('show topological heads only')),
3580 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3581 ('c', 'closed', False, _('show normal and closed branch heads')),
3582 ]
3583 + templateopts,
3029 _('[-ct] [-r STARTREV] [REV]...'), 3584 _('[-ct] [-r STARTREV] [REV]...'),
3030 helpcategory=command.CATEGORY_CHANGE_NAVIGATION, 3585 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3031 intents={INTENT_READONLY}) 3586 intents={INTENT_READONLY},
3587 )
3032 def heads(ui, repo, *branchrevs, **opts): 3588 def heads(ui, repo, *branchrevs, **opts):
3033 """show branch heads 3589 """show branch heads
3034 3590
3035 With no arguments, show all open branch heads in the repository. 3591 With no arguments, show all open branch heads in the repository.
3036 Branch heads are changesets that have no descendants on the 3592 Branch heads are changesets that have no descendants on the
3068 for branch in repo.branchmap(): 3624 for branch in repo.branchmap():
3069 heads += repo.branchheads(branch, start, opts.get('closed')) 3625 heads += repo.branchheads(branch, start, opts.get('closed'))
3070 heads = [repo[h] for h in heads] 3626 heads = [repo[h] for h in heads]
3071 3627
3072 if branchrevs: 3628 if branchrevs:
3073 branches = set(repo[r].branch() 3629 branches = set(
3074 for r in scmutil.revrange(repo, branchrevs)) 3630 repo[r].branch() for r in scmutil.revrange(repo, branchrevs)
3631 )
3075 heads = [h for h in heads if h.branch() in branches] 3632 heads = [h for h in heads if h.branch() in branches]
3076 3633
3077 if opts.get('active') and branchrevs: 3634 if opts.get('active') and branchrevs:
3078 dagheads = repo.heads(start) 3635 dagheads = repo.heads(start)
3079 heads = [h for h in heads if h.node() in dagheads] 3636 heads = [h for h in heads if h.node() in dagheads]
3089 3646
3090 if not heads: 3647 if not heads:
3091 return 1 3648 return 1
3092 3649
3093 ui.pager('heads') 3650 ui.pager('heads')
3094 heads = sorted(heads, key=lambda x: -x.rev()) 3651 heads = sorted(heads, key=lambda x: -(x.rev()))
3095 displayer = logcmdutil.changesetdisplayer(ui, repo, opts) 3652 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
3096 for ctx in heads: 3653 for ctx in heads:
3097 displayer.show(ctx) 3654 displayer.show(ctx)
3098 displayer.close() 3655 displayer.close()
3099 3656
3100 @command('help', 3657
3101 [('e', 'extension', None, _('show only help for extensions')), 3658 @command(
3102 ('c', 'command', None, _('show only help for commands')), 3659 'help',
3103 ('k', 'keyword', None, _('show topics matching keyword')), 3660 [
3104 ('s', 'system', [], 3661 ('e', 'extension', None, _('show only help for extensions')),
3105 _('show help for specific platform(s)'), _('PLATFORM')), 3662 ('c', 'command', None, _('show only help for commands')),
3106 ], 3663 ('k', 'keyword', None, _('show topics matching keyword')),
3664 (
3665 's',
3666 'system',
3667 [],
3668 _('show help for specific platform(s)'),
3669 _('PLATFORM'),
3670 ),
3671 ],
3107 _('[-eck] [-s PLATFORM] [TOPIC]'), 3672 _('[-eck] [-s PLATFORM] [TOPIC]'),
3108 helpcategory=command.CATEGORY_HELP, 3673 helpcategory=command.CATEGORY_HELP,
3109 norepo=True, 3674 norepo=True,
3110 intents={INTENT_READONLY}) 3675 intents={INTENT_READONLY},
3676 )
3111 def help_(ui, name=None, **opts): 3677 def help_(ui, name=None, **opts):
3112 """show help for a given topic or a help overview 3678 """show help for a given topic or a help overview
3113 3679
3114 With no arguments, print a list of commands with short help messages. 3680 With no arguments, print a list of commands with short help messages.
3115 3681
3137 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts) 3703 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3138 ui.pager('help') 3704 ui.pager('help')
3139 ui.write(formatted) 3705 ui.write(formatted)
3140 3706
3141 3707
3142 @command('identify|id', 3708 @command(
3143 [('r', 'rev', '', 3709 'identify|id',
3144 _('identify the specified revision'), _('REV')), 3710 [
3145 ('n', 'num', None, _('show local revision number')), 3711 ('r', 'rev', '', _('identify the specified revision'), _('REV')),
3146 ('i', 'id', None, _('show global revision id')), 3712 ('n', 'num', None, _('show local revision number')),
3147 ('b', 'branch', None, _('show branch')), 3713 ('i', 'id', None, _('show global revision id')),
3148 ('t', 'tags', None, _('show tags')), 3714 ('b', 'branch', None, _('show branch')),
3149 ('B', 'bookmarks', None, _('show bookmarks')), 3715 ('t', 'tags', None, _('show tags')),
3150 ] + remoteopts + formatteropts, 3716 ('B', 'bookmarks', None, _('show bookmarks')),
3717 ]
3718 + remoteopts
3719 + formatteropts,
3151 _('[-nibtB] [-r REV] [SOURCE]'), 3720 _('[-nibtB] [-r REV] [SOURCE]'),
3152 helpcategory=command.CATEGORY_CHANGE_NAVIGATION, 3721 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3153 optionalrepo=True, 3722 optionalrepo=True,
3154 intents={INTENT_READONLY}) 3723 intents={INTENT_READONLY},
3155 def identify(ui, repo, source=None, rev=None, 3724 )
3156 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts): 3725 def identify(
3726 ui,
3727 repo,
3728 source=None,
3729 rev=None,
3730 num=None,
3731 id=None,
3732 branch=None,
3733 tags=None,
3734 bookmarks=None,
3735 **opts
3736 ):
3157 """identify the working directory or specified revision 3737 """identify the working directory or specified revision
3158 3738
3159 Print a summary identifying the repository state at REV using one or 3739 Print a summary identifying the repository state at REV using one or
3160 two parent hash identifiers, followed by a "+" if the working 3740 two parent hash identifiers, followed by a "+" if the working
3161 directory has uncommitted changes, the branch name (if not default), 3741 directory has uncommitted changes, the branch name (if not default),
3200 Returns 0 if successful. 3780 Returns 0 if successful.
3201 """ 3781 """
3202 3782
3203 opts = pycompat.byteskwargs(opts) 3783 opts = pycompat.byteskwargs(opts)
3204 if not repo and not source: 3784 if not repo and not source:
3205 raise error.Abort(_("there is no Mercurial repository here " 3785 raise error.Abort(
3206 "(.hg not found)")) 3786 _("there is no Mercurial repository here " "(.hg not found)")
3787 )
3207 3788
3208 default = not (num or id or branch or tags or bookmarks) 3789 default = not (num or id or branch or tags or bookmarks)
3209 output = [] 3790 output = []
3210 revs = [] 3791 revs = []
3211 3792
3212 if source: 3793 if source:
3213 source, branches = hg.parseurl(ui.expandpath(source)) 3794 source, branches = hg.parseurl(ui.expandpath(source))
3214 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo 3795 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3215 repo = peer.local() 3796 repo = peer.local()
3216 revs, checkout = hg.addbranchrevs(repo, peer, branches, None) 3797 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3217 3798
3218 fm = ui.formatter('identify', opts) 3799 fm = ui.formatter('identify', opts)
3219 fm.startitem() 3800 fm.startitem()
3220 3801
3221 if not repo: 3802 if not repo:
3222 if num or branch or tags: 3803 if num or branch or tags:
3223 raise error.Abort( 3804 raise error.Abort(
3224 _("can't query remote revision number, branch, or tags")) 3805 _("can't query remote revision number, branch, or tags")
3806 )
3225 if not rev and revs: 3807 if not rev and revs:
3226 rev = revs[0] 3808 rev = revs[0]
3227 if not rev: 3809 if not rev:
3228 rev = "tip" 3810 rev = "tip"
3229 3811
3237 def getbms(): 3819 def getbms():
3238 bms = [] 3820 bms = []
3239 3821
3240 if 'bookmarks' in peer.listkeys('namespaces'): 3822 if 'bookmarks' in peer.listkeys('namespaces'):
3241 hexremoterev = hex(remoterev) 3823 hexremoterev = hex(remoterev)
3242 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems() 3824 bms = [
3243 if bmr == hexremoterev] 3825 bm
3826 for bm, bmr in peer.listkeys('bookmarks').iteritems()
3827 if bmr == hexremoterev
3828 ]
3244 3829
3245 return sorted(bms) 3830 return sorted(bms)
3246 3831
3247 if fm.isplain(): 3832 if fm.isplain():
3248 if bookmarks: 3833 if bookmarks:
3280 3865
3281 if num: 3866 if num:
3282 numoutput = ["%d" % p.rev() for p in parents] 3867 numoutput = ["%d" % p.rev() for p in parents]
3283 output.append("%s%s" % ('+'.join(numoutput), dirty)) 3868 output.append("%s%s" % ('+'.join(numoutput), dirty))
3284 3869
3285 fm.data(parents=fm.formatlist([fm.hexfunc(p.node()) 3870 fm.data(
3286 for p in parents], name='node')) 3871 parents=fm.formatlist(
3872 [fm.hexfunc(p.node()) for p in parents], name='node'
3873 )
3874 )
3287 else: 3875 else:
3288 hexoutput = fm.hexfunc(ctx.node()) 3876 hexoutput = fm.hexfunc(ctx.node())
3289 if default or id: 3877 if default or id:
3290 output = [hexoutput] 3878 output = [hexoutput]
3291 fm.data(id=hexoutput) 3879 fm.data(id=hexoutput)
3325 fm.context(ctx=ctx) 3913 fm.context(ctx=ctx)
3326 3914
3327 fm.plain("%s\n" % ' '.join(output)) 3915 fm.plain("%s\n" % ' '.join(output))
3328 fm.end() 3916 fm.end()
3329 3917
3330 @command('import|patch', 3918
3331 [('p', 'strip', 1, 3919 @command(
3332 _('directory strip option for patch. This has the same ' 3920 'import|patch',
3333 'meaning as the corresponding patch option'), _('NUM')), 3921 [
3334 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')), 3922 (
3335 ('e', 'edit', False, _('invoke editor on commit messages')), 3923 'p',
3336 ('f', 'force', None, 3924 'strip',
3337 _('skip check for outstanding uncommitted changes (DEPRECATED)')), 3925 1,
3338 ('', 'no-commit', None, 3926 _(
3339 _("don't commit, just update the working directory")), 3927 'directory strip option for patch. This has the same '
3340 ('', 'bypass', None, 3928 'meaning as the corresponding patch option'
3341 _("apply patch without touching the working directory")), 3929 ),
3342 ('', 'partial', None, 3930 _('NUM'),
3343 _('commit even if some hunks fail')), 3931 ),
3344 ('', 'exact', None, 3932 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3345 _('abort if patch would apply lossily')), 3933 ('e', 'edit', False, _('invoke editor on commit messages')),
3346 ('', 'prefix', '', 3934 (
3347 _('apply patch to subdirectory'), _('DIR')), 3935 'f',
3348 ('', 'import-branch', None, 3936 'force',
3349 _('use any branch information in patch (implied by --exact)'))] + 3937 None,
3350 commitopts + commitopts2 + similarityopts, 3938 _('skip check for outstanding uncommitted changes (DEPRECATED)'),
3939 ),
3940 (
3941 '',
3942 'no-commit',
3943 None,
3944 _("don't commit, just update the working directory"),
3945 ),
3946 (
3947 '',
3948 'bypass',
3949 None,
3950 _("apply patch without touching the working directory"),
3951 ),
3952 ('', 'partial', None, _('commit even if some hunks fail')),
3953 ('', 'exact', None, _('abort if patch would apply lossily')),
3954 ('', 'prefix', '', _('apply patch to subdirectory'), _('DIR')),
3955 (
3956 '',
3957 'import-branch',
3958 None,
3959 _('use any branch information in patch (implied by --exact)'),
3960 ),
3961 ]
3962 + commitopts
3963 + commitopts2
3964 + similarityopts,
3351 _('[OPTION]... PATCH...'), 3965 _('[OPTION]... PATCH...'),
3352 helpcategory=command.CATEGORY_IMPORT_EXPORT) 3966 helpcategory=command.CATEGORY_IMPORT_EXPORT,
3967 )
3353 def import_(ui, repo, patch1=None, *patches, **opts): 3968 def import_(ui, repo, patch1=None, *patches, **opts):
3354 """import an ordered set of patches 3969 """import an ordered set of patches
3355 3970
3356 Import a list of patches and commit them individually (unless 3971 Import a list of patches and commit them individually (unless
3357 --no-commit is specified). 3972 --no-commit is specified).
3482 ret = 0 4097 ret = 0
3483 4098
3484 with repo.wlock(): 4099 with repo.wlock():
3485 if update: 4100 if update:
3486 cmdutil.checkunfinished(repo) 4101 cmdutil.checkunfinished(repo)
3487 if (exact or not opts.get('force')): 4102 if exact or not opts.get('force'):
3488 cmdutil.bailifchanged(repo) 4103 cmdutil.bailifchanged(repo)
3489 4104
3490 if not opts.get('no_commit'): 4105 if not opts.get('no_commit'):
3491 lock = repo.lock 4106 lock = repo.lock
3492 tr = lambda: repo.transaction('import') 4107 tr = lambda: repo.transaction('import')
3499 parents = repo[None].parents() 4114 parents = repo[None].parents()
3500 for patchurl in patches: 4115 for patchurl in patches:
3501 if patchurl == '-': 4116 if patchurl == '-':
3502 ui.status(_('applying patch from stdin\n')) 4117 ui.status(_('applying patch from stdin\n'))
3503 patchfile = ui.fin 4118 patchfile = ui.fin
3504 patchurl = 'stdin' # for error message 4119 patchurl = 'stdin' # for error message
3505 else: 4120 else:
3506 patchurl = os.path.join(base, patchurl) 4121 patchurl = os.path.join(base, patchurl)
3507 ui.status(_('applying %s\n') % patchurl) 4122 ui.status(_('applying %s\n') % patchurl)
3508 patchfile = hg.openpath(ui, patchurl, sendaccept=False) 4123 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
3509 4124
3510 haspatch = False 4125 haspatch = False
3511 for hunk in patch.split(patchfile): 4126 for hunk in patch.split(patchfile):
3512 with patch.extract(ui, hunk) as patchdata: 4127 with patch.extract(ui, hunk) as patchdata:
3513 msg, node, rej = cmdutil.tryimportone(ui, repo, 4128 msg, node, rej = cmdutil.tryimportone(
3514 patchdata, 4129 ui, repo, patchdata, parents, opts, msgs, hg.clean
3515 parents, opts, 4130 )
3516 msgs, hg.clean)
3517 if msg: 4131 if msg:
3518 haspatch = True 4132 haspatch = True
3519 ui.note(msg + '\n') 4133 ui.note(msg + '\n')
3520 if update or exact: 4134 if update or exact:
3521 parents = repo[None].parents() 4135 parents = repo[None].parents()
3522 else: 4136 else:
3523 parents = [repo[node]] 4137 parents = [repo[node]]
3524 if rej: 4138 if rej:
3525 ui.write_err(_("patch applied partially\n")) 4139 ui.write_err(_("patch applied partially\n"))
3526 ui.write_err(_("(fix the .rej files and run " 4140 ui.write_err(
3527 "`hg commit --amend`)\n")) 4141 _(
4142 "(fix the .rej files and run "
4143 "`hg commit --amend`)\n"
4144 )
4145 )
3528 ret = 1 4146 ret = 1
3529 break 4147 break
3530 4148
3531 if not haspatch: 4149 if not haspatch:
3532 raise error.Abort(_('%s: no diffs found') % patchurl) 4150 raise error.Abort(_('%s: no diffs found') % patchurl)
3533 4151
3534 if msgs: 4152 if msgs:
3535 repo.savecommitmessage('\n* * *\n'.join(msgs)) 4153 repo.savecommitmessage('\n* * *\n'.join(msgs))
3536 return ret 4154 return ret
3537 4155
3538 @command('incoming|in', 4156
3539 [('f', 'force', None, 4157 @command(
3540 _('run even if remote repository is unrelated')), 4158 'incoming|in',
3541 ('n', 'newest-first', None, _('show newest record first')), 4159 [
3542 ('', 'bundle', '', 4160 ('f', 'force', None, _('run even if remote repository is unrelated')),
3543 _('file to store the bundles into'), _('FILE')), 4161 ('n', 'newest-first', None, _('show newest record first')),
3544 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')), 4162 ('', 'bundle', '', _('file to store the bundles into'), _('FILE')),
3545 ('B', 'bookmarks', False, _("compare bookmarks")), 4163 (
3546 ('b', 'branch', [], 4164 'r',
3547 _('a specific branch you would like to pull'), _('BRANCH')), 4165 'rev',
3548 ] + logopts + remoteopts + subrepoopts, 4166 [],
4167 _('a remote changeset intended to be added'),
4168 _('REV'),
4169 ),
4170 ('B', 'bookmarks', False, _("compare bookmarks")),
4171 (
4172 'b',
4173 'branch',
4174 [],
4175 _('a specific branch you would like to pull'),
4176 _('BRANCH'),
4177 ),
4178 ]
4179 + logopts
4180 + remoteopts
4181 + subrepoopts,
3549 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'), 4182 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
3550 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT) 4183 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4184 )
3551 def incoming(ui, repo, source="default", **opts): 4185 def incoming(ui, repo, source="default", **opts):
3552 """show new changesets found in source 4186 """show new changesets found in source
3553 4187
3554 Show new changesets found in the specified path/URL or the default 4188 Show new changesets found in the specified path/URL or the default
3555 pull location. These are the changesets that would have been pulled 4189 pull location. These are the changesets that would have been pulled
3603 Returns 0 if there are incoming changes, 1 otherwise. 4237 Returns 0 if there are incoming changes, 1 otherwise.
3604 """ 4238 """
3605 opts = pycompat.byteskwargs(opts) 4239 opts = pycompat.byteskwargs(opts)
3606 if opts.get('graph'): 4240 if opts.get('graph'):
3607 logcmdutil.checkunsupportedgraphflags([], opts) 4241 logcmdutil.checkunsupportedgraphflags([], opts)
4242
3608 def display(other, chlist, displayer): 4243 def display(other, chlist, displayer):
3609 revdag = logcmdutil.graphrevs(other, chlist, opts) 4244 revdag = logcmdutil.graphrevs(other, chlist, opts)
3610 logcmdutil.displaygraph(ui, repo, revdag, displayer, 4245 logcmdutil.displaygraph(
3611 graphmod.asciiedges) 4246 ui, repo, revdag, displayer, graphmod.asciiedges
4247 )
3612 4248
3613 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True) 4249 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3614 return 0 4250 return 0
3615 4251
3616 if opts.get('bundle') and opts.get('subrepos'): 4252 if opts.get('bundle') and opts.get('subrepos'):
3617 raise error.Abort(_('cannot combine --bundle and --subrepos')) 4253 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3618 4254
3619 if opts.get('bookmarks'): 4255 if opts.get('bookmarks'):
3620 source, branches = hg.parseurl(ui.expandpath(source), 4256 source, branches = hg.parseurl(
3621 opts.get('branch')) 4257 ui.expandpath(source), opts.get('branch')
4258 )
3622 other = hg.peer(repo, opts, source) 4259 other = hg.peer(repo, opts, source)
3623 if 'bookmarks' not in other.listkeys('namespaces'): 4260 if 'bookmarks' not in other.listkeys('namespaces'):
3624 ui.warn(_("remote doesn't support bookmarks\n")) 4261 ui.warn(_("remote doesn't support bookmarks\n"))
3625 return 0 4262 return 0
3626 ui.pager('incoming') 4263 ui.pager('incoming')
3632 return hg.incoming(ui, repo, source, opts) 4269 return hg.incoming(ui, repo, source, opts)
3633 finally: 4270 finally:
3634 del repo._subtoppath 4271 del repo._subtoppath
3635 4272
3636 4273
3637 @command('init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'), 4274 @command(
3638 helpcategory=command.CATEGORY_REPO_CREATION, 4275 'init',
3639 helpbasic=True, norepo=True) 4276 remoteopts,
4277 _('[-e CMD] [--remotecmd CMD] [DEST]'),
4278 helpcategory=command.CATEGORY_REPO_CREATION,
4279 helpbasic=True,
4280 norepo=True,
4281 )
3640 def init(ui, dest=".", **opts): 4282 def init(ui, dest=".", **opts):
3641 """create a new repository in the given directory 4283 """create a new repository in the given directory
3642 4284
3643 Initialize a new repository in the given directory. If the given 4285 Initialize a new repository in the given directory. If the given
3644 directory does not exist, it will be created. 4286 directory does not exist, it will be created.
3651 Returns 0 on success. 4293 Returns 0 on success.
3652 """ 4294 """
3653 opts = pycompat.byteskwargs(opts) 4295 opts = pycompat.byteskwargs(opts)
3654 hg.peer(ui, opts, ui.expandpath(dest), create=True) 4296 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3655 4297
3656 @command('locate', 4298
3657 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')), 4299 @command(
3658 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')), 4300 'locate',
3659 ('f', 'fullpath', None, _('print complete paths from the filesystem root')), 4301 [
3660 ] + walkopts, 4302 ('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4303 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4304 (
4305 'f',
4306 'fullpath',
4307 None,
4308 _('print complete paths from the filesystem root'),
4309 ),
4310 ]
4311 + walkopts,
3661 _('[OPTION]... [PATTERN]...'), 4312 _('[OPTION]... [PATTERN]...'),
3662 helpcategory=command.CATEGORY_WORKING_DIRECTORY) 4313 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4314 )
3663 def locate(ui, repo, *pats, **opts): 4315 def locate(ui, repo, *pats, **opts):
3664 """locate files matching specific patterns (DEPRECATED) 4316 """locate files matching specific patterns (DEPRECATED)
3665 4317
3666 Print files under Mercurial control in the working directory whose 4318 Print files under Mercurial control in the working directory whose
3667 names match the given patterns. 4319 names match the given patterns.
3688 else: 4340 else:
3689 end = '\n' 4341 end = '\n'
3690 ctx = scmutil.revsingle(repo, opts.get('rev'), None) 4342 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3691 4343
3692 ret = 1 4344 ret = 1
3693 m = scmutil.match(ctx, pats, opts, default='relglob', 4345 m = scmutil.match(
3694 badfn=lambda x, y: False) 4346 ctx, pats, opts, default='relglob', badfn=lambda x, y: False
4347 )
3695 4348
3696 ui.pager('locate') 4349 ui.pager('locate')
3697 if ctx.rev() is None: 4350 if ctx.rev() is None:
3698 # When run on the working copy, "locate" includes removed files, so 4351 # When run on the working copy, "locate" includes removed files, so
3699 # we get the list of files from the dirstate. 4352 # we get the list of files from the dirstate.
3708 ui.write(uipathfn(abs), end) 4361 ui.write(uipathfn(abs), end)
3709 ret = 0 4362 ret = 0
3710 4363
3711 return ret 4364 return ret
3712 4365
3713 @command('log|history', 4366
3714 [('f', 'follow', None, 4367 @command(
3715 _('follow changeset history, or file history across copies and renames')), 4368 'log|history',
3716 ('', 'follow-first', None, 4369 [
3717 _('only follow the first parent of merge changesets (DEPRECATED)')), 4370 (
3718 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')), 4371 'f',
3719 ('C', 'copies', None, _('show copied files')), 4372 'follow',
3720 ('k', 'keyword', [], 4373 None,
3721 _('do case-insensitive search for a given text'), _('TEXT')), 4374 _(
3722 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')), 4375 'follow changeset history, or file history across copies and renames'
3723 ('L', 'line-range', [], 4376 ),
3724 _('follow line range of specified file (EXPERIMENTAL)'), 4377 ),
3725 _('FILE,RANGE')), 4378 (
3726 ('', 'removed', None, _('include revisions where files were removed')), 4379 '',
3727 ('m', 'only-merges', None, 4380 'follow-first',
3728 _('show only merges (DEPRECATED) (use -r "merge()" instead)')), 4381 None,
3729 ('u', 'user', [], _('revisions committed by user'), _('USER')), 4382 _('only follow the first parent of merge changesets (DEPRECATED)'),
3730 ('', 'only-branch', [], 4383 ),
3731 _('show only changesets within the given named branch (DEPRECATED)'), 4384 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3732 _('BRANCH')), 4385 ('C', 'copies', None, _('show copied files')),
3733 ('b', 'branch', [], 4386 (
3734 _('show changesets within the given named branch'), _('BRANCH')), 4387 'k',
3735 ('P', 'prune', [], 4388 'keyword',
3736 _('do not display revision or any of its ancestors'), _('REV')), 4389 [],
3737 ] + logopts + walkopts, 4390 _('do case-insensitive search for a given text'),
4391 _('TEXT'),
4392 ),
4393 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4394 (
4395 'L',
4396 'line-range',
4397 [],
4398 _('follow line range of specified file (EXPERIMENTAL)'),
4399 _('FILE,RANGE'),
4400 ),
4401 ('', 'removed', None, _('include revisions where files were removed')),
4402 (
4403 'm',
4404 'only-merges',
4405 None,
4406 _('show only merges (DEPRECATED) (use -r "merge()" instead)'),
4407 ),
4408 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4409 (
4410 '',
4411 'only-branch',
4412 [],
4413 _(
4414 'show only changesets within the given named branch (DEPRECATED)'
4415 ),
4416 _('BRANCH'),
4417 ),
4418 (
4419 'b',
4420 'branch',
4421 [],
4422 _('show changesets within the given named branch'),
4423 _('BRANCH'),
4424 ),
4425 (
4426 'P',
4427 'prune',
4428 [],
4429 _('do not display revision or any of its ancestors'),
4430 _('REV'),
4431 ),
4432 ]
4433 + logopts
4434 + walkopts,
3738 _('[OPTION]... [FILE]'), 4435 _('[OPTION]... [FILE]'),
3739 helpcategory=command.CATEGORY_CHANGE_NAVIGATION, 4436 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3740 helpbasic=True, inferrepo=True, 4437 helpbasic=True,
3741 intents={INTENT_READONLY}) 4438 inferrepo=True,
4439 intents={INTENT_READONLY},
4440 )
3742 def log(ui, repo, *pats, **opts): 4441 def log(ui, repo, *pats, **opts):
3743 """show revision history of entire repository or files 4442 """show revision history of entire repository or files
3744 4443
3745 Print the revision history of the specified files or the entire 4444 Print the revision history of the specified files or the entire
3746 project. 4445 project.
3892 if revs: 4591 if revs:
3893 endrev = revs.max() + 1 4592 endrev = revs.max() + 1
3894 getcopies = scmutil.getcopiesfn(repo, endrev=endrev) 4593 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
3895 4594
3896 ui.pager('log') 4595 ui.pager('log')
3897 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, differ, 4596 displayer = logcmdutil.changesetdisplayer(
3898 buffered=True) 4597 ui, repo, opts, differ, buffered=True
4598 )
3899 if opts.get('graph'): 4599 if opts.get('graph'):
3900 displayfn = logcmdutil.displaygraphrevs 4600 displayfn = logcmdutil.displaygraphrevs
3901 else: 4601 else:
3902 displayfn = logcmdutil.displayrevs 4602 displayfn = logcmdutil.displayrevs
3903 displayfn(ui, repo, revs, displayer, getcopies) 4603 displayfn(ui, repo, revs, displayer, getcopies)
3904 4604
3905 @command('manifest', 4605
3906 [('r', 'rev', '', _('revision to display'), _('REV')), 4606 @command(
3907 ('', 'all', False, _("list files from all revisions"))] 4607 'manifest',
3908 + formatteropts, 4608 [
4609 ('r', 'rev', '', _('revision to display'), _('REV')),
4610 ('', 'all', False, _("list files from all revisions")),
4611 ]
4612 + formatteropts,
3909 _('[-r REV]'), 4613 _('[-r REV]'),
3910 helpcategory=command.CATEGORY_MAINTENANCE, 4614 helpcategory=command.CATEGORY_MAINTENANCE,
3911 intents={INTENT_READONLY}) 4615 intents={INTENT_READONLY},
4616 )
3912 def manifest(ui, repo, node=None, rev=None, **opts): 4617 def manifest(ui, repo, node=None, rev=None, **opts):
3913 """output the current or given revision of the project manifest 4618 """output the current or given revision of the project manifest
3914 4619
3915 Print a list of version controlled files for the given revision. 4620 Print a list of version controlled files for the given revision.
3916 If no revision is given, the first parent of the working directory 4621 If no revision is given, the first parent of the working directory
3963 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f])) 4668 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3964 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl]) 4669 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3965 fm.write('path', '%s\n', f) 4670 fm.write('path', '%s\n', f)
3966 fm.end() 4671 fm.end()
3967 4672
3968 @command('merge', 4673
3969 [('f', 'force', None, 4674 @command(
3970 _('force a merge including outstanding changes (DEPRECATED)')), 4675 'merge',
3971 ('r', 'rev', '', _('revision to merge'), _('REV')), 4676 [
3972 ('P', 'preview', None, 4677 (
3973 _('review revisions to merge (no merge is performed)')), 4678 'f',
3974 ('', 'abort', None, _('abort the ongoing merge')), 4679 'force',
3975 ] + mergetoolopts, 4680 None,
4681 _('force a merge including outstanding changes (DEPRECATED)'),
4682 ),
4683 ('r', 'rev', '', _('revision to merge'), _('REV')),
4684 (
4685 'P',
4686 'preview',
4687 None,
4688 _('review revisions to merge (no merge is performed)'),
4689 ),
4690 ('', 'abort', None, _('abort the ongoing merge')),
4691 ]
4692 + mergetoolopts,
3976 _('[-P] [[-r] REV]'), 4693 _('[-P] [[-r] REV]'),
3977 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, helpbasic=True) 4694 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
4695 helpbasic=True,
4696 )
3978 def merge(ui, repo, node=None, **opts): 4697 def merge(ui, repo, node=None, **opts):
3979 """merge another revision into working directory 4698 """merge another revision into working directory
3980 4699
3981 The current working directory is updated with all changes made in 4700 The current working directory is updated with all changes made in
3982 the requested revision since the last common predecessor revision. 4701 the requested revision since the last common predecessor revision.
4009 if abort and repo.dirstate.p2() == nullid: 4728 if abort and repo.dirstate.p2() == nullid:
4010 cmdutil.wrongtooltocontinue(repo, _('merge')) 4729 cmdutil.wrongtooltocontinue(repo, _('merge'))
4011 if abort: 4730 if abort:
4012 state = cmdutil.getunfinishedstate(repo) 4731 state = cmdutil.getunfinishedstate(repo)
4013 if state and state._opname != 'merge': 4732 if state and state._opname != 'merge':
4014 raise error.Abort(_('cannot abort merge with %s in progress') % 4733 raise error.Abort(
4015 (state._opname), hint=state.hint()) 4734 _('cannot abort merge with %s in progress') % (state._opname),
4735 hint=state.hint(),
4736 )
4016 if node: 4737 if node:
4017 raise error.Abort(_("cannot specify a node with --abort")) 4738 raise error.Abort(_("cannot specify a node with --abort"))
4018 if opts.get('rev'): 4739 if opts.get('rev'):
4019 raise error.Abort(_("cannot specify both --rev and --abort")) 4740 raise error.Abort(_("cannot specify both --rev and --abort"))
4020 if opts.get('preview'): 4741 if opts.get('preview'):
4045 # ui.forcemerge is an internal variable, do not document 4766 # ui.forcemerge is an internal variable, do not document
4046 overrides = {('ui', 'forcemerge'): opts.get('tool', '')} 4767 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
4047 with ui.configoverride(overrides, 'merge'): 4768 with ui.configoverride(overrides, 'merge'):
4048 force = opts.get('force') 4769 force = opts.get('force')
4049 labels = ['working copy', 'merge rev'] 4770 labels = ['working copy', 'merge rev']
4050 return hg.merge(repo, node, force=force, mergeforce=force, 4771 return hg.merge(
4051 labels=labels, abort=abort) 4772 repo,
4773 node,
4774 force=force,
4775 mergeforce=force,
4776 labels=labels,
4777 abort=abort,
4778 )
4779
4052 4780
4053 statemod.addunfinished( 4781 statemod.addunfinished(
4054 'merge', fname=None, clearable=True, allowcommit=True, 4782 'merge',
4055 cmdmsg=_('outstanding uncommitted merge'), abortfunc=hg.abortmerge, 4783 fname=None,
4056 statushint=_('To continue: hg commit\n' 4784 clearable=True,
4057 'To abort: hg merge --abort'), 4785 allowcommit=True,
4058 cmdhint=_("use 'hg commit' or 'hg merge --abort'") 4786 cmdmsg=_('outstanding uncommitted merge'),
4787 abortfunc=hg.abortmerge,
4788 statushint=_(
4789 'To continue: hg commit\n' 'To abort: hg merge --abort'
4790 ),
4791 cmdhint=_("use 'hg commit' or 'hg merge --abort'"),
4059 ) 4792 )
4060 4793
4061 @command('outgoing|out', 4794
4062 [('f', 'force', None, _('run even when the destination is unrelated')), 4795 @command(
4063 ('r', 'rev', [], 4796 'outgoing|out',
4064 _('a changeset intended to be included in the destination'), _('REV')), 4797 [
4065 ('n', 'newest-first', None, _('show newest record first')), 4798 ('f', 'force', None, _('run even when the destination is unrelated')),
4066 ('B', 'bookmarks', False, _('compare bookmarks')), 4799 (
4067 ('b', 'branch', [], _('a specific branch you would like to push'), 4800 'r',
4068 _('BRANCH')), 4801 'rev',
4069 ] + logopts + remoteopts + subrepoopts, 4802 [],
4803 _('a changeset intended to be included in the destination'),
4804 _('REV'),
4805 ),
4806 ('n', 'newest-first', None, _('show newest record first')),
4807 ('B', 'bookmarks', False, _('compare bookmarks')),
4808 (
4809 'b',
4810 'branch',
4811 [],
4812 _('a specific branch you would like to push'),
4813 _('BRANCH'),
4814 ),
4815 ]
4816 + logopts
4817 + remoteopts
4818 + subrepoopts,
4070 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'), 4819 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
4071 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT) 4820 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4821 )
4072 def outgoing(ui, repo, dest=None, **opts): 4822 def outgoing(ui, repo, dest=None, **opts):
4073 """show changesets not found in the destination 4823 """show changesets not found in the destination
4074 4824
4075 Show changesets not found in the specified destination repository 4825 Show changesets not found in the specified destination repository
4076 or the default push location. These are the changesets that would 4826 or the default push location. These are the changesets that would
4107 """ 4857 """
4108 # hg._outgoing() needs to re-resolve the path in order to handle #branch 4858 # hg._outgoing() needs to re-resolve the path in order to handle #branch
4109 # style URLs, so don't overwrite dest. 4859 # style URLs, so don't overwrite dest.
4110 path = ui.paths.getpath(dest, default=('default-push', 'default')) 4860 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4111 if not path: 4861 if not path:
4112 raise error.Abort(_('default repository not configured!'), 4862 raise error.Abort(
4113 hint=_("see 'hg help config.paths'")) 4863 _('default repository not configured!'),
4864 hint=_("see 'hg help config.paths'"),
4865 )
4114 4866
4115 opts = pycompat.byteskwargs(opts) 4867 opts = pycompat.byteskwargs(opts)
4116 if opts.get('graph'): 4868 if opts.get('graph'):
4117 logcmdutil.checkunsupportedgraphflags([], opts) 4869 logcmdutil.checkunsupportedgraphflags([], opts)
4118 o, other = hg._outgoing(ui, repo, dest, opts) 4870 o, other = hg._outgoing(ui, repo, dest, opts)
4121 return 4873 return
4122 4874
4123 revdag = logcmdutil.graphrevs(repo, o, opts) 4875 revdag = logcmdutil.graphrevs(repo, o, opts)
4124 ui.pager('outgoing') 4876 ui.pager('outgoing')
4125 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True) 4877 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
4126 logcmdutil.displaygraph(ui, repo, revdag, displayer, 4878 logcmdutil.displaygraph(
4127 graphmod.asciiedges) 4879 ui, repo, revdag, displayer, graphmod.asciiedges
4880 )
4128 cmdutil.outgoinghooks(ui, repo, other, opts, o) 4881 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4129 return 0 4882 return 0
4130 4883
4131 if opts.get('bookmarks'): 4884 if opts.get('bookmarks'):
4132 dest = path.pushloc or path.loc 4885 dest = path.pushloc or path.loc
4142 try: 4895 try:
4143 return hg.outgoing(ui, repo, dest, opts) 4896 return hg.outgoing(ui, repo, dest, opts)
4144 finally: 4897 finally:
4145 del repo._subtoppath 4898 del repo._subtoppath
4146 4899
4147 @command('parents', 4900
4148 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')), 4901 @command(
4149 ] + templateopts, 4902 'parents',
4903 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),]
4904 + templateopts,
4150 _('[-r REV] [FILE]'), 4905 _('[-r REV] [FILE]'),
4151 helpcategory=command.CATEGORY_CHANGE_NAVIGATION, 4906 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4152 inferrepo=True) 4907 inferrepo=True,
4908 )
4153 def parents(ui, repo, file_=None, **opts): 4909 def parents(ui, repo, file_=None, **opts):
4154 """show the parents of the working directory or revision (DEPRECATED) 4910 """show the parents of the working directory or revision (DEPRECATED)
4155 4911
4156 Print the working directory's parent revisions. If a revision is 4912 Print the working directory's parent revisions. If a revision is
4157 given via -r/--rev, the parent of that revision will be printed. 4913 given via -r/--rev, the parent of that revision will be printed.
4203 for n in p: 4959 for n in p:
4204 if n != nullid: 4960 if n != nullid:
4205 displayer.show(repo[n]) 4961 displayer.show(repo[n])
4206 displayer.close() 4962 displayer.close()
4207 4963
4208 @command('paths', formatteropts, _('[NAME]'), 4964
4965 @command(
4966 'paths',
4967 formatteropts,
4968 _('[NAME]'),
4209 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT, 4969 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4210 optionalrepo=True, intents={INTENT_READONLY}) 4970 optionalrepo=True,
4971 intents={INTENT_READONLY},
4972 )
4211 def paths(ui, repo, search=None, **opts): 4973 def paths(ui, repo, search=None, **opts):
4212 """show aliases for remote repositories 4974 """show aliases for remote repositories
4213 4975
4214 Show definition of symbolic path name NAME. If no name is given, 4976 Show definition of symbolic path name NAME. If no name is given,
4215 show definition of all available names. 4977 show definition of all available names.
4251 """ 5013 """
4252 5014
4253 opts = pycompat.byteskwargs(opts) 5015 opts = pycompat.byteskwargs(opts)
4254 ui.pager('paths') 5016 ui.pager('paths')
4255 if search: 5017 if search:
4256 pathitems = [(name, path) for name, path in ui.paths.iteritems() 5018 pathitems = [
4257 if name == search] 5019 (name, path)
5020 for name, path in ui.paths.iteritems()
5021 if name == search
5022 ]
4258 else: 5023 else:
4259 pathitems = sorted(ui.paths.iteritems()) 5024 pathitems = sorted(ui.paths.iteritems())
4260 5025
4261 fm = ui.formatter('paths', opts) 5026 fm = ui.formatter('paths', opts)
4262 if fm.isplain(): 5027 if fm.isplain():
4286 ui.warn(_("not found!\n")) 5051 ui.warn(_("not found!\n"))
4287 return 1 5052 return 1
4288 else: 5053 else:
4289 return 0 5054 return 0
4290 5055
4291 @command('phase', 5056
4292 [('p', 'public', False, _('set changeset phase to public')), 5057 @command(
4293 ('d', 'draft', False, _('set changeset phase to draft')), 5058 'phase',
4294 ('s', 'secret', False, _('set changeset phase to secret')), 5059 [
4295 ('f', 'force', False, _('allow to move boundary backward')), 5060 ('p', 'public', False, _('set changeset phase to public')),
4296 ('r', 'rev', [], _('target revision'), _('REV')), 5061 ('d', 'draft', False, _('set changeset phase to draft')),
5062 ('s', 'secret', False, _('set changeset phase to secret')),
5063 ('f', 'force', False, _('allow to move boundary backward')),
5064 ('r', 'rev', [], _('target revision'), _('REV')),
4297 ], 5065 ],
4298 _('[-p|-d|-s] [-f] [-r] [REV...]'), 5066 _('[-p|-d|-s] [-f] [-r] [REV...]'),
4299 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) 5067 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5068 )
4300 def phase(ui, repo, *revs, **opts): 5069 def phase(ui, repo, *revs, **opts):
4301 """set or show the current phase name 5070 """set or show the current phase name
4302 5071
4303 With no argument, show the phase name of the current revision(s). 5072 With no argument, show the phase name of the current revision(s).
4304 5073
4355 phases.retractboundary(repo, tr, targetphase, nodes) 5124 phases.retractboundary(repo, tr, targetphase, nodes)
4356 getphase = unfi._phasecache.phase 5125 getphase = unfi._phasecache.phase
4357 newdata = [getphase(unfi, r) for r in unfi] 5126 newdata = [getphase(unfi, r) for r in unfi]
4358 changes = sum(newdata[r] != olddata[r] for r in unfi) 5127 changes = sum(newdata[r] != olddata[r] for r in unfi)
4359 cl = unfi.changelog 5128 cl = unfi.changelog
4360 rejected = [n for n in nodes 5129 rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
4361 if newdata[cl.rev(n)] < targetphase]
4362 if rejected: 5130 if rejected:
4363 ui.warn(_('cannot move %i changesets to a higher ' 5131 ui.warn(
4364 'phase, use --force\n') % len(rejected)) 5132 _(
5133 'cannot move %i changesets to a higher '
5134 'phase, use --force\n'
5135 )
5136 % len(rejected)
5137 )
4365 ret = 1 5138 ret = 1
4366 if changes: 5139 if changes:
4367 msg = _('phase changed for %i changesets\n') % changes 5140 msg = _('phase changed for %i changesets\n') % changes
4368 if ret: 5141 if ret:
4369 ui.status(msg) 5142 ui.status(msg)
4370 else: 5143 else:
4371 ui.note(msg) 5144 ui.note(msg)
4372 else: 5145 else:
4373 ui.warn(_('no phases changed\n')) 5146 ui.warn(_('no phases changed\n'))
4374 return ret 5147 return ret
5148
4375 5149
4376 def postincoming(ui, repo, modheads, optupdate, checkout, brev): 5150 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
4377 """Run after a changegroup has been added via pull/unbundle 5151 """Run after a changegroup has been added via pull/unbundle
4378 5152
4379 This takes arguments below: 5153 This takes arguments below:
4395 if modheads is not None and modheads > 1: 5169 if modheads is not None and modheads > 1:
4396 currentbranchheads = len(repo.branchheads()) 5170 currentbranchheads = len(repo.branchheads())
4397 if currentbranchheads == modheads: 5171 if currentbranchheads == modheads:
4398 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n")) 5172 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4399 elif currentbranchheads > 1: 5173 elif currentbranchheads > 1:
4400 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to " 5174 ui.status(
4401 "merge)\n")) 5175 _("(run 'hg heads .' to see heads, 'hg merge' to " "merge)\n")
5176 )
4402 else: 5177 else:
4403 ui.status(_("(run 'hg heads' to see heads)\n")) 5178 ui.status(_("(run 'hg heads' to see heads)\n"))
4404 elif not ui.configbool('commands', 'update.requiredest'): 5179 elif not ui.configbool('commands', 'update.requiredest'):
4405 ui.status(_("(run 'hg update' to get a working copy)\n")) 5180 ui.status(_("(run 'hg update' to get a working copy)\n"))
4406 5181
4407 @command('pull', 5182
4408 [('u', 'update', None, 5183 @command(
4409 _('update to new branch head if new descendants were pulled')), 5184 'pull',
4410 ('f', 'force', None, _('run even when remote repository is unrelated')), 5185 [
4411 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')), 5186 (
4412 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')), 5187 'u',
4413 ('b', 'branch', [], _('a specific branch you would like to pull'), 5188 'update',
4414 _('BRANCH')), 5189 None,
4415 ] + remoteopts, 5190 _('update to new branch head if new descendants were pulled'),
5191 ),
5192 ('f', 'force', None, _('run even when remote repository is unrelated')),
5193 (
5194 'r',
5195 'rev',
5196 [],
5197 _('a remote changeset intended to be added'),
5198 _('REV'),
5199 ),
5200 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5201 (
5202 'b',
5203 'branch',
5204 [],
5205 _('a specific branch you would like to pull'),
5206 _('BRANCH'),
5207 ),
5208 ]
5209 + remoteopts,
4416 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'), 5210 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
4417 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT, 5211 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4418 helpbasic=True) 5212 helpbasic=True,
5213 )
4419 def pull(ui, repo, source="default", **opts): 5214 def pull(ui, repo, source="default", **opts):
4420 """pull changes from the specified source 5215 """pull changes from the specified source
4421 5216
4422 Pull changes from a remote repository to a local one. 5217 Pull changes from a remote repository to a local one.
4423 5218
4454 5249
4455 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch')) 5250 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4456 ui.status(_('pulling from %s\n') % util.hidepassword(source)) 5251 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4457 other = hg.peer(repo, opts, source) 5252 other = hg.peer(repo, opts, source)
4458 try: 5253 try:
4459 revs, checkout = hg.addbranchrevs(repo, other, branches, 5254 revs, checkout = hg.addbranchrevs(
4460 opts.get('rev')) 5255 repo, other, branches, opts.get('rev')
5256 )
4461 5257
4462 pullopargs = {} 5258 pullopargs = {}
4463 5259
4464 nodes = None 5260 nodes = None
4465 if opts.get('bookmark') or revs: 5261 if opts.get('bookmark') or revs:
4469 # version of the server state (issue 4700). 5265 # version of the server state (issue 4700).
4470 nodes = [] 5266 nodes = []
4471 fnodes = [] 5267 fnodes = []
4472 revs = revs or [] 5268 revs = revs or []
4473 if revs and not other.capable('lookup'): 5269 if revs and not other.capable('lookup'):
4474 err = _("other repository doesn't support revision lookup, " 5270 err = _(
4475 "so a rev cannot be specified.") 5271 "other repository doesn't support revision lookup, "
5272 "so a rev cannot be specified."
5273 )
4476 raise error.Abort(err) 5274 raise error.Abort(err)
4477 with other.commandexecutor() as e: 5275 with other.commandexecutor() as e:
4478 fremotebookmarks = e.callcommand('listkeys', { 5276 fremotebookmarks = e.callcommand(
4479 'namespace': 'bookmarks' 5277 'listkeys', {'namespace': 'bookmarks'}
4480 }) 5278 )
4481 for r in revs: 5279 for r in revs:
4482 fnodes.append(e.callcommand('lookup', {'key': r})) 5280 fnodes.append(e.callcommand('lookup', {'key': r}))
4483 remotebookmarks = fremotebookmarks.result() 5281 remotebookmarks = fremotebookmarks.result()
4484 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks) 5282 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
4485 pullopargs['remotebookmarks'] = remotebookmarks 5283 pullopargs['remotebookmarks'] = remotebookmarks
4497 wlock = util.nullcontextmanager() 5295 wlock = util.nullcontextmanager()
4498 if opts.get('update'): 5296 if opts.get('update'):
4499 wlock = repo.wlock() 5297 wlock = repo.wlock()
4500 with wlock: 5298 with wlock:
4501 pullopargs.update(opts.get('opargs', {})) 5299 pullopargs.update(opts.get('opargs', {}))
4502 modheads = exchange.pull(repo, other, heads=nodes, 5300 modheads = exchange.pull(
4503 force=opts.get('force'), 5301 repo,
4504 bookmarks=opts.get('bookmark', ()), 5302 other,
4505 opargs=pullopargs).cgresult 5303 heads=nodes,
5304 force=opts.get('force'),
5305 bookmarks=opts.get('bookmark', ()),
5306 opargs=pullopargs,
5307 ).cgresult
4506 5308
4507 # brev is a name, which might be a bookmark to be activated at 5309 # brev is a name, which might be a bookmark to be activated at
4508 # the end of the update. In other words, it is an explicit 5310 # the end of the update. In other words, it is an explicit
4509 # destination of the update 5311 # destination of the update
4510 brev = None 5312 brev = None
4521 brev = opts['branch'][0] 5323 brev = opts['branch'][0]
4522 else: 5324 else:
4523 brev = branches[0] 5325 brev = branches[0]
4524 repo._subtoppath = source 5326 repo._subtoppath = source
4525 try: 5327 try:
4526 ret = postincoming(ui, repo, modheads, opts.get('update'), 5328 ret = postincoming(
4527 checkout, brev) 5329 ui, repo, modheads, opts.get('update'), checkout, brev
5330 )
4528 except error.FilteredRepoLookupError as exc: 5331 except error.FilteredRepoLookupError as exc:
4529 msg = _('cannot update to target: %s') % exc.args[0] 5332 msg = _('cannot update to target: %s') % exc.args[0]
4530 exc.args = (msg,) + exc.args[1:] 5333 exc.args = (msg,) + exc.args[1:]
4531 raise 5334 raise
4532 finally: 5335 finally:
4534 5337
4535 finally: 5338 finally:
4536 other.close() 5339 other.close()
4537 return ret 5340 return ret
4538 5341
4539 @command('push', 5342
4540 [('f', 'force', None, _('force push')), 5343 @command(
4541 ('r', 'rev', [], 5344 'push',
4542 _('a changeset intended to be included in the destination'), 5345 [
4543 _('REV')), 5346 ('f', 'force', None, _('force push')),
4544 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')), 5347 (
4545 ('b', 'branch', [], 5348 'r',
4546 _('a specific branch you would like to push'), _('BRANCH')), 5349 'rev',
4547 ('', 'new-branch', False, _('allow pushing a new branch')), 5350 [],
4548 ('', 'pushvars', [], _('variables that can be sent to server (ADVANCED)')), 5351 _('a changeset intended to be included in the destination'),
4549 ('', 'publish', False, _('push the changeset as public (EXPERIMENTAL)')), 5352 _('REV'),
4550 ] + remoteopts, 5353 ),
5354 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5355 (
5356 'b',
5357 'branch',
5358 [],
5359 _('a specific branch you would like to push'),
5360 _('BRANCH'),
5361 ),
5362 ('', 'new-branch', False, _('allow pushing a new branch')),
5363 (
5364 '',
5365 'pushvars',
5366 [],
5367 _('variables that can be sent to server (ADVANCED)'),
5368 ),
5369 (
5370 '',
5371 'publish',
5372 False,
5373 _('push the changeset as public (EXPERIMENTAL)'),
5374 ),
5375 ]
5376 + remoteopts,
4551 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'), 5377 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
4552 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT, 5378 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4553 helpbasic=True) 5379 helpbasic=True,
5380 )
4554 def push(ui, repo, dest=None, **opts): 5381 def push(ui, repo, dest=None, **opts):
4555 """push changes to the specified destination 5382 """push changes to the specified destination
4556 5383
4557 Push changesets from the local repository to the specified 5384 Push changesets from the local repository to the specified
4558 destination. 5385 destination.
4621 # this lets simultaneous -r, -b options continue working 5448 # this lets simultaneous -r, -b options continue working
4622 opts.setdefault('rev', []).append("null") 5449 opts.setdefault('rev', []).append("null")
4623 5450
4624 path = ui.paths.getpath(dest, default=('default-push', 'default')) 5451 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4625 if not path: 5452 if not path:
4626 raise error.Abort(_('default repository not configured!'), 5453 raise error.Abort(
4627 hint=_("see 'hg help config.paths'")) 5454 _('default repository not configured!'),
5455 hint=_("see 'hg help config.paths'"),
5456 )
4628 dest = path.pushloc or path.loc 5457 dest = path.pushloc or path.loc
4629 branches = (path.branch, opts.get('branch') or []) 5458 branches = (path.branch, opts.get('branch') or [])
4630 ui.status(_('pushing to %s\n') % util.hidepassword(dest)) 5459 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4631 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev')) 5460 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4632 other = hg.peer(repo, opts, dest) 5461 other = hg.peer(repo, opts, dest)
4633 5462
4634 if revs: 5463 if revs:
4635 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)] 5464 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
4636 if not revs: 5465 if not revs:
4637 raise error.Abort(_("specified revisions evaluate to an empty set"), 5466 raise error.Abort(
4638 hint=_("use different revision arguments")) 5467 _("specified revisions evaluate to an empty set"),
5468 hint=_("use different revision arguments"),
5469 )
4639 elif path.pushrev: 5470 elif path.pushrev:
4640 # It doesn't make any sense to specify ancestor revisions. So limit 5471 # It doesn't make any sense to specify ancestor revisions. So limit
4641 # to DAG heads to make discovery simpler. 5472 # to DAG heads to make discovery simpler.
4642 expr = revsetlang.formatspec('heads(%r)', path.pushrev) 5473 expr = revsetlang.formatspec('heads(%r)', path.pushrev)
4643 revs = scmutil.revrange(repo, [expr]) 5474 revs = scmutil.revrange(repo, [expr])
4644 revs = [repo[rev].node() for rev in revs] 5475 revs = [repo[rev].node() for rev in revs]
4645 if not revs: 5476 if not revs:
4646 raise error.Abort(_('default push revset for path evaluates to an ' 5477 raise error.Abort(
4647 'empty set')) 5478 _('default push revset for path evaluates to an ' 'empty set')
5479 )
4648 5480
4649 repo._subtoppath = dest 5481 repo._subtoppath = dest
4650 try: 5482 try:
4651 # push subrepos depth-first for coherent ordering 5483 # push subrepos depth-first for coherent ordering
4652 c = repo['.'] 5484 c = repo['.']
4653 subs = c.substate # only repos that are committed 5485 subs = c.substate # only repos that are committed
4654 for s in sorted(subs): 5486 for s in sorted(subs):
4655 result = c.sub(s).push(opts) 5487 result = c.sub(s).push(opts)
4656 if result == 0: 5488 if result == 0:
4657 return not result 5489 return not result
4658 finally: 5490 finally:
4659 del repo._subtoppath 5491 del repo._subtoppath
4660 5492
4661 opargs = dict(opts.get('opargs', {})) # copy opargs since we may mutate it 5493 opargs = dict(opts.get('opargs', {})) # copy opargs since we may mutate it
4662 opargs.setdefault('pushvars', []).extend(opts.get('pushvars', [])) 5494 opargs.setdefault('pushvars', []).extend(opts.get('pushvars', []))
4663 5495
4664 pushop = exchange.push(repo, other, opts.get('force'), revs=revs, 5496 pushop = exchange.push(
4665 newbranch=opts.get('new_branch'), 5497 repo,
4666 bookmarks=opts.get('bookmark', ()), 5498 other,
4667 publish=opts.get('publish'), 5499 opts.get('force'),
4668 opargs=opargs) 5500 revs=revs,
5501 newbranch=opts.get('new_branch'),
5502 bookmarks=opts.get('bookmark', ()),
5503 publish=opts.get('publish'),
5504 opargs=opargs,
5505 )
4669 5506
4670 result = not pushop.cgresult 5507 result = not pushop.cgresult
4671 5508
4672 if pushop.bkresult is not None: 5509 if pushop.bkresult is not None:
4673 if pushop.bkresult == 2: 5510 if pushop.bkresult == 2:
4675 elif not result and pushop.bkresult: 5512 elif not result and pushop.bkresult:
4676 result = 2 5513 result = 2
4677 5514
4678 return result 5515 return result
4679 5516
4680 @command('recover', 5517
4681 [('','verify', True, "run `hg verify` after succesful recover"), 5518 @command(
4682 ], 5519 'recover',
4683 helpcategory=command.CATEGORY_MAINTENANCE) 5520 [('', 'verify', True, "run `hg verify` after succesful recover"),],
5521 helpcategory=command.CATEGORY_MAINTENANCE,
5522 )
4684 def recover(ui, repo, **opts): 5523 def recover(ui, repo, **opts):
4685 """roll back an interrupted transaction 5524 """roll back an interrupted transaction
4686 5525
4687 Recover from an interrupted commit or pull. 5526 Recover from an interrupted commit or pull.
4688 5527
4695 ret = repo.recover() 5534 ret = repo.recover()
4696 if ret: 5535 if ret:
4697 if opts[r'verify']: 5536 if opts[r'verify']:
4698 return hg.verify(repo) 5537 return hg.verify(repo)
4699 else: 5538 else:
4700 msg = _("(verify step skipped, run `hg verify` to check your " 5539 msg = _(
4701 "repository content)\n") 5540 "(verify step skipped, run `hg verify` to check your "
5541 "repository content)\n"
5542 )
4702 ui.warn(msg) 5543 ui.warn(msg)
4703 return 0 5544 return 0
4704 return 1 5545 return 1
4705 5546
4706 @command('remove|rm', 5547
4707 [('A', 'after', None, _('record delete for missing files')), 5548 @command(
4708 ('f', 'force', None, 5549 'remove|rm',
4709 _('forget added files, delete modified files')), 5550 [
4710 ] + subrepoopts + walkopts + dryrunopts, 5551 ('A', 'after', None, _('record delete for missing files')),
5552 ('f', 'force', None, _('forget added files, delete modified files')),
5553 ]
5554 + subrepoopts
5555 + walkopts
5556 + dryrunopts,
4711 _('[OPTION]... FILE...'), 5557 _('[OPTION]... FILE...'),
4712 helpcategory=command.CATEGORY_WORKING_DIRECTORY, 5558 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4713 helpbasic=True, inferrepo=True) 5559 helpbasic=True,
5560 inferrepo=True,
5561 )
4714 def remove(ui, repo, *pats, **opts): 5562 def remove(ui, repo, *pats, **opts):
4715 """remove the specified files on the next commit 5563 """remove the specified files on the next commit
4716 5564
4717 Schedule the indicated files for removal from the current branch. 5565 Schedule the indicated files for removal from the current branch.
4718 5566
4757 raise error.Abort(_('no files specified')) 5605 raise error.Abort(_('no files specified'))
4758 5606
4759 m = scmutil.match(repo[None], pats, opts) 5607 m = scmutil.match(repo[None], pats, opts)
4760 subrepos = opts.get('subrepos') 5608 subrepos = opts.get('subrepos')
4761 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) 5609 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
4762 return cmdutil.remove(ui, repo, m, "", uipathfn, after, force, subrepos, 5610 return cmdutil.remove(
4763 dryrun=dryrun) 5611 ui, repo, m, "", uipathfn, after, force, subrepos, dryrun=dryrun
4764 5612 )
4765 @command('rename|move|mv', 5613
4766 [('A', 'after', None, _('record a rename that has already occurred')), 5614
4767 ('f', 'force', None, _('forcibly move over an existing managed file')), 5615 @command(
4768 ] + walkopts + dryrunopts, 5616 'rename|move|mv',
5617 [
5618 ('A', 'after', None, _('record a rename that has already occurred')),
5619 ('f', 'force', None, _('forcibly move over an existing managed file')),
5620 ]
5621 + walkopts
5622 + dryrunopts,
4769 _('[OPTION]... SOURCE... DEST'), 5623 _('[OPTION]... SOURCE... DEST'),
4770 helpcategory=command.CATEGORY_WORKING_DIRECTORY) 5624 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5625 )
4771 def rename(ui, repo, *pats, **opts): 5626 def rename(ui, repo, *pats, **opts):
4772 """rename files; equivalent of copy + remove 5627 """rename files; equivalent of copy + remove
4773 5628
4774 Mark dest as copies of sources; mark sources for deletion. If dest 5629 Mark dest as copies of sources; mark sources for deletion. If dest
4775 is a directory, copies are put in that directory. If dest is a 5630 is a directory, copies are put in that directory. If dest is a
4786 """ 5641 """
4787 opts = pycompat.byteskwargs(opts) 5642 opts = pycompat.byteskwargs(opts)
4788 with repo.wlock(False): 5643 with repo.wlock(False):
4789 return cmdutil.copy(ui, repo, pats, opts, rename=True) 5644 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4790 5645
4791 @command('resolve', 5646
4792 [('a', 'all', None, _('select all unresolved files')), 5647 @command(
4793 ('l', 'list', None, _('list state of files needing merge')), 5648 'resolve',
4794 ('m', 'mark', None, _('mark files as resolved')), 5649 [
4795 ('u', 'unmark', None, _('mark files as unresolved')), 5650 ('a', 'all', None, _('select all unresolved files')),
4796 ('n', 'no-status', None, _('hide status prefix')), 5651 ('l', 'list', None, _('list state of files needing merge')),
4797 ('', 're-merge', None, _('re-merge files'))] 5652 ('m', 'mark', None, _('mark files as resolved')),
4798 + mergetoolopts + walkopts + formatteropts, 5653 ('u', 'unmark', None, _('mark files as unresolved')),
5654 ('n', 'no-status', None, _('hide status prefix')),
5655 ('', 're-merge', None, _('re-merge files')),
5656 ]
5657 + mergetoolopts
5658 + walkopts
5659 + formatteropts,
4799 _('[OPTION]... [FILE]...'), 5660 _('[OPTION]... [FILE]...'),
4800 helpcategory=command.CATEGORY_WORKING_DIRECTORY, 5661 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4801 inferrepo=True) 5662 inferrepo=True,
5663 )
4802 def resolve(ui, repo, *pats, **opts): 5664 def resolve(ui, repo, *pats, **opts):
4803 """redo merges or set/view the merge status of files 5665 """redo merges or set/view the merge status of files
4804 5666
4805 Merges with unresolved conflicts are often the result of 5667 Merges with unresolved conflicts are often the result of
4806 non-interactive merging using the ``internal:merge`` configuration 5668 non-interactive merging using the ``internal:merge`` configuration
4852 """ 5714 """
4853 5715
4854 opts = pycompat.byteskwargs(opts) 5716 opts = pycompat.byteskwargs(opts)
4855 confirm = ui.configbool('commands', 'resolve.confirm') 5717 confirm = ui.configbool('commands', 'resolve.confirm')
4856 flaglist = 'all mark unmark list no_status re_merge'.split() 5718 flaglist = 'all mark unmark list no_status re_merge'.split()
4857 all, mark, unmark, show, nostatus, remerge = [ 5719 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
4858 opts.get(o) for o in flaglist]
4859 5720
4860 actioncount = len(list(filter(None, [show, mark, unmark, remerge]))) 5721 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
4861 if actioncount > 1: 5722 if actioncount > 1:
4862 raise error.Abort(_("too many actions specified")) 5723 raise error.Abort(_("too many actions specified"))
4863 elif (actioncount == 0 5724 elif actioncount == 0 and ui.configbool(
4864 and ui.configbool('commands', 'resolve.explicit-re-merge')): 5725 'commands', 'resolve.explicit-re-merge'
5726 ):
4865 hint = _('use --mark, --unmark, --list or --re-merge') 5727 hint = _('use --mark, --unmark, --list or --re-merge')
4866 raise error.Abort(_('no action specified'), hint=hint) 5728 raise error.Abort(_('no action specified'), hint=hint)
4867 if pats and all: 5729 if pats and all:
4868 raise error.Abort(_("can't specify --all and patterns")) 5730 raise error.Abort(_("can't specify --all and patterns"))
4869 if not (all or pats or show or mark or unmark): 5731 if not (all or pats or show or mark or unmark):
4870 raise error.Abort(_('no files or directories specified'), 5732 raise error.Abort(
4871 hint=('use --all to re-merge all unresolved files')) 5733 _('no files or directories specified'),
5734 hint='use --all to re-merge all unresolved files',
5735 )
4872 5736
4873 if confirm: 5737 if confirm:
4874 if all: 5738 if all:
4875 if ui.promptchoice(_(b're-merge all unresolved files (yn)?' 5739 if ui.promptchoice(
4876 b'$$ &Yes $$ &No')): 5740 _(b're-merge all unresolved files (yn)?' b'$$ &Yes $$ &No')
5741 ):
4877 raise error.Abort(_('user quit')) 5742 raise error.Abort(_('user quit'))
4878 if mark and not pats: 5743 if mark and not pats:
4879 if ui.promptchoice(_(b'mark all unresolved files as resolved (yn)?' 5744 if ui.promptchoice(
4880 b'$$ &Yes $$ &No')): 5745 _(
5746 b'mark all unresolved files as resolved (yn)?'
5747 b'$$ &Yes $$ &No'
5748 )
5749 ):
4881 raise error.Abort(_('user quit')) 5750 raise error.Abort(_('user quit'))
4882 if unmark and not pats: 5751 if unmark and not pats:
4883 if ui.promptchoice(_(b'mark all resolved files as unresolved (yn)?' 5752 if ui.promptchoice(
4884 b'$$ &Yes $$ &No')): 5753 _(
5754 b'mark all resolved files as unresolved (yn)?'
5755 b'$$ &Yes $$ &No'
5756 )
5757 ):
4885 raise error.Abort(_('user quit')) 5758 raise error.Abort(_('user quit'))
4886 5759
4887 uipathfn = scmutil.getuipathfn(repo) 5760 uipathfn = scmutil.getuipathfn(repo)
4888 5761
4889 if show: 5762 if show:
4899 mergestateinfo = { 5772 mergestateinfo = {
4900 mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'), 5773 mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'),
4901 mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'), 5774 mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'),
4902 mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'), 5775 mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'),
4903 mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'), 5776 mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'),
4904 mergemod.MERGE_RECORD_DRIVER_RESOLVED: ('resolve.driverresolved', 5777 mergemod.MERGE_RECORD_DRIVER_RESOLVED: (
4905 'D'), 5778 'resolve.driverresolved',
5779 'D',
5780 ),
4906 } 5781 }
4907 5782
4908 for f in ms: 5783 for f in ms:
4909 if not m(f): 5784 if not m(f):
4910 continue 5785 continue
4921 with repo.wlock(): 5796 with repo.wlock():
4922 ms = mergemod.mergestate.read(repo) 5797 ms = mergemod.mergestate.read(repo)
4923 5798
4924 if not (ms.active() or repo.dirstate.p2() != nullid): 5799 if not (ms.active() or repo.dirstate.p2() != nullid):
4925 raise error.Abort( 5800 raise error.Abort(
4926 _('resolve command not applicable when not merging')) 5801 _('resolve command not applicable when not merging')
5802 )
4927 5803
4928 wctx = repo[None] 5804 wctx = repo[None]
4929 5805
4930 if (ms.mergedriver 5806 if (
4931 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED): 5807 ms.mergedriver
5808 and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED
5809 ):
4932 proceed = mergemod.driverpreprocess(repo, ms, wctx) 5810 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4933 ms.commit() 5811 ms.commit()
4934 # allow mark and unmark to go through 5812 # allow mark and unmark to go through
4935 if not mark and not unmark and not proceed: 5813 if not mark and not unmark and not proceed:
4936 return 1 5814 return 1
4957 # step if asked to resolve 5835 # step if asked to resolve
4958 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED: 5836 if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
4959 exact = m.exact(f) 5837 exact = m.exact(f)
4960 if mark: 5838 if mark:
4961 if exact: 5839 if exact:
4962 ui.warn(_('not marking %s as it is driver-resolved\n') 5840 ui.warn(
4963 % uipathfn(f)) 5841 _('not marking %s as it is driver-resolved\n')
5842 % uipathfn(f)
5843 )
4964 elif unmark: 5844 elif unmark:
4965 if exact: 5845 if exact:
4966 ui.warn(_('not unmarking %s as it is driver-resolved\n') 5846 ui.warn(
4967 % uipathfn(f)) 5847 _('not unmarking %s as it is driver-resolved\n')
5848 % uipathfn(f)
5849 )
4968 else: 5850 else:
4969 runconclude = True 5851 runconclude = True
4970 continue 5852 continue
4971 5853
4972 # path conflicts must be resolved manually 5854 # path conflicts must be resolved manually
4973 if ms[f] in (mergemod.MERGE_RECORD_UNRESOLVED_PATH, 5855 if ms[f] in (
4974 mergemod.MERGE_RECORD_RESOLVED_PATH): 5856 mergemod.MERGE_RECORD_UNRESOLVED_PATH,
5857 mergemod.MERGE_RECORD_RESOLVED_PATH,
5858 ):
4975 if mark: 5859 if mark:
4976 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH) 5860 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
4977 elif unmark: 5861 elif unmark:
4978 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH) 5862 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
4979 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH: 5863 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
4980 ui.warn(_('%s: path conflict must be resolved manually\n') 5864 ui.warn(
4981 % uipathfn(f)) 5865 _('%s: path conflict must be resolved manually\n')
5866 % uipathfn(f)
5867 )
4982 continue 5868 continue
4983 5869
4984 if mark: 5870 if mark:
4985 if markcheck: 5871 if markcheck:
4986 fdata = repo.wvfs.tryread(f) 5872 fdata = repo.wvfs.tryread(f)
4987 if (filemerge.hasconflictmarkers(fdata) and 5873 if (
4988 ms[f] != mergemod.MERGE_RECORD_RESOLVED): 5874 filemerge.hasconflictmarkers(fdata)
5875 and ms[f] != mergemod.MERGE_RECORD_RESOLVED
5876 ):
4989 hasconflictmarkers.append(f) 5877 hasconflictmarkers.append(f)
4990 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED) 5878 ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
4991 elif unmark: 5879 elif unmark:
4992 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED) 5880 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
4993 else: 5881 else:
5013 5901
5014 # replace filemerge's .orig file with our resolve file, but only 5902 # replace filemerge's .orig file with our resolve file, but only
5015 # for merges that are complete 5903 # for merges that are complete
5016 if complete: 5904 if complete:
5017 try: 5905 try:
5018 util.rename(a + ".resolve", 5906 util.rename(
5019 scmutil.backuppath(ui, repo, f)) 5907 a + ".resolve", scmutil.backuppath(ui, repo, f)
5908 )
5020 except OSError as inst: 5909 except OSError as inst:
5021 if inst.errno != errno.ENOENT: 5910 if inst.errno != errno.ENOENT:
5022 raise 5911 raise
5023 5912
5024 if hasconflictmarkers: 5913 if hasconflictmarkers:
5025 ui.warn(_('warning: the following files still have conflict ' 5914 ui.warn(
5026 'markers:\n') + ''.join(' ' + uipathfn(f) + '\n' 5915 _(
5027 for f in hasconflictmarkers)) 5916 'warning: the following files still have conflict '
5917 'markers:\n'
5918 )
5919 + ''.join(' ' + uipathfn(f) + '\n' for f in hasconflictmarkers)
5920 )
5028 if markcheck == 'abort' and not all and not pats: 5921 if markcheck == 'abort' and not all and not pats:
5029 raise error.Abort(_('conflict markers detected'), 5922 raise error.Abort(
5030 hint=_('use --all to mark anyway')) 5923 _('conflict markers detected'),
5924 hint=_('use --all to mark anyway'),
5925 )
5031 5926
5032 for f in tocomplete: 5927 for f in tocomplete:
5033 try: 5928 try:
5034 # resolve file 5929 # resolve file
5035 overrides = {('ui', 'forcemerge'): opts.get('tool', '')} 5930 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
5057 pats = ['path:%s' % p for p in pats] 5952 pats = ['path:%s' % p for p in pats]
5058 m = scmutil.match(wctx, pats, opts) 5953 m = scmutil.match(wctx, pats, opts)
5059 for f in ms: 5954 for f in ms:
5060 if not m(f): 5955 if not m(f):
5061 continue 5956 continue
5957
5062 def flag(o): 5958 def flag(o):
5063 if o == 're_merge': 5959 if o == 're_merge':
5064 return '--re-merge ' 5960 return '--re-merge '
5065 return '-%s ' % o[0:1] 5961 return '-%s ' % o[0:1]
5962
5066 flags = ''.join([flag(o) for o in flaglist if opts.get(o)]) 5963 flags = ''.join([flag(o) for o in flaglist if opts.get(o)])
5067 hint = _("(try: hg resolve %s%s)\n") % ( 5964 hint = _("(try: hg resolve %s%s)\n") % (
5068 flags, 5965 flags,
5069 ' '.join(pats)) 5966 ' '.join(pats),
5967 )
5070 break 5968 break
5071 ui.warn(_("arguments do not match paths that need resolving\n")) 5969 ui.warn(_("arguments do not match paths that need resolving\n"))
5072 if hint: 5970 if hint:
5073 ui.warn(hint) 5971 ui.warn(hint)
5074 elif ms.mergedriver and ms.mdstate() != 's': 5972 elif ms.mergedriver and ms.mdstate() != 's':
5075 # run conclude step when either a driver-resolved file is requested 5973 # run conclude step when either a driver-resolved file is requested
5076 # or there are no driver-resolved files 5974 # or there are no driver-resolved files
5077 # we can't use 'ret' to determine whether any files are unresolved 5975 # we can't use 'ret' to determine whether any files are unresolved
5078 # because we might not have tried to resolve some 5976 # because we might not have tried to resolve some
5079 if ((runconclude or not list(ms.driverresolved())) 5977 if (runconclude or not list(ms.driverresolved())) and not list(
5080 and not list(ms.unresolved())): 5978 ms.unresolved()
5979 ):
5081 proceed = mergemod.driverconclude(repo, ms, wctx) 5980 proceed = mergemod.driverconclude(repo, ms, wctx)
5082 ms.commit() 5981 ms.commit()
5083 if not proceed: 5982 if not proceed:
5084 return 1 5983 return 1
5085 5984
5088 driverresolvedf = list(ms.driverresolved()) 5987 driverresolvedf = list(ms.driverresolved())
5089 if not unresolvedf and not driverresolvedf: 5988 if not unresolvedf and not driverresolvedf:
5090 ui.status(_('(no more unresolved files)\n')) 5989 ui.status(_('(no more unresolved files)\n'))
5091 cmdutil.checkafterresolved(repo) 5990 cmdutil.checkafterresolved(repo)
5092 elif not unresolvedf: 5991 elif not unresolvedf:
5093 ui.status(_('(no more unresolved files -- ' 5992 ui.status(
5094 'run "hg resolve --all" to conclude)\n')) 5993 _(
5994 '(no more unresolved files -- '
5995 'run "hg resolve --all" to conclude)\n'
5996 )
5997 )
5095 5998
5096 return ret 5999 return ret
5097 6000
5098 @command('revert', 6001
5099 [('a', 'all', None, _('revert all changes when no arguments given')), 6002 @command(
5100 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')), 6003 'revert',
5101 ('r', 'rev', '', _('revert to the specified revision'), _('REV')), 6004 [
5102 ('C', 'no-backup', None, _('do not save backup copies of files')), 6005 ('a', 'all', None, _('revert all changes when no arguments given')),
5103 ('i', 'interactive', None, _('interactively select the changes')), 6006 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5104 ] + walkopts + dryrunopts, 6007 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
6008 ('C', 'no-backup', None, _('do not save backup copies of files')),
6009 ('i', 'interactive', None, _('interactively select the changes')),
6010 ]
6011 + walkopts
6012 + dryrunopts,
5105 _('[OPTION]... [-r REV] [NAME]...'), 6013 _('[OPTION]... [-r REV] [NAME]...'),
5106 helpcategory=command.CATEGORY_WORKING_DIRECTORY) 6014 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6015 )
5107 def revert(ui, repo, *pats, **opts): 6016 def revert(ui, repo, *pats, **opts):
5108 """restore files to their checkout state 6017 """restore files to their checkout state
5109 6018
5110 .. note:: 6019 .. note::
5111 6020
5148 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"]) 6057 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5149 6058
5150 parent, p2 = repo.dirstate.parents() 6059 parent, p2 = repo.dirstate.parents()
5151 if not opts.get('rev') and p2 != nullid: 6060 if not opts.get('rev') and p2 != nullid:
5152 # revert after merge is a trap for new users (issue2915) 6061 # revert after merge is a trap for new users (issue2915)
5153 raise error.Abort(_('uncommitted merge with no revision specified'), 6062 raise error.Abort(
5154 hint=_("use 'hg update' or see 'hg help revert'")) 6063 _('uncommitted merge with no revision specified'),
6064 hint=_("use 'hg update' or see 'hg help revert'"),
6065 )
5155 6066
5156 rev = opts.get('rev') 6067 rev = opts.get('rev')
5157 if rev: 6068 if rev:
5158 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn') 6069 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
5159 ctx = scmutil.revsingle(repo, rev) 6070 ctx = scmutil.revsingle(repo, rev)
5160 6071
5161 if (not (pats or opts.get('include') or opts.get('exclude') or 6072 if not (
5162 opts.get('all') or opts.get('interactive'))): 6073 pats
6074 or opts.get('include')
6075 or opts.get('exclude')
6076 or opts.get('all')
6077 or opts.get('interactive')
6078 ):
5163 msg = _("no files or directories specified") 6079 msg = _("no files or directories specified")
5164 if p2 != nullid: 6080 if p2 != nullid:
5165 hint = _("uncommitted merge, use --all to discard all changes," 6081 hint = _(
5166 " or 'hg update -C .' to abort the merge") 6082 "uncommitted merge, use --all to discard all changes,"
6083 " or 'hg update -C .' to abort the merge"
6084 )
5167 raise error.Abort(msg, hint=hint) 6085 raise error.Abort(msg, hint=hint)
5168 dirty = any(repo.status()) 6086 dirty = any(repo.status())
5169 node = ctx.node() 6087 node = ctx.node()
5170 if node != parent: 6088 if node != parent:
5171 if dirty: 6089 if dirty:
5172 hint = _("uncommitted changes, use --all to discard all" 6090 hint = (
5173 " changes, or 'hg update %d' to update") % ctx.rev() 6091 _(
6092 "uncommitted changes, use --all to discard all"
6093 " changes, or 'hg update %d' to update"
6094 )
6095 % ctx.rev()
6096 )
5174 else: 6097 else:
5175 hint = _("use --all to revert all files," 6098 hint = (
5176 " or 'hg update %d' to update") % ctx.rev() 6099 _(
6100 "use --all to revert all files,"
6101 " or 'hg update %d' to update"
6102 )
6103 % ctx.rev()
6104 )
5177 elif dirty: 6105 elif dirty:
5178 hint = _("uncommitted changes, use --all to discard all changes") 6106 hint = _("uncommitted changes, use --all to discard all changes")
5179 else: 6107 else:
5180 hint = _("use --all to revert all files") 6108 hint = _("use --all to revert all files")
5181 raise error.Abort(msg, hint=hint) 6109 raise error.Abort(msg, hint=hint)
5182 6110
5183 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, 6111 return cmdutil.revert(
5184 **pycompat.strkwargs(opts)) 6112 ui, repo, ctx, (parent, p2), *pats, **pycompat.strkwargs(opts)
6113 )
6114
5185 6115
5186 @command( 6116 @command(
5187 'rollback', 6117 'rollback',
5188 dryrunopts + [('f', 'force', False, _('ignore safety measures'))], 6118 dryrunopts + [('f', 'force', False, _('ignore safety measures'))],
5189 helpcategory=command.CATEGORY_MAINTENANCE) 6119 helpcategory=command.CATEGORY_MAINTENANCE,
6120 )
5190 def rollback(ui, repo, **opts): 6121 def rollback(ui, repo, **opts):
5191 """roll back the last transaction (DANGEROUS) (DEPRECATED) 6122 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5192 6123
5193 Please use :hg:`commit --amend` instead of rollback to correct 6124 Please use :hg:`commit --amend` instead of rollback to correct
5194 mistakes in the last commit. 6125 mistakes in the last commit.
5231 may fail if a rollback is performed. 6162 may fail if a rollback is performed.
5232 6163
5233 Returns 0 on success, 1 if no rollback data is available. 6164 Returns 0 on success, 1 if no rollback data is available.
5234 """ 6165 """
5235 if not ui.configbool('ui', 'rollback'): 6166 if not ui.configbool('ui', 'rollback'):
5236 raise error.Abort(_('rollback is disabled because it is unsafe'), 6167 raise error.Abort(
5237 hint=('see `hg help -v rollback` for information')) 6168 _('rollback is disabled because it is unsafe'),
5238 return repo.rollback(dryrun=opts.get(r'dry_run'), 6169 hint='see `hg help -v rollback` for information',
5239 force=opts.get(r'force')) 6170 )
6171 return repo.rollback(dryrun=opts.get(r'dry_run'), force=opts.get(r'force'))
6172
5240 6173
5241 @command( 6174 @command(
5242 'root', [] + formatteropts, intents={INTENT_READONLY}, 6175 'root',
5243 helpcategory=command.CATEGORY_WORKING_DIRECTORY) 6176 [] + formatteropts,
6177 intents={INTENT_READONLY},
6178 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6179 )
5244 def root(ui, repo, **opts): 6180 def root(ui, repo, **opts):
5245 """print the root (top) of the current working directory 6181 """print the root (top) of the current working directory
5246 6182
5247 Print the root directory of the current repository. 6183 Print the root directory of the current repository.
5248 6184
5262 with ui.formatter('root', opts) as fm: 6198 with ui.formatter('root', opts) as fm:
5263 fm.startitem() 6199 fm.startitem()
5264 fm.write('reporoot', '%s\n', repo.root) 6200 fm.write('reporoot', '%s\n', repo.root)
5265 fm.data(hgpath=repo.path, storepath=repo.spath) 6201 fm.data(hgpath=repo.path, storepath=repo.spath)
5266 6202
5267 @command('serve', 6203
5268 [('A', 'accesslog', '', _('name of access log file to write to'), 6204 @command(
5269 _('FILE')), 6205 'serve',
5270 ('d', 'daemon', None, _('run server in background')), 6206 [
5271 ('', 'daemon-postexec', [], _('used internally by daemon mode')), 6207 (
5272 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')), 6208 'A',
5273 # use string type, then we can check if something was passed 6209 'accesslog',
5274 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')), 6210 '',
5275 ('a', 'address', '', _('address to listen on (default: all interfaces)'), 6211 _('name of access log file to write to'),
5276 _('ADDR')), 6212 _('FILE'),
5277 ('', 'prefix', '', _('prefix path to serve from (default: server root)'), 6213 ),
5278 _('PREFIX')), 6214 ('d', 'daemon', None, _('run server in background')),
5279 ('n', 'name', '', 6215 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
5280 _('name to show in web pages (default: working directory)'), _('NAME')), 6216 (
5281 ('', 'web-conf', '', 6217 'E',
5282 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')), 6218 'errorlog',
5283 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'), 6219 '',
5284 _('FILE')), 6220 _('name of error log file to write to'),
5285 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')), 6221 _('FILE'),
5286 ('', 'stdio', None, _('for remote clients (ADVANCED)')), 6222 ),
5287 ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')), 6223 # use string type, then we can check if something was passed
5288 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')), 6224 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5289 ('', 'style', '', _('template style to use'), _('STYLE')), 6225 (
5290 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')), 6226 'a',
5291 ('', 'certificate', '', _('SSL certificate file'), _('FILE')), 6227 'address',
5292 ('', 'print-url', None, _('start and print only the URL'))] 6228 '',
5293 + subrepoopts, 6229 _('address to listen on (default: all interfaces)'),
6230 _('ADDR'),
6231 ),
6232 (
6233 '',
6234 'prefix',
6235 '',
6236 _('prefix path to serve from (default: server root)'),
6237 _('PREFIX'),
6238 ),
6239 (
6240 'n',
6241 'name',
6242 '',
6243 _('name to show in web pages (default: working directory)'),
6244 _('NAME'),
6245 ),
6246 (
6247 '',
6248 'web-conf',
6249 '',
6250 _("name of the hgweb config file (see 'hg help hgweb')"),
6251 _('FILE'),
6252 ),
6253 (
6254 '',
6255 'webdir-conf',
6256 '',
6257 _('name of the hgweb config file (DEPRECATED)'),
6258 _('FILE'),
6259 ),
6260 (
6261 '',
6262 'pid-file',
6263 '',
6264 _('name of file to write process ID to'),
6265 _('FILE'),
6266 ),
6267 ('', 'stdio', None, _('for remote clients (ADVANCED)')),
6268 ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')),
6269 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
6270 ('', 'style', '', _('template style to use'), _('STYLE')),
6271 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
6272 ('', 'certificate', '', _('SSL certificate file'), _('FILE')),
6273 ('', 'print-url', None, _('start and print only the URL')),
6274 ]
6275 + subrepoopts,
5294 _('[OPTION]...'), 6276 _('[OPTION]...'),
5295 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT, 6277 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5296 helpbasic=True, optionalrepo=True) 6278 helpbasic=True,
6279 optionalrepo=True,
6280 )
5297 def serve(ui, repo, **opts): 6281 def serve(ui, repo, **opts):
5298 """start stand-alone webserver 6282 """start stand-alone webserver
5299 6283
5300 Start a local HTTP repository browser and pull server. You can use 6284 Start a local HTTP repository browser and pull server. You can use
5301 this for ad-hoc sharing and browsing of repositories. It is 6285 this for ad-hoc sharing and browsing of repositories. It is
5325 if opts["print_url"] and ui.verbose: 6309 if opts["print_url"] and ui.verbose:
5326 raise error.Abort(_("cannot use --print-url with --verbose")) 6310 raise error.Abort(_("cannot use --print-url with --verbose"))
5327 6311
5328 if opts["stdio"]: 6312 if opts["stdio"]:
5329 if repo is None: 6313 if repo is None:
5330 raise error.RepoError(_("there is no Mercurial repository here" 6314 raise error.RepoError(
5331 " (.hg not found)")) 6315 _("there is no Mercurial repository here" " (.hg not found)")
6316 )
5332 s = wireprotoserver.sshserver(ui, repo) 6317 s = wireprotoserver.sshserver(ui, repo)
5333 s.serve_forever() 6318 s.serve_forever()
5334 6319
5335 service = server.createservice(ui, repo, opts) 6320 service = server.createservice(ui, repo, opts)
5336 return server.runservice(opts, initfn=service.init, runfn=service.run) 6321 return server.runservice(opts, initfn=service.init, runfn=service.run)
5337 6322
5338 @command('shelve', 6323
5339 [('A', 'addremove', None, 6324 @command(
5340 _('mark new/missing files as added/removed before shelving')), 6325 'shelve',
5341 ('u', 'unknown', None, 6326 [
5342 _('store unknown files in the shelve')), 6327 (
5343 ('', 'cleanup', None, 6328 'A',
5344 _('delete all shelved changes')), 6329 'addremove',
5345 ('', 'date', '', 6330 None,
5346 _('shelve with the specified commit date'), _('DATE')), 6331 _('mark new/missing files as added/removed before shelving'),
5347 ('d', 'delete', None, 6332 ),
5348 _('delete the named shelved change(s)')), 6333 ('u', 'unknown', None, _('store unknown files in the shelve')),
5349 ('e', 'edit', False, 6334 ('', 'cleanup', None, _('delete all shelved changes')),
5350 _('invoke editor on commit messages')), 6335 ('', 'date', '', _('shelve with the specified commit date'), _('DATE')),
5351 ('k', 'keep', False, 6336 ('d', 'delete', None, _('delete the named shelved change(s)')),
5352 _('shelve, but keep changes in the working directory')), 6337 ('e', 'edit', False, _('invoke editor on commit messages')),
5353 ('l', 'list', None, 6338 (
5354 _('list current shelves')), 6339 'k',
5355 ('m', 'message', '', 6340 'keep',
5356 _('use text as shelve message'), _('TEXT')), 6341 False,
5357 ('n', 'name', '', 6342 _('shelve, but keep changes in the working directory'),
5358 _('use the given name for the shelved commit'), _('NAME')), 6343 ),
5359 ('p', 'patch', None, 6344 ('l', 'list', None, _('list current shelves')),
5360 _('output patches for changes (provide the names of the shelved ' 6345 ('m', 'message', '', _('use text as shelve message'), _('TEXT')),
5361 'changes as positional arguments)')), 6346 (
5362 ('i', 'interactive', None, 6347 'n',
5363 _('interactive mode')), 6348 'name',
5364 ('', 'stat', None, 6349 '',
5365 _('output diffstat-style summary of changes (provide the names of ' 6350 _('use the given name for the shelved commit'),
5366 'the shelved changes as positional arguments)') 6351 _('NAME'),
5367 )] + cmdutil.walkopts, 6352 ),
5368 _('hg shelve [OPTION]... [FILE]...'), 6353 (
5369 helpcategory=command.CATEGORY_WORKING_DIRECTORY) 6354 'p',
6355 'patch',
6356 None,
6357 _(
6358 'output patches for changes (provide the names of the shelved '
6359 'changes as positional arguments)'
6360 ),
6361 ),
6362 ('i', 'interactive', None, _('interactive mode')),
6363 (
6364 '',
6365 'stat',
6366 None,
6367 _(
6368 'output diffstat-style summary of changes (provide the names of '
6369 'the shelved changes as positional arguments)'
6370 ),
6371 ),
6372 ]
6373 + cmdutil.walkopts,
6374 _('hg shelve [OPTION]... [FILE]...'),
6375 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6376 )
5370 def shelve(ui, repo, *pats, **opts): 6377 def shelve(ui, repo, *pats, **opts):
5371 '''save and set aside changes from the working directory 6378 '''save and set aside changes from the working directory
5372 6379
5373 Shelving takes files that "hg status" reports as not clean, saves 6380 Shelving takes files that "hg status" reports as not clean, saves
5374 the modifications to a bundle (a shelved change), and reverts the 6381 the modifications to a bundle (a shelved change), and reverts the
5400 To delete specific shelved changes, use ``--delete``. To delete 6407 To delete specific shelved changes, use ``--delete``. To delete
5401 all shelved changes, use ``--cleanup``. 6408 all shelved changes, use ``--cleanup``.
5402 ''' 6409 '''
5403 opts = pycompat.byteskwargs(opts) 6410 opts = pycompat.byteskwargs(opts)
5404 allowables = [ 6411 allowables = [
5405 ('addremove', {'create'}), # 'create' is pseudo action 6412 ('addremove', {'create'}), # 'create' is pseudo action
5406 ('unknown', {'create'}), 6413 ('unknown', {'create'}),
5407 ('cleanup', {'cleanup'}), 6414 ('cleanup', {'cleanup'}),
5408 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests 6415 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
5409 ('delete', {'delete'}), 6416 ('delete', {'delete'}),
5410 ('edit', {'create'}), 6417 ('edit', {'create'}),
5411 ('keep', {'create'}), 6418 ('keep', {'create'}),
5412 ('list', {'list'}), 6419 ('list', {'list'}),
5413 ('message', {'create'}), 6420 ('message', {'create'}),
5414 ('name', {'create'}), 6421 ('name', {'create'}),
5415 ('patch', {'patch', 'list'}), 6422 ('patch', {'patch', 'list'}),
5416 ('stat', {'stat', 'list'}), 6423 ('stat', {'stat', 'list'}),
5417 ] 6424 ]
6425
5418 def checkopt(opt): 6426 def checkopt(opt):
5419 if opts.get(opt): 6427 if opts.get(opt):
5420 for i, allowable in allowables: 6428 for i, allowable in allowables:
5421 if opts[i] and opt not in allowable: 6429 if opts[i] and opt not in allowable:
5422 raise error.Abort(_("options '--%s' and '--%s' may not be " 6430 raise error.Abort(
5423 "used together") % (opt, i)) 6431 _(
6432 "options '--%s' and '--%s' may not be "
6433 "used together"
6434 )
6435 % (opt, i)
6436 )
5424 return True 6437 return True
6438
5425 if checkopt('cleanup'): 6439 if checkopt('cleanup'):
5426 if pats: 6440 if pats:
5427 raise error.Abort(_("cannot specify names when using '--cleanup'")) 6441 raise error.Abort(_("cannot specify names when using '--cleanup'"))
5428 return shelvemod.cleanupcmd(ui, repo) 6442 return shelvemod.cleanupcmd(ui, repo)
5429 elif checkopt('delete'): 6443 elif checkopt('delete'):
5433 elif checkopt('patch') or checkopt('stat'): 6447 elif checkopt('patch') or checkopt('stat'):
5434 return shelvemod.patchcmds(ui, repo, pats, opts) 6448 return shelvemod.patchcmds(ui, repo, pats, opts)
5435 else: 6449 else:
5436 return shelvemod.createcmd(ui, repo, pats, opts) 6450 return shelvemod.createcmd(ui, repo, pats, opts)
5437 6451
6452
5438 _NOTTERSE = 'nothing' 6453 _NOTTERSE = 'nothing'
5439 6454
5440 @command('status|st', 6455
5441 [('A', 'all', None, _('show status of all files')), 6456 @command(
5442 ('m', 'modified', None, _('show only modified files')), 6457 'status|st',
5443 ('a', 'added', None, _('show only added files')), 6458 [
5444 ('r', 'removed', None, _('show only removed files')), 6459 ('A', 'all', None, _('show status of all files')),
5445 ('d', 'deleted', None, _('show only deleted (but tracked) files')), 6460 ('m', 'modified', None, _('show only modified files')),
5446 ('c', 'clean', None, _('show only files without changes')), 6461 ('a', 'added', None, _('show only added files')),
5447 ('u', 'unknown', None, _('show only unknown (not tracked) files')), 6462 ('r', 'removed', None, _('show only removed files')),
5448 ('i', 'ignored', None, _('show only ignored files')), 6463 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5449 ('n', 'no-status', None, _('hide status prefix')), 6464 ('c', 'clean', None, _('show only files without changes')),
5450 ('t', 'terse', _NOTTERSE, _('show the terse output (EXPERIMENTAL)')), 6465 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5451 ('C', 'copies', None, _('show source of copied files')), 6466 ('i', 'ignored', None, _('show only ignored files')),
5452 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')), 6467 ('n', 'no-status', None, _('hide status prefix')),
5453 ('', 'rev', [], _('show difference from revision'), _('REV')), 6468 ('t', 'terse', _NOTTERSE, _('show the terse output (EXPERIMENTAL)')),
5454 ('', 'change', '', _('list the changed files of a revision'), _('REV')), 6469 ('C', 'copies', None, _('show source of copied files')),
5455 ] + walkopts + subrepoopts + formatteropts, 6470 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
6471 ('', 'rev', [], _('show difference from revision'), _('REV')),
6472 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
6473 ]
6474 + walkopts
6475 + subrepoopts
6476 + formatteropts,
5456 _('[OPTION]... [FILE]...'), 6477 _('[OPTION]... [FILE]...'),
5457 helpcategory=command.CATEGORY_WORKING_DIRECTORY, 6478 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5458 helpbasic=True, inferrepo=True, 6479 helpbasic=True,
5459 intents={INTENT_READONLY}) 6480 inferrepo=True,
6481 intents={INTENT_READONLY},
6482 )
5460 def status(ui, repo, *pats, **opts): 6483 def status(ui, repo, *pats, **opts):
5461 """show changed files in the working directory 6484 """show changed files in the working directory
5462 6485
5463 Show status of files in the repository. If names are given, only 6486 Show status of files in the repository. If names are given, only
5464 files that match are shown. Files that are clean or ignored or 6487 files that match are shown. Files that are clean or ignored or
5577 ctx1, ctx2 = scmutil.revpair(repo, revs) 6600 ctx1, ctx2 = scmutil.revpair(repo, revs)
5578 6601
5579 forcerelativevalue = None 6602 forcerelativevalue = None
5580 if ui.hasconfig('commands', 'status.relative'): 6603 if ui.hasconfig('commands', 'status.relative'):
5581 forcerelativevalue = ui.configbool('commands', 'status.relative') 6604 forcerelativevalue = ui.configbool('commands', 'status.relative')
5582 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats), 6605 uipathfn = scmutil.getuipathfn(
5583 forcerelativevalue=forcerelativevalue) 6606 repo,
6607 legacyrelativevalue=bool(pats),
6608 forcerelativevalue=forcerelativevalue,
6609 )
5584 6610
5585 if opts.get('print0'): 6611 if opts.get('print0'):
5586 end = '\0' 6612 end = '\0'
5587 else: 6613 else:
5588 end = '\n' 6614 end = '\n'
5599 show = states[:5] 6625 show = states[:5]
5600 6626
5601 m = scmutil.match(ctx2, pats, opts) 6627 m = scmutil.match(ctx2, pats, opts)
5602 if terse: 6628 if terse:
5603 # we need to compute clean and unknown to terse 6629 # we need to compute clean and unknown to terse
5604 stat = repo.status(ctx1.node(), ctx2.node(), m, 6630 stat = repo.status(
5605 'ignored' in show or 'i' in terse, 6631 ctx1.node(),
5606 clean=True, unknown=True, 6632 ctx2.node(),
5607 listsubrepos=opts.get('subrepos')) 6633 m,
6634 'ignored' in show or 'i' in terse,
6635 clean=True,
6636 unknown=True,
6637 listsubrepos=opts.get('subrepos'),
6638 )
5608 6639
5609 stat = cmdutil.tersedir(stat, terse) 6640 stat = cmdutil.tersedir(stat, terse)
5610 else: 6641 else:
5611 stat = repo.status(ctx1.node(), ctx2.node(), m, 6642 stat = repo.status(
5612 'ignored' in show, 'clean' in show, 6643 ctx1.node(),
5613 'unknown' in show, opts.get('subrepos')) 6644 ctx2.node(),
6645 m,
6646 'ignored' in show,
6647 'clean' in show,
6648 'unknown' in show,
6649 opts.get('subrepos'),
6650 )
5614 6651
5615 changestates = zip(states, pycompat.iterbytestr('MAR!?IC'), stat) 6652 changestates = zip(states, pycompat.iterbytestr('MAR!?IC'), stat)
5616 6653
5617 if (opts.get('all') or opts.get('copies') 6654 if (
5618 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'): 6655 opts.get('all')
6656 or opts.get('copies')
6657 or ui.configbool('ui', 'statuscopies')
6658 ) and not opts.get('no_status'):
5619 copy = copies.pathcopies(ctx1, ctx2, m) 6659 copy = copies.pathcopies(ctx1, ctx2, m)
5620 6660
5621 ui.pager('status') 6661 ui.pager('status')
5622 fm = ui.formatter('status', opts) 6662 fm = ui.formatter('status', opts)
5623 fmt = '%s' + end 6663 fmt = '%s' + end
5632 fm.data(path=f) 6672 fm.data(path=f)
5633 fm.condwrite(showchar, 'status', '%s ', char, label=label) 6673 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5634 fm.plain(fmt % uipathfn(f), label=label) 6674 fm.plain(fmt % uipathfn(f), label=label)
5635 if f in copy: 6675 if f in copy:
5636 fm.data(source=copy[f]) 6676 fm.data(source=copy[f])
5637 fm.plain((' %s' + end) % uipathfn(copy[f]), 6677 fm.plain(
5638 label='status.copied') 6678 (' %s' + end) % uipathfn(copy[f]),
5639 6679 label='status.copied',
5640 if ((ui.verbose or ui.configbool('commands', 'status.verbose')) 6680 )
5641 and not ui.plain()): 6681
6682 if (
6683 ui.verbose or ui.configbool('commands', 'status.verbose')
6684 ) and not ui.plain():
5642 cmdutil.morestatus(repo, fm) 6685 cmdutil.morestatus(repo, fm)
5643 fm.end() 6686 fm.end()
5644 6687
5645 @command('summary|sum', 6688
6689 @command(
6690 'summary|sum',
5646 [('', 'remote', None, _('check for push and pull'))], 6691 [('', 'remote', None, _('check for push and pull'))],
5647 '[--remote]', 6692 '[--remote]',
5648 helpcategory=command.CATEGORY_WORKING_DIRECTORY, 6693 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5649 helpbasic=True, 6694 helpbasic=True,
5650 intents={INTENT_READONLY}) 6695 intents={INTENT_READONLY},
6696 )
5651 def summary(ui, repo, **opts): 6697 def summary(ui, repo, **opts):
5652 """summarize working directory state 6698 """summarize working directory state
5653 6699
5654 This generates a brief summary of the working directory state, 6700 This generates a brief summary of the working directory state,
5655 including parents, branch, commit status, phase and available updates. 6701 including parents, branch, commit status, phase and available updates.
5670 try: 6716 try:
5671 ms = mergemod.mergestate.read(repo) 6717 ms = mergemod.mergestate.read(repo)
5672 except error.UnsupportedMergeRecords as e: 6718 except error.UnsupportedMergeRecords as e:
5673 s = ' '.join(e.recordtypes) 6719 s = ' '.join(e.recordtypes)
5674 ui.warn( 6720 ui.warn(
5675 _('warning: merge state has unsupported record types: %s\n') % s) 6721 _('warning: merge state has unsupported record types: %s\n') % s
6722 )
5676 unresolved = [] 6723 unresolved = []
5677 else: 6724 else:
5678 unresolved = list(ms.unresolved()) 6725 unresolved = list(ms.unresolved())
5679 6726
5680 for p in parents: 6727 for p in parents:
5681 # label with log.changeset (instead of log.parent) since this 6728 # label with log.changeset (instead of log.parent) since this
5682 # shows a working directory parent *changeset*: 6729 # shows a working directory parent *changeset*:
5683 # i18n: column positioning for "hg summary" 6730 # i18n: column positioning for "hg summary"
5684 ui.write(_('parent: %d:%s ') % (p.rev(), p), 6731 ui.write(
5685 label=logcmdutil.changesetlabels(p)) 6732 _('parent: %d:%s ') % (p.rev(), p),
6733 label=logcmdutil.changesetlabels(p),
6734 )
5686 ui.write(' '.join(p.tags()), label='log.tag') 6735 ui.write(' '.join(p.tags()), label='log.tag')
5687 if p.bookmarks(): 6736 if p.bookmarks():
5688 marks.extend(p.bookmarks()) 6737 marks.extend(p.bookmarks())
5689 if p.rev() == -1: 6738 if p.rev() == -1:
5690 if not len(repo): 6739 if not len(repo):
5692 else: 6741 else:
5693 ui.write(_(' (no revision checked out)')) 6742 ui.write(_(' (no revision checked out)'))
5694 if p.obsolete(): 6743 if p.obsolete():
5695 ui.write(_(' (obsolete)')) 6744 ui.write(_(' (obsolete)'))
5696 if p.isunstable(): 6745 if p.isunstable():
5697 instabilities = (ui.label(instability, 'trouble.%s' % instability) 6746 instabilities = (
5698 for instability in p.instabilities()) 6747 ui.label(instability, 'trouble.%s' % instability)
5699 ui.write(' (' 6748 for instability in p.instabilities()
5700 + ', '.join(instabilities) 6749 )
5701 + ')') 6750 ui.write(' (' + ', '.join(instabilities) + ')')
5702 ui.write('\n') 6751 ui.write('\n')
5703 if p.description(): 6752 if p.description():
5704 ui.status(' ' + p.description().splitlines()[0].strip() + '\n', 6753 ui.status(
5705 label='log.summary') 6754 ' ' + p.description().splitlines()[0].strip() + '\n',
6755 label='log.summary',
6756 )
5706 6757
5707 branch = ctx.branch() 6758 branch = ctx.branch()
5708 bheads = repo.branchheads(branch) 6759 bheads = repo.branchheads(branch)
5709 # i18n: column positioning for "hg summary" 6760 # i18n: column positioning for "hg summary"
5710 m = _('branch: %s\n') % branch 6761 m = _('branch: %s\n') % branch
5740 if d in status.added: 6791 if d in status.added:
5741 status.added.remove(d) 6792 status.added.remove(d)
5742 6793
5743 subs = [s for s in ctx.substate if ctx.sub(s).dirty()] 6794 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5744 6795
5745 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified), 6796 labels = [
5746 (ui.label(_('%d added'), 'status.added'), status.added), 6797 (ui.label(_('%d modified'), 'status.modified'), status.modified),
5747 (ui.label(_('%d removed'), 'status.removed'), status.removed), 6798 (ui.label(_('%d added'), 'status.added'), status.added),
5748 (ui.label(_('%d renamed'), 'status.copied'), renamed), 6799 (ui.label(_('%d removed'), 'status.removed'), status.removed),
5749 (ui.label(_('%d copied'), 'status.copied'), copied), 6800 (ui.label(_('%d renamed'), 'status.copied'), renamed),
5750 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted), 6801 (ui.label(_('%d copied'), 'status.copied'), copied),
5751 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown), 6802 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
5752 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved), 6803 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
5753 (ui.label(_('%d subrepos'), 'status.modified'), subs)] 6804 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
6805 (ui.label(_('%d subrepos'), 'status.modified'), subs),
6806 ]
5754 t = [] 6807 t = []
5755 for l, s in labels: 6808 for l, s in labels:
5756 if s: 6809 if s:
5757 t.append(l % len(s)) 6810 t.append(l % len(s))
5758 6811
5765 t += _(' (interrupted update)') 6818 t += _(' (interrupted update)')
5766 elif len(parents) > 1: 6819 elif len(parents) > 1:
5767 t += _(' (merge)') 6820 t += _(' (merge)')
5768 elif branch != parents[0].branch(): 6821 elif branch != parents[0].branch():
5769 t += _(' (new branch)') 6822 t += _(' (new branch)')
5770 elif (parents[0].closesbranch() and 6823 elif parents[0].closesbranch() and pnode in repo.branchheads(
5771 pnode in repo.branchheads(branch, closed=True)): 6824 branch, closed=True
6825 ):
5772 t += _(' (head closed)') 6826 t += _(' (head closed)')
5773 elif not (status.modified or status.added or status.removed or renamed or 6827 elif not (
5774 copied or subs): 6828 status.modified
6829 or status.added
6830 or status.removed
6831 or renamed
6832 or copied
6833 or subs
6834 ):
5775 t += _(' (clean)') 6835 t += _(' (clean)')
5776 cleanworkdir = True 6836 cleanworkdir = True
5777 elif pnode not in bheads: 6837 elif pnode not in bheads:
5778 t += _(' (new branch head)') 6838 t += _(' (new branch head)')
5779 6839
5791 else: 6851 else:
5792 # i18n: column positioning for "hg summary" 6852 # i18n: column positioning for "hg summary"
5793 ui.write(_('commit: %s\n') % t.strip()) 6853 ui.write(_('commit: %s\n') % t.strip())
5794 6854
5795 # all ancestors of branch heads - all ancestors of parent = new csets 6855 # all ancestors of branch heads - all ancestors of parent = new csets
5796 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents], 6856 new = len(
5797 bheads)) 6857 repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
6858 )
5798 6859
5799 if new == 0: 6860 if new == 0:
5800 # i18n: column positioning for "hg summary" 6861 # i18n: column positioning for "hg summary"
5801 ui.status(_('update: (current)\n')) 6862 ui.status(_('update: (current)\n'))
5802 elif pnode not in bheads: 6863 elif pnode not in bheads:
5803 # i18n: column positioning for "hg summary" 6864 # i18n: column positioning for "hg summary"
5804 ui.write(_('update: %d new changesets (update)\n') % new) 6865 ui.write(_('update: %d new changesets (update)\n') % new)
5805 else: 6866 else:
5806 # i18n: column positioning for "hg summary" 6867 # i18n: column positioning for "hg summary"
5807 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') % 6868 ui.write(
5808 (new, len(bheads))) 6869 _('update: %d new changesets, %d branch heads (merge)\n')
6870 % (new, len(bheads))
6871 )
5809 6872
5810 t = [] 6873 t = []
5811 draft = len(repo.revs('draft()')) 6874 draft = len(repo.revs('draft()'))
5812 if draft: 6875 if draft:
5813 t.append(_('%d draft') % draft) 6876 t.append(_('%d draft') % draft)
5821 if obsolete.isenabled(repo, obsolete.createmarkersopt): 6884 if obsolete.isenabled(repo, obsolete.createmarkersopt):
5822 for trouble in ("orphan", "contentdivergent", "phasedivergent"): 6885 for trouble in ("orphan", "contentdivergent", "phasedivergent"):
5823 numtrouble = len(repo.revs(trouble + "()")) 6886 numtrouble = len(repo.revs(trouble + "()"))
5824 # We write all the possibilities to ease translation 6887 # We write all the possibilities to ease translation
5825 troublemsg = { 6888 troublemsg = {
5826 "orphan": _("orphan: %d changesets"), 6889 "orphan": _("orphan: %d changesets"),
5827 "contentdivergent": _("content-divergent: %d changesets"), 6890 "contentdivergent": _("content-divergent: %d changesets"),
5828 "phasedivergent": _("phase-divergent: %d changesets"), 6891 "phasedivergent": _("phase-divergent: %d changesets"),
5829 } 6892 }
5830 if numtrouble > 0: 6893 if numtrouble > 0:
5831 ui.status(troublemsg[trouble] % numtrouble + "\n") 6894 ui.status(troublemsg[trouble] % numtrouble + "\n")
5832 6895
5833 cmdutil.summaryhooks(ui, repo) 6896 cmdutil.summaryhooks(ui, repo)
5882 elif sother is None: 6945 elif sother is None:
5883 # there is no explicit destination peer, but source one is invalid 6946 # there is no explicit destination peer, but source one is invalid
5884 return dest, dbranch, None, None 6947 return dest, dbranch, None, None
5885 else: 6948 else:
5886 dother = sother 6949 dother = sother
5887 if (source != dest or (sbranch is not None and sbranch != dbranch)): 6950 if source != dest or (sbranch is not None and sbranch != dbranch):
5888 common = None 6951 common = None
5889 else: 6952 else:
5890 common = commoninc 6953 common = commoninc
5891 if revs: 6954 if revs:
5892 revs = [repo.lookup(rev) for rev in revs] 6955 revs = [repo.lookup(rev) for rev in revs]
5893 repo.ui.pushbuffer() 6956 repo.ui.pushbuffer()
5894 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs, 6957 outgoing = discovery.findcommonoutgoing(
5895 commoninc=common) 6958 repo, dother, onlyheads=revs, commoninc=common
6959 )
5896 repo.ui.popbuffer() 6960 repo.ui.popbuffer()
5897 return dest, dbranch, dother, outgoing 6961 return dest, dbranch, dother, outgoing
5898 6962
5899 if needsoutgoing: 6963 if needsoutgoing:
5900 dest, dbranch, dother, outgoing = getoutgoing() 6964 dest, dbranch, dother, outgoing = getoutgoing()
5921 ui.write(_('remote: %s\n') % (', '.join(t))) 6985 ui.write(_('remote: %s\n') % (', '.join(t)))
5922 else: 6986 else:
5923 # i18n: column positioning for "hg summary" 6987 # i18n: column positioning for "hg summary"
5924 ui.status(_('remote: (synced)\n')) 6988 ui.status(_('remote: (synced)\n'))
5925 6989
5926 cmdutil.summaryremotehooks(ui, repo, opts, 6990 cmdutil.summaryremotehooks(
5927 ((source, sbranch, sother, commoninc), 6991 ui,
5928 (dest, dbranch, dother, outgoing))) 6992 repo,
5929 6993 opts,
5930 @command('tag', 6994 (
5931 [('f', 'force', None, _('force tag')), 6995 (source, sbranch, sother, commoninc),
5932 ('l', 'local', None, _('make the tag local')), 6996 (dest, dbranch, dother, outgoing),
5933 ('r', 'rev', '', _('revision to tag'), _('REV')), 6997 ),
5934 ('', 'remove', None, _('remove a tag')), 6998 )
5935 # -l/--local is already there, commitopts cannot be used 6999
5936 ('e', 'edit', None, _('invoke editor on commit messages')), 7000
5937 ('m', 'message', '', _('use text as commit message'), _('TEXT')), 7001 @command(
5938 ] + commitopts2, 7002 'tag',
7003 [
7004 ('f', 'force', None, _('force tag')),
7005 ('l', 'local', None, _('make the tag local')),
7006 ('r', 'rev', '', _('revision to tag'), _('REV')),
7007 ('', 'remove', None, _('remove a tag')),
7008 # -l/--local is already there, commitopts cannot be used
7009 ('e', 'edit', None, _('invoke editor on commit messages')),
7010 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
7011 ]
7012 + commitopts2,
5939 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'), 7013 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
5940 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) 7014 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7015 )
5941 def tag(ui, repo, name1, *names, **opts): 7016 def tag(ui, repo, name1, *names, **opts):
5942 """add one or more tags for the current or given revision 7017 """add one or more tags for the current or given revision
5943 7018
5944 Name a particular revision using <name>. 7019 Name a particular revision using <name>.
5945 7020
5977 if len(names) != len(set(names)): 7052 if len(names) != len(set(names)):
5978 raise error.Abort(_('tag names must be unique')) 7053 raise error.Abort(_('tag names must be unique'))
5979 for n in names: 7054 for n in names:
5980 scmutil.checknewlabel(repo, n, 'tag') 7055 scmutil.checknewlabel(repo, n, 'tag')
5981 if not n: 7056 if not n:
5982 raise error.Abort(_('tag names cannot consist entirely of ' 7057 raise error.Abort(
5983 'whitespace')) 7058 _('tag names cannot consist entirely of ' 'whitespace')
7059 )
5984 if opts.get('rev') and opts.get('remove'): 7060 if opts.get('rev') and opts.get('remove'):
5985 raise error.Abort(_("--rev and --remove are incompatible")) 7061 raise error.Abort(_("--rev and --remove are incompatible"))
5986 if opts.get('rev'): 7062 if opts.get('rev'):
5987 rev_ = opts['rev'] 7063 rev_ = opts['rev']
5988 message = opts.get('message') 7064 message = opts.get('message')
6009 # we don't translate commit messages 7085 # we don't translate commit messages
6010 message = 'Removed tag %s' % ', '.join(names) 7086 message = 'Removed tag %s' % ', '.join(names)
6011 elif not opts.get('force'): 7087 elif not opts.get('force'):
6012 for n in names: 7088 for n in names:
6013 if n in repo.tags(): 7089 if n in repo.tags():
6014 raise error.Abort(_("tag '%s' already exists " 7090 raise error.Abort(
6015 "(use -f to force)") % n) 7091 _("tag '%s' already exists " "(use -f to force)") % n
7092 )
6016 if not opts.get('local'): 7093 if not opts.get('local'):
6017 p1, p2 = repo.dirstate.parents() 7094 p1, p2 = repo.dirstate.parents()
6018 if p2 != nullid: 7095 if p2 != nullid:
6019 raise error.Abort(_('uncommitted merge')) 7096 raise error.Abort(_('uncommitted merge'))
6020 bheads = repo.branchheads() 7097 bheads = repo.branchheads()
6021 if not opts.get('force') and bheads and p1 not in bheads: 7098 if not opts.get('force') and bheads and p1 not in bheads:
6022 raise error.Abort(_('working directory is not at a branch head ' 7099 raise error.Abort(
6023 '(use -f to force)')) 7100 _(
7101 'working directory is not at a branch head '
7102 '(use -f to force)'
7103 )
7104 )
6024 node = scmutil.revsingle(repo, rev_).node() 7105 node = scmutil.revsingle(repo, rev_).node()
6025 7106
6026 if not message: 7107 if not message:
6027 # we don't translate commit messages 7108 # we don't translate commit messages
6028 message = ('Added tag %s for changeset %s' % 7109 message = 'Added tag %s for changeset %s' % (
6029 (', '.join(names), short(node))) 7110 ', '.join(names),
7111 short(node),
7112 )
6030 7113
6031 date = opts.get('date') 7114 date = opts.get('date')
6032 if date: 7115 if date:
6033 date = dateutil.parsedate(date) 7116 date = dateutil.parsedate(date)
6034 7117
6035 if opts.get('remove'): 7118 if opts.get('remove'):
6036 editform = 'tag.remove' 7119 editform = 'tag.remove'
6037 else: 7120 else:
6038 editform = 'tag.add' 7121 editform = 'tag.add'
6039 editor = cmdutil.getcommiteditor(editform=editform, 7122 editor = cmdutil.getcommiteditor(
6040 **pycompat.strkwargs(opts)) 7123 editform=editform, **pycompat.strkwargs(opts)
7124 )
6041 7125
6042 # don't allow tagging the null rev 7126 # don't allow tagging the null rev
6043 if (not opts.get('remove') and 7127 if (
6044 scmutil.revsingle(repo, rev_).rev() == nullrev): 7128 not opts.get('remove')
7129 and scmutil.revsingle(repo, rev_).rev() == nullrev
7130 ):
6045 raise error.Abort(_("cannot tag null revision")) 7131 raise error.Abort(_("cannot tag null revision"))
6046 7132
6047 tagsmod.tag(repo, names, node, message, opts.get('local'), 7133 tagsmod.tag(
6048 opts.get('user'), date, editor=editor) 7134 repo,
7135 names,
7136 node,
7137 message,
7138 opts.get('local'),
7139 opts.get('user'),
7140 date,
7141 editor=editor,
7142 )
7143
6049 7144
6050 @command( 7145 @command(
6051 'tags', formatteropts, '', 7146 'tags',
7147 formatteropts,
7148 '',
6052 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, 7149 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
6053 intents={INTENT_READONLY}) 7150 intents={INTENT_READONLY},
7151 )
6054 def tags(ui, repo, **opts): 7152 def tags(ui, repo, **opts):
6055 """list repository tags 7153 """list repository tags
6056 7154
6057 This lists both regular and local tags. When the -v/--verbose 7155 This lists both regular and local tags. When the -v/--verbose
6058 switch is used, a third column "local" is printed for local tags. 7156 switch is used, a third column "local" is printed for local tags.
6086 7184
6087 fm.startitem() 7185 fm.startitem()
6088 fm.context(repo=repo) 7186 fm.context(repo=repo)
6089 fm.write('tag', '%s', t, label=label) 7187 fm.write('tag', '%s', t, label=label)
6090 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s' 7188 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6091 fm.condwrite(not ui.quiet, 'rev node', fmt, 7189 fm.condwrite(
6092 repo.changelog.rev(n), hn, label=label) 7190 not ui.quiet,
6093 fm.condwrite(ui.verbose and tagtype, 'type', ' %s', 7191 'rev node',
6094 tagtype, label=label) 7192 fmt,
7193 repo.changelog.rev(n),
7194 hn,
7195 label=label,
7196 )
7197 fm.condwrite(
7198 ui.verbose and tagtype, 'type', ' %s', tagtype, label=label
7199 )
6095 fm.plain('\n') 7200 fm.plain('\n')
6096 fm.end() 7201 fm.end()
6097 7202
6098 @command('tip', 7203
6099 [('p', 'patch', None, _('show patch')), 7204 @command(
6100 ('g', 'git', None, _('use git extended diff format')), 7205 'tip',
6101 ] + templateopts, 7206 [
7207 ('p', 'patch', None, _('show patch')),
7208 ('g', 'git', None, _('use git extended diff format')),
7209 ]
7210 + templateopts,
6102 _('[-p] [-g]'), 7211 _('[-p] [-g]'),
6103 helpcategory=command.CATEGORY_CHANGE_NAVIGATION) 7212 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
7213 )
6104 def tip(ui, repo, **opts): 7214 def tip(ui, repo, **opts):
6105 """show the tip revision (DEPRECATED) 7215 """show the tip revision (DEPRECATED)
6106 7216
6107 The tip revision (usually just called the tip) is the changeset 7217 The tip revision (usually just called the tip) is the changeset
6108 most recently added to the repository (and therefore the most 7218 most recently added to the repository (and therefore the most
6120 opts = pycompat.byteskwargs(opts) 7230 opts = pycompat.byteskwargs(opts)
6121 displayer = logcmdutil.changesetdisplayer(ui, repo, opts) 7231 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
6122 displayer.show(repo['tip']) 7232 displayer.show(repo['tip'])
6123 displayer.close() 7233 displayer.close()
6124 7234
6125 @command('unbundle', 7235
6126 [('u', 'update', None, 7236 @command(
6127 _('update to new branch head if changesets were unbundled'))], 7237 'unbundle',
7238 [
7239 (
7240 'u',
7241 'update',
7242 None,
7243 _('update to new branch head if changesets were unbundled'),
7244 )
7245 ],
6128 _('[-u] FILE...'), 7246 _('[-u] FILE...'),
6129 helpcategory=command.CATEGORY_IMPORT_EXPORT) 7247 helpcategory=command.CATEGORY_IMPORT_EXPORT,
7248 )
6130 def unbundle(ui, repo, fname1, *fnames, **opts): 7249 def unbundle(ui, repo, fname1, *fnames, **opts):
6131 """apply one or more bundle files 7250 """apply one or more bundle files
6132 7251
6133 Apply one or more bundle files generated by :hg:`bundle`. 7252 Apply one or more bundle files generated by :hg:`bundle`.
6134 7253
6140 for fname in fnames: 7259 for fname in fnames:
6141 f = hg.openpath(ui, fname) 7260 f = hg.openpath(ui, fname)
6142 gen = exchange.readbundle(ui, f, fname) 7261 gen = exchange.readbundle(ui, f, fname)
6143 if isinstance(gen, streamclone.streamcloneapplier): 7262 if isinstance(gen, streamclone.streamcloneapplier):
6144 raise error.Abort( 7263 raise error.Abort(
6145 _('packed bundles cannot be applied with ' 7264 _('packed bundles cannot be applied with ' '"hg unbundle"'),
6146 '"hg unbundle"'), 7265 hint=_('use "hg debugapplystreamclonebundle"'),
6147 hint=_('use "hg debugapplystreamclonebundle"')) 7266 )
6148 url = 'bundle:' + fname 7267 url = 'bundle:' + fname
6149 try: 7268 try:
6150 txnname = 'unbundle' 7269 txnname = 'unbundle'
6151 if not isinstance(gen, bundle2.unbundle20): 7270 if not isinstance(gen, bundle2.unbundle20):
6152 txnname = 'unbundle\n%s' % util.hidepassword(url) 7271 txnname = 'unbundle\n%s' % util.hidepassword(url)
6153 with repo.transaction(txnname) as tr: 7272 with repo.transaction(txnname) as tr:
6154 op = bundle2.applybundle(repo, gen, tr, source='unbundle', 7273 op = bundle2.applybundle(
6155 url=url) 7274 repo, gen, tr, source='unbundle', url=url
7275 )
6156 except error.BundleUnknownFeatureError as exc: 7276 except error.BundleUnknownFeatureError as exc:
6157 raise error.Abort( 7277 raise error.Abort(
6158 _('%s: unknown bundle feature, %s') % (fname, exc), 7278 _('%s: unknown bundle feature, %s') % (fname, exc),
6159 hint=_("see https://mercurial-scm.org/" 7279 hint=_(
6160 "wiki/BundleFeature for more " 7280 "see https://mercurial-scm.org/"
6161 "information")) 7281 "wiki/BundleFeature for more "
7282 "information"
7283 ),
7284 )
6162 modheads = bundle2.combinechangegroupresults(op) 7285 modheads = bundle2.combinechangegroupresults(op)
6163 7286
6164 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None) 7287 return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
6165 7288
6166 @command('unshelve', 7289
6167 [('a', 'abort', None, 7290 @command(
6168 _('abort an incomplete unshelve operation')), 7291 'unshelve',
6169 ('c', 'continue', None, 7292 [
6170 _('continue an incomplete unshelve operation')), 7293 ('a', 'abort', None, _('abort an incomplete unshelve operation')),
6171 ('i', 'interactive', None, 7294 ('c', 'continue', None, _('continue an incomplete unshelve operation')),
6172 _('use interactive mode (EXPERIMENTAL)')), 7295 ('i', 'interactive', None, _('use interactive mode (EXPERIMENTAL)')),
6173 ('k', 'keep', None, 7296 ('k', 'keep', None, _('keep shelve after unshelving')),
6174 _('keep shelve after unshelving')), 7297 (
6175 ('n', 'name', '', 7298 'n',
6176 _('restore shelved change with given name'), _('NAME')), 7299 'name',
6177 ('t', 'tool', '', _('specify merge tool')), 7300 '',
6178 ('', 'date', '', 7301 _('restore shelved change with given name'),
6179 _('set date for temporary commits (DEPRECATED)'), _('DATE'))], 7302 _('NAME'),
6180 _('hg unshelve [OPTION]... [FILE]... [-n SHELVED]'), 7303 ),
6181 helpcategory=command.CATEGORY_WORKING_DIRECTORY) 7304 ('t', 'tool', '', _('specify merge tool')),
7305 (
7306 '',
7307 'date',
7308 '',
7309 _('set date for temporary commits (DEPRECATED)'),
7310 _('DATE'),
7311 ),
7312 ],
7313 _('hg unshelve [OPTION]... [FILE]... [-n SHELVED]'),
7314 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7315 )
6182 def unshelve(ui, repo, *shelved, **opts): 7316 def unshelve(ui, repo, *shelved, **opts):
6183 """restore a shelved change to the working directory 7317 """restore a shelved change to the working directory
6184 7318
6185 This command accepts an optional name of a shelved change to 7319 This command accepts an optional name of a shelved change to
6186 restore. If none is given, the most recent shelved change is used. 7320 restore. If none is given, the most recent shelved change is used.
6224 unshelved. 7358 unshelved.
6225 """ 7359 """
6226 with repo.wlock(): 7360 with repo.wlock():
6227 return shelvemod.dounshelve(ui, repo, *shelved, **opts) 7361 return shelvemod.dounshelve(ui, repo, *shelved, **opts)
6228 7362
7363
6229 statemod.addunfinished( 7364 statemod.addunfinished(
6230 'unshelve', fname='shelvedstate', continueflag=True, 7365 'unshelve',
7366 fname='shelvedstate',
7367 continueflag=True,
6231 abortfunc=shelvemod.hgabortunshelve, 7368 abortfunc=shelvemod.hgabortunshelve,
6232 continuefunc=shelvemod.hgcontinueunshelve, 7369 continuefunc=shelvemod.hgcontinueunshelve,
6233 cmdmsg=_('unshelve already in progress'), 7370 cmdmsg=_('unshelve already in progress'),
6234 ) 7371 )
6235 7372
6236 @command('update|up|checkout|co', 7373
6237 [('C', 'clean', None, _('discard uncommitted changes (no backup)')), 7374 @command(
6238 ('c', 'check', None, _('require clean working directory')), 7375 'update|up|checkout|co',
6239 ('m', 'merge', None, _('merge uncommitted changes')), 7376 [
6240 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')), 7377 ('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6241 ('r', 'rev', '', _('revision'), _('REV')) 7378 ('c', 'check', None, _('require clean working directory')),
6242 ] + mergetoolopts, 7379 ('m', 'merge', None, _('merge uncommitted changes')),
7380 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
7381 ('r', 'rev', '', _('revision'), _('REV')),
7382 ]
7383 + mergetoolopts,
6243 _('[-C|-c|-m] [-d DATE] [[-r] REV]'), 7384 _('[-C|-c|-m] [-d DATE] [[-r] REV]'),
6244 helpcategory=command.CATEGORY_WORKING_DIRECTORY, 7385 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6245 helpbasic=True) 7386 helpbasic=True,
7387 )
6246 def update(ui, repo, node=None, **opts): 7388 def update(ui, repo, node=None, **opts):
6247 """update working directory (or switch revisions) 7389 """update working directory (or switch revisions)
6248 7390
6249 Update the repository's working directory to the specified 7391 Update the repository's working directory to the specified
6250 changeset. If no changeset is specified, update to the tip of the 7392 changeset. If no changeset is specified, update to the tip of the
6306 if rev and node: 7448 if rev and node:
6307 raise error.Abort(_("please specify just one revision")) 7449 raise error.Abort(_("please specify just one revision"))
6308 7450
6309 if ui.configbool('commands', 'update.requiredest'): 7451 if ui.configbool('commands', 'update.requiredest'):
6310 if not node and not rev and not date: 7452 if not node and not rev and not date:
6311 raise error.Abort(_('you must specify a destination'), 7453 raise error.Abort(
6312 hint=_('for example: hg update ".::"')) 7454 _('you must specify a destination'),
7455 hint=_('for example: hg update ".::"'),
7456 )
6313 7457
6314 if rev is None or rev == '': 7458 if rev is None or rev == '':
6315 rev = node 7459 rev = node
6316 7460
6317 if date and rev is not None: 7461 if date and rev is not None:
6318 raise error.Abort(_("you can't specify a revision and a date")) 7462 raise error.Abort(_("you can't specify a revision and a date"))
6319 7463
6320 if len([x for x in (clean, check, merge) if x]) > 1: 7464 if len([x for x in (clean, check, merge) if x]) > 1:
6321 raise error.Abort(_("can only specify one of -C/--clean, -c/--check, " 7465 raise error.Abort(
6322 "or -m/--merge")) 7466 _(
7467 "can only specify one of -C/--clean, -c/--check, "
7468 "or -m/--merge"
7469 )
7470 )
6323 7471
6324 updatecheck = None 7472 updatecheck = None
6325 if check: 7473 if check:
6326 updatecheck = 'abort' 7474 updatecheck = 'abort'
6327 elif merge: 7475 elif merge:
6339 ctx = scmutil.revsingle(repo, rev, default=None) 7487 ctx = scmutil.revsingle(repo, rev, default=None)
6340 rev = ctx.rev() 7488 rev = ctx.rev()
6341 hidden = ctx.hidden() 7489 hidden = ctx.hidden()
6342 overrides = {('ui', 'forcemerge'): opts.get(r'tool', '')} 7490 overrides = {('ui', 'forcemerge'): opts.get(r'tool', '')}
6343 with ui.configoverride(overrides, 'update'): 7491 with ui.configoverride(overrides, 'update'):
6344 ret = hg.updatetotally(ui, repo, rev, brev, clean=clean, 7492 ret = hg.updatetotally(
6345 updatecheck=updatecheck) 7493 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
7494 )
6346 if hidden: 7495 if hidden:
6347 ctxstr = ctx.hex()[:12] 7496 ctxstr = ctx.hex()[:12]
6348 ui.warn(_("updated to hidden changeset %s\n") % ctxstr) 7497 ui.warn(_("updated to hidden changeset %s\n") % ctxstr)
6349 7498
6350 if ctx.obsolete(): 7499 if ctx.obsolete():
6351 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx) 7500 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
6352 ui.warn("(%s)\n" % obsfatemsg) 7501 ui.warn("(%s)\n" % obsfatemsg)
6353 return ret 7502 return ret
6354 7503
6355 @command('verify', 7504
6356 [('', 'full', False, 'perform more checks (EXPERIMENTAL)')], 7505 @command(
6357 helpcategory=command.CATEGORY_MAINTENANCE) 7506 'verify',
7507 [('', 'full', False, 'perform more checks (EXPERIMENTAL)')],
7508 helpcategory=command.CATEGORY_MAINTENANCE,
7509 )
6358 def verify(ui, repo, **opts): 7510 def verify(ui, repo, **opts):
6359 """verify the integrity of the repository 7511 """verify the integrity of the repository
6360 7512
6361 Verify the integrity of the current repository. 7513 Verify the integrity of the current repository.
6362 7514
6376 level = None 7528 level = None
6377 if opts['full']: 7529 if opts['full']:
6378 level = verifymod.VERIFY_FULL 7530 level = verifymod.VERIFY_FULL
6379 return hg.verify(repo, level) 7531 return hg.verify(repo, level)
6380 7532
7533
6381 @command( 7534 @command(
6382 'version', [] + formatteropts, helpcategory=command.CATEGORY_HELP, 7535 'version',
6383 norepo=True, intents={INTENT_READONLY}) 7536 [] + formatteropts,
7537 helpcategory=command.CATEGORY_HELP,
7538 norepo=True,
7539 intents={INTENT_READONLY},
7540 )
6384 def version_(ui, **opts): 7541 def version_(ui, **opts):
6385 """output version and copyright information 7542 """output version and copyright information
6386 7543
6387 .. container:: verbose 7544 .. container:: verbose
6388 7545
6402 opts = pycompat.byteskwargs(opts) 7559 opts = pycompat.byteskwargs(opts)
6403 if ui.verbose: 7560 if ui.verbose:
6404 ui.pager('version') 7561 ui.pager('version')
6405 fm = ui.formatter("version", opts) 7562 fm = ui.formatter("version", opts)
6406 fm.startitem() 7563 fm.startitem()
6407 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"), 7564 fm.write(
6408 util.version()) 7565 "ver", _("Mercurial Distributed SCM (version %s)\n"), util.version()
7566 )
6409 license = _( 7567 license = _(
6410 "(see https://mercurial-scm.org for more information)\n" 7568 "(see https://mercurial-scm.org for more information)\n"
6411 "\nCopyright (C) 2005-2019 Matt Mackall and others\n" 7569 "\nCopyright (C) 2005-2019 Matt Mackall and others\n"
6412 "This is free software; see the source for copying conditions. " 7570 "This is free software; see the source for copying conditions. "
6413 "There is NO\nwarranty; " 7571 "There is NO\nwarranty; "
6440 if ui.verbose: 7598 if ui.verbose:
6441 fn.plain("\n") 7599 fn.plain("\n")
6442 fn.end() 7600 fn.end()
6443 fm.end() 7601 fm.end()
6444 7602
7603
6445 def loadcmdtable(ui, name, cmdtable): 7604 def loadcmdtable(ui, name, cmdtable):
6446 """Load command functions from specified cmdtable 7605 """Load command functions from specified cmdtable
6447 """ 7606 """
6448 overrides = [cmd for cmd in cmdtable if cmd in table] 7607 overrides = [cmd for cmd in cmdtable if cmd in table]
6449 if overrides: 7608 if overrides:
6450 ui.warn(_("extension '%s' overrides commands: %s\n") 7609 ui.warn(
6451 % (name, " ".join(overrides))) 7610 _("extension '%s' overrides commands: %s\n")
7611 % (name, " ".join(overrides))
7612 )
6452 table.update(cmdtable) 7613 table.update(cmdtable)