Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The Windows implementations currently evaluate both metadata lookups unconditionally, losing the Unix branch’s intentional early-return behavior and causing avoidable I/O in common missing-target scenarios.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Implements Windows support for are_hardlinks_to_same_file (and the related “hardlink-or-one-way-symlink” helper) by leveraging existing FileInformation / infos_refer_to_same_file identity comparisons in uucore’s filesystem feature module.
Changes:
- Add Windows implementations for
are_hardlinks_to_same_fileandare_hardlinks_or_one_way_symlink_to_same_fileusingFileInformation::from_path(...). - Adjust unit tests to exercise these helpers beyond Unix-only, including a new symlink behavior test.
- Minor test cleanup/consistency changes (imports and
NamedTempFileusage).
File summaries
| File | Description |
|---|---|
| src/uucore/src/lib/features/fs.rs | Adds Windows hardlink/symlink identity checks via FileInformation, and expands tests to cover the new behavior. |
Review details
Suppressed comments (1)
src/uucore/src/lib/features/fs.rs:884
- Same short-circuit issue as above: on Windows both
FileInformation::from_path(...)calls are evaluated unconditionally, so you still open the source even when the target lookup fails. The Unix branch avoids that extra work; mirroring it here keeps behavior consistent and reduces unnecessary syscalls.
infos_refer_to_same_file(
FileInformation::from_path(source, true),
FileInformation::from_path(target, false),
)
}
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🟡 Changes recommended
The PR should include/enable Windows end-to-end regression coverage for the claimed cp --remove-destination / mv --backup fixes, and there are also unit-test cleanup issues to address.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
src/uucore/src/lib/features/fs.rs:1397
test_are_hardlinks_to_same_file_hard_linkcreates an additional hardlink path (path2) next to theNamedTempFile, butNamedTempFileonly cleans up its own original path. The extra hardlink is left behind in the OS temp directory after the test, which can accumulate across runs. Prefer creating the temp file inside atempdir()and placing the hardlink inside that directory so everything is cleaned up when the directory is dropped.
src/uucore/src/lib/features/fs.rs:1401- The test name
test_are_hardlinks_to_same_file_symlinkis misleading: it primarily verifies that a symlink is not treated as a hardlink byare_hardlinks_to_same_file, and thatare_hardlinks_or_one_way_symlink_to_same_filereturns true when the source is a symlink to the target. Renaming the test to reflect the one-way symlink semantics will make failures easier to interpret.
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Lite
There was a problem hiding this comment.
🟡 Changes recommended
The updated uucore hardlink/symlink identity unit tests now run on unsupported targets (e.g. non-unix/windows) and will fail without restoring appropriate platform gating.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
src/uucore/src/lib/features/fs.rs:1387
- This test uses
fs::hard_link(...).unwrap()but is no longer#[cfg(unix)]; on targets where hard links are unsupported/restricted (e.g. WASI), it will panic or fail. Gate it to unix/windows (and exclude Android if necessary).
#[test]
fn test_are_hardlinks_to_same_file_hard_link() {
src/uucore/src/lib/features/fs.rs:1372
- This test currently runs on non-unix/windows targets as well, where
are_hardlinks_to_same_filealways returnsfalse, causing a guaranteed failure. Gate the test to unix/windows (and exclude Android if hard links are not supported there).
#[test]
fn test_are_hardlinks_to_same_file_different_files() {
src/uucore/src/lib/features/fs.rs:1400
- This symlink-based test currently runs on targets where neither the unix nor windows symlink creation branch is compiled, leaving
path2uncreated and making the subsequent assertions fail. Gate it to unix/windows (and exclude Android if hard links are not supported there).
#[test]
fn test_are_hardlinks_to_same_file_symlink() {
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
|
GNU testsuite comparison: |
There was a problem hiding this comment.
🔵 Needs a closer look
The PR claims to fix mv --backup on Windows but doesn’t add/enable a Windows mv integration/regression test to verify the behavior end-to-end.
Review details
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
src/uucore/src/lib/features/fs.rs:1404
- This test name suggests
are_hardlinks_to_same_fileshould succeed, but the test is primarily about the symlink-resolving behavior ofare_hardlinks_or_one_way_symlink_to_same_file. Renaming it would make failures easier to interpret.
src/uucore/src/lib/features/fs.rs:841
- The new Windows implementation is intended to fix
mv --backup, but there isn't a Windows integration/regression test exercising themvbackup guard behavior (the existing hardlink/backup tests intests/by-util/test_mv.rsare still#[cfg(all(unix, ...))]). Adding/enabling a Windowsmv --backuptest would help ensure this doesn't regress again.
#[cfg(windows)]
{
let Ok(target_metadata) = FileInformation::from_path(target, false) else {
return false;
};
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Lite
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
🟡 Changes recommended
Address the Windows deletion scenario, WASI test guards, and stale test documentation.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
src/uucore/src/lib/features/fs.rs:888
- The newly added public documentation uses the ungrammatical phrase “if either two paths”; please reword it so the two alternatives are unambiguous.
/// Checks if either two paths are hard links to the same file or if the source path is a symbolic link which when fully resolved points to target path
tests/by-util/test_cp.rs:1197
- The adjacent comment still says this test does not work on Windows, but removing this
cfgnow schedules it on Windows. Please remove or update that stale claim so a Windows failure is not treated as expected.
fn test_cp_arg_remove_destination() {
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Lite
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved moderate and critical issues affect Windows behavior and test portability.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (4)
src/uucore/src/lib/features/fs.rs:852
- On Windows this calls
FileInformation::from_path, which opens each entry withread(true). That requires read access and can fail for an entry that is still metadata-queryable/deletable (for example, an ACL-restricted source or destination), so the helper returnsfalseandmvcan miss the same-hardlink check. The existing Windowssame_fileimplementation deliberately opens withaccess_mode(0)(src/uu/test/src/platform/windows.rs:347-358); use the same no-data-access metadata path here (or expose it throughFileInformation) so identity checks do not depend on read permission.
let Ok(target_metadata) = FileInformation::from_path(target, false) else {
return false;
};
let Ok(source_metadata) = FileInformation::from_path(source, false) else {
src/uucore/src/lib/features/fs.rs:846
- The PR description says this fixes
mv --backup, but this helper is skipped wheneveropts.backup != BackupMode::None(mv.rs:530-533); the backup-specific guard instead callsbackup_would_destroy_source(mv.rs:378-385), which already comparesFileInformationdirectly. As written, adding the Windows hardlink helper does not change themv --backuppath, so either that path needs to be updated or the description should not claim this fix.
pub fn are_hardlinks_to_same_file(source: &Path, target: &Path) -> bool {
tests/by-util/test_cp.rs:1194
- Enabling this test on Windows makes it fail for the existing reason this guard was present: the destination is made read-only, but
--remove-destinationdoes not setoptions.force(), sodelete_pathleaves the Windows read-only attribute set andfs::remove_filereturns access denied. Either make the deletion path clear the attribute forRemoveDestination, or keep this test Windows-gated until that behavior is implemented.
/// from --force. This test originally checked file timestamps, which
tests/by-util/test_mv.rs:554
not(target_os = "android")is broader than the previous Unix guard: it also compiles this hard-link regression test for WASI and other non-Unix/non-Windows targets, whereare_hardlinks_to_same_fileis thefalsestub atfs.rs:859-862. The test then expectsmvto reject a hard-link pair and fails; restrict the test to Unix (except Android) or Windows.
#[cfg(not(target_os = "android"))]
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Lite
Primitively implements hardlink detection using the
existing
infos_refer_to_same_filefacilities.This fixes
cp --remove-destinationandmv --backup.