# HG changeset patch # User Martin von Zweigbergk # Date 1576885813 28800 # Node ID 8be0c63535b5d41093bc41375420cb85cf1e7440 # Parent f7459da77f234502a2a4b1ce8523cc1886442f54 copy: add option to unmark file as copied To unmark a file as copied, the user currently has to do this: hg forget hg add The new command simplifies that to: hg copy --forget That's not a very big improvement, but I'm planning to also teach `hg copy [--forget]` a `--at-rev` argument for marking/unmarking copies after commit (usually with `--at-rev .`). Differential Revision: https://phab.mercurial-scm.org/D8029 diff -r f7459da77f23 -r 8be0c63535b5 mercurial/cmdutil.py --- a/mercurial/cmdutil.py Tue Feb 11 11:18:52 2020 +0100 +++ b/mercurial/cmdutil.py Fri Dec 20 15:50:13 2019 -0800 @@ -1410,12 +1410,15 @@ def copy(ui, repo, pats, opts, rename=False): + check_incompatible_arguments(opts, b'forget', [b'dry_run']) + # called with the repo lock held # # hgsep => pathname that uses "/" to separate directories # ossep => pathname that uses os.sep to separate directories cwd = repo.getcwd() targets = {} + forget = opts.get(b"forget") after = opts.get(b"after") dryrun = opts.get(b"dry_run") ctx = repo[None] @@ -1423,6 +1426,24 @@ 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): + if f in current_copies: + wctx[f].markcopied(None) + elif match.exact(f): + ui.warn( + _( + b'%s: not unmarking as copy - file is not marked as copied\n' + ) + % uipathfn(f) + ) + return + def walkpat(pat): srcs = [] m = scmutil.match(ctx, [pat], opts, globbed=True) diff -r f7459da77f23 -r 8be0c63535b5 mercurial/commands.py --- a/mercurial/commands.py Tue Feb 11 11:18:52 2020 +0100 +++ b/mercurial/commands.py Fri Dec 20 15:50:13 2019 -0800 @@ -2309,6 +2309,7 @@ @command( b'copy|cp', [ + (b'', b'forget', None, _(b'unmark a file as copied')), (b'A', b'after', None, _(b'record a copy that has already occurred')), ( b'f', @@ -2333,8 +2334,11 @@ exist in the working directory. If invoked with -A/--after, the operation is recorded, but no copying is performed. - This command takes effect with the next commit. To undo a copy - before that, see :hg:`revert`. + To undo marking a file as copied, use --forget. With that option, + all given (positional) arguments are unmarked as copies. The destination + file(s) will be left in place (still tracked). + + This command takes effect with the next commit. Returns 0 on success, 1 if errors are encountered. """ diff -r f7459da77f23 -r 8be0c63535b5 relnotes/next --- a/relnotes/next Tue Feb 11 11:18:52 2020 +0100 +++ b/relnotes/next Fri Dec 20 15:50:13 2019 -0800 @@ -12,6 +12,8 @@ commits that are being merged, when there are conflicts. Also works for conflicts caused by e.g. `hg graft`. + * `hg copy --forget` can be used to unmark a file as copied. + == New Experimental Features == diff -r f7459da77f23 -r 8be0c63535b5 tests/test-completion.t --- a/tests/test-completion.t Tue Feb 11 11:18:52 2020 +0100 +++ b/tests/test-completion.t Fri Dec 20 15:50:13 2019 -0800 @@ -257,7 +257,7 @@ commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos config: untrusted, edit, local, global, template continue: dry-run - copy: after, force, include, exclude, dry-run + copy: forget, after, force, include, exclude, dry-run debugancestor: debugapplystreamclonebundle: debugbuilddag: mergeable-file, overwritten-file, new-file diff -r f7459da77f23 -r 8be0c63535b5 tests/test-copy.t --- a/tests/test-copy.t Tue Feb 11 11:18:52 2020 +0100 +++ b/tests/test-copy.t Fri Dec 20 15:50:13 2019 -0800 @@ -262,5 +262,62 @@ xyzzy: not overwriting - file exists ('hg copy --after' to record the copy) [1] + $ hg co -qC . + $ rm baz xyzzy + + +Test unmarking copy of a single file + +# Set up by creating a copy + $ hg cp bar baz +# Test uncopying a non-existent file + $ hg copy --forget non-existent + non-existent: $ENOENT$ +# Test uncopying an tracked but unrelated file + $ hg copy --forget foo + foo: not unmarking as copy - file is not marked as copied +# Test uncopying a copy source + $ hg copy --forget bar + bar: not unmarking as copy - file is not marked as copied +# baz should still be marked as a copy + $ hg st -C + A baz + bar +# Test the normal case + $ hg copy --forget baz + $ hg st -C + A baz +# Test uncopy with matching an non-matching patterns + $ hg cp bar baz --after + $ hg copy --forget bar baz + bar: not unmarking as copy - file is not marked as copied + $ hg st -C + A baz +# Test uncopy with no exact matches + $ hg cp bar baz --after + $ hg copy --forget . + $ hg st -C + A baz + $ hg forget baz + $ rm baz + +Test unmarking copy of a directory + + $ mkdir dir + $ echo foo > dir/foo + $ echo bar > dir/bar + $ hg add dir + adding dir/bar + adding dir/foo + $ hg ci -m 'add dir/' + $ hg cp dir dir2 + copying dir/bar to dir2/bar + copying dir/foo to dir2/foo + $ touch dir2/untracked + $ hg copy --forget dir2 + $ hg st -C + A dir2/bar + A dir2/foo + ? dir2/untracked $ cd ..