330 note = opts.get(b'note') |
330 note = opts.get(b'note') |
331 if not note: |
331 if not note: |
332 return |
332 return |
333 |
333 |
334 if len(note) > 255: |
334 if len(note) > 255: |
335 raise error.Abort(_(b"cannot store a note of more than 255 bytes")) |
335 raise error.InputError(_(b"cannot store a note of more than 255 bytes")) |
336 if b'\n' in note: |
336 if b'\n' in note: |
337 raise error.Abort(_(b"note cannot contain a newline")) |
337 raise error.InputError(_(b"note cannot contain a newline")) |
338 |
338 |
339 |
339 |
340 def ishunk(x): |
340 def ishunk(x): |
341 hunkclasses = (crecordmod.uihunk, patch.recordhunk) |
341 hunkclasses = (crecordmod.uihunk, patch.recordhunk) |
342 return isinstance(x, hunkclasses) |
342 return isinstance(x, hunkclasses) |
424 if not ui.interactive(): |
424 if not ui.interactive(): |
425 if cmdsuggest: |
425 if cmdsuggest: |
426 msg = _(b'running non-interactively, use %s instead') % cmdsuggest |
426 msg = _(b'running non-interactively, use %s instead') % cmdsuggest |
427 else: |
427 else: |
428 msg = _(b'running non-interactively') |
428 msg = _(b'running non-interactively') |
429 raise error.Abort(msg) |
429 raise error.InputError(msg) |
430 |
430 |
431 # make sure username is set before going interactive |
431 # make sure username is set before going interactive |
432 if not opts.get(b'user'): |
432 if not opts.get(b'user'): |
433 ui.username() # raise exception, username not provided |
433 ui.username() # raise exception, username not provided |
434 |
434 |
449 if not opts.get(b'interactive-unshelve'): |
449 if not opts.get(b'interactive-unshelve'): |
450 checkunfinished(repo, commit=True) |
450 checkunfinished(repo, commit=True) |
451 wctx = repo[None] |
451 wctx = repo[None] |
452 merge = len(wctx.parents()) > 1 |
452 merge = len(wctx.parents()) > 1 |
453 if merge: |
453 if merge: |
454 raise error.Abort( |
454 raise error.InputError( |
455 _( |
455 _( |
456 b'cannot partially commit a merge ' |
456 b'cannot partially commit a merge ' |
457 b'(use "hg commit" instead)' |
457 b'(use "hg commit" instead)' |
458 ) |
458 ) |
459 ) |
459 ) |
508 |
508 |
509 # 1. filter patch, since we are intending to apply subset of it |
509 # 1. filter patch, since we are intending to apply subset of it |
510 try: |
510 try: |
511 chunks, newopts = filterfn(ui, originalchunks, match) |
511 chunks, newopts = filterfn(ui, originalchunks, match) |
512 except error.PatchError as err: |
512 except error.PatchError as err: |
513 raise error.Abort(_(b'error parsing patch: %s') % err) |
513 raise error.InputError(_(b'error parsing patch: %s') % err) |
514 opts.update(newopts) |
514 opts.update(newopts) |
515 |
515 |
516 # We need to keep a backup of files that have been newly added and |
516 # We need to keep a backup of files that have been newly added and |
517 # modified during the recording process because there is a previous |
517 # modified during the recording process because there is a previous |
518 # version without the edit in the workdir. We also will need to restore |
518 # version without the edit in the workdir. We also will need to restore |
598 try: |
598 try: |
599 ui.debug(b'applying patch\n') |
599 ui.debug(b'applying patch\n') |
600 ui.debug(fp.getvalue()) |
600 ui.debug(fp.getvalue()) |
601 patch.internalpatch(ui, repo, fp, 1, eolmode=None) |
601 patch.internalpatch(ui, repo, fp, 1, eolmode=None) |
602 except error.PatchError as err: |
602 except error.PatchError as err: |
603 raise error.Abort(pycompat.bytestr(err)) |
603 raise error.InputError(pycompat.bytestr(err)) |
604 del fp |
604 del fp |
605 |
605 |
606 # 4. We prepared working directory according to filtered |
606 # 4. We prepared working directory according to filtered |
607 # patch. Now is the time to delegate the job to |
607 # patch. Now is the time to delegate the job to |
608 # commit/qrefresh or the like! |
608 # commit/qrefresh or the like! |
760 allst = (b'm', b'a', b'r', b'd', b'u', b'i', b'c') |
760 allst = (b'm', b'a', b'r', b'd', b'u', b'i', b'c') |
761 |
761 |
762 # checking the argument validity |
762 # checking the argument validity |
763 for s in pycompat.bytestr(terseargs): |
763 for s in pycompat.bytestr(terseargs): |
764 if s not in allst: |
764 if s not in allst: |
765 raise error.Abort(_(b"'%s' not recognized") % s) |
765 raise error.InputError(_(b"'%s' not recognized") % s) |
766 |
766 |
767 # creating a dirnode object for the root of the repo |
767 # creating a dirnode object for the root of the repo |
768 rootobj = dirnode(b'') |
768 rootobj = dirnode(b'') |
769 pstatus = ( |
769 pstatus = ( |
770 b'modified', |
770 b'modified', |
966 with repo.wlock(), repo.lock(), repo.transaction(b'branches'): |
966 with repo.wlock(), repo.lock(), repo.transaction(b'branches'): |
967 # abort in case of uncommitted merge or dirty wdir |
967 # abort in case of uncommitted merge or dirty wdir |
968 bailifchanged(repo) |
968 bailifchanged(repo) |
969 revs = scmutil.revrange(repo, revs) |
969 revs = scmutil.revrange(repo, revs) |
970 if not revs: |
970 if not revs: |
971 raise error.Abort(b"empty revision set") |
971 raise error.InputError(b"empty revision set") |
972 roots = repo.revs(b'roots(%ld)', revs) |
972 roots = repo.revs(b'roots(%ld)', revs) |
973 if len(roots) > 1: |
973 if len(roots) > 1: |
974 raise error.Abort( |
974 raise error.InputError( |
975 _(b"cannot change branch of non-linear revisions") |
975 _(b"cannot change branch of non-linear revisions") |
976 ) |
976 ) |
977 rewriteutil.precheck(repo, revs, b'change branch of') |
977 rewriteutil.precheck(repo, revs, b'change branch of') |
978 |
978 |
979 root = repo[roots.first()] |
979 root = repo[roots.first()] |
981 if ( |
981 if ( |
982 not opts.get(b'force') |
982 not opts.get(b'force') |
983 and label not in rpb |
983 and label not in rpb |
984 and label in repo.branchmap() |
984 and label in repo.branchmap() |
985 ): |
985 ): |
986 raise error.Abort(_(b"a branch of the same name already exists")) |
986 raise error.InputError( |
|
987 _(b"a branch of the same name already exists") |
|
988 ) |
987 |
989 |
988 if repo.revs(b'obsolete() and %ld', revs): |
990 if repo.revs(b'obsolete() and %ld', revs): |
989 raise error.Abort( |
991 raise error.InputError( |
990 _(b"cannot change branch of a obsolete changeset") |
992 _(b"cannot change branch of a obsolete changeset") |
991 ) |
993 ) |
992 |
994 |
993 # make sure only topological heads |
995 # make sure only topological heads |
994 if repo.revs(b'heads(%ld) - head()', revs): |
996 if repo.revs(b'heads(%ld) - head()', revs): |
995 raise error.Abort(_(b"cannot change branch in middle of a stack")) |
997 raise error.InputError( |
|
998 _(b"cannot change branch in middle of a stack") |
|
999 ) |
996 |
1000 |
997 replacements = {} |
1001 replacements = {} |
998 # avoid import cycle mercurial.cmdutil -> mercurial.context -> |
1002 # avoid import cycle mercurial.cmdutil -> mercurial.context -> |
999 # mercurial.subrepo -> mercurial.cmdutil |
1003 # mercurial.subrepo -> mercurial.cmdutil |
1000 from . import context |
1004 from . import context |
1371 msg = _( |
1375 msg = _( |
1372 b'cannot specify --changelog or --manifest or --dir ' |
1376 b'cannot specify --changelog or --manifest or --dir ' |
1373 b'without a repository' |
1377 b'without a repository' |
1374 ) |
1378 ) |
1375 if msg: |
1379 if msg: |
1376 raise error.Abort(msg) |
1380 raise error.InputError(msg) |
1377 |
1381 |
1378 r = None |
1382 r = None |
1379 if repo: |
1383 if repo: |
1380 if cl: |
1384 if cl: |
1381 r = repo.unfiltered().changelog |
1385 r = repo.unfiltered().changelog |
1382 elif dir: |
1386 elif dir: |
1383 if not scmutil.istreemanifest(repo): |
1387 if not scmutil.istreemanifest(repo): |
1384 raise error.Abort( |
1388 raise error.InputError( |
1385 _( |
1389 _( |
1386 b"--dir can only be used on repos with " |
1390 b"--dir can only be used on repos with " |
1387 b"treemanifest enabled" |
1391 b"treemanifest enabled" |
1388 ) |
1392 ) |
1389 ) |
1393 ) |
1405 if isinstance(r, revlog.revlog): |
1409 if isinstance(r, revlog.revlog): |
1406 pass |
1410 pass |
1407 elif util.safehasattr(r, b'_revlog'): |
1411 elif util.safehasattr(r, b'_revlog'): |
1408 r = r._revlog # pytype: disable=attribute-error |
1412 r = r._revlog # pytype: disable=attribute-error |
1409 elif r is not None: |
1413 elif r is not None: |
1410 raise error.Abort(_(b'%r does not appear to be a revlog') % r) |
1414 raise error.InputError( |
|
1415 _(b'%r does not appear to be a revlog') % r |
|
1416 ) |
1411 |
1417 |
1412 if not r: |
1418 if not r: |
1413 if not returnrevlog: |
1419 if not returnrevlog: |
1414 raise error.Abort(_(b'cannot give path to non-revlog')) |
1420 raise error.InputError(_(b'cannot give path to non-revlog')) |
1415 |
1421 |
1416 if not file_: |
1422 if not file_: |
1417 raise error.CommandError(cmd, _(b'invalid arguments')) |
1423 raise error.CommandError(cmd, _(b'invalid arguments')) |
1418 if not os.path.isfile(file_): |
1424 if not os.path.isfile(file_): |
1419 raise error.Abort(_(b"revlog '%s' not found") % file_) |
1425 raise error.InputError(_(b"revlog '%s' not found") % file_) |
1420 r = revlog.revlog( |
1426 r = revlog.revlog( |
1421 vfsmod.vfs(encoding.getcwd(), audit=False), file_[:-2] + b".i" |
1427 vfsmod.vfs(encoding.getcwd(), audit=False), file_[:-2] + b".i" |
1422 ) |
1428 ) |
1423 return r |
1429 return r |
1424 |
1430 |
1451 rev = opts.get(b'at_rev') |
1457 rev = opts.get(b'at_rev') |
1452 if rev: |
1458 if rev: |
1453 if not forget and not after: |
1459 if not forget and not after: |
1454 # TODO: Remove this restriction and make it also create the copy |
1460 # TODO: Remove this restriction and make it also create the copy |
1455 # targets (and remove the rename source if rename==True). |
1461 # targets (and remove the rename source if rename==True). |
1456 raise error.Abort(_(b'--at-rev requires --after')) |
1462 raise error.InputError(_(b'--at-rev requires --after')) |
1457 ctx = scmutil.revsingle(repo, rev) |
1463 ctx = scmutil.revsingle(repo, rev) |
1458 if len(ctx.parents()) > 1: |
1464 if len(ctx.parents()) > 1: |
1459 raise error.Abort(_(b'cannot mark/unmark copy in merge commit')) |
1465 raise error.InputError( |
|
1466 _(b'cannot mark/unmark copy in merge commit') |
|
1467 ) |
1460 else: |
1468 else: |
1461 ctx = repo[None] |
1469 ctx = repo[None] |
1462 |
1470 |
1463 pctx = ctx.p1() |
1471 pctx = ctx.p1() |
1464 |
1472 |
1467 if forget: |
1475 if forget: |
1468 if ctx.rev() is None: |
1476 if ctx.rev() is None: |
1469 new_ctx = ctx |
1477 new_ctx = ctx |
1470 else: |
1478 else: |
1471 if len(ctx.parents()) > 1: |
1479 if len(ctx.parents()) > 1: |
1472 raise error.Abort(_(b'cannot unmark copy in merge commit')) |
1480 raise error.InputError(_(b'cannot unmark copy in merge commit')) |
1473 # avoid cycle context -> subrepo -> cmdutil |
1481 # avoid cycle context -> subrepo -> cmdutil |
1474 from . import context |
1482 from . import context |
1475 |
1483 |
1476 rewriteutil.precheck(repo, [ctx.rev()], b'uncopy') |
1484 rewriteutil.precheck(repo, [ctx.rev()], b'uncopy') |
1477 new_ctx = context.overlayworkingctx(repo) |
1485 new_ctx = context.overlayworkingctx(repo) |
1552 |
1560 |
1553 if ctx.rev() is not None: |
1561 if ctx.rev() is not None: |
1554 rewriteutil.precheck(repo, [ctx.rev()], b'uncopy') |
1562 rewriteutil.precheck(repo, [ctx.rev()], b'uncopy') |
1555 absdest = pathutil.canonpath(repo.root, cwd, dest) |
1563 absdest = pathutil.canonpath(repo.root, cwd, dest) |
1556 if ctx.hasdir(absdest): |
1564 if ctx.hasdir(absdest): |
1557 raise error.Abort( |
1565 raise error.InputError( |
1558 _(b'%s: --at-rev does not support a directory as destination') |
1566 _(b'%s: --at-rev does not support a directory as destination') |
1559 % uipathfn(absdest) |
1567 % uipathfn(absdest) |
1560 ) |
1568 ) |
1561 if absdest not in ctx: |
1569 if absdest not in ctx: |
1562 raise error.Abort( |
1570 raise error.InputError( |
1563 _(b'%s: copy destination does not exist in %s') |
1571 _(b'%s: copy destination does not exist in %s') |
1564 % (uipathfn(absdest), ctx) |
1572 % (uipathfn(absdest), ctx) |
1565 ) |
1573 ) |
1566 |
1574 |
1567 # avoid cycle context -> subrepo -> cmdutil |
1575 # avoid cycle context -> subrepo -> cmdutil |
1574 continue |
1582 continue |
1575 for abs, rel, exact in srcs: |
1583 for abs, rel, exact in srcs: |
1576 copylist.append(abs) |
1584 copylist.append(abs) |
1577 |
1585 |
1578 if not copylist: |
1586 if not copylist: |
1579 raise error.Abort(_(b'no files to copy')) |
1587 raise error.InputError(_(b'no files to copy')) |
1580 # TODO: Add support for `hg cp --at-rev . foo bar dir` and |
1588 # TODO: Add support for `hg cp --at-rev . foo bar dir` and |
1581 # `hg cp --at-rev . dir1 dir2`, preferably unifying the code with the |
1589 # `hg cp --at-rev . dir1 dir2`, preferably unifying the code with the |
1582 # existing functions below. |
1590 # existing functions below. |
1583 if len(copylist) != 1: |
1591 if len(copylist) != 1: |
1584 raise error.Abort(_(b'--at-rev requires a single source')) |
1592 raise error.InputError(_(b'--at-rev requires a single source')) |
1585 |
1593 |
1586 new_ctx = context.overlayworkingctx(repo) |
1594 new_ctx = context.overlayworkingctx(repo) |
1587 new_ctx.setbase(ctx.p1()) |
1595 new_ctx.setbase(ctx.p1()) |
1588 mergemod.graft(repo, ctx, wctx=new_ctx) |
1596 mergemod.graft(repo, ctx, wctx=new_ctx) |
1589 |
1597 |
1807 return res |
1815 return res |
1808 |
1816 |
1809 destdirexists = os.path.isdir(dest) and not os.path.islink(dest) |
1817 destdirexists = os.path.isdir(dest) and not os.path.islink(dest) |
1810 if not destdirexists: |
1818 if not destdirexists: |
1811 if len(pats) > 1 or matchmod.patkind(pats[0]): |
1819 if len(pats) > 1 or matchmod.patkind(pats[0]): |
1812 raise error.Abort( |
1820 raise error.InputError( |
1813 _( |
1821 _( |
1814 b'with multiple sources, destination must be an ' |
1822 b'with multiple sources, destination must be an ' |
1815 b'existing directory' |
1823 b'existing directory' |
1816 ) |
1824 ) |
1817 ) |
1825 ) |
1818 if util.endswithsep(dest): |
1826 if util.endswithsep(dest): |
1819 raise error.Abort(_(b'destination %s is not a directory') % dest) |
1827 raise error.InputError( |
|
1828 _(b'destination %s is not a directory') % dest |
|
1829 ) |
1820 |
1830 |
1821 tfn = targetpathfn |
1831 tfn = targetpathfn |
1822 if after: |
1832 if after: |
1823 tfn = targetpathafterfn |
1833 tfn = targetpathafterfn |
1824 copylist = [] |
1834 copylist = [] |
1826 srcs = walkpat(pat) |
1836 srcs = walkpat(pat) |
1827 if not srcs: |
1837 if not srcs: |
1828 continue |
1838 continue |
1829 copylist.append((tfn(pat, dest, srcs), srcs)) |
1839 copylist.append((tfn(pat, dest, srcs), srcs)) |
1830 if not copylist: |
1840 if not copylist: |
1831 raise error.Abort(_(b'no files to copy')) |
1841 raise error.InputError(_(b'no files to copy')) |
1832 |
1842 |
1833 errors = 0 |
1843 errors = 0 |
1834 for targetpath, srcs in copylist: |
1844 for targetpath, srcs in copylist: |
1835 for abssrc, relsrc, exact in srcs: |
1845 for abssrc, relsrc, exact in srcs: |
1836 if copyfile(abssrc, relsrc, targetpath(abssrc), exact): |
1846 if copyfile(abssrc, relsrc, targetpath(abssrc), exact): |
1917 |
1927 |
1918 if len(parents) == 1: |
1928 if len(parents) == 1: |
1919 parents.append(repo[nullid]) |
1929 parents.append(repo[nullid]) |
1920 if opts.get(b'exact'): |
1930 if opts.get(b'exact'): |
1921 if not nodeid or not p1: |
1931 if not nodeid or not p1: |
1922 raise error.Abort(_(b'not a Mercurial patch')) |
1932 raise error.InputError(_(b'not a Mercurial patch')) |
1923 p1 = repo[p1] |
1933 p1 = repo[p1] |
1924 p2 = repo[p2 or nullid] |
1934 p2 = repo[p2 or nullid] |
1925 elif p2: |
1935 elif p2: |
1926 try: |
1936 try: |
1927 p1 = repo[p1] |
1937 p1 = repo[p1] |
2253 """Find the tipmost changeset that matches the given date spec""" |
2263 """Find the tipmost changeset that matches the given date spec""" |
2254 mrevs = repo.revs(b'date(%s)', date) |
2264 mrevs = repo.revs(b'date(%s)', date) |
2255 try: |
2265 try: |
2256 rev = mrevs.max() |
2266 rev = mrevs.max() |
2257 except ValueError: |
2267 except ValueError: |
2258 raise error.Abort(_(b"revision matching date not found")) |
2268 raise error.InputError(_(b"revision matching date not found")) |
2259 |
2269 |
2260 ui.status( |
2270 ui.status( |
2261 _(b"found revision %d from %s\n") |
2271 _(b"found revision %d from %s\n") |
2262 % (rev, dateutil.datestr(repo[rev].date())) |
2272 % (rev, dateutil.datestr(repo[rev].date())) |
2263 ) |
2273 ) |
2336 |
2346 |
2337 def forget( |
2347 def forget( |
2338 ui, repo, match, prefix, uipathfn, explicitonly, dryrun, interactive |
2348 ui, repo, match, prefix, uipathfn, explicitonly, dryrun, interactive |
2339 ): |
2349 ): |
2340 if dryrun and interactive: |
2350 if dryrun and interactive: |
2341 raise error.Abort(_(b"cannot specify both --dry-run and --interactive")) |
2351 raise error.InputError( |
|
2352 _(b"cannot specify both --dry-run and --interactive") |
|
2353 ) |
2342 bad = [] |
2354 bad = [] |
2343 badfn = lambda x, y: bad.append(x) or match.bad(x, y) |
2355 badfn = lambda x, y: bad.append(x) or match.bad(x, y) |
2344 wctx = repo[None] |
2356 wctx = repo[None] |
2345 forgot = [] |
2357 forgot = [] |
2346 |
2358 |
3048 os.chdir(olddir) |
3060 os.chdir(olddir) |
3049 |
3061 |
3050 if finishdesc: |
3062 if finishdesc: |
3051 text = finishdesc(text) |
3063 text = finishdesc(text) |
3052 if not text.strip(): |
3064 if not text.strip(): |
3053 raise error.Abort(_(b"empty commit message")) |
3065 raise error.InputError(_(b"empty commit message")) |
3054 if unchangedmessagedetection and editortext == templatetext: |
3066 if unchangedmessagedetection and editortext == templatetext: |
3055 raise error.Abort(_(b"commit message unchanged")) |
3067 raise error.InputError(_(b"commit message unchanged")) |
3056 |
3068 |
3057 return text |
3069 return text |
3058 |
3070 |
3059 |
3071 |
3060 def buildcommittemplate(repo, ctx, subs, extramsg, ref): |
3072 def buildcommittemplate(repo, ctx, subs, extramsg, ref): |