bug#69532: mv's new -x option should be made orthogonal to -t/-T/default

2024-03-04 Thread Petr Malat
On Mon, Mar 04, 2024 at 04:24:27PM -0800, Paul Eggert wrote:
> On 3/4/24 15:37, Petr Malat wrote:
> > Why do you expect this?
> 
> I expect it because mv has always treated destination directories that way.
> This has been true since the 1970s. We should not change this basic mode of
> operation.

But it doesn't behave like that when one uses -T, which is fine, because it's
documented.
 
> > > To fix this, 'mv -x' should respect the usual mv behavior with respect to
> > > directories. For example, when D is a directory 'mv -x A B C D' should act
> > > like 'mv A B C D' except that D's old entries should be renamed back to A 
> > > B
> > > and C. And the -t and -T options should work with -x the same way they 
> > > work
> > > when -x is not specified.
> > 
> > I do not think this is a good idea, because that operation is not
> > atomic.
> 
> There's nothing wrong with 'mv -x a b c d/' being nonatomic. "mv a b c d/"
> is not atomic either, and that's fine too.

The swap option description explicitly says it's atomic and the atomicity
was the only motivation for adding the new option.
 
> > Probably, the user wants to prepare a temporary directory
> > instead and then atomically swap it with the directory in use.
> 
> This usage was not at all obvious to me. If it's the intended use, I suggest
> inventing a new command, or adding -x to the 'rename' command instead.
> Pushing this flag onto 'mv', without making the flag reasonably orthogonal
> to mv's other options, would be a mistake because it would cause too much
> confusion.

The problem with a new command is that it's hard to find and rename
seems worst fitting than mv, because its main purpose is to replace
a pattern in a filename (e.g. change .JPG to .jpeg), so to "implement"
  mv A B
with rename one has to do
  rename A B A

Implementing atomic swap operation there doesn't seem logical to me,
I would never look for such a feature there. On the other hand when
I call mv A B, I'm generally interested in knowing if there is a time
frame, when no version of B exists.

> > Supporting swap for more than 2 files also brings a problem, when
> > the operation fails as then one doesn't know what has been swapped
> > and what not.
> 
> I don't see why not. The user can look at mv's diagnostics. It's the same as
> regular "mv a b c d/".

I don't find parsing diagnostics reliable and in general, it's something
I try to avoid in scripts. In a case I would do something like mv *.X d/,
and mv would fail, I would rather iterate over *.X than parse the output
to handle the error.
  Petr





bug#69532: mv's new -x option should be made orthogonal to -t/-T/default

2024-03-04 Thread Petr Malat
On Mon, Mar 04, 2024 at 08:35:03PM +, P??draig Brady wrote:
> On 04/03/2024 15:47, P??draig Brady wrote:
> > On 04/03/2024 00:44, Paul Eggert wrote:
> > > Although I like the idea of exposing file swaps to the user, the first
> > > cut of 'mv -x' has significant problems.
> > > 
> > > I expect 'mv -x A B' to act like 'mv A B' except the destination must
> > > exist and is renamed back to A. However, this is not true for 'mv -x A
> > > B' when B is a directory; it renames B to A rather than renaming B/A to
> > > A as I expect. That is, 'mv -x' acts as if -T (--no-target-directory) is
> > > also specified. There is no way to get mv's traditional behavior, or to
> > > get mv -t behavior.
> > > 
> > > To fix this, 'mv -x' should respect the usual mv behavior with respect
> > > to directories. For example, when D is a directory 'mv -x A B C D'
> > > should act like 'mv A B C D' except that D's old entries should be
> > > renamed back to A B and C. And the -t and -T options should work with -x
> > > the same way they work when -x is not specified.
> > > 
> > > This needs to happen before the next coreutils release, to avoid
> > > confusion about 'mv -x'.
> > 
> > So you're saying the current mv -x behavior should only be with -T 
> > explicitly specified.
> > With the current implementation, we should at least document that -x 
> > implies -T.
> > 
> > By changing as you suggest, we'd not be adding any significant 
> > functionality,
> > but potentially reducing confusion by following mv traditional arg handling.
> > I agree with you I think, but not strongly.
> > 
> > It's worth stating though that if users want to swap 2 directories
> > they'd have to `mv -Tx d1 d2`, which may also be a little confusing.
> > 
> > The use case we don't currently support directly is:
> > cd source_dir && mv -x * "$dest_dir"
> > Instead that currently requires:
> > for f in *; do mv -x "$f" "$dest_dir"; done
> > 
> > For completeness, stating disadvantages of pulling this use case within mv,
> > is that by requiring the for loop for this would allow users
> > to programatically determine which swap failed, and I see --swap
> > as primarily a programatic interface used by scripts.
> > Also if we made this change, We'd have to document that `mv -x 1 2 ... d`
> > was not atomic over the whole set.
I do not think this would be ever needed in a real life. It's more likely
one actually wants something like this:
  mkdir d.tmp
  ln -s -t d.tmp d/*
  # Modify d.tmp as needed (without propagating changes to d)
  mv --swap d d.tmp

> > I will look at making the change before the upcoming release.
> 
> Another point worth mentioning before changing this,
> is that changing would make the --swap operation non symmetric.
> I.e. `mv -x a d` would be different to `mv -x d a` where d in a directory.
I think this would lead to bugs. I prefer KISS principle and allowing
swapping just 2 paths. Explicitly mentioning -x automatically implies
-t may be added to the documentation. In general, I do not think there
is any need to make mv -x behave similar to plain mv. It's normal an
option changes behavior, at the end -t does the same.

> p.s. Re dir swapping I noticed that specifying '/' or '.' dirs always gives 
> EBUSY:
>   $ mv -x . .
>   mv: swap of '.' and '.' failed: Device or resource busy
That's because it's CWD of mv and your shell.
  Petr





bug#69532: mv's new -x option should be made orthogonal to -t/-T/default

2024-03-04 Thread Petr Malat
Hi Paul,
On Sun, Mar 03, 2024 at 04:44:52PM -0800, Paul Eggert wrote:
> Although I like the idea of exposing file swaps to the user, the first cut
> of 'mv -x' has significant problems.
> 
> I expect 'mv -x A B' to act like 'mv A B' except the destination must exist
> and is renamed back to A. However, this is not true for 'mv -x A B' when B
> is a directory; it renames B to A rather than renaming B/A to A as I expect.
> That is, 'mv -x' acts as if -T (--no-target-directory) is also specified.
> There is no way to get mv's traditional behavior, or to get mv -t behavior.

Why do you expect this? If the description in the help output was not
clear enough we can improve it by mentioning it implies -T.

> To fix this, 'mv -x' should respect the usual mv behavior with respect to
> directories. For example, when D is a directory 'mv -x A B C D' should act
> like 'mv A B C D' except that D's old entries should be renamed back to A B
> and C. And the -t and -T options should work with -x the same way they work
> when -x is not specified.

I do not think this is a good idea, because that operation is not
atomic. Probably, the user wants to prepare a temporary directory
instead and then atomically swap it with the directory in use.

The main motivation for this option is not to preserve old files, 
but to be able to atomically replace one file with another. If one
needs to preserve replaced files, he can use the backup option.

Supporting swap for more than 2 files also brings a problem, when
the operation fails as then one doesn't know what has been swapped
and what not. With plain mv one knows the file was moved if the
original location is unlinked.
BR,
  Petr