Repository navigation
cp: fix recursive copy of a filesystem root such as W:/ on Windows - #15700
Open
armadavalor wants to merge 2 commits into
Open
armadavalor wants to merge 2 commits into
armadavalor wants to merge 2 commits into
Conversation
Fixes uutils#5166 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
sylvestre
reviewed
Oct 24, 2026
| .filter(|c| { | ||
| !matches!( | ||
| c, | ||
| std::path::Component::Prefix(_) | std::path::Component::RootDir |
Contributor
There was a problem hiding this comment.
could you please import std::path::Component? it would fit on one line
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5166
cp -r W:/ deston Windows failed with'W:/id.dat' and 'W:/id.dat' are the same file.A filesystem root has no parent, so
Context::newleavesroot_parentasNone, andget_local_to_root_parentthen returned the absolute source path unchanged.Entry::newdoestarget.join(descendant), and joining an absolute path (or one with a drive prefix) discardstarget, so every entry was mapped onto itself. WithW:/*it worked because the glob givesroot_parent = Some(..).The
Nonearm now drops thePrefixandRootDircomponents, so the entries are placed relative to the target (dest/id.dat,dest/sub/x.txt). This is not Windows-specific logic:cp -r / destgoes through the same path, so I added a portable unit test as well as a Windows one.Testing:
copydir.rs(one portable, onecfg(windows))subst Q: <dir>thencp -r Q:/ destandcp -r Q:\ dest— before: the "same file" error, after:dest/id.dat,dest/sub/x.txtcargo test --features cp --test tests test_cp::gives the same result before and after the change (136 passed, 41 failed); all 41 are tests that create symlinks, which need a privilege this Windows machine lacks.I did not add an integration test in
tests/by-util/test_cp.rs, since reproducing the bug needs a drive root (subst/mounted volume), which isn't reliably available in CI. Happy to add one if you have a preferred approach.I have not verified the Unix side (
cp -r / dest) by running it.🤖 Generated with Claude Code