1419 cwd = repo.getcwd() |
1419 cwd = repo.getcwd() |
1420 targets = {} |
1420 targets = {} |
1421 forget = opts.get(b"forget") |
1421 forget = opts.get(b"forget") |
1422 after = opts.get(b"after") |
1422 after = opts.get(b"after") |
1423 dryrun = opts.get(b"dry_run") |
1423 dryrun = opts.get(b"dry_run") |
1424 ctx = repo[None] |
1424 rev = opts.get(b'at_rev') |
|
1425 if rev: |
|
1426 if not forget and not after: |
|
1427 # TODO: Remove this restriction and make it also create the copy |
|
1428 # targets (and remove the rename source if rename==True). |
|
1429 raise error.Abort(_(b'--at-rev requires --after')) |
|
1430 ctx = scmutil.revsingle(repo, rev) |
|
1431 if len(ctx.parents()) > 1: |
|
1432 raise error.Abort(_(b'cannot mark/unmark copy in merge commit')) |
|
1433 else: |
|
1434 ctx = repo[None] |
|
1435 |
1425 pctx = ctx.p1() |
1436 pctx = ctx.p1() |
1426 |
1437 |
1427 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) |
1438 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) |
1428 |
1439 |
1429 if forget: |
1440 if forget: |
1430 rev = opts[b'at_rev'] |
|
1431 if rev: |
|
1432 ctx = scmutil.revsingle(repo, rev) |
|
1433 else: |
|
1434 ctx = repo[None] |
|
1435 if ctx.rev() is None: |
1441 if ctx.rev() is None: |
1436 new_ctx = ctx |
1442 new_ctx = ctx |
1437 else: |
1443 else: |
1438 if len(ctx.parents()) > 1: |
1444 if len(ctx.parents()) > 1: |
1439 raise error.Abort(_(b'cannot unmark copy in merge commit')) |
1445 raise error.Abort(_(b'cannot unmark copy in merge commit')) |
1481 if not pats: |
1487 if not pats: |
1482 raise error.Abort(_(b'no source or destination specified')) |
1488 raise error.Abort(_(b'no source or destination specified')) |
1483 if len(pats) == 1: |
1489 if len(pats) == 1: |
1484 raise error.Abort(_(b'no destination specified')) |
1490 raise error.Abort(_(b'no destination specified')) |
1485 dest = pats.pop() |
1491 dest = pats.pop() |
1486 |
|
1487 if opts.get(b'at_rev'): |
|
1488 raise error.Abort(_("--at-rev is only supported with --forget")) |
|
1489 |
1492 |
1490 def walkpat(pat): |
1493 def walkpat(pat): |
1491 srcs = [] |
1494 srcs = [] |
1492 m = scmutil.match(ctx, [pat], opts, globbed=True) |
1495 m = scmutil.match(ctx, [pat], opts, globbed=True) |
1493 for abs in ctx.walk(m): |
1496 for abs in ctx.walk(m): |
1514 |
1517 |
1515 # abs: hgsep |
1518 # abs: hgsep |
1516 # rel: ossep |
1519 # rel: ossep |
1517 srcs.append((abs, rel, exact)) |
1520 srcs.append((abs, rel, exact)) |
1518 return srcs |
1521 return srcs |
|
1522 |
|
1523 if ctx.rev() is not None: |
|
1524 rewriteutil.precheck(repo, [ctx.rev()], b'uncopy') |
|
1525 absdest = pathutil.canonpath(repo.root, cwd, dest) |
|
1526 if ctx.hasdir(absdest): |
|
1527 raise error.Abort( |
|
1528 _(b'%s: --at-rev does not support a directory as destination') |
|
1529 % uipathfn(absdest) |
|
1530 ) |
|
1531 if absdest not in ctx: |
|
1532 raise error.Abort( |
|
1533 _(b'%s: copy destination does not exist in %s') |
|
1534 % (uipathfn(absdest), ctx) |
|
1535 ) |
|
1536 |
|
1537 # avoid cycle context -> subrepo -> cmdutil |
|
1538 from . import context |
|
1539 |
|
1540 copylist = [] |
|
1541 for pat in pats: |
|
1542 srcs = walkpat(pat) |
|
1543 if not srcs: |
|
1544 continue |
|
1545 for abs, rel, exact in srcs: |
|
1546 copylist.append(abs) |
|
1547 |
|
1548 # TODO: Add support for `hg cp --at-rev . foo bar dir` and |
|
1549 # `hg cp --at-rev . dir1 dir2`, preferably unifying the code with the |
|
1550 # existing functions below. |
|
1551 if len(copylist) != 1: |
|
1552 raise error.Abort(_(b'--at-rev requires a single source')) |
|
1553 |
|
1554 new_ctx = context.overlayworkingctx(repo) |
|
1555 new_ctx.setbase(ctx.p1()) |
|
1556 mergemod.graft(repo, ctx, wctx=new_ctx) |
|
1557 |
|
1558 new_ctx.markcopied(absdest, copylist[0]) |
|
1559 |
|
1560 with repo.lock(): |
|
1561 mem_ctx = new_ctx.tomemctx_for_amend(ctx) |
|
1562 new_node = mem_ctx.commit() |
|
1563 |
|
1564 if repo.dirstate.p1() == ctx.node(): |
|
1565 with repo.dirstate.parentchange(): |
|
1566 scmutil.movedirstate(repo, repo[new_node]) |
|
1567 replacements = {ctx.node(): [new_node]} |
|
1568 scmutil.cleanupnodes(repo, replacements, b'copy', fixphase=True) |
|
1569 |
|
1570 return |
1519 |
1571 |
1520 # abssrc: hgsep |
1572 # abssrc: hgsep |
1521 # relsrc: ossep |
1573 # relsrc: ossep |
1522 # otarget: ossep |
1574 # otarget: ossep |
1523 def copyfile(abssrc, relsrc, otarget, exact): |
1575 def copyfile(abssrc, relsrc, otarget, exact): |