diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -859,7 +859,7 @@ wlock.release() if nolfiles and nonormalfiles: - raise error.Abort(_(b'no files to copy')) + raise error.InputError(_(b'no files to copy')) return result diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -279,7 +279,7 @@ for x in args: if opts.get(x): if previous: - raise error.Abort( + raise error.InputError( _(b'cannot specify both --%s and --%s') % (to_display(previous), to_display(x)) ) @@ -332,9 +332,9 @@ return if len(note) > 255: - raise error.Abort(_(b"cannot store a note of more than 255 bytes")) + raise error.InputError(_(b"cannot store a note of more than 255 bytes")) if b'\n' in note: - raise error.Abort(_(b"note cannot contain a newline")) + raise error.InputError(_(b"note cannot contain a newline")) def ishunk(x): @@ -426,7 +426,7 @@ msg = _(b'running non-interactively, use %s instead') % cmdsuggest else: msg = _(b'running non-interactively') - raise error.Abort(msg) + raise error.InputError(msg) # make sure username is set before going interactive if not opts.get(b'user'): @@ -451,7 +451,7 @@ wctx = repo[None] merge = len(wctx.parents()) > 1 if merge: - raise error.Abort( + raise error.InputError( _( b'cannot partially commit a merge ' b'(use "hg commit" instead)' @@ -762,7 +762,7 @@ # checking the argument validity for s in pycompat.bytestr(terseargs): if s not in allst: - raise error.Abort(_(b"'%s' not recognized") % s) + raise error.InputError(_(b"'%s' not recognized") % s) # creating a dirnode object for the root of the repo rootobj = dirnode(b'') @@ -968,10 +968,10 @@ bailifchanged(repo) revs = scmutil.revrange(repo, revs) if not revs: - raise error.Abort(b"empty revision set") + raise error.InputError(b"empty revision set") roots = repo.revs(b'roots(%ld)', revs) if len(roots) > 1: - raise error.Abort( + raise error.InputError( _(b"cannot change branch of non-linear revisions") ) rewriteutil.precheck(repo, revs, b'change branch of') @@ -983,16 +983,20 @@ and label not in rpb and label in repo.branchmap() ): - raise error.Abort(_(b"a branch of the same name already exists")) + raise error.InputError( + _(b"a branch of the same name already exists") + ) if repo.revs(b'obsolete() and %ld', revs): - raise error.Abort( + raise error.InputError( _(b"cannot change branch of a obsolete changeset") ) # make sure only topological heads if repo.revs(b'heads(%ld) - head()', revs): - raise error.Abort(_(b"cannot change branch in middle of a stack")) + raise error.InputError( + _(b"cannot change branch in middle of a stack") + ) replacements = {} # avoid import cycle mercurial.cmdutil -> mercurial.context -> @@ -1349,7 +1353,7 @@ b'without a repository' ) if msg: - raise error.Abort(msg) + raise error.InputError(msg) r = None if repo: @@ -1357,7 +1361,7 @@ r = repo.unfiltered().changelog elif dir: if not scmutil.istreemanifest(repo): - raise error.Abort( + raise error.InputError( _( b"--dir can only be used on repos with " b"treemanifest enabled" @@ -1383,11 +1387,13 @@ elif util.safehasattr(r, b'_revlog'): r = r._revlog # pytype: disable=attribute-error elif r is not None: - raise error.Abort(_(b'%r does not appear to be a revlog') % r) + raise error.InputError( + _(b'%r does not appear to be a revlog') % r + ) if not r: if not returnrevlog: - raise error.Abort(_(b'cannot give path to non-revlog')) + raise error.InputError(_(b'cannot give path to non-revlog')) if not file_: raise error.CommandError(cmd, _(b'invalid arguments')) @@ -1429,10 +1435,12 @@ if not forget and not after: # TODO: Remove this restriction and make it also create the copy # targets (and remove the rename source if rename==True). - raise error.Abort(_(b'--at-rev requires --after')) + raise error.InputError(_(b'--at-rev requires --after')) ctx = scmutil.revsingle(repo, rev) if len(ctx.parents()) > 1: - raise error.Abort(_(b'cannot mark/unmark copy in merge commit')) + raise error.InputError( + _(b'cannot mark/unmark copy in merge commit') + ) else: ctx = repo[None] @@ -1445,7 +1453,7 @@ new_ctx = ctx else: if len(ctx.parents()) > 1: - raise error.Abort(_(b'cannot unmark copy in merge commit')) + raise error.InputError(_(b'cannot unmark copy in merge commit')) # avoid cycle context -> subrepo -> cmdutil from . import context @@ -1488,9 +1496,9 @@ pats = scmutil.expandpats(pats) if not pats: - raise error.Abort(_(b'no source or destination specified')) + raise error.InputError(_(b'no source or destination specified')) if len(pats) == 1: - raise error.Abort(_(b'no destination specified')) + raise error.InputError(_(b'no destination specified')) dest = pats.pop() def walkpat(pat): @@ -1530,12 +1538,12 @@ rewriteutil.precheck(repo, [ctx.rev()], b'uncopy') absdest = pathutil.canonpath(repo.root, cwd, dest) if ctx.hasdir(absdest): - raise error.Abort( + raise error.InputError( _(b'%s: --at-rev does not support a directory as destination') % uipathfn(absdest) ) if absdest not in ctx: - raise error.Abort( + raise error.InputError( _(b'%s: copy destination does not exist in %s') % (uipathfn(absdest), ctx) ) @@ -1552,12 +1560,12 @@ copylist.append(abs) if not copylist: - raise error.Abort(_(b'no files to copy')) + raise error.InputError(_(b'no files to copy')) # TODO: Add support for `hg cp --at-rev . foo bar dir` and # `hg cp --at-rev . dir1 dir2`, preferably unifying the code with the # existing functions below. if len(copylist) != 1: - raise error.Abort(_(b'--at-rev requires a single source')) + raise error.InputError(_(b'--at-rev requires a single source')) new_ctx = context.overlayworkingctx(repo) new_ctx.setbase(ctx.p1()) @@ -1785,14 +1793,16 @@ destdirexists = os.path.isdir(dest) and not os.path.islink(dest) if not destdirexists: if len(pats) > 1 or matchmod.patkind(pats[0]): - raise error.Abort( + raise error.InputError( _( b'with multiple sources, destination must be an ' b'existing directory' ) ) if util.endswithsep(dest): - raise error.Abort(_(b'destination %s is not a directory') % dest) + raise error.InputError( + _(b'destination %s is not a directory') % dest + ) tfn = targetpathfn if after: @@ -1804,7 +1814,7 @@ continue copylist.append((tfn(pat, dest, srcs), srcs)) if not copylist: - raise error.Abort(_(b'no files to copy')) + raise error.InputError(_(b'no files to copy')) errors = 0 for targetpath, srcs in copylist: @@ -1895,7 +1905,7 @@ parents.append(repo[nullid]) if opts.get(b'exact'): if not nodeid or not p1: - raise error.Abort(_(b'not a Mercurial patch')) + raise error.InputError(_(b'not a Mercurial patch')) p1 = repo[p1] p2 = repo[p2 or nullid] elif p2: @@ -2231,7 +2241,7 @@ try: rev = mrevs.max() except ValueError: - raise error.Abort(_(b"revision matching date not found")) + raise error.InputError(_(b"revision matching date not found")) ui.status( _(b"found revision %d from %s\n") @@ -2363,7 +2373,9 @@ ui, repo, match, prefix, uipathfn, explicitonly, dryrun, interactive ): if dryrun and interactive: - raise error.Abort(_(b"cannot specify both --dry-run and --interactive")) + raise error.InputError( + _(b"cannot specify both --dry-run and --interactive") + ) bad = [] badfn = lambda x, y: bad.append(x) or match.bad(x, y) wctx = repo[None] @@ -3075,9 +3087,9 @@ if finishdesc: text = finishdesc(text) if not text.strip(): - raise error.Abort(_(b"empty commit message")) + raise error.InputError(_(b"empty commit message")) if unchangedmessagedetection and editortext == templatetext: - raise error.Abort(_(b"commit message unchanged")) + raise error.InputError(_(b"commit message unchanged")) return text diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2034,11 +2034,13 @@ extra[b'close'] = b'1' if repo[b'.'].closesbranch(): - raise error.Abort( + raise error.InputError( _(b'current revision is already a branch closing head') ) elif not bheads: - raise error.Abort(_(b'branch "%s" has no heads to close') % branch) + raise error.InputError( + _(b'branch "%s" has no heads to close') % branch + ) elif ( branch == repo[b'.'].branch() and repo[b'.'].node() not in bheads @@ -2048,17 +2050,19 @@ b'use --force-close-branch to close branch from a non-head' b' changeset' ) - raise error.Abort(_(b'can only close branch heads'), hint=hint) + raise error.InputError(_(b'can only close branch heads'), hint=hint) elif opts.get(b'amend'): if ( repo[b'.'].p1().branch() != branch and repo[b'.'].p2().branch() != branch ): - raise error.Abort(_(b'can only close branch heads')) + raise error.InputError(_(b'can only close branch heads')) if opts.get(b'amend'): if ui.configbool(b'ui', b'commitsubrepos'): - raise error.Abort(_(b'cannot amend with ui.commitsubrepos enabled')) + raise error.InputError( + _(b'cannot amend with ui.commitsubrepos enabled') + ) old = repo[b'.'] rewriteutil.precheck(repo, [old.rev()], b'amend') @@ -2196,17 +2200,19 @@ cmdutil.check_at_most_one_arg(opts, *editopts[1:]) if opts.get(b'local'): if not repo: - raise error.Abort(_(b"can't use --local outside a repository")) + raise error.InputError( + _(b"can't use --local outside a repository") + ) paths = [repo.vfs.join(b'hgrc')] elif opts.get(b'global'): paths = rcutil.systemrcpath() elif opts.get(b'shared'): if not repo.shared(): - raise error.Abort( + raise error.InputError( _(b"repository is not shared; can't use --shared") ) if requirements.SHARESAFE_REQUIREMENT not in repo.requirements: - raise error.Abort( + raise error.InputError( _( b"share safe feature not unabled; " b"unable to edit shared source repository config" @@ -2235,7 +2241,7 @@ editor = ui.geteditor() ui.system( b"%s \"%s\"" % (editor, f), - onerr=error.Abort, + onerr=error.InputError, errprefix=_(b"edit failed"), blockedtag=b'config_edit', ) @@ -2643,7 +2649,7 @@ if bookmark: if bookmark not in repo._bookmarks: - raise error.Abort(_(b"bookmark '%s' not found") % bookmark) + raise error.InputError(_(b"bookmark '%s' not found") % bookmark) revs = scmutil.bookmarkrevs(repo, bookmark) else: @@ -2654,7 +2660,7 @@ revs = scmutil.revrange(repo, changesets) if not revs: - raise error.Abort(_(b"export requires at least one changeset")) + raise error.InputError(_(b"export requires at least one changeset")) if len(revs) > 1: ui.note(_(b'exporting patches:\n')) else: @@ -2819,7 +2825,7 @@ opts = pycompat.byteskwargs(opts) if not pats: - raise error.Abort(_(b'no files specified')) + raise error.InputError(_(b'no files specified')) m = scmutil.match(repo[None], pats, opts) dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive') @@ -3046,7 +3052,7 @@ elif opts.get(b'continue'): cont = True if revs: - raise error.Abort(_(b"can't specify --continue and revisions")) + raise error.InputError(_(b"can't specify --continue and revisions")) # read in unfinished revisions if graftstate.exists(): statedata = cmdutil.readgraftstate(repo, graftstate) @@ -3066,7 +3072,7 @@ cmdutil.wrongtooltocontinue(repo, _(b'graft')) else: if not revs: - raise error.Abort(_(b'no revisions specified')) + raise error.InputError(_(b'no revisions specified')) cmdutil.checkunfinished(repo) cmdutil.bailifchanged(repo) revs = scmutil.revrange(repo, revs) @@ -3084,7 +3090,7 @@ if not revs: return -1 if basectx is not None and len(revs) != 1: - raise error.Abort(_(b'only one revision allowed with --base ')) + raise error.InputError(_(b'only one revision allowed with --base ')) # Don't check in the --continue case, in effect retaining --force across # --continues. That's because without --force, any revisions we decided to @@ -3372,7 +3378,9 @@ opts = pycompat.byteskwargs(opts) diff = opts.get(b'all') or opts.get(b'diff') if diff and opts.get(b'all_files'): - raise error.Abort(_(b'--diff and --all-files are mutually exclusive')) + raise error.InputError( + _(b'--diff and --all-files are mutually exclusive') + ) if opts.get(b'all_files') is None and not diff: opts[b'all_files'] = True plaingrep = ( @@ -3916,7 +3924,7 @@ opts = pycompat.byteskwargs(opts) if not repo and not source: - raise error.Abort( + raise error.InputError( _(b"there is no Mercurial repository here (.hg not found)") ) @@ -3935,7 +3943,7 @@ if not repo: if num or branch or tags: - raise error.Abort( + raise error.InputError( _(b"can't query remote revision number, branch, or tags") ) if not rev and revs: @@ -4203,7 +4211,7 @@ opts = pycompat.byteskwargs(opts) if not patch1: - raise error.Abort(_(b'need at least one patch to import')) + raise error.InputError(_(b'need at least one patch to import')) patches = (patch1,) + patches @@ -4214,22 +4222,22 @@ exact = opts.get(b'exact') update = not opts.get(b'bypass') if not update and opts.get(b'no_commit'): - raise error.Abort(_(b'cannot use --no-commit with --bypass')) + raise error.InputError(_(b'cannot use --no-commit with --bypass')) if opts.get(b'secret') and opts.get(b'no_commit'): - raise error.Abort(_(b'cannot use --no-commit with --secret')) + raise error.InputError(_(b'cannot use --no-commit with --secret')) try: sim = float(opts.get(b'similarity') or 0) except ValueError: - raise error.Abort(_(b'similarity must be a number')) + raise error.InputError(_(b'similarity must be a number')) if sim < 0 or sim > 100: - raise error.Abort(_(b'similarity must be between 0 and 100')) + raise error.InputError(_(b'similarity must be between 0 and 100')) if sim and not update: - raise error.Abort(_(b'cannot use --similarity with --bypass')) + raise error.InputError(_(b'cannot use --similarity with --bypass')) if exact: if opts.get(b'edit'): - raise error.Abort(_(b'cannot use --exact with --edit')) + raise error.InputError(_(b'cannot use --exact with --edit')) if opts.get(b'prefix'): - raise error.Abort(_(b'cannot use --exact with --prefix')) + raise error.InputError(_(b'cannot use --exact with --prefix')) base = opts[b"base"] msgs = [] @@ -4743,11 +4751,11 @@ linerange = opts.get(b'line_range') if linerange and not opts.get(b'follow'): - raise error.Abort(_(b'--line-range requires --follow')) + raise error.InputError(_(b'--line-range requires --follow')) if linerange and pats: # TODO: take pats as patterns with no line-range filter - raise error.Abort( + raise error.InputError( _(b'FILE arguments are not compatible with --line-range option') ) @@ -4809,7 +4817,7 @@ if opts.get(b'all'): if rev or node: - raise error.Abort(_(b"can't specify a revision with --all")) + raise error.InputError(_(b"can't specify a revision with --all")) res = set() for rev in repo: @@ -4824,7 +4832,7 @@ return if rev and node: - raise error.Abort(_(b"please specify just one revision")) + raise error.InputError(_(b"please specify just one revision")) if not node: node = rev @@ -4911,11 +4919,11 @@ hint=state.hint(), ) if node: - raise error.Abort(_(b"cannot specify a node with --abort")) + raise error.InputError(_(b"cannot specify a node with --abort")) return hg.abortmerge(repo.ui, repo) if opts.get(b'rev') and node: - raise error.Abort(_(b"please specify just one revision")) + raise error.InputError(_(b"please specify just one revision")) if not node: node = opts.get(b'rev') @@ -4923,7 +4931,7 @@ ctx = scmutil.revsingle(repo, node) else: if ui.configbool(b'commands', b'merge.require-rev'): - raise error.Abort( + raise error.InputError( _( b'configuration requires specifying revision to merge ' b'with' @@ -4932,7 +4940,9 @@ ctx = repo[destutil.destmerge(repo)] if ctx.node() is None: - raise error.Abort(_(b'merging with the working copy has no effect')) + raise error.InputError( + _(b'merging with the working copy has no effect') + ) if opts.get(b'preview'): # find nodes that are ancestors of p2 but not of p1 @@ -5125,7 +5135,7 @@ if file_: m = scmutil.match(ctx, (file_,), opts) if m.anypats() or len(m.files()) != 1: - raise error.Abort(_(b'can only specify an explicit filename')) + raise error.InputError(_(b'can only specify an explicit filename')) file_ = m.files()[0] filenodes = [] for cp in ctx.parents(): @@ -5136,7 +5146,7 @@ except error.LookupError: pass if not filenodes: - raise error.Abort(_(b"'%s' not found in manifest!") % file_) + raise error.InputError(_(b"'%s' not found in manifest!") % file_) p = [] for fn in filenodes: fctx = repo.filectx(file_, fileid=fn) @@ -5278,7 +5288,7 @@ for idx, name in enumerate(phases.cmdphasenames): if opts[name]: if targetphase is not None: - raise error.Abort(_(b'only one phase can be specified')) + raise error.InputError(_(b'only one phase can be specified')) targetphase = idx # look for specified revision @@ -5301,7 +5311,7 @@ with repo.lock(), repo.transaction(b"phase") as tr: # set phase if not revs: - raise error.Abort(_(b'empty revision set')) + raise error.InputError(_(b'empty revision set')) nodes = [repo[r].node() for r in revs] # moving revision from public to draft may hide them # We have to check result on an unfiltered repository @@ -5444,7 +5454,7 @@ ): msg = _(b'update destination required by configuration') hint = _(b'use hg pull followed by hg update DEST') - raise error.Abort(msg, hint=hint) + raise error.InputError(msg, hint=hint) source, branches = hg.parseurl(ui.expandpath(source), opts.get(b'branch')) ui.status(_(b'pulling from %s\n') % util.hidepassword(source)) @@ -5483,7 +5493,9 @@ for b in opts.get(b'bookmark', []): b = repo._bookmarks.expandname(b) if b not in remotebookmarks: - raise error.Abort(_(b'remote bookmark %s not found!') % b) + raise error.InputError( + _(b'remote bookmark %s not found!') % b + ) nodes.append(remotebookmarks[b]) for i, rev in enumerate(revs): node = fnodes[i].result() @@ -5663,7 +5675,7 @@ if revs: revs = [repo[r].node() for r in scmutil.revrange(repo, revs)] if not revs: - raise error.Abort( + raise error.InputError( _(b"specified revisions evaluate to an empty set"), hint=_(b"use different revision arguments"), ) @@ -5674,11 +5686,11 @@ revs = scmutil.revrange(repo, [expr]) revs = [repo[rev].node() for rev in revs] if not revs: - raise error.Abort( + raise error.InputError( _(b'default push revset for path evaluates to an empty set') ) elif ui.configbool(b'commands', b'push.require-revs'): - raise error.Abort( + raise error.InputError( _(b'no revisions specified to push'), hint=_(b'did you mean "hg push -r ."?'), ) @@ -5807,7 +5819,7 @@ after, force = opts.get(b'after'), opts.get(b'force') dryrun = opts.get(b'dry_run') if not pats and not after: - raise error.Abort(_(b'no files specified')) + raise error.InputError(_(b'no files specified')) m = scmutil.match(repo[None], pats, opts) subrepos = opts.get(b'subrepos') @@ -5937,16 +5949,16 @@ actioncount = len(list(filter(None, [show, mark, unmark, remerge]))) if actioncount > 1: - raise error.Abort(_(b"too many actions specified")) + raise error.InputError(_(b"too many actions specified")) elif actioncount == 0 and ui.configbool( b'commands', b'resolve.explicit-re-merge' ): hint = _(b'use --mark, --unmark, --list or --re-merge') - raise error.Abort(_(b'no action specified'), hint=hint) + raise error.InputError(_(b'no action specified'), hint=hint) if pats and all: - raise error.Abort(_(b"can't specify --all and patterns")) + raise error.InputError(_(b"can't specify --all and patterns")) if not (all or pats or show or mark or unmark): - raise error.Abort( + raise error.InputError( _(b'no files or directories specified'), hint=b'use --all to re-merge all unresolved files', ) @@ -5956,7 +5968,7 @@ if ui.promptchoice( _(b're-merge all unresolved files (yn)?$$ &Yes $$ &No') ): - raise error.Abort(_(b'user quit')) + raise error.InputError(_(b'user quit')) if mark and not pats: if ui.promptchoice( _( @@ -5964,7 +5976,7 @@ b'$$ &Yes $$ &No' ) ): - raise error.Abort(_(b'user quit')) + raise error.InputError(_(b'user quit')) if unmark and not pats: if ui.promptchoice( _( @@ -5972,7 +5984,7 @@ b'$$ &Yes $$ &No' ) ): - raise error.Abort(_(b'user quit')) + raise error.InputError(_(b'user quit')) uipathfn = scmutil.getuipathfn(repo) @@ -6225,13 +6237,15 @@ opts = pycompat.byteskwargs(opts) if opts.get(b"date"): if opts.get(b"rev"): - raise error.Abort(_(b"you can't specify a revision and a date")) + raise error.InputError( + _(b"you can't specify a revision and a date") + ) opts[b"rev"] = cmdutil.finddate(ui, repo, opts[b"date"]) parent, p2 = repo.dirstate.parents() if not opts.get(b'rev') and p2 != nullid: # revert after merge is a trap for new users (issue2915) - raise error.Abort( + raise error.InputError( _(b'uncommitted merge with no revision specified'), hint=_(b"use 'hg update' or see 'hg help revert'"), ) @@ -6254,7 +6268,7 @@ b"uncommitted merge, use --all to discard all changes," b" or 'hg update -C .' to abort the merge" ) - raise error.Abort(msg, hint=hint) + raise error.InputError(msg, hint=hint) dirty = any(repo.status()) node = ctx.node() if node != parent: @@ -6278,7 +6292,7 @@ hint = _(b"uncommitted changes, use --all to discard all changes") else: hint = _(b"use --all to revert all files") - raise error.Abort(msg, hint=hint) + raise error.InputError(msg, hint=hint) return cmdutil.revert(ui, repo, ctx, *pats, **pycompat.strkwargs(opts)) @@ -6487,9 +6501,9 @@ opts = pycompat.byteskwargs(opts) if opts[b"stdio"] and opts[b"cmdserver"]: - raise error.Abort(_(b"cannot use --stdio with --cmdserver")) + raise error.InputError(_(b"cannot use --stdio with --cmdserver")) if opts[b"print_url"] and ui.verbose: - raise error.Abort(_(b"cannot use --print-url with --verbose")) + raise error.InputError(_(b"cannot use --print-url with --verbose")) if opts[b"stdio"]: if repo is None: @@ -6615,7 +6629,7 @@ if opts.get(opt): for i, allowable in allowables: if opts[i] and opt not in allowable: - raise error.Abort( + raise error.InputError( _( b"options '--%s' and '--%s' may not be " b"used together" @@ -6626,7 +6640,9 @@ if checkopt(b'cleanup'): if pats: - raise error.Abort(_(b"cannot specify names when using '--cleanup'")) + raise error.InputError( + _(b"cannot specify names when using '--cleanup'") + ) return shelvemod.cleanupcmd(ui, repo) elif checkopt(b'delete'): return shelvemod.deletecmd(ui, repo, pats) @@ -6792,7 +6808,7 @@ if revs and terse: msg = _(b'cannot use --terse with --rev') - raise error.Abort(msg) + raise error.InputError(msg) elif change: repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn') ctx2 = scmutil.revsingle(repo, change, None) @@ -7262,15 +7278,15 @@ rev_ = b"." names = [t.strip() for t in (name1,) + names] if len(names) != len(set(names)): - raise error.Abort(_(b'tag names must be unique')) + raise error.InputError(_(b'tag names must be unique')) for n in names: scmutil.checknewlabel(repo, n, b'tag') if not n: - raise error.Abort( + raise error.InputError( _(b'tag names cannot consist entirely of whitespace') ) if opts.get(b'rev') and opts.get(b'remove'): - raise error.Abort(_(b"--rev and --remove are incompatible")) + raise error.InputError(_(b"--rev and --remove are incompatible")) if opts.get(b'rev'): rev_ = opts[b'rev'] message = opts.get(b'message') @@ -7284,16 +7300,20 @@ if repo.tagtype(n) == b'global': alltags = tagsmod.findglobaltags(ui, repo) if alltags[n][0] == nullid: - raise error.Abort(_(b"tag '%s' is already removed") % n) + raise error.InputError( + _(b"tag '%s' is already removed") % n + ) if not repo.tagtype(n): - raise error.Abort(_(b"tag '%s' does not exist") % n) + raise error.InputError(_(b"tag '%s' does not exist") % n) if repo.tagtype(n) != expectedtype: if expectedtype == b'global': - raise error.Abort( + raise error.InputError( _(b"tag '%s' is not a global tag") % n ) else: - raise error.Abort(_(b"tag '%s' is not a local tag") % n) + raise error.InputError( + _(b"tag '%s' is not a local tag") % n + ) rev_ = b'null' if not message: # we don't translate commit messages @@ -7301,7 +7321,7 @@ elif not opts.get(b'force'): for n in names: if n in repo.tags(): - raise error.Abort( + raise error.InputError( _(b"tag '%s' already exists (use -f to force)") % n ) if not opts.get(b'local'): @@ -7342,7 +7362,7 @@ not opts.get(b'remove') and scmutil.revsingle(repo, rev_).rev() == nullrev ): - raise error.Abort(_(b"cannot tag null revision")) + raise error.InputError(_(b"cannot tag null revision")) tagsmod.tag( repo, @@ -7474,7 +7494,7 @@ f = hg.openpath(ui, fname) gen = exchange.readbundle(ui, f, fname) if isinstance(gen, streamclone.streamcloneapplier): - raise error.Abort( + raise error.InputError( _( b'packed bundles cannot be applied with ' b'"hg unbundle"' @@ -7669,11 +7689,11 @@ check = opts.get('check') merge = opts.get('merge') if rev and node: - raise error.Abort(_(b"please specify just one revision")) + raise error.InputError(_(b"please specify just one revision")) if ui.configbool(b'commands', b'update.requiredest'): if not node and not rev and not date: - raise error.Abort( + raise error.InputError( _(b'you must specify a destination'), hint=_(b'for example: hg update ".::"'), ) @@ -7682,7 +7702,7 @@ rev = node if date and rev is not None: - raise error.Abort(_(b"you can't specify a revision and a date")) + raise error.InputError(_(b"you can't specify a revision and a date")) updatecheck = None if check: diff --git a/mercurial/error.py b/mercurial/error.py --- a/mercurial/error.py +++ b/mercurial/error.py @@ -174,6 +174,13 @@ return pycompat.sysstr(self.__bytes__()) +class InputError(Abort): + """Indicates that the user made an error in their input. + + Examples: Invalid command, invalid flags, invalid revision. + """ + + class HookLoadError(Abort): """raised when loading a hook fails, aborting an operation diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -215,6 +215,10 @@ return 1 except error.WdirUnsupported: ui.error(_(b"abort: working directory revision cannot be specified\n")) + except error.InputError as inst: + ui.error(_(b"abort: %s\n") % inst.message) + if inst.hint: + ui.error(_(b"(%s)\n") % inst.hint) except error.Abort as inst: ui.error(_(b"abort: %s\n") % inst.message) if inst.hint: