mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +00: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:
parent
72193f8adc
commit
a4775d288b
2 changed files with 31 additions and 3 deletions
|
@ -87,6 +87,9 @@ struct Context<'a> {
|
||||||
|
|
||||||
/// The target path to which the directory will be copied.
|
/// The target path to which the directory will be copied.
|
||||||
target: &'a Path,
|
target: &'a Path,
|
||||||
|
|
||||||
|
/// The source path from which the directory will be copied.
|
||||||
|
root: &'a Path,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Context<'a> {
|
impl<'a> Context<'a> {
|
||||||
|
@ -102,6 +105,7 @@ impl<'a> Context<'a> {
|
||||||
current_dir,
|
current_dir,
|
||||||
root_parent,
|
root_parent,
|
||||||
target,
|
target,
|
||||||
|
root,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,11 +160,19 @@ struct Entry {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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_relative = direntry.path().to_path_buf();
|
||||||
let source_absolute = context.current_dir.join(&source_relative);
|
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())?;
|
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 local_to_target = context.target.join(descendant);
|
||||||
let target_is_file = context.target.is_file();
|
let target_is_file = context.target.is_file();
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -389,7 +401,7 @@ pub(crate) fn copy_directory(
|
||||||
{
|
{
|
||||||
match direntry_result {
|
match direntry_result {
|
||||||
Ok(direntry) => {
|
Ok(direntry) => {
|
||||||
let entry = Entry::new(&context, &direntry)?;
|
let entry = Entry::new(&context, &direntry, options.no_target_dir)?;
|
||||||
copy_direntry(
|
copy_direntry(
|
||||||
progress_bar,
|
progress_bar,
|
||||||
entry,
|
entry,
|
||||||
|
|
|
@ -230,6 +230,22 @@ fn test_cp_arg_no_target_directory() {
|
||||||
.stderr_contains("cannot overwrite 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]
|
#[test]
|
||||||
fn test_cp_target_directory_is_file() {
|
fn test_cp_target_directory_is_file() {
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue