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

login
register
mail settings
Submitter Augie Fackler
Date Oct. 8, 2016, 5:11 p.m.
Message ID <3d6ce2e360155bcc7e5a.1475946706@augie-macbookair2.roam.corp.google.com>
Download mbox | patch
Permalink /patch/16957/
State Accepted
Headers show

Comments

Augie Fackler - Oct. 8, 2016, 5:11 p.m.
# HG changeset patch
# User Augie Fackler <augie@google.com>
# Date 1474319739 14400
#      Mon Sep 19 17:15:39 2016 -0400
# Node ID 3d6ce2e360155bcc7e5af21fd0fda3415aa03110
# Parent  dd0ff715a82caa9afd0fa999dccca4d967a506a3
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:

target exists  --after  --force  |  action
      n            n      *    |  copy
      n            y      *    |  (1)
  untracked        n      n    |  (4) NEWHINT
  untracked        n      y    |  (3)
  untracked        y      *    |  (2)
      y            n      n    |  (4) NEWHINT
      y            n      y    |  (3)
      y            y      n    |  (2)
      y            y      y    |  (3)
   deleted         n      n    |  copy
   deleted         n      y    |  (3)
   deleted         y      n    |  (1)
   deleted         y      y    |  (1)

* = don't care
(1) <src>: not recording move - <target> does not exist
(2) preserve target contents
(3) replace target contents
(4) <target>: not overwriting - file {exists,already committed}

Credit to Kevin for wholly rewriting my table to cover more cases we
discovered at the sprint.

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.
timeless - Oct. 26, 2016, 7:03 p.m.
Augie Fackler wrote:
> +                        hint = _('(hg rename %s to replace the file by '
> +                                 'recording a rename)\n') % flags
> +                        hint = _('(hg copy %s to replace the file by '
> +                                 'recording a copy)\n') % flags
> +                        hint = _('(hg rename --after to record the rename)\n')
> +                        hint = _('(hg copy --after to record the copy)\n')

I know it's too late, but do we want to include backticks around the
part that's a command?

Otherwise it's hard for people (and translators, and people reading
translations) to figure out what to do...
Augie Fackler - Oct. 26, 2016, 8:05 p.m.
> On Oct 26, 2016, at 15:03, timeless <timeless@gmail.com> wrote:
> 
> Augie Fackler wrote:
>> +                        hint = _('(hg rename %s to replace the file by '
>> +                                 'recording a rename)\n') % flags
>> +                        hint = _('(hg copy %s to replace the file by '
>> +                                 'recording a copy)\n') % flags
>> +                        hint = _('(hg rename --after to record the rename)\n')
>> +                        hint = _('(hg copy --after to record the copy)\n')
> 
> I know it's too late, but do we want to include backticks around the
> part that's a command?
> 
> Otherwise it's hard for people (and translators, and people reading
> translations) to figure out what to do...

If that's something we normally do, can you prep a patch to mail early in the 4.1 cycle? (This is just a hint, so we can change the hint text safely.)
Pierre-Yves David - Oct. 28, 2016, 8:58 a.m.
On 10/26/2016 10:10 PM, Kevin Bullock wrote:
>> On Oct 26, 2016, at 15:05, Augie Fackler <raf@durin42.com> wrote:
>>
>>> On Oct 26, 2016, at 15:03, timeless <timeless@gmail.com> wrote:
>>>
>>> Augie Fackler wrote:
>>>> +                        hint = _('(hg rename %s to replace the file by '
>>>> +                                 'recording a rename)\n') % flags
>>>> +                        hint = _('(hg copy %s to replace the file by '
>>>> +                                 'recording a copy)\n') % flags
>>>> +                        hint = _('(hg rename --after to record the rename)\n')
>>>> +                        hint = _('(hg copy --after to record the copy)\n')
>>>
>>> I know it's too late, but do we want to include backticks around the
>>> part that's a command?
>>>
>>> Otherwise it's hard for people (and translators, and people reading
>>> translations) to figure out what to do...
>>
>> If that's something we normally do, can you prep a patch to mail early in the 4.1 cycle? (This is just a hint, so we can change the hint text safely.)
>
> Changes to hint text should be fine during a freeze. No need to wait until November.

I can't remember what the exact policy have been in the past, but 
doesn't this change the translated string impacting the translator work 
during the freeze window ?

Cheers,
Pierre-Yves David - Oct. 29, 2016, 12:21 a.m.
On 10/28/2016 06:20 PM, Kevin Bullock wrote:
>> On Oct 28, 2016, at 03:58, Pierre-Yves David <pierre-yves.david@ens-lyon.org> wrote:
>>
>> On 10/26/2016 10:10 PM, Kevin Bullock wrote:
>>>> On Oct 26, 2016, at 15:05, Augie Fackler <raf@durin42.com> wrote:
>>>>
>>>>> On Oct 26, 2016, at 15:03, timeless <timeless@gmail.com> wrote:
>>>>>
>>>>> Augie Fackler wrote:
>>>>>> +                        hint = _('(hg rename %s to replace the file by '
>>>>>> +                                 'recording a rename)\n') % flags
>>>>>> +                        hint = _('(hg copy %s to replace the file by '
>>>>>> +                                 'recording a copy)\n') % flags
>>>>>> +                        hint = _('(hg rename --after to record the rename)\n')
>>>>>> +                        hint = _('(hg copy --after to record the copy)\n')
>>>>>
>>>>> I know it's too late, but do we want to include backticks around the
>>>>> part that's a command?
>>>>>
>>>>> Otherwise it's hard for people (and translators, and people reading
>>>>> translations) to figure out what to do...
>>>>
>>>> If that's something we normally do, can you prep a patch to mail early in the 4.1 cycle? (This is just a hint, so we can change the hint text safely.)
>>>
>>> Changes to hint text should be fine during a freeze. No need to wait until November.
>>
>> I can't remember what the exact policy have been in the past, but doesn't this change the translated string impacting the translator work during the freeze window ?
>
> I'm not totally clear on what our approach to translations during a freeze is either. I'm going by the freeze rules on the wiki, and the fact that translation always happens on stable anyway, both of which lead me to believe it should be okay?
>
> Last time this was discussed seems to be: <http://markmail.org/message/uka2mhpamqyvfsub>

Okay, I don't have a too strong opinion on this and I trust you will 
take the right decision. Worse case will have user or translator 
(hopefully) complaining and we'll adjust.

Cheers,
timeless - Nov. 4, 2016, 2:34 p.m.
Kevin Bullock wrote:
> I'm not totally clear on what our approach to translations during a freeze is either. I'm going by the freeze rules on the wiki, and the fact that translation always happens on stable anyway, both of which lead me to believe it should be okay?

We should probably clarify this.

Note that in other projects the normal approach is that at freeze,
conceptually all strings are sent to localizers, who can then take the
project-as-is-at-freeze-time and update translations, and then
asynchronously transmit their updates.

This means that if I change canonical, I've broken the translation system.

There are a number of ways to handle this, but it's worth
understanding (and documenting) how freezes should work for a project.

Pierre-Yves David wrote:
> Okay, I don't have a too strong opinion on this and I trust you will take
> the right decision.

> Worse case will have user or translator (hopefully) complaining and we'll adjust.

Sorry for not getting back to this quickly, fwiw, hoping translators
will complain is close to
{pick-any-expression-describing-impossible-wishes}.

Patch

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