mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
cp: fix cp -rT dir dir2 leads to different result than with GNU cp (#5467)
* add a test case test_cp_treat_dest_as_a_normal_file * fix 5457 * cp: fix comment --------- Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
This commit is contained in:
@@ -87,6 +87,9 @@ struct Context<'a> {
|
||||
|
||||
/// The target path to which the directory will be copied.
|
||||
target: &'a Path,
|
||||
|
||||
/// The source path from which the directory will be copied.
|
||||
root: &'a Path,
|
||||
}
|
||||
|
||||
impl<'a> Context<'a> {
|
||||
@@ -102,6 +105,7 @@ impl<'a> Context<'a> {
|
||||
current_dir,
|
||||
root_parent,
|
||||
target,
|
||||
root,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -156,11 +160,19 @@ struct Entry {
|
||||
}
|
||||
|
||||
impl Entry {
|
||||
fn new(context: &Context, direntry: &DirEntry) -> Result<Self, StripPrefixError> {
|
||||
fn new(
|
||||
context: &Context,
|
||||
direntry: &DirEntry,
|
||||
no_target_dir: bool,
|
||||
) -> Result<Self, StripPrefixError> {
|
||||
let source_relative = direntry.path().to_path_buf();
|
||||
let source_absolute = context.current_dir.join(&source_relative);
|
||||
let descendant =
|
||||
let mut descendant =
|
||||
get_local_to_root_parent(&source_absolute, context.root_parent.as_deref())?;
|
||||
if no_target_dir {
|
||||
descendant = descendant.strip_prefix(context.root)?.to_path_buf();
|
||||
}
|
||||
|
||||
let local_to_target = context.target.join(descendant);
|
||||
let target_is_file = context.target.is_file();
|
||||
Ok(Self {
|
||||
@@ -389,7 +401,7 @@ pub(crate) fn copy_directory(
|
||||
{
|
||||
match direntry_result {
|
||||
Ok(direntry) => {
|
||||
let entry = Entry::new(&context, &direntry)?;
|
||||
let entry = Entry::new(&context, &direntry, options.no_target_dir)?;
|
||||
copy_direntry(
|
||||
progress_bar,
|
||||
entry,
|
||||
|
||||
@@ -230,6 +230,22 @@ fn test_cp_arg_no_target_directory() {
|
||||
.stderr_contains("cannot overwrite directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_arg_no_target_directory_with_recursive() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
at.mkdir("dir");
|
||||
at.mkdir("dir2");
|
||||
at.touch("dir/a");
|
||||
at.touch("dir/b");
|
||||
|
||||
ucmd.arg("-rT").arg("dir").arg("dir2").succeeds();
|
||||
|
||||
assert!(at.plus("dir2").join("a").exists());
|
||||
assert!(at.plus("dir2").join("b").exists());
|
||||
assert!(!at.plus("dir2").join("dir").exists());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_target_directory_is_file() {
|
||||
new_ucmd!()
|
||||
|
||||
Reference in New Issue
Block a user