coreutils
coreutils copied to clipboard
mv: moving(renaming) case-sensitive files errors out on macOS
Hi, Two main issues occur when renaming files/directories on macOS.
Platform: macOS mv version: 0.0.22
rename_directory
mkdir somedir
touch somedir/somefile.txt
> uutils mv somedir Somedir
# mv: cannot move 'somedir' to a subdirectory of itself, 'somedir/somedir'
rename_file
touch samefile.txt
> uutils mv samefile.txt Samefile.txt
# mv: 'somefile.txt' and 'Samefile.txt' are the same file.
Expected behavior: Same as Linux, to rename both dir/files rather than error out. Not sure what the behavior is on Windows. This was raised originally on nushell's PR, specifically comment
My guess is that mv tries to handle too many cases on its own instead of just showing the OS error. Some parts of the error handling honestly seem pretty shaky at the moment. It could use some refactoring if you're up for that.
I went to Windows to see if I could reproduce but I could only reproduce 1, not both: So,
> uutils mv somedir Somedir
mv: cannot move 'somedir' to a subdirectory of itself, 'Somedir/somedir'
Also I find strange that in Windows is Somedir/somedir (note capital S), but on macOS is somedir/somedir, completely crazy haha.
For the second case, it succeeds. Thus create samefile.txt and:
> uutils mv samefile.txt Samefile.txt #succeeds
copies just fine.
So this seems odd, on windows one failing, but 2 on macOS. I do not own a mac, so if anyone feels free to tackle this it would be great:).
However, it does look like related to the use of the fs_extra upstream dependency. See fs_extra issue, with the nushell issue linked there as well.
This is what I get on MacOS.
Test with Dir
❯ mkdir somedir
❯ touch somedir/somefile.txt
❯ /opt/homebrew/Cellar/uutils-coreutils/0.0.22/libexec/uubin/mv somedir Somedir
/opt/homebrew/Cellar/uutils-coreutils/0.0.22/libexec/uubin/mv: cannot move 'somedir' to a subdirectory of itself, 'somedir/somedir'
Test with File
❯ touch samefile.txt
❯ /opt/homebrew/Cellar/uutils-coreutils/0.0.22/libexec/uubin/mv samefile.txt Samefile.txt
/opt/homebrew/Cellar/uutils-coreutils/0.0.22/libexec/uubin/mv: 'samefile.txt' and 'Samefile.txt' are the same file
Not sure where to go from here but it would be nice to fix this somehow. I wonder if there is another way to make this work via a fix to fs_extra, which I guess isn't fixed yet, or some other 3rd party crate?
Any new ideas on how to fix this? It would be nice to move nushell to uu_mv.
I was trying to debug this -- seems like std::fs treats both the lower-case and upper-case files as the same file 0_o.
With some debug statements:
$ cargo run mv somefile.txt Somefile.txt
Compiling bigdecimal v0.4.0
Compiling uu_seq v0.0.23 (/Users/ditao1/coreutils/src/uu/seq)
Compiling coreutils v0.0.23 (/Users/ditao1/coreutils)
Finished dev [unoptimized + debuginfo] target(s) in 2.99s
Running `/Users/ditao1/coreutils/target/debug/coreutils mv somefile.txt Somefile.txt`
[src/uucore/src/lib/features/fs.rs:672] source = "somefile.txt"
[src/uucore/src/lib/features/fs.rs:677] target = "Somefile.txt"
[src/uucore/src/lib/features/fs.rs:682] source_metadata.ino() = 173549816
[src/uucore/src/lib/features/fs.rs:682] target_metadata.ino() = 173549816
[src/uu/mv/src/mv.rs:329] are_hardlinks_to_same_file(source, target) = true
mv: 'somefile.txt' and 'Somefile.txt' are the same file
Now note, I don't have a Somefile.txt in my directory, but if we do a stat call...
$ stat somefile.txt
16777229 173549816 -rw-r--r-- 1 ditao1 staff 0 0 "Nov 26 19:18:20 2023" "Nov 26 19:18:20 2023" "Nov 26 19:18:20 2023" "Nov 26 19:18:20 2023" 4096 0 0 somefile.txt
$ stat Somefile.txt
16777229 173549816 -rw-r--r-- 1 ditao1 staff 0 0 "Nov 26 19:18:20 2023" "Nov 26 19:18:20 2023" "Nov 26 19:18:20 2023" "Nov 26 19:18:20 2023" 4096 0 0 Somefile.txt
One more -- doing a normal mv of a file into itself... doesn't really matter.
mv somefile.txt somefile.txt
Of note, it's also impossible in MacOS to have a hardlink be a different case through ln:
$ ln somefile.txt Somefile.txt
ln: Somefile.txt: File exists
$ ln somefile.txt test.txt //is fine
So, I don't quite know how we got here. It just seems like darwin's file system is wonky.
This still errors on MacOS 14.5... Mac's own mv works normally.
❯ touch AA
❯ mv AA aa
gmv: 'AA' and 'aa' are the same file
❯ /bin/mv AA aa
❯ ls aa
aa