Fix mv <symlink>/ target for various situations. Align error message with GNU#10060
Fix mv <symlink>/ target for various situations. Align error message with GNU#10060Vitamin9C wants to merge 2 commits intouutils:mainfrom
Conversation
d15e43f to
341c0f4
Compare
|
The error messages of the failures in CI for win actually matches the error messages yielded with GNU Coreutils on Windows (which is different from GNU Coreutils on my local MacOS). It's just we need to craft these 3 tests for Unix and Windows with different expected values. # MacOS
~/Wo/2026/tests ls -al 1 х │ system Node │ 08:09:45
total 0
drwxr-xr-x 6 schen 192 Jan 5 08:09 .
drwxr-xr-x 6 schen 192 Jan 3 13:09 ..
-rw-r--r-- 1 schen 0 Jan 5 08:09 a
drwxr-xr-x 2 schen 64 Jan 5 08:09 bar-dir
drwxr-xr-x 2 schen 64 Jan 5 08:09 foo-dir
lrwxr-xr-x 1 schen 7 Jan 5 08:09 foo-link -> foo-dir
~/Wo/2026/tests gmv foo-link/ a ✔ │ system Node │ 08:09:50
gmv: cannot overwrite non-directory 'a' with directory 'foo-link/'
~/Wo/2026/tests gmv foo-link/ foo-dir 1 х │ system Node │ 08:10:26
gmv: cannot move 'foo-link/' to 'foo-dir/foo-link': Not a directory
~/Wo/2026/tests gmv foo-link/ bar-dir 1 х │ system Node │ 08:10:32
gmv: cannot move 'foo-link/' to 'bar-dir/foo-link': Not a directory# Win
C:\Workspace\Personal\uutils>ls -al
total 8
drw-rw-rw- 4 chens 0 0 2026-01-05 08:07 .
drw-rw-rw- 7 chens 0 4096 2026-01-05 08:03 ..
-rw-rw-rw- 1 chens 0 0 2026-01-05 08:04 a
drw-rw-rw- 2 chens 0 0 2026-01-05 08:07 bar-dir
drw-rw-rw- 2 chens 0 0 2026-01-05 08:04 foo-dir
lr--r--r-- 1 chens 0 838 2026-01-05 08:04 foo-link.lnk -> C:/Workspace/Personal/uutils/foo-dir
C:\Workspace\Personal\uutils>mv foo-link\ a
mv: cannot stat `foo-link\\': No such file or directory
C:\Workspace\Personal\uutils>mv foo-link\ foo-dir
mv: cannot stat `foo-link\\': No such file or directory
C:\Workspace\Personal\uutils>mv foo-link/ bar-dir
mv: cannot stat `foo-link/': No such file or directory |
341c0f4 to
dce0a26
Compare
|
please replace the screenshots by text |
dce0a26 to
c5b7ce0
Compare
|
Sorry I forgot to fmt before the last commit...... force-pushed again to prevent consuming CI time. |
|
GNU testsuite comparison: |
|
Hi @sylvestre. I wonder if I can do something further to get this PR be improved, reviewed, and merged? It's my first PR to this project and I wish to improve its quality and do better to contribute. |
|
sorry, i missed it |
| } | ||
|
|
||
| #[cfg(unix)] | ||
| pub fn is_symlink_with_trailing(path: &Path) -> bool { |
There was a problem hiding this comment.
please add unit tests for this function
including cases like symlink// or /symlink/////
| let len = bytes.len(); | ||
| let stripped = &bytes[..len - 1]; |
There was a problem hiding this comment.
| let len = bytes.len(); | |
| let stripped = &bytes[..len - 1]; | |
| let stripped = &bytes[..bytes.len() - 1] |
| if is_symlink_with_trailing(source) { | ||
| if !source_is_dir { | ||
| return Err(MvError::CannotStatNotADirectory(source.quote().to_string()).into()); | ||
| } else if target_is_dir { |
There was a problem hiding this comment.
It seems that when source is a symlink-to-dir with trailing slash and target is NOT a directory and does NOT exist, the code falls through. please verify this matches GNU behavior for 'mv symlink/ nonexistent' and add a test.
Merging this PR will degrade performance by 6.7%
Performance Changes
Comparing Footnotes
|
Description
Resolve problems described in #10026
mv symlink_foo/ bar(will move symlink destination folder or file to bar)Changes
mvlikepath_ends_with_terminator,are_hardlinks_to_same_file). (Didn't reusepath_ends_with_terminatorin Unix implementation for performance, reused it in Windows implementation cuz Windows U16 would worsen the performance anyway)mv.rsto handlesymlink_to_file/andsymlink_to_dir/asmvsource correctly and consistently with GNU.mv symlink/ targetwhich would fail before this PR.