Subject: bug#29205: --force doesn't work

From: Assaf Gordon <[email-masked]>
Date: Mon, 29 Oct 2018 20:01:09 -0600

tags 29205 notabug
close 29205
stop

(triaging old bugs)

It seems your message was lost and not replied to in a year.
Sorry about that.

On 2017-11-08 2:35 a.m., Konstantin Kharlamov wrote:
> Steps to reproduce:
> 
> 1. $ mkdir -p foo/bar/buzz1
> 2. $ mkdir -p bar/buzz2
> 3. $ mv --force bar foo/
> 
> Expected result: "bar" is merged into the other "bar"
> Actual result: error "mv: cannot move 'bar' to 'foo/bar': Directory not 
> empty"

This is the Linux kernel refusing to move (using the rename(2) syscall)
source to a non-empty directory:

Using 'strace' we can see the sys-call failure:

     rename("bar", "foo/bar")  = -1 ENOTEMPTY (Directory not empty)

In the kernel's rename(2) syscall manual page, the error is explained:
   ENOTEMPTY or EEXIST
     newpath is a nonempty directory, that is, contains entries
     other than "." and "..".
http://man7.org/linux/man-pages/man2/rename.2.html#ERRORS

mv(1) simply forwards the kernel error to the user.

> So I'm removing this dir, and trying to continue `mv`ing, and here we 
> coming to the bug I'm reporting.
> 
> Of course I could just copy, but `mv`ing is α) much faster, and β) 
> leaves dates of file creation in places, so I don't need to rebuild the 
> whole thing over again, only the files I gonna change.

"cp" will copy all files from inside "bar" to "foo/bar".
"mv" tries to replace "foo/bar" with "bar",
and because "foo/bar" is not empty, the kernel refuses to replace it.

If you care about preserving the fiels inside "bar/", but not the "bar"
directory itself, you can use:

     mv bar/* foo/bar/

Or you can just delete the "foo/bar" directory
(using -f ensures it will not complain if the directory doesn't exist):

    rm -rf ./foo/bar ; mv bar foo

As such, I'm closing this bug.
Discussion can continue by replying to this thread.

-assaf