comparison mercurial/commands.py @ 45827:8d72e29ad1e0

errors: introduce InputError and use it from commands and cmdutil This patch introduces a `InputError` class and replaces many uses of `error.Abort` by it in `commands` and `cmdutil`. This is a part of https://www.mercurial-scm.org/wiki/ErrorCategoriesPlan. There will later be a different class for state errors (to raise e.g. when there's an unfinished operation). It's not always clear when one should report an input error and when it should be a state error. We can always adjust later if I got something wrong in this patch (but feel free to point out any you notice now). Differential Revision: https://phab.mercurial-scm.org/D9167
author Martin von Zweigbergk <martinvonz@google.com>
date Tue, 06 Oct 2020 22:36:15 -0700
parents d6279c43fc60
children 527ce85c2e60
comparison
equal deleted inserted replaced
45826:21733e8c924f 45827:8d72e29ad1e0
187 dryrun = opts.get('dry_run') 187 dryrun = opts.get('dry_run')
188 abortstate = cmdutil.getunfinishedstate(repo) 188 abortstate = cmdutil.getunfinishedstate(repo)
189 if not abortstate: 189 if not abortstate:
190 raise error.Abort(_(b'no operation in progress')) 190 raise error.Abort(_(b'no operation in progress'))
191 if not abortstate.abortfunc: 191 if not abortstate.abortfunc:
192 raise error.Abort( 192 raise error.InputError(
193 ( 193 (
194 _(b"%s in progress but does not support 'hg abort'") 194 _(b"%s in progress but does not support 'hg abort'")
195 % (abortstate._opname) 195 % (abortstate._opname)
196 ), 196 ),
197 hint=abortstate.hint(), 197 hint=abortstate.hint(),
416 416
417 Returns 0 on success. 417 Returns 0 on success.
418 """ 418 """
419 opts = pycompat.byteskwargs(opts) 419 opts = pycompat.byteskwargs(opts)
420 if not pats: 420 if not pats:
421 raise error.Abort(_(b'at least one filename or pattern is required')) 421 raise error.InputError(
422 _(b'at least one filename or pattern is required')
423 )
422 424
423 if opts.get(b'follow'): 425 if opts.get(b'follow'):
424 # --follow is deprecated and now just an alias for -f/--file 426 # --follow is deprecated and now just an alias for -f/--file
425 # to mimic the behavior of Mercurial before version 1.5 427 # to mimic the behavior of Mercurial before version 1.5
426 opts[b'file'] = True 428 opts[b'file'] = True
437 if ( 439 if (
438 linenumber 440 linenumber
439 and (not opts.get(b'changeset')) 441 and (not opts.get(b'changeset'))
440 and (not opts.get(b'number')) 442 and (not opts.get(b'number'))
441 ): 443 ):
442 raise error.Abort(_(b'at least one of -n/-c is required for -l')) 444 raise error.InputError(_(b'at least one of -n/-c is required for -l'))
443 445
444 rev = opts.get(b'rev') 446 rev = opts.get(b'rev')
445 if rev: 447 if rev:
446 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn') 448 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
447 ctx = scmutil.revsingle(repo, rev) 449 ctx = scmutil.revsingle(repo, rev)
648 rev = opts.get(b'rev') 650 rev = opts.get(b'rev')
649 if rev: 651 if rev:
650 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn') 652 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
651 ctx = scmutil.revsingle(repo, rev) 653 ctx = scmutil.revsingle(repo, rev)
652 if not ctx: 654 if not ctx:
653 raise error.Abort(_(b'no working directory: please specify a revision')) 655 raise error.InputError(
656 _(b'no working directory: please specify a revision')
657 )
654 node = ctx.node() 658 node = ctx.node()
655 dest = cmdutil.makefilename(ctx, dest) 659 dest = cmdutil.makefilename(ctx, dest)
656 if os.path.realpath(dest) == repo.root: 660 if os.path.realpath(dest) == repo.root:
657 raise error.Abort(_(b'repository root cannot be destination')) 661 raise error.InputError(_(b'repository root cannot be destination'))
658 662
659 kind = opts.get(b'type') or archival.guesskind(dest) or b'files' 663 kind = opts.get(b'type') or archival.guesskind(dest) or b'files'
660 prefix = opts.get(b'prefix') 664 prefix = opts.get(b'prefix')
661 665
662 if dest == b'-': 666 if dest == b'-':
663 if kind == b'files': 667 if kind == b'files':
664 raise error.Abort(_(b'cannot archive plain files to stdout')) 668 raise error.InputError(_(b'cannot archive plain files to stdout'))
665 dest = cmdutil.makefileobj(ctx, dest) 669 dest = cmdutil.makefileobj(ctx, dest)
666 if not prefix: 670 if not prefix:
667 prefix = os.path.basename(repo.root) + b'-%h' 671 prefix = os.path.basename(repo.root) + b'-%h'
668 672
669 prefix = cmdutil.makefilename(ctx, prefix) 673 prefix = cmdutil.makefilename(ctx, prefix)
772 def _dobackout(ui, repo, node=None, rev=None, **opts): 776 def _dobackout(ui, repo, node=None, rev=None, **opts):
773 cmdutil.check_incompatible_arguments(opts, 'no_commit', ['commit', 'merge']) 777 cmdutil.check_incompatible_arguments(opts, 'no_commit', ['commit', 'merge'])
774 opts = pycompat.byteskwargs(opts) 778 opts = pycompat.byteskwargs(opts)
775 779
776 if rev and node: 780 if rev and node:
777 raise error.Abort(_(b"please specify just one revision")) 781 raise error.InputError(_(b"please specify just one revision"))
778 782
779 if not rev: 783 if not rev:
780 rev = node 784 rev = node
781 785
782 if not rev: 786 if not rev:
783 raise error.Abort(_(b"please specify a revision to backout")) 787 raise error.InputError(_(b"please specify a revision to backout"))
784 788
785 date = opts.get(b'date') 789 date = opts.get(b'date')
786 if date: 790 if date:
787 opts[b'date'] = dateutil.parsedate(date) 791 opts[b'date'] = dateutil.parsedate(date)
788 792
791 ctx = scmutil.revsingle(repo, rev) 795 ctx = scmutil.revsingle(repo, rev)
792 node = ctx.node() 796 node = ctx.node()
793 797
794 op1, op2 = repo.dirstate.parents() 798 op1, op2 = repo.dirstate.parents()
795 if not repo.changelog.isancestor(node, op1): 799 if not repo.changelog.isancestor(node, op1):
796 raise error.Abort(_(b'cannot backout change that is not an ancestor')) 800 raise error.InputError(
801 _(b'cannot backout change that is not an ancestor')
802 )
797 803
798 p1, p2 = repo.changelog.parents(node) 804 p1, p2 = repo.changelog.parents(node)
799 if p1 == nullid: 805 if p1 == nullid:
800 raise error.Abort(_(b'cannot backout a change with no parents')) 806 raise error.InputError(_(b'cannot backout a change with no parents'))
801 if p2 != nullid: 807 if p2 != nullid:
802 if not opts.get(b'parent'): 808 if not opts.get(b'parent'):
803 raise error.Abort(_(b'cannot backout a merge changeset')) 809 raise error.InputError(_(b'cannot backout a merge changeset'))
804 p = repo.lookup(opts[b'parent']) 810 p = repo.lookup(opts[b'parent'])
805 if p not in (p1, p2): 811 if p not in (p1, p2):
806 raise error.Abort( 812 raise error.InputError(
807 _(b'%s is not a parent of %s') % (short(p), short(node)) 813 _(b'%s is not a parent of %s') % (short(p), short(node))
808 ) 814 )
809 parent = p 815 parent = p
810 else: 816 else:
811 if opts.get(b'parent'): 817 if opts.get(b'parent'):
812 raise error.Abort(_(b'cannot use --parent on non-merge changeset')) 818 raise error.InputError(
819 _(b'cannot use --parent on non-merge changeset')
820 )
813 parent = p1 821 parent = p1
814 822
815 # the backout should appear on the same branch 823 # the backout should appear on the same branch
816 branch = repo.dirstate.branch() 824 branch = repo.dirstate.branch()
817 bheads = repo.branchheads(branch) 825 bheads = repo.branchheads(branch)
999 elif cmd == b"bad": 1007 elif cmd == b"bad":
1000 bad = True 1008 bad = True
1001 else: 1009 else:
1002 reset = True 1010 reset = True
1003 elif extra: 1011 elif extra:
1004 raise error.Abort(_(b'incompatible arguments')) 1012 raise error.InputError(_(b'incompatible arguments'))
1005 1013
1006 incompatibles = { 1014 incompatibles = {
1007 b'--bad': bad, 1015 b'--bad': bad,
1008 b'--command': bool(command), 1016 b'--command': bool(command),
1009 b'--extend': extend, 1017 b'--extend': extend,
1013 } 1021 }
1014 1022
1015 enabled = [x for x in incompatibles if incompatibles[x]] 1023 enabled = [x for x in incompatibles if incompatibles[x]]
1016 1024
1017 if len(enabled) > 1: 1025 if len(enabled) > 1:
1018 raise error.Abort( 1026 raise error.InputError(
1019 _(b'%s and %s are incompatible') % tuple(sorted(enabled)[0:2]) 1027 _(b'%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
1020 ) 1028 )
1021 1029
1022 if reset: 1030 if reset:
1023 hbisect.resetstate(repo) 1031 hbisect.resetstate(repo)
1234 1242
1235 cmdutil.check_incompatible_arguments( 1243 cmdutil.check_incompatible_arguments(
1236 opts, b'inactive', [b'delete', b'list'] 1244 opts, b'inactive', [b'delete', b'list']
1237 ) 1245 )
1238 if not names and action in {b'add', b'delete'}: 1246 if not names and action in {b'add', b'delete'}:
1239 raise error.Abort(_(b"bookmark name required")) 1247 raise error.InputError(_(b"bookmark name required"))
1240 1248
1241 if action in {b'add', b'delete', b'rename', b'inactive'}: 1249 if action in {b'add', b'delete', b'rename', b'inactive'}:
1242 with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr: 1250 with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
1243 if action == b'delete': 1251 if action == b'delete':
1244 names = pycompat.maplist(repo._bookmarks.expandname, names) 1252 names = pycompat.maplist(repo._bookmarks.expandname, names)
1245 bookmarks.delete(repo, tr, names) 1253 bookmarks.delete(repo, tr, names)
1246 elif action == b'rename': 1254 elif action == b'rename':
1247 if not names: 1255 if not names:
1248 raise error.Abort(_(b"new bookmark name required")) 1256 raise error.InputError(_(b"new bookmark name required"))
1249 elif len(names) > 1: 1257 elif len(names) > 1:
1250 raise error.Abort(_(b"only one new bookmark name allowed")) 1258 raise error.InputError(
1259 _(b"only one new bookmark name allowed")
1260 )
1251 oldname = repo._bookmarks.expandname(opts[b'rename']) 1261 oldname = repo._bookmarks.expandname(opts[b'rename'])
1252 bookmarks.rename(repo, tr, oldname, names[0], force, inactive) 1262 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1253 elif action == b'add': 1263 elif action == b'add':
1254 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive) 1264 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1255 elif action == b'inactive': 1265 elif action == b'inactive':
1321 if label: 1331 if label:
1322 label = label.strip() 1332 label = label.strip()
1323 1333
1324 if not opts.get(b'clean') and not label: 1334 if not opts.get(b'clean') and not label:
1325 if revs: 1335 if revs:
1326 raise error.Abort(_(b"no branch name specified for the revisions")) 1336 raise error.InputError(
1337 _(b"no branch name specified for the revisions")
1338 )
1327 ui.write(b"%s\n" % repo.dirstate.branch()) 1339 ui.write(b"%s\n" % repo.dirstate.branch())
1328 return 1340 return
1329 1341
1330 with repo.wlock(): 1342 with repo.wlock():
1331 if opts.get(b'clean'): 1343 if opts.get(b'clean'):
1338 if revs: 1350 if revs:
1339 return cmdutil.changebranch(ui, repo, revs, label, opts) 1351 return cmdutil.changebranch(ui, repo, revs, label, opts)
1340 1352
1341 if not opts.get(b'force') and label in repo.branchmap(): 1353 if not opts.get(b'force') and label in repo.branchmap():
1342 if label not in [p.branch() for p in repo[None].parents()]: 1354 if label not in [p.branch() for p in repo[None].parents()]:
1343 raise error.Abort( 1355 raise error.InputError(
1344 _(b'a branch of the same name already exists'), 1356 _(b'a branch of the same name already exists'),
1345 # i18n: "it" refers to an existing branch 1357 # i18n: "it" refers to an existing branch
1346 hint=_(b"use 'hg update' to switch to it"), 1358 hint=_(b"use 'hg update' to switch to it"),
1347 ) 1359 )
1348 1360
1540 revs = None 1552 revs = None
1541 if b'rev' in opts: 1553 if b'rev' in opts:
1542 revstrings = opts[b'rev'] 1554 revstrings = opts[b'rev']
1543 revs = scmutil.revrange(repo, revstrings) 1555 revs = scmutil.revrange(repo, revstrings)
1544 if revstrings and not revs: 1556 if revstrings and not revs:
1545 raise error.Abort(_(b'no commits to bundle')) 1557 raise error.InputError(_(b'no commits to bundle'))
1546 1558
1547 bundletype = opts.get(b'type', b'bzip2').lower() 1559 bundletype = opts.get(b'type', b'bzip2').lower()
1548 try: 1560 try:
1549 bundlespec = bundlecaches.parsebundlespec( 1561 bundlespec = bundlecaches.parsebundlespec(
1550 repo, bundletype, strict=False 1562 repo, bundletype, strict=False
1551 ) 1563 )
1552 except error.UnsupportedBundleSpecification as e: 1564 except error.UnsupportedBundleSpecification as e:
1553 raise error.Abort( 1565 raise error.InputError(
1554 pycompat.bytestr(e), 1566 pycompat.bytestr(e),
1555 hint=_(b"see 'hg help bundlespec' for supported values for --type"), 1567 hint=_(b"see 'hg help bundlespec' for supported values for --type"),
1556 ) 1568 )
1557 cgversion = bundlespec.contentopts[b"cg.version"] 1569 cgversion = bundlespec.contentopts[b"cg.version"]
1558 1570
1559 # Packed bundles are a pseudo bundle format for now. 1571 # Packed bundles are a pseudo bundle format for now.
1560 if cgversion == b's1': 1572 if cgversion == b's1':
1561 raise error.Abort( 1573 raise error.InputError(
1562 _(b'packed bundles cannot be produced by "hg bundle"'), 1574 _(b'packed bundles cannot be produced by "hg bundle"'),
1563 hint=_(b"use 'hg debugcreatestreamclonebundle'"), 1575 hint=_(b"use 'hg debugcreatestreamclonebundle'"),
1564 ) 1576 )
1565 1577
1566 if opts.get(b'all'): 1578 if opts.get(b'all'):
1567 if dest: 1579 if dest:
1568 raise error.Abort( 1580 raise error.InputError(
1569 _(b"--all is incompatible with specifying a destination") 1581 _(b"--all is incompatible with specifying a destination")
1570 ) 1582 )
1571 if opts.get(b'base'): 1583 if opts.get(b'base'):
1572 ui.warn(_(b"ignoring --base because --all was specified\n")) 1584 ui.warn(_(b"ignoring --base because --all was specified\n"))
1573 base = [nullrev] 1585 base = [nullrev]
1578 _(b"repository does not support bundle version %s") % cgversion 1590 _(b"repository does not support bundle version %s") % cgversion
1579 ) 1591 )
1580 1592
1581 if base: 1593 if base:
1582 if dest: 1594 if dest:
1583 raise error.Abort( 1595 raise error.InputError(
1584 _(b"--base is incompatible with specifying a destination") 1596 _(b"--base is incompatible with specifying a destination")
1585 ) 1597 )
1586 common = [repo[rev].node() for rev in base] 1598 common = [repo[rev].node() for rev in base]
1587 heads = [repo[r].node() for r in revs] if revs else None 1599 heads = [repo[r].node() for r in revs] if revs else None
1588 outgoing = discovery.outgoing(repo, common, heads) 1600 outgoing = discovery.outgoing(repo, common, heads)
2032 extra = {} 2044 extra = {}
2033 if opts.get(b'close_branch') or opts.get(b'force_close_branch'): 2045 if opts.get(b'close_branch') or opts.get(b'force_close_branch'):
2034 extra[b'close'] = b'1' 2046 extra[b'close'] = b'1'
2035 2047
2036 if repo[b'.'].closesbranch(): 2048 if repo[b'.'].closesbranch():
2037 raise error.Abort( 2049 raise error.InputError(
2038 _(b'current revision is already a branch closing head') 2050 _(b'current revision is already a branch closing head')
2039 ) 2051 )
2040 elif not bheads: 2052 elif not bheads:
2041 raise error.Abort(_(b'branch "%s" has no heads to close') % branch) 2053 raise error.InputError(
2054 _(b'branch "%s" has no heads to close') % branch
2055 )
2042 elif ( 2056 elif (
2043 branch == repo[b'.'].branch() 2057 branch == repo[b'.'].branch()
2044 and repo[b'.'].node() not in bheads 2058 and repo[b'.'].node() not in bheads
2045 and not opts.get(b'force_close_branch') 2059 and not opts.get(b'force_close_branch')
2046 ): 2060 ):
2047 hint = _( 2061 hint = _(
2048 b'use --force-close-branch to close branch from a non-head' 2062 b'use --force-close-branch to close branch from a non-head'
2049 b' changeset' 2063 b' changeset'
2050 ) 2064 )
2051 raise error.Abort(_(b'can only close branch heads'), hint=hint) 2065 raise error.InputError(_(b'can only close branch heads'), hint=hint)
2052 elif opts.get(b'amend'): 2066 elif opts.get(b'amend'):
2053 if ( 2067 if (
2054 repo[b'.'].p1().branch() != branch 2068 repo[b'.'].p1().branch() != branch
2055 and repo[b'.'].p2().branch() != branch 2069 and repo[b'.'].p2().branch() != branch
2056 ): 2070 ):
2057 raise error.Abort(_(b'can only close branch heads')) 2071 raise error.InputError(_(b'can only close branch heads'))
2058 2072
2059 if opts.get(b'amend'): 2073 if opts.get(b'amend'):
2060 if ui.configbool(b'ui', b'commitsubrepos'): 2074 if ui.configbool(b'ui', b'commitsubrepos'):
2061 raise error.Abort(_(b'cannot amend with ui.commitsubrepos enabled')) 2075 raise error.InputError(
2076 _(b'cannot amend with ui.commitsubrepos enabled')
2077 )
2062 2078
2063 old = repo[b'.'] 2079 old = repo[b'.']
2064 rewriteutil.precheck(repo, [old.rev()], b'amend') 2080 rewriteutil.precheck(repo, [old.rev()], b'amend')
2065 2081
2066 # Currently histedit gets confused if an amend happens while histedit 2082 # Currently histedit gets confused if an amend happens while histedit
2198 editopts = (b'edit', b'local', b'global', b'shared', b'non_shared') 2214 editopts = (b'edit', b'local', b'global', b'shared', b'non_shared')
2199 if any(opts.get(o) for o in editopts): 2215 if any(opts.get(o) for o in editopts):
2200 cmdutil.check_at_most_one_arg(opts, *editopts[1:]) 2216 cmdutil.check_at_most_one_arg(opts, *editopts[1:])
2201 if opts.get(b'local'): 2217 if opts.get(b'local'):
2202 if not repo: 2218 if not repo:
2203 raise error.Abort(_(b"can't use --local outside a repository")) 2219 raise error.InputError(
2220 _(b"can't use --local outside a repository")
2221 )
2204 paths = [repo.vfs.join(b'hgrc')] 2222 paths = [repo.vfs.join(b'hgrc')]
2205 elif opts.get(b'global'): 2223 elif opts.get(b'global'):
2206 paths = rcutil.systemrcpath() 2224 paths = rcutil.systemrcpath()
2207 elif opts.get(b'shared'): 2225 elif opts.get(b'shared'):
2208 if not repo.shared(): 2226 if not repo.shared():
2209 raise error.Abort( 2227 raise error.InputError(
2210 _(b"repository is not shared; can't use --shared") 2228 _(b"repository is not shared; can't use --shared")
2211 ) 2229 )
2212 if requirements.SHARESAFE_REQUIREMENT not in repo.requirements: 2230 if requirements.SHARESAFE_REQUIREMENT not in repo.requirements:
2213 raise error.Abort( 2231 raise error.InputError(
2214 _( 2232 _(
2215 b"share safe feature not unabled; " 2233 b"share safe feature not unabled; "
2216 b"unable to edit shared source repository config" 2234 b"unable to edit shared source repository config"
2217 ) 2235 )
2218 ) 2236 )
2239 fp.close() 2257 fp.close()
2240 2258
2241 editor = ui.geteditor() 2259 editor = ui.geteditor()
2242 ui.system( 2260 ui.system(
2243 b"%s \"%s\"" % (editor, f), 2261 b"%s \"%s\"" % (editor, f),
2244 onerr=error.Abort, 2262 onerr=error.InputError,
2245 errprefix=_(b"edit failed"), 2263 errprefix=_(b"edit failed"),
2246 blockedtag=b'config_edit', 2264 blockedtag=b'config_edit',
2247 ) 2265 )
2248 return 2266 return
2249 ui.pager(b'config') 2267 ui.pager(b'config')
2647 2665
2648 cmdutil.check_at_most_one_arg(opts, b'rev', b'bookmark') 2666 cmdutil.check_at_most_one_arg(opts, b'rev', b'bookmark')
2649 2667
2650 if bookmark: 2668 if bookmark:
2651 if bookmark not in repo._bookmarks: 2669 if bookmark not in repo._bookmarks:
2652 raise error.Abort(_(b"bookmark '%s' not found") % bookmark) 2670 raise error.InputError(_(b"bookmark '%s' not found") % bookmark)
2653 2671
2654 revs = scmutil.bookmarkrevs(repo, bookmark) 2672 revs = scmutil.bookmarkrevs(repo, bookmark)
2655 else: 2673 else:
2656 if not changesets: 2674 if not changesets:
2657 changesets = [b'.'] 2675 changesets = [b'.']
2658 2676
2659 repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn') 2677 repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
2660 revs = scmutil.revrange(repo, changesets) 2678 revs = scmutil.revrange(repo, changesets)
2661 2679
2662 if not revs: 2680 if not revs:
2663 raise error.Abort(_(b"export requires at least one changeset")) 2681 raise error.InputError(_(b"export requires at least one changeset"))
2664 if len(revs) > 1: 2682 if len(revs) > 1:
2665 ui.note(_(b'exporting patches:\n')) 2683 ui.note(_(b'exporting patches:\n'))
2666 else: 2684 else:
2667 ui.note(_(b'exporting patch:\n')) 2685 ui.note(_(b'exporting patch:\n'))
2668 2686
2823 Returns 0 on success. 2841 Returns 0 on success.
2824 """ 2842 """
2825 2843
2826 opts = pycompat.byteskwargs(opts) 2844 opts = pycompat.byteskwargs(opts)
2827 if not pats: 2845 if not pats:
2828 raise error.Abort(_(b'no files specified')) 2846 raise error.InputError(_(b'no files specified'))
2829 2847
2830 m = scmutil.match(repo[None], pats, opts) 2848 m = scmutil.match(repo[None], pats, opts)
2831 dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive') 2849 dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive')
2832 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) 2850 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2833 rejected = cmdutil.forget( 2851 rejected = cmdutil.forget(
3050 ) 3068 )
3051 return cmdutil.abortgraft(ui, repo, graftstate) 3069 return cmdutil.abortgraft(ui, repo, graftstate)
3052 elif opts.get(b'continue'): 3070 elif opts.get(b'continue'):
3053 cont = True 3071 cont = True
3054 if revs: 3072 if revs:
3055 raise error.Abort(_(b"can't specify --continue and revisions")) 3073 raise error.InputError(_(b"can't specify --continue and revisions"))
3056 # read in unfinished revisions 3074 # read in unfinished revisions
3057 if graftstate.exists(): 3075 if graftstate.exists():
3058 statedata = cmdutil.readgraftstate(repo, graftstate) 3076 statedata = cmdutil.readgraftstate(repo, graftstate)
3059 if statedata.get(b'date'): 3077 if statedata.get(b'date'):
3060 opts[b'date'] = statedata[b'date'] 3078 opts[b'date'] = statedata[b'date']
3070 revs = [repo[node].rev() for node in nodes] 3088 revs = [repo[node].rev() for node in nodes]
3071 else: 3089 else:
3072 cmdutil.wrongtooltocontinue(repo, _(b'graft')) 3090 cmdutil.wrongtooltocontinue(repo, _(b'graft'))
3073 else: 3091 else:
3074 if not revs: 3092 if not revs:
3075 raise error.Abort(_(b'no revisions specified')) 3093 raise error.InputError(_(b'no revisions specified'))
3076 cmdutil.checkunfinished(repo) 3094 cmdutil.checkunfinished(repo)
3077 cmdutil.bailifchanged(repo) 3095 cmdutil.bailifchanged(repo)
3078 revs = scmutil.revrange(repo, revs) 3096 revs = scmutil.revrange(repo, revs)
3079 3097
3080 skipped = set() 3098 skipped = set()
3088 skipped.add(rev) 3106 skipped.add(rev)
3089 revs = [r for r in revs if r not in skipped] 3107 revs = [r for r in revs if r not in skipped]
3090 if not revs: 3108 if not revs:
3091 return -1 3109 return -1
3092 if basectx is not None and len(revs) != 1: 3110 if basectx is not None and len(revs) != 1:
3093 raise error.Abort(_(b'only one revision allowed with --base ')) 3111 raise error.InputError(_(b'only one revision allowed with --base '))
3094 3112
3095 # Don't check in the --continue case, in effect retaining --force across 3113 # Don't check in the --continue case, in effect retaining --force across
3096 # --continues. That's because without --force, any revisions we decided to 3114 # --continues. That's because without --force, any revisions we decided to
3097 # skip would have been filtered out here, so they wouldn't have made their 3115 # skip would have been filtered out here, so they wouldn't have made their
3098 # way to the graftstate. With --force, any revisions we would have otherwise 3116 # way to the graftstate. With --force, any revisions we would have otherwise
3763 Returns 0 if successful. 3781 Returns 0 if successful.
3764 """ 3782 """
3765 3783
3766 opts = pycompat.byteskwargs(opts) 3784 opts = pycompat.byteskwargs(opts)
3767 if not repo and not source: 3785 if not repo and not source:
3768 raise error.Abort( 3786 raise error.InputError(
3769 _(b"there is no Mercurial repository here (.hg not found)") 3787 _(b"there is no Mercurial repository here (.hg not found)")
3770 ) 3788 )
3771 3789
3772 default = not (num or id or branch or tags or bookmarks) 3790 default = not (num or id or branch or tags or bookmarks)
3773 output = [] 3791 output = []
3782 fm = ui.formatter(b'identify', opts) 3800 fm = ui.formatter(b'identify', opts)
3783 fm.startitem() 3801 fm.startitem()
3784 3802
3785 if not repo: 3803 if not repo:
3786 if num or branch or tags: 3804 if num or branch or tags:
3787 raise error.Abort( 3805 raise error.InputError(
3788 _(b"can't query remote revision number, branch, or tags") 3806 _(b"can't query remote revision number, branch, or tags")
3789 ) 3807 )
3790 if not rev and revs: 3808 if not rev and revs:
3791 rev = revs[0] 3809 rev = revs[0]
3792 if not rev: 3810 if not rev:
4054 opts, 'no_commit', ['bypass', 'secret'] 4072 opts, 'no_commit', ['bypass', 'secret']
4055 ) 4073 )
4056 cmdutil.check_incompatible_arguments(opts, 'exact', ['edit', 'prefix']) 4074 cmdutil.check_incompatible_arguments(opts, 'exact', ['edit', 'prefix'])
4057 opts = pycompat.byteskwargs(opts) 4075 opts = pycompat.byteskwargs(opts)
4058 if not patch1: 4076 if not patch1:
4059 raise error.Abort(_(b'need at least one patch to import')) 4077 raise error.InputError(_(b'need at least one patch to import'))
4060 4078
4061 patches = (patch1,) + patches 4079 patches = (patch1,) + patches
4062 4080
4063 date = opts.get(b'date') 4081 date = opts.get(b'date')
4064 if date: 4082 if date:
4067 exact = opts.get(b'exact') 4085 exact = opts.get(b'exact')
4068 update = not opts.get(b'bypass') 4086 update = not opts.get(b'bypass')
4069 try: 4087 try:
4070 sim = float(opts.get(b'similarity') or 0) 4088 sim = float(opts.get(b'similarity') or 0)
4071 except ValueError: 4089 except ValueError:
4072 raise error.Abort(_(b'similarity must be a number')) 4090 raise error.InputError(_(b'similarity must be a number'))
4073 if sim < 0 or sim > 100: 4091 if sim < 0 or sim > 100:
4074 raise error.Abort(_(b'similarity must be between 0 and 100')) 4092 raise error.InputError(_(b'similarity must be between 0 and 100'))
4075 if sim and not update: 4093 if sim and not update:
4076 raise error.Abort(_(b'cannot use --similarity with --bypass')) 4094 raise error.InputError(_(b'cannot use --similarity with --bypass'))
4077 4095
4078 base = opts[b"base"] 4096 base = opts[b"base"]
4079 msgs = [] 4097 msgs = []
4080 ret = 0 4098 ret = 0
4081 4099
4128 ) 4146 )
4129 ret = 1 4147 ret = 1
4130 break 4148 break
4131 4149
4132 if not haspatch: 4150 if not haspatch:
4133 raise error.Abort(_(b'%s: no diffs found') % patchurl) 4151 raise error.InputError(_(b'%s: no diffs found') % patchurl)
4134 4152
4135 if msgs: 4153 if msgs:
4136 repo.savecommitmessage(b'\n* * *\n'.join(msgs)) 4154 repo.savecommitmessage(b'\n* * *\n'.join(msgs))
4137 return ret 4155 return ret
4138 4156
4584 """ 4602 """
4585 opts = pycompat.byteskwargs(opts) 4603 opts = pycompat.byteskwargs(opts)
4586 linerange = opts.get(b'line_range') 4604 linerange = opts.get(b'line_range')
4587 4605
4588 if linerange and not opts.get(b'follow'): 4606 if linerange and not opts.get(b'follow'):
4589 raise error.Abort(_(b'--line-range requires --follow')) 4607 raise error.InputError(_(b'--line-range requires --follow'))
4590 4608
4591 if linerange and pats: 4609 if linerange and pats:
4592 # TODO: take pats as patterns with no line-range filter 4610 # TODO: take pats as patterns with no line-range filter
4593 raise error.Abort( 4611 raise error.InputError(
4594 _(b'FILE arguments are not compatible with --line-range option') 4612 _(b'FILE arguments are not compatible with --line-range option')
4595 ) 4613 )
4596 4614
4597 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn') 4615 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
4598 revs, differ = logcmdutil.getrevs( 4616 revs, differ = logcmdutil.getrevs(
4650 opts = pycompat.byteskwargs(opts) 4668 opts = pycompat.byteskwargs(opts)
4651 fm = ui.formatter(b'manifest', opts) 4669 fm = ui.formatter(b'manifest', opts)
4652 4670
4653 if opts.get(b'all'): 4671 if opts.get(b'all'):
4654 if rev or node: 4672 if rev or node:
4655 raise error.Abort(_(b"can't specify a revision with --all")) 4673 raise error.InputError(_(b"can't specify a revision with --all"))
4656 4674
4657 res = set() 4675 res = set()
4658 for rev in repo: 4676 for rev in repo:
4659 ctx = repo[rev] 4677 ctx = repo[rev]
4660 res |= set(ctx.files()) 4678 res |= set(ctx.files())
4665 fm.write(b"path", b'%s\n', f) 4683 fm.write(b"path", b'%s\n', f)
4666 fm.end() 4684 fm.end()
4667 return 4685 return
4668 4686
4669 if rev and node: 4687 if rev and node:
4670 raise error.Abort(_(b"please specify just one revision")) 4688 raise error.InputError(_(b"please specify just one revision"))
4671 4689
4672 if not node: 4690 if not node:
4673 node = rev 4691 node = rev
4674 4692
4675 char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'} 4693 char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'}
4752 raise error.Abort( 4770 raise error.Abort(
4753 _(b'cannot abort merge with %s in progress') % (state._opname), 4771 _(b'cannot abort merge with %s in progress') % (state._opname),
4754 hint=state.hint(), 4772 hint=state.hint(),
4755 ) 4773 )
4756 if node: 4774 if node:
4757 raise error.Abort(_(b"cannot specify a node with --abort")) 4775 raise error.InputError(_(b"cannot specify a node with --abort"))
4758 return hg.abortmerge(repo.ui, repo) 4776 return hg.abortmerge(repo.ui, repo)
4759 4777
4760 if opts.get(b'rev') and node: 4778 if opts.get(b'rev') and node:
4761 raise error.Abort(_(b"please specify just one revision")) 4779 raise error.InputError(_(b"please specify just one revision"))
4762 if not node: 4780 if not node:
4763 node = opts.get(b'rev') 4781 node = opts.get(b'rev')
4764 4782
4765 if node: 4783 if node:
4766 ctx = scmutil.revsingle(repo, node) 4784 ctx = scmutil.revsingle(repo, node)
4767 else: 4785 else:
4768 if ui.configbool(b'commands', b'merge.require-rev'): 4786 if ui.configbool(b'commands', b'merge.require-rev'):
4769 raise error.Abort( 4787 raise error.InputError(
4770 _( 4788 _(
4771 b'configuration requires specifying revision to merge ' 4789 b'configuration requires specifying revision to merge '
4772 b'with' 4790 b'with'
4773 ) 4791 )
4774 ) 4792 )
4775 ctx = repo[destutil.destmerge(repo)] 4793 ctx = repo[destutil.destmerge(repo)]
4776 4794
4777 if ctx.node() is None: 4795 if ctx.node() is None:
4778 raise error.Abort(_(b'merging with the working copy has no effect')) 4796 raise error.InputError(
4797 _(b'merging with the working copy has no effect')
4798 )
4779 4799
4780 if opts.get(b'preview'): 4800 if opts.get(b'preview'):
4781 # find nodes that are ancestors of p2 but not of p1 4801 # find nodes that are ancestors of p2 but not of p1
4782 p1 = repo[b'.'].node() 4802 p1 = repo[b'.'].node()
4783 p2 = ctx.node() 4803 p2 = ctx.node()
4966 ctx = scmutil.revsingle(repo, rev, None) 4986 ctx = scmutil.revsingle(repo, rev, None)
4967 4987
4968 if file_: 4988 if file_:
4969 m = scmutil.match(ctx, (file_,), opts) 4989 m = scmutil.match(ctx, (file_,), opts)
4970 if m.anypats() or len(m.files()) != 1: 4990 if m.anypats() or len(m.files()) != 1:
4971 raise error.Abort(_(b'can only specify an explicit filename')) 4991 raise error.InputError(_(b'can only specify an explicit filename'))
4972 file_ = m.files()[0] 4992 file_ = m.files()[0]
4973 filenodes = [] 4993 filenodes = []
4974 for cp in ctx.parents(): 4994 for cp in ctx.parents():
4975 if not cp: 4995 if not cp:
4976 continue 4996 continue
4977 try: 4997 try:
4978 filenodes.append(cp.filenode(file_)) 4998 filenodes.append(cp.filenode(file_))
4979 except error.LookupError: 4999 except error.LookupError:
4980 pass 5000 pass
4981 if not filenodes: 5001 if not filenodes:
4982 raise error.Abort(_(b"'%s' not found in manifest!") % file_) 5002 raise error.InputError(_(b"'%s' not found in manifest!") % file_)
4983 p = [] 5003 p = []
4984 for fn in filenodes: 5004 for fn in filenodes:
4985 fctx = repo.filectx(file_, fileid=fn) 5005 fctx = repo.filectx(file_, fileid=fn)
4986 p.append(fctx.node()) 5006 p.append(fctx.node())
4987 else: 5007 else:
5119 # search for a unique phase argument 5139 # search for a unique phase argument
5120 targetphase = None 5140 targetphase = None
5121 for idx, name in enumerate(phases.cmdphasenames): 5141 for idx, name in enumerate(phases.cmdphasenames):
5122 if opts[name]: 5142 if opts[name]:
5123 if targetphase is not None: 5143 if targetphase is not None:
5124 raise error.Abort(_(b'only one phase can be specified')) 5144 raise error.InputError(_(b'only one phase can be specified'))
5125 targetphase = idx 5145 targetphase = idx
5126 5146
5127 # look for specified revision 5147 # look for specified revision
5128 revs = list(revs) 5148 revs = list(revs)
5129 revs.extend(opts[b'rev']) 5149 revs.extend(opts[b'rev'])
5142 ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr())) 5162 ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5143 else: 5163 else:
5144 with repo.lock(), repo.transaction(b"phase") as tr: 5164 with repo.lock(), repo.transaction(b"phase") as tr:
5145 # set phase 5165 # set phase
5146 if not revs: 5166 if not revs:
5147 raise error.Abort(_(b'empty revision set')) 5167 raise error.InputError(_(b'empty revision set'))
5148 nodes = [repo[r].node() for r in revs] 5168 nodes = [repo[r].node() for r in revs]
5149 # moving revision from public to draft may hide them 5169 # moving revision from public to draft may hide them
5150 # We have to check result on an unfiltered repository 5170 # We have to check result on an unfiltered repository
5151 unfi = repo.unfiltered() 5171 unfi = repo.unfiltered()
5152 getphase = unfi._phasecache.phase 5172 getphase = unfi._phasecache.phase
5285 if ui.configbool(b'commands', b'update.requiredest') and opts.get( 5305 if ui.configbool(b'commands', b'update.requiredest') and opts.get(
5286 b'update' 5306 b'update'
5287 ): 5307 ):
5288 msg = _(b'update destination required by configuration') 5308 msg = _(b'update destination required by configuration')
5289 hint = _(b'use hg pull followed by hg update DEST') 5309 hint = _(b'use hg pull followed by hg update DEST')
5290 raise error.Abort(msg, hint=hint) 5310 raise error.InputError(msg, hint=hint)
5291 5311
5292 source, branches = hg.parseurl(ui.expandpath(source), opts.get(b'branch')) 5312 source, branches = hg.parseurl(ui.expandpath(source), opts.get(b'branch'))
5293 ui.status(_(b'pulling from %s\n') % util.hidepassword(source)) 5313 ui.status(_(b'pulling from %s\n') % util.hidepassword(source))
5294 other = hg.peer(repo, opts, source) 5314 other = hg.peer(repo, opts, source)
5295 try: 5315 try:
5324 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks) 5344 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
5325 pullopargs[b'remotebookmarks'] = remotebookmarks 5345 pullopargs[b'remotebookmarks'] = remotebookmarks
5326 for b in opts.get(b'bookmark', []): 5346 for b in opts.get(b'bookmark', []):
5327 b = repo._bookmarks.expandname(b) 5347 b = repo._bookmarks.expandname(b)
5328 if b not in remotebookmarks: 5348 if b not in remotebookmarks:
5329 raise error.Abort(_(b'remote bookmark %s not found!') % b) 5349 raise error.InputError(
5350 _(b'remote bookmark %s not found!') % b
5351 )
5330 nodes.append(remotebookmarks[b]) 5352 nodes.append(remotebookmarks[b])
5331 for i, rev in enumerate(revs): 5353 for i, rev in enumerate(revs):
5332 node = fnodes[i].result() 5354 node = fnodes[i].result()
5333 nodes.append(node) 5355 nodes.append(node)
5334 if rev == checkout: 5356 if rev == checkout:
5513 other = hg.peer(repo, opts, dest) 5535 other = hg.peer(repo, opts, dest)
5514 5536
5515 if revs: 5537 if revs:
5516 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)] 5538 revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
5517 if not revs: 5539 if not revs:
5518 raise error.Abort( 5540 raise error.InputError(
5519 _(b"specified revisions evaluate to an empty set"), 5541 _(b"specified revisions evaluate to an empty set"),
5520 hint=_(b"use different revision arguments"), 5542 hint=_(b"use different revision arguments"),
5521 ) 5543 )
5522 elif path.pushrev: 5544 elif path.pushrev:
5523 # It doesn't make any sense to specify ancestor revisions. So limit 5545 # It doesn't make any sense to specify ancestor revisions. So limit
5524 # to DAG heads to make discovery simpler. 5546 # to DAG heads to make discovery simpler.
5525 expr = revsetlang.formatspec(b'heads(%r)', path.pushrev) 5547 expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
5526 revs = scmutil.revrange(repo, [expr]) 5548 revs = scmutil.revrange(repo, [expr])
5527 revs = [repo[rev].node() for rev in revs] 5549 revs = [repo[rev].node() for rev in revs]
5528 if not revs: 5550 if not revs:
5529 raise error.Abort( 5551 raise error.InputError(
5530 _(b'default push revset for path evaluates to an empty set') 5552 _(b'default push revset for path evaluates to an empty set')
5531 ) 5553 )
5532 elif ui.configbool(b'commands', b'push.require-revs'): 5554 elif ui.configbool(b'commands', b'push.require-revs'):
5533 raise error.Abort( 5555 raise error.InputError(
5534 _(b'no revisions specified to push'), 5556 _(b'no revisions specified to push'),
5535 hint=_(b'did you mean "hg push -r ."?'), 5557 hint=_(b'did you mean "hg push -r ."?'),
5536 ) 5558 )
5537 5559
5538 repo._subtoppath = dest 5560 repo._subtoppath = dest
5657 5679
5658 opts = pycompat.byteskwargs(opts) 5680 opts = pycompat.byteskwargs(opts)
5659 after, force = opts.get(b'after'), opts.get(b'force') 5681 after, force = opts.get(b'after'), opts.get(b'force')
5660 dryrun = opts.get(b'dry_run') 5682 dryrun = opts.get(b'dry_run')
5661 if not pats and not after: 5683 if not pats and not after:
5662 raise error.Abort(_(b'no files specified')) 5684 raise error.InputError(_(b'no files specified'))
5663 5685
5664 m = scmutil.match(repo[None], pats, opts) 5686 m = scmutil.match(repo[None], pats, opts)
5665 subrepos = opts.get(b'subrepos') 5687 subrepos = opts.get(b'subrepos')
5666 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) 5688 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
5667 return cmdutil.remove( 5689 return cmdutil.remove(
5787 flaglist = b'all mark unmark list no_status re_merge'.split() 5809 flaglist = b'all mark unmark list no_status re_merge'.split()
5788 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist] 5810 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
5789 5811
5790 actioncount = len(list(filter(None, [show, mark, unmark, remerge]))) 5812 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
5791 if actioncount > 1: 5813 if actioncount > 1:
5792 raise error.Abort(_(b"too many actions specified")) 5814 raise error.InputError(_(b"too many actions specified"))
5793 elif actioncount == 0 and ui.configbool( 5815 elif actioncount == 0 and ui.configbool(
5794 b'commands', b'resolve.explicit-re-merge' 5816 b'commands', b'resolve.explicit-re-merge'
5795 ): 5817 ):
5796 hint = _(b'use --mark, --unmark, --list or --re-merge') 5818 hint = _(b'use --mark, --unmark, --list or --re-merge')
5797 raise error.Abort(_(b'no action specified'), hint=hint) 5819 raise error.InputError(_(b'no action specified'), hint=hint)
5798 if pats and all: 5820 if pats and all:
5799 raise error.Abort(_(b"can't specify --all and patterns")) 5821 raise error.InputError(_(b"can't specify --all and patterns"))
5800 if not (all or pats or show or mark or unmark): 5822 if not (all or pats or show or mark or unmark):
5801 raise error.Abort( 5823 raise error.InputError(
5802 _(b'no files or directories specified'), 5824 _(b'no files or directories specified'),
5803 hint=b'use --all to re-merge all unresolved files', 5825 hint=b'use --all to re-merge all unresolved files',
5804 ) 5826 )
5805 5827
5806 if confirm: 5828 if confirm:
6080 opts[b"rev"] = cmdutil.finddate(ui, repo, opts[b"date"]) 6102 opts[b"rev"] = cmdutil.finddate(ui, repo, opts[b"date"])
6081 6103
6082 parent, p2 = repo.dirstate.parents() 6104 parent, p2 = repo.dirstate.parents()
6083 if not opts.get(b'rev') and p2 != nullid: 6105 if not opts.get(b'rev') and p2 != nullid:
6084 # revert after merge is a trap for new users (issue2915) 6106 # revert after merge is a trap for new users (issue2915)
6085 raise error.Abort( 6107 raise error.InputError(
6086 _(b'uncommitted merge with no revision specified'), 6108 _(b'uncommitted merge with no revision specified'),
6087 hint=_(b"use 'hg update' or see 'hg help revert'"), 6109 hint=_(b"use 'hg update' or see 'hg help revert'"),
6088 ) 6110 )
6089 6111
6090 rev = opts.get(b'rev') 6112 rev = opts.get(b'rev')
6103 if p2 != nullid: 6125 if p2 != nullid:
6104 hint = _( 6126 hint = _(
6105 b"uncommitted merge, use --all to discard all changes," 6127 b"uncommitted merge, use --all to discard all changes,"
6106 b" or 'hg update -C .' to abort the merge" 6128 b" or 'hg update -C .' to abort the merge"
6107 ) 6129 )
6108 raise error.Abort(msg, hint=hint) 6130 raise error.InputError(msg, hint=hint)
6109 dirty = any(repo.status()) 6131 dirty = any(repo.status())
6110 node = ctx.node() 6132 node = ctx.node()
6111 if node != parent: 6133 if node != parent:
6112 if dirty: 6134 if dirty:
6113 hint = ( 6135 hint = (
6127 ) 6149 )
6128 elif dirty: 6150 elif dirty:
6129 hint = _(b"uncommitted changes, use --all to discard all changes") 6151 hint = _(b"uncommitted changes, use --all to discard all changes")
6130 else: 6152 else:
6131 hint = _(b"use --all to revert all files") 6153 hint = _(b"use --all to revert all files")
6132 raise error.Abort(msg, hint=hint) 6154 raise error.InputError(msg, hint=hint)
6133 6155
6134 return cmdutil.revert(ui, repo, ctx, *pats, **pycompat.strkwargs(opts)) 6156 return cmdutil.revert(ui, repo, ctx, *pats, **pycompat.strkwargs(opts))
6135 6157
6136 6158
6137 @command( 6159 @command(
6337 """ 6359 """
6338 6360
6339 cmdutil.check_incompatible_arguments(opts, 'stdio', ['cmdserver']) 6361 cmdutil.check_incompatible_arguments(opts, 'stdio', ['cmdserver'])
6340 opts = pycompat.byteskwargs(opts) 6362 opts = pycompat.byteskwargs(opts)
6341 if opts[b"print_url"] and ui.verbose: 6363 if opts[b"print_url"] and ui.verbose:
6342 raise error.Abort(_(b"cannot use --print-url with --verbose")) 6364 raise error.InputError(_(b"cannot use --print-url with --verbose"))
6343 6365
6344 if opts[b"stdio"]: 6366 if opts[b"stdio"]:
6345 if repo is None: 6367 if repo is None:
6346 raise error.RepoError( 6368 raise error.RepoError(
6347 _(b"there is no Mercurial repository here (.hg not found)") 6369 _(b"there is no Mercurial repository here (.hg not found)")
6464 6486
6465 def checkopt(opt): 6487 def checkopt(opt):
6466 if opts.get(opt): 6488 if opts.get(opt):
6467 for i, allowable in allowables: 6489 for i, allowable in allowables:
6468 if opts[i] and opt not in allowable: 6490 if opts[i] and opt not in allowable:
6469 raise error.Abort( 6491 raise error.InputError(
6470 _( 6492 _(
6471 b"options '--%s' and '--%s' may not be " 6493 b"options '--%s' and '--%s' may not be "
6472 b"used together" 6494 b"used together"
6473 ) 6495 )
6474 % (opt, i) 6496 % (opt, i)
6475 ) 6497 )
6476 return True 6498 return True
6477 6499
6478 if checkopt(b'cleanup'): 6500 if checkopt(b'cleanup'):
6479 if pats: 6501 if pats:
6480 raise error.Abort(_(b"cannot specify names when using '--cleanup'")) 6502 raise error.InputError(
6503 _(b"cannot specify names when using '--cleanup'")
6504 )
6481 return shelvemod.cleanupcmd(ui, repo) 6505 return shelvemod.cleanupcmd(ui, repo)
6482 elif checkopt(b'delete'): 6506 elif checkopt(b'delete'):
6483 return shelvemod.deletecmd(ui, repo, pats) 6507 return shelvemod.deletecmd(ui, repo, pats)
6484 elif checkopt(b'list'): 6508 elif checkopt(b'list'):
6485 return shelvemod.listcmd(ui, repo, pats, opts) 6509 return shelvemod.listcmd(ui, repo, pats, opts)
6641 else: 6665 else:
6642 terse = ui.config(b'commands', b'status.terse') 6666 terse = ui.config(b'commands', b'status.terse')
6643 6667
6644 if revs and terse: 6668 if revs and terse:
6645 msg = _(b'cannot use --terse with --rev') 6669 msg = _(b'cannot use --terse with --rev')
6646 raise error.Abort(msg) 6670 raise error.InputError(msg)
6647 elif change: 6671 elif change:
6648 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn') 6672 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
6649 ctx2 = scmutil.revsingle(repo, change, None) 6673 ctx2 = scmutil.revsingle(repo, change, None)
6650 ctx1 = ctx2.p1() 6674 ctx1 = ctx2.p1()
6651 else: 6675 else:
7112 opts = pycompat.byteskwargs(opts) 7136 opts = pycompat.byteskwargs(opts)
7113 with repo.wlock(), repo.lock(): 7137 with repo.wlock(), repo.lock():
7114 rev_ = b"." 7138 rev_ = b"."
7115 names = [t.strip() for t in (name1,) + names] 7139 names = [t.strip() for t in (name1,) + names]
7116 if len(names) != len(set(names)): 7140 if len(names) != len(set(names)):
7117 raise error.Abort(_(b'tag names must be unique')) 7141 raise error.InputError(_(b'tag names must be unique'))
7118 for n in names: 7142 for n in names:
7119 scmutil.checknewlabel(repo, n, b'tag') 7143 scmutil.checknewlabel(repo, n, b'tag')
7120 if not n: 7144 if not n:
7121 raise error.Abort( 7145 raise error.InputError(
7122 _(b'tag names cannot consist entirely of whitespace') 7146 _(b'tag names cannot consist entirely of whitespace')
7123 ) 7147 )
7124 if opts.get(b'rev'): 7148 if opts.get(b'rev'):
7125 rev_ = opts[b'rev'] 7149 rev_ = opts[b'rev']
7126 message = opts.get(b'message') 7150 message = opts.get(b'message')
7132 7156
7133 for n in names: 7157 for n in names:
7134 if repo.tagtype(n) == b'global': 7158 if repo.tagtype(n) == b'global':
7135 alltags = tagsmod.findglobaltags(ui, repo) 7159 alltags = tagsmod.findglobaltags(ui, repo)
7136 if alltags[n][0] == nullid: 7160 if alltags[n][0] == nullid:
7137 raise error.Abort(_(b"tag '%s' is already removed") % n) 7161 raise error.InputError(
7162 _(b"tag '%s' is already removed") % n
7163 )
7138 if not repo.tagtype(n): 7164 if not repo.tagtype(n):
7139 raise error.Abort(_(b"tag '%s' does not exist") % n) 7165 raise error.InputError(_(b"tag '%s' does not exist") % n)
7140 if repo.tagtype(n) != expectedtype: 7166 if repo.tagtype(n) != expectedtype:
7141 if expectedtype == b'global': 7167 if expectedtype == b'global':
7142 raise error.Abort( 7168 raise error.InputError(
7143 _(b"tag '%s' is not a global tag") % n 7169 _(b"tag '%s' is not a global tag") % n
7144 ) 7170 )
7145 else: 7171 else:
7146 raise error.Abort(_(b"tag '%s' is not a local tag") % n) 7172 raise error.InputError(
7173 _(b"tag '%s' is not a local tag") % n
7174 )
7147 rev_ = b'null' 7175 rev_ = b'null'
7148 if not message: 7176 if not message:
7149 # we don't translate commit messages 7177 # we don't translate commit messages
7150 message = b'Removed tag %s' % b', '.join(names) 7178 message = b'Removed tag %s' % b', '.join(names)
7151 elif not opts.get(b'force'): 7179 elif not opts.get(b'force'):
7152 for n in names: 7180 for n in names:
7153 if n in repo.tags(): 7181 if n in repo.tags():
7154 raise error.Abort( 7182 raise error.InputError(
7155 _(b"tag '%s' already exists (use -f to force)") % n 7183 _(b"tag '%s' already exists (use -f to force)") % n
7156 ) 7184 )
7157 if not opts.get(b'local'): 7185 if not opts.get(b'local'):
7158 p1, p2 = repo.dirstate.parents() 7186 p1, p2 = repo.dirstate.parents()
7159 if p2 != nullid: 7187 if p2 != nullid:
7160 raise error.Abort(_(b'uncommitted merge')) 7188 raise error.Abort(_(b'uncommitted merge'))
7161 bheads = repo.branchheads() 7189 bheads = repo.branchheads()
7162 if not opts.get(b'force') and bheads and p1 not in bheads: 7190 if not opts.get(b'force') and bheads and p1 not in bheads:
7163 raise error.Abort( 7191 raise error.InputError(
7164 _( 7192 _(
7165 b'working directory is not at a branch head ' 7193 b'working directory is not at a branch head '
7166 b'(use -f to force)' 7194 b'(use -f to force)'
7167 ) 7195 )
7168 ) 7196 )
7190 # don't allow tagging the null rev 7218 # don't allow tagging the null rev
7191 if ( 7219 if (
7192 not opts.get(b'remove') 7220 not opts.get(b'remove')
7193 and scmutil.revsingle(repo, rev_).rev() == nullrev 7221 and scmutil.revsingle(repo, rev_).rev() == nullrev
7194 ): 7222 ):
7195 raise error.Abort(_(b"cannot tag null revision")) 7223 raise error.InputError(_(b"cannot tag null revision"))
7196 7224
7197 tagsmod.tag( 7225 tagsmod.tag(
7198 repo, 7226 repo,
7199 names, 7227 names,
7200 node, 7228 node,
7322 with repo.lock(): 7350 with repo.lock():
7323 for fname in fnames: 7351 for fname in fnames:
7324 f = hg.openpath(ui, fname) 7352 f = hg.openpath(ui, fname)
7325 gen = exchange.readbundle(ui, f, fname) 7353 gen = exchange.readbundle(ui, f, fname)
7326 if isinstance(gen, streamclone.streamcloneapplier): 7354 if isinstance(gen, streamclone.streamcloneapplier):
7327 raise error.Abort( 7355 raise error.InputError(
7328 _( 7356 _(
7329 b'packed bundles cannot be applied with ' 7357 b'packed bundles cannot be applied with '
7330 b'"hg unbundle"' 7358 b'"hg unbundle"'
7331 ), 7359 ),
7332 hint=_(b'use "hg debugapplystreamclonebundle"'), 7360 hint=_(b'use "hg debugapplystreamclonebundle"'),
7517 date = opts.get('date') 7545 date = opts.get('date')
7518 clean = opts.get('clean') 7546 clean = opts.get('clean')
7519 check = opts.get('check') 7547 check = opts.get('check')
7520 merge = opts.get('merge') 7548 merge = opts.get('merge')
7521 if rev and node: 7549 if rev and node:
7522 raise error.Abort(_(b"please specify just one revision")) 7550 raise error.InputError(_(b"please specify just one revision"))
7523 7551
7524 if ui.configbool(b'commands', b'update.requiredest'): 7552 if ui.configbool(b'commands', b'update.requiredest'):
7525 if not node and not rev and not date: 7553 if not node and not rev and not date:
7526 raise error.Abort( 7554 raise error.InputError(
7527 _(b'you must specify a destination'), 7555 _(b'you must specify a destination'),
7528 hint=_(b'for example: hg update ".::"'), 7556 hint=_(b'for example: hg update ".::"'),
7529 ) 7557 )
7530 7558
7531 if rev is None or rev == b'': 7559 if rev is None or rev == b'':
7532 rev = node 7560 rev = node
7533 7561
7534 if date and rev is not None: 7562 if date and rev is not None:
7535 raise error.Abort(_(b"you can't specify a revision and a date")) 7563 raise error.InputError(_(b"you can't specify a revision and a date"))
7536 7564
7537 updatecheck = None 7565 updatecheck = None
7538 if check: 7566 if check:
7539 updatecheck = b'abort' 7567 updatecheck = b'abort'
7540 elif merge: 7568 elif merge: