-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
mv: improve the hardlink support #8296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
GNU testsuite comparison:
|
Kudos, three passing GNU tests :) Unfortunately, there is also a regression:
|
at.write("f", "file content"); | ||
at.hard_link("f", "g"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You already test moving a file and a hard link in test_mv_preserves_hardlinks_across_partitions
and thus I wouldn't do it again in this test function.
let moved_dir_a_file = other_fs_tempdir.path().join("a/1"); | ||
let moved_dir_second_file = other_fs_tempdir.path().join("b/1"); | ||
let moved_dir_a_file_metadata = metadata(&moved_dir_a_file).unwrap(); | ||
let moved_dir_second_file_metadata = metadata(&moved_dir_second_file).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming with "a_file" and "second_file" feels a bit odd. Maybe it would be better to use names that contain "a1" and "b1", similar to the naming on lines 2096/2097?
tests/by-util/test_mv.rs
Outdated
#[test] | ||
fn test_mv_error_handling_graceful_fallback() { | ||
let (at, mut ucmd) = at_and_ucmd!(); | ||
|
||
at.write("file1", "test content"); | ||
|
||
at.mkdir("target"); | ||
|
||
// Move with verbose output to test error handling messages | ||
ucmd.arg("--verbose").arg("file1").arg("target").succeeds(); | ||
|
||
assert!(at.file_exists("target/file1")); | ||
assert!(!at.file_exists("file1")); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what the purpose of this test is: the function name and the comment indicate the test is related to some error handling, but there is no error. Currently, it looks like the test function is a duplicate of test_mv_move_file_into_dir
.
tests/by-util/test_mv.rs
Outdated
#[test] | ||
#[cfg(unix)] | ||
fn test_mv_hardlink_scanning_with_permissions() { | ||
let (at, mut ucmd) = at_and_ucmd!(); | ||
|
||
// Create files that we can control permissions on | ||
at.write("accessible_file", "content"); | ||
at.mkdir("target"); | ||
|
||
// Test with verbose mode to ensure graceful error handling | ||
ucmd.arg("--verbose") | ||
.arg("accessible_file") | ||
.arg("target") | ||
.succeeds(); | ||
|
||
assert!(at.file_exists("target/accessible_file")); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test function also looks like a duplicate of test_mv_move_file_into_dir
.
tests/by-util/test_mv.rs
Outdated
#[test] | ||
#[cfg(unix)] | ||
fn test_mv_empty_hardlink_groups() { | ||
let (at, mut ucmd) = at_and_ucmd!(); | ||
|
||
at.write("single1", "content1"); | ||
at.write("single2", "content2"); | ||
at.mkdir("target"); | ||
|
||
// Test with files that have no hardlinks | ||
ucmd.arg("--verbose") | ||
.arg("single1") | ||
.arg("single2") | ||
.arg("target") | ||
.succeeds(); | ||
|
||
assert!(at.file_exists("target/single1")); | ||
assert!(at.file_exists("target/single2")); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test function also looks like a duplicate of test_mv_move_file_into_dir
.
src/uu/mv/src/mv.rs
Outdated
#[cfg(unix)] | ||
{ | ||
let (mut hardlink_tracker, hardlink_scanner) = create_hardlink_context(); | ||
rename( | ||
source, | ||
target, | ||
opts, | ||
None, | ||
Some(&mut hardlink_tracker), | ||
Some(&hardlink_scanner), | ||
) | ||
}) | ||
.map_err_context(|| { | ||
get_message_with_args( | ||
"mv-error-cannot-move", | ||
HashMap::from([ | ||
("source".to_string(), source.quote().to_string()), | ||
("target".to_string(), target.quote().to_string()), | ||
]), | ||
) | ||
}) | ||
} | ||
#[cfg(not(unix))] | ||
{ | ||
rename(source, target, opts, None, None, None).map_err_context(|| { | ||
get_message_with_args( | ||
"mv-error-cannot-move", | ||
HashMap::from([ | ||
("source".to_string(), source.quote().to_string()), | ||
("target".to_string(), target.quote().to_string()), | ||
]), | ||
) | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could use a similar approach as on lines 659 - 662 and use the same call of rename
for both unix and non-unix.
src/uu/mv/src/mv.rs
Outdated
#[cfg(unix)] | ||
{ | ||
let (mut hardlink_tracker, hardlink_scanner) = create_hardlink_context(); | ||
rename( | ||
source, | ||
target, | ||
opts, | ||
None, | ||
Some(&mut hardlink_tracker), | ||
Some(&hardlink_scanner), | ||
) | ||
.map_err(|e| USimpleError::new(1, format!("{e}"))) | ||
} | ||
#[cfg(not(unix))] | ||
{ | ||
rename(source, target, opts, None, None, None) | ||
.map_err(|e| USimpleError::new(1, format!("{e}"))) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
GNU testsuite comparison:
|
Should fix GNU tests/mv/part-hardlink.sh tests/mv/hard-link-1.sh Co-authored-by: Daniel Hofstetter <[email protected]>
b2aeefd
to
232233c
Compare
GNU testsuite comparison:
|
No description provided.