1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

cp: correctly copy ancestor dirs in --parents mode

Fix a bug where `cp` failed to copy ancestor directories when using
the `--parents` option. For example, before this commit:

    $ mkdir -p a/b/c d
    $ cp --parents a/b/c d
    $ find d
    d
    d/c

After this commit

    $ mkdir -p a/b/c d
    $ cp --parents a/b/c d
    $ find d
    d
    d/a
    d/a/b
    d/a/b/c

This commit also adds the correct messages for `--verbose` mode:

    $ cp -r --parents --verbose a/b/c d
    a -> d/a
    a/b -> d/a/b
    'a/b/c' -> 'd/a/b/c'

Fixes #3332.
This commit is contained in:
Jeffrey Finkelstein 2022-09-01 22:12:16 -04:00
parent cd3f7b89a7
commit ac3fcca6c0
2 changed files with 34 additions and 0 deletions

View file

@ -303,6 +303,27 @@ pub(crate) fn copy_directory(
.into());
}
// If in `--parents` mode, create all the necessary ancestor directories.
//
// For example, if the command is `cp --parents a/b/c d`, that
// means we need to copy the two ancestor directories first:
//
// a -> d/a
// a/b -> d/a/b
//
let tmp = if options.parents {
if let Some(parent) = root.parent() {
let new_target = target.join(parent);
std::fs::create_dir_all(&new_target)?;
new_target
} else {
target.to_path_buf()
}
} else {
target.to_path_buf()
};
let target = tmp.as_path();
let mut hard_links: Vec<(String, u64)> = vec![];
let preserve_hard_links = options.preserve_hard_links();

View file

@ -1999,6 +1999,19 @@ fn test_copy_same_symlink_no_dereference_dangling() {
ucmd.args(&["-d", "a", "b"]).succeeds();
}
#[cfg(not(windows))]
#[test]
fn test_cp_parents_2_dirs() {
let (at, mut ucmd) = at_and_ucmd!();
at.mkdir_all("a/b/c");
at.mkdir("d");
ucmd.args(&["-a", "--parents", "a/b/c", "d"])
.succeeds()
.no_stderr()
.no_stdout();
assert!(at.dir_exists("d/a/b/c"));
}
#[test]
#[ignore = "issue #3332"]
fn test_cp_parents_2() {