Patchwork D8029: uncopy: add new `hg uncopy` command

login
register
mail settings
Submitter phabricator
Date Jan. 30, 2020, 5:09 p.m.
Message ID <e70be31d3c167a46d2b02c906aee853e@localhost.localdomain>
Download mbox | patch
Permalink /patch/44793/
State Not Applicable
Headers show

Comments

phabricator - Jan. 30, 2020, 5:09 p.m.
martinvonz updated this revision to Diff 19725.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8029?vs=19692&id=19725

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8029/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8029

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  relnotes/next
  tests/test-completion.t
  tests/test-copy.t
  tests/test-globalopts.t
  tests/test-help-hide.t
  tests/test-help.t
  tests/test-hgweb-json.t

CHANGE DETAILS




To: martinvonz, #hg-reviewers, durin42
Cc: pulkit, durin42, marmoute, mercurial-devel

Patch

diff --git a/tests/test-hgweb-json.t b/tests/test-hgweb-json.t
--- a/tests/test-hgweb-json.t
+++ b/tests/test-hgweb-json.t
@@ -2226,6 +2226,10 @@ 
         "topic": "unbundle"
       },
       {
+        "summary": "unmark files as copied",
+        "topic": "uncopy"
+      },
+      {
         "summary": "restore a shelved change to the working directory",
         "topic": "unshelve"
       },
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -93,6 +93,7 @@ 
    copy          mark files as copied for the next commit
    diff          diff repository (or selected files)
    grep          search for a pattern in specified files
+   uncopy        unmark files as copied
   
   Change navigation:
   
@@ -221,6 +222,7 @@ 
    copy          mark files as copied for the next commit
    diff          diff repository (or selected files)
    grep          search for a pattern in specified files
+   uncopy        unmark files as copied
   
   Change navigation:
   
@@ -2754,6 +2756,13 @@ 
   apply one or more bundle files
   </td></tr>
   <tr><td>
+  <a href="/help/uncopy">
+  uncopy
+  </a>
+  </td><td>
+  unmark files as copied
+  </td></tr>
+  <tr><td>
   <a href="/help/unshelve">
   unshelve
   </a>
diff --git a/tests/test-help-hide.t b/tests/test-help-hide.t
--- a/tests/test-help-hide.t
+++ b/tests/test-help-hide.t
@@ -41,6 +41,7 @@ 
    copy          mark files as copied for the next commit
    diff          diff repository (or selected files)
    grep          search for a pattern in specified files
+   uncopy        unmark files as copied
   
   Change navigation:
   
@@ -177,6 +178,7 @@ 
    copy          mark files as copied for the next commit
    diff          diff repository (or selected files)
    grep          search for a pattern in specified files
+   uncopy        unmark files as copied
   
   Change navigation:
   
diff --git a/tests/test-globalopts.t b/tests/test-globalopts.t
--- a/tests/test-globalopts.t
+++ b/tests/test-globalopts.t
@@ -337,6 +337,7 @@ 
    copy          mark files as copied for the next commit
    diff          diff repository (or selected files)
    grep          search for a pattern in specified files
+   uncopy        unmark files as copied
   
   Change navigation:
   
@@ -469,6 +470,7 @@ 
    copy          mark files as copied for the next commit
    diff          diff repository (or selected files)
    grep          search for a pattern in specified files
+   uncopy        unmark files as copied
   
   Change navigation:
   
diff --git a/tests/test-copy.t b/tests/test-copy.t
--- a/tests/test-copy.t
+++ b/tests/test-copy.t
@@ -262,5 +262,62 @@ 
   xyzzy: not overwriting - file exists
   ('hg copy --after' to record the copy)
   [1]
+  $ hg co -qC .
+  $ rm baz xyzzy
+
+
+Test uncopy of a single file
+
+# Set up by creating a copy
+  $ hg cp bar baz
+# Test uncopying a non-existent file
+  $ hg uncopy non-existent
+  non-existent: $ENOENT$
+# Test uncopying an tracked but unrelated file
+  $ hg uncopy foo
+  foo: not uncopying - file is not marked as copied
+# Test uncopying a copy source
+  $ hg uncopy bar
+  bar: not uncopying - 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 uncopy baz
+  $ hg st -C
+  A baz
+# Test uncopy with matching an non-matching patterns
+  $ hg cp bar baz --after
+  $ hg uncopy bar baz
+  bar: not uncopying - file is not marked as copied
+  $ hg st -C
+  A baz
+# Test uncopy with no exact matches
+  $ hg cp bar baz --after
+  $ hg uncopy .
+  $ hg st -C
+  A baz
+  $ hg forget baz
+  $ rm baz
+
+Test uncopy 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 uncopy dir2
+  $ hg st -C
+  A dir2/bar
+  A dir2/foo
+  ? dir2/untracked
 
   $ cd ..
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -54,6 +54,7 @@ 
   tags
   tip
   unbundle
+  uncopy
   unshelve
   update
   verify
@@ -356,6 +357,7 @@ 
   tags: template
   tip: patch, git, style, template
   unbundle: update
+  uncopy: include, exclude
   unshelve: abort, continue, interactive, keep, name, tool, date
   update: clean, check, merge, date, rev, tool
   verify: full
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -1,5 +1,7 @@ 
 == New Features ==
 
+ * `hg uncopy` can be used to unmark a file as copied.
+
 
 == New Experimental Features ==
 
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -7494,6 +7494,26 @@ 
 
 
 @command(
+    b'uncopy',
+    walkopts,
+    _(b'[OPTION]... DEST...'),
+    helpcategory=command.CATEGORY_FILE_CONTENTS,
+)
+def uncopy(ui, repo, *pats, **opts):
+    """unmark files as copied
+
+    Unmark DEST as having copies of source files.
+
+    This command takes effect with the next commit.
+
+    Returns 0 on success, 1 if errors are encountered.
+    """
+    opts = pycompat.byteskwargs(opts)
+    with repo.wlock(False):
+        return cmdutil.uncopy(ui, repo, pats, opts)
+
+
+@command(
     b'unshelve',
     [
         (b'a', b'abort', None, _(b'abort an incomplete unshelve operation')),
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1694,6 +1694,25 @@ 
     return errors != 0
 
 
+def uncopy(ui, repo, pats, opts):
+    ctx = repo[None]
+
+    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:
+            ctx[f].markcopied(None)
+        elif match.exact(f):
+            ui.warn(
+                _(b'%s: not uncopying - file is not marked as copied\n')
+                % uipathfn(f)
+            )
+
+
 ## facility to let extension process additional data into an import patch
 # list of identifier to be executed in order
 extrapreimport = []  # run before commit