Subject: bug#62572: cp --no-clobber behavior has changed

From: Paul Eggert <[email-masked]>
Date: Sat, 1 Apr 2023 15:44:53 -0700

On 2023-04-01 08:44, Pádraig Brady wrote:

> OK first stab at --update=none support is attached.

Thanks, some comments:

> +  /* Always Overwrite.  */
> +  UPDATE_OVERWRITE,

Might be better to call this UPDATE_ALL as it doesn't overwrite if you 
use cp -l or -s or (in some cases) --preserve=links.

> +static char const *const update_type_string[] =
> +{
> +  "none", "older", NULL
> +};

Perhaps there should also be an --update=all, which is the same as no 
update option at all? It would presumably override previous --update 
suboptions.

>    -n, --no-clobber             do not overwrite an existing file (overrides\n\
> -                                 a previous -i option)\n\
> +                                 a -u or previous -i option)\n\

Shouldn't -n override only previous -u or --update options? I thought 
these options were processed left to right, with later overriding earlier.

> +  -u                           only update when the SOURCE file is newer\n\
>                                   than the destination file or when the\n\
>                                   destination file is missing\n\
> +  --update[=UPDATE_MODE]       like -u, but support skipping existing files;\n\
> +                                 UPDATE_MODE={none,older(default)}\n\

This might be clearer if we describe --update first, and then say that 
-u is equivalent to plain --update.

> +  if (make_backups && x.interactive == I_ALWAYS_SKIP)
> +    {
> +      error (0, 0,
> +             _("options --backup and --update=none are mutually exclusive"));
> +      usage (EXIT_FAILURE);
> +    }

Why is this needed? --backup and -u are not mutually exclusive now. 
Admittedly --backup is useless when -u is given, but it seems a bit 
harsh to error out.