mercurial/cmdutil.py
changeset 44367 9dab3fa64325
parent 44366 d8b49bf6cfec
child 44374 f5c006621f07
equal deleted inserted replaced
44366:d8b49bf6cfec 44367:9dab3fa64325
  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):