[PATCH v4] copy: distinguish "file exists" cases and add a hint (BC)

Augie Fackler raf at durin42.com
Tue Sep 27 21:33:09 UTC 2016


# HG changeset patch
# User Augie Fackler <augie at google.com>
# Date 1474319739 14400
#      Mon Sep 19 17:15:39 2016 -0400
# Node ID db1ec3971aa0ad8cee1db87465195d10e75bbb71
# Parent  e83f89d3b1f733d0ee5f23f6a2293279a17fbbfb
copy: distinguish "file exists" cases and add a hint (BC)

Users that want to add a copy record to an existing commit with 'hg
commit --amend' should be guided towards this workflow, rather than
reaching for some sort of uncommit-recommit flow. As part of this,
distinguish in the top-line error message whether the file merely
already exists (untracked) on disk or the file already exists in
history.

The full list of copy and rename cases and how they interact with
flags are listed below:

+-------------+------------+--------------+
|             |            |              |
|             | replace    |  preserve    |
|             | dest.      |  dest.       |
|             | contents   |  contents    |
|             |            |              |
+-------------+------------+--------------+
|             |            |              |
| dest        |            |  --after     |
| doesn't     | [no flags] | [an error]   |
| exist       |            |              |
+-------------+------------+--------------+
|             |            |              |
| dest. exists|            |              |
| but is not  | --force    | --after      |
| tracked     |            |              |
|             |            |              |
+-------------+------------+--------------+
|             |            |              |
| dest exists |            |              |
| and is      | --force    | --after      |
| tracked     |            | --force      |
|             |            |              |
+-------------+------------+--------------+

I think this change gets the hints correct in all cases, but I'd
appreciate close inspection of the test cases to make sure I haven't
gotten turned around in here.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -640,8 +640,26 @@ def copy(ui, repo, pats, opts, rename=Fa
 
         if not after and exists or after and state in 'mn':
             if not opts['force']:
-                ui.warn(_('%s: not overwriting - file exists\n') %
-                        reltarget)
+                if state in 'mn':
+                    msg = _('%s: not overwriting - file already committed\n')
+                    if after:
+                        flags = '--after --force'
+                    else:
+                        flags = '--force'
+                    if rename:
+                        hint = _('(hg rename %s to replace the file by '
+                                 'recording a rename)\n') % flags
+                    else:
+                        hint = _('(hg copy %s to replace the file by '
+                                 'recording a copy)\n') % flags
+                else:
+                    msg = _('%s: not overwriting - file exists\n')
+                    if rename:
+                        hint = _('(hg rename --after to record the rename)\n')
+                    else:
+                        hint = _('(hg copy --after to record the copy)\n')
+                ui.warn(msg % reltarget)
+                ui.warn(hint)
                 return
 
         if after:
diff --git a/tests/test-copy.t b/tests/test-copy.t
--- a/tests/test-copy.t
+++ b/tests/test-copy.t
@@ -226,11 +226,23 @@ foo was clean:
   C foo
 Trying to copy on top of an existing file fails,
   $ hg copy -A bar foo
-  foo: not overwriting - file exists
+  foo: not overwriting - file already committed
+  (hg copy --after --force to replace the file by recording a copy)
+same error without the --after, so the user doesn't have to go through
+two hints:
+  $ hg copy bar foo
+  foo: not overwriting - file already committed
+  (hg copy --force to replace the file by recording a copy)
 but it's considered modified after a copy --after --force
   $ hg copy -Af bar foo
   $ hg st -AC foo
   M foo
     bar
+The hint for a file that exists but is not in file history doesn't
+mention --force:
+  $ touch xyzzy
+  $ hg cp bar xyzzy
+  xyzzy: not overwriting - file exists
+  (hg copy --after to record the copy)
 
   $ cd ..
diff --git a/tests/test-rename.t b/tests/test-rename.t
--- a/tests/test-rename.t
+++ b/tests/test-rename.t
@@ -265,7 +265,8 @@ move everything under directory d1 to ex
 overwrite existing files (d2/b)
 
   $ hg rename d1/* d2
-  d2/b: not overwriting - file exists
+  d2/b: not overwriting - file already committed
+  (hg rename --force to replace the file by recording a rename)
   moving d1/d11/a1 to d2/d11/a1 (glob)
   $ hg status -C
   A d2/a
@@ -370,6 +371,7 @@ attempt to overwrite an existing file
   $ echo "ca" > d1/ca
   $ hg rename d1/ba d1/ca
   d1/ca: not overwriting - file exists
+  (hg rename --after to record the rename)
   $ hg status -C
   ? d1/ca
   $ hg update -C
@@ -393,6 +395,7 @@ attempt to overwrite an existing broken 
   $ ln -s ba d1/ca
   $ hg rename --traceback d1/ba d1/ca
   d1/ca: not overwriting - file exists
+  (hg rename --after to record the rename)
   $ hg status -C
   ? d1/ca
   $ hg update -C


More information about the Mercurial-devel mailing list