Mercurial > public > mercurial-scm > hg-stable
diff mercurial/cmdutil.py @ 44399:7c4b98a4e536
copy: add experimetal support for unmarking committed copies
The simplest way I'm aware of to unmark a file as copied after
committing is this:
hg uncommit --keep <dest>
hg forget <dest>
hg add <dest>
hg amend
This patch teaches `hg copy --forget` a `-r` argument to simplify that into:
hg copy --forget --at-rev . <dest>
In addition to being simpler, it doesn't touch the working copy, so it
can easily be used even if the destination file has been modified in
the working copy.
I'll teach `hg copy` without `--forget` to work with `--at-rev` next.
Differential Revision: https://phab.mercurial-scm.org/D8030
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Tue, 28 Jan 2020 14:07:57 -0800 |
parents | 8be0c63535b5 |
children | d8b49bf6cfec |
line wrap: on
line diff
--- a/mercurial/cmdutil.py Fri Dec 20 15:50:13 2019 -0800 +++ b/mercurial/cmdutil.py Tue Jan 28 14:07:57 2020 -0800 @@ -1427,14 +1427,33 @@ uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True) if forget: - match = scmutil.match(wctx, pats, opts) - - current_copies = wctx.p1copies() - current_copies.update(wctx.p2copies()) - - for f in wctx.walk(match): + rev = opts[b'at_rev'] + if rev: + ctx = scmutil.revsingle(repo, rev) + else: + ctx = repo[None] + if ctx.rev() is None: + new_ctx = ctx + else: + if len(ctx.parents()) > 1: + raise error.Abort(_(b'cannot unmark copy in merge commit')) + # avoid cycle context -> subrepo -> cmdutil + from . import context + + rewriteutil.precheck(repo, [ctx.rev()], b'uncopy') + new_ctx = context.overlayworkingctx(repo) + new_ctx.setbase(ctx.p1()) + mergemod.graft(repo, ctx, wctx=new_ctx) + + match = scmutil.match(ctx, pats, opts) + + current_copies = ctx.p1copies() + current_copies.update(ctx.p2copies()) + + uipathfn = scmutil.getuipathfn(repo) + for f in ctx.walk(match): if f in current_copies: - wctx[f].markcopied(None) + new_ctx[f].markcopied(None) elif match.exact(f): ui.warn( _( @@ -1442,8 +1461,25 @@ ) % uipathfn(f) ) + + if ctx.rev() is not None: + with repo.lock(): + mem_ctx = new_ctx.tomemctx_for_amend(ctx) + new_node = mem_ctx.commit() + + if repo.dirstate.p1() == ctx.node(): + with repo.dirstate.parentchange(): + scmutil.movedirstate(repo, repo[new_node]) + replacements = {ctx.node(): [new_node]} + scmutil.cleanupnodes( + repo, replacements, b'uncopy', fixphase=True + ) + return + if opts.get(b'at_rev'): + raise error.Abort(_("--at-rev is only supported with --forget")) + def walkpat(pat): srcs = [] m = scmutil.match(ctx, [pat], opts, globbed=True)