mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
cp: reduce memory usage for cp -al by skipping unnecessary tracking (#9805)
Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
This commit is contained in:
co-authored by
Sylvestre Ledru
parent
b5a49f33b5
commit
27fd41125b
@@ -27,7 +27,8 @@ use uucore::uio_error;
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
|
||||
use crate::{
|
||||
CopyResult, CpError, Options, aligned_ancestors, context_for, copy_attributes, copy_file,
|
||||
CopyMode, CopyResult, CpError, Options, aligned_ancestors, context_for, copy_attributes,
|
||||
copy_file,
|
||||
};
|
||||
|
||||
/// Ensure a Windows path starts with a `\\?`.
|
||||
@@ -468,6 +469,15 @@ pub(crate) fn copy_directory(
|
||||
let is_dir_for_permissions =
|
||||
entry_is_dir_no_follow || (options.dereference && direntry_path.is_dir());
|
||||
if is_dir_for_permissions {
|
||||
// For --link mode, copy attributes immediately to avoid O(n) memory
|
||||
if options.copy_mode == CopyMode::Link {
|
||||
copy_attributes(
|
||||
&entry.source_absolute,
|
||||
&entry.local_to_target,
|
||||
&options.attributes,
|
||||
)?;
|
||||
continue;
|
||||
}
|
||||
// Add this directory to our list for permission fixing later
|
||||
dirs_needing_permissions
|
||||
.push((entry.source_absolute.clone(), entry.local_to_target.clone()));
|
||||
|
||||
+11
-5
@@ -2448,7 +2448,9 @@ fn copy_file(
|
||||
return Err(translate!("cp-error-cannot-change-attribute", "dest" => dest.quote()).into());
|
||||
}
|
||||
|
||||
if options.preserve_hard_links() {
|
||||
// When using --link mode, hard link structure is automatically preserved
|
||||
// because we link to source files (which share inodes).
|
||||
if options.preserve_hard_links() && options.copy_mode != CopyMode::Link {
|
||||
// if we encounter a matching device/inode pair in the source tree
|
||||
// we can arrange to create a hard link between the corresponding names
|
||||
// in the destination tree.
|
||||
@@ -2565,10 +2567,14 @@ fn copy_file(
|
||||
}
|
||||
}
|
||||
|
||||
copied_files.insert(
|
||||
FileInformation::from_path(source, options.dereference(source_in_command_line))?,
|
||||
dest.to_path_buf(),
|
||||
);
|
||||
// Skip tracking copied files when using --link mode since hard link
|
||||
// structure is automatically preserved
|
||||
if options.copy_mode != CopyMode::Link {
|
||||
copied_files.insert(
|
||||
FileInformation::from_path(source, options.dereference(source_in_command_line))?,
|
||||
dest.to_path_buf(),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(progress_bar) = progress_bar {
|
||||
progress_bar.inc(source_metadata.len());
|
||||
|
||||
Reference in New Issue
Block a user