Fix cp -u/mv -u when the dst doesn't exist (#9662)

Fixes #9655
This commit is contained in:
mengsuenyan 2023-07-13 00:12:59 +08:00 committed by GitHub
parent 7c9edbd9ee
commit 026335fff0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 7 deletions

View file

@ -184,7 +184,7 @@ impl Command for Cp {
canonicalize_with(dst.as_path(), &current_dir_path).unwrap_or(dst); canonicalize_with(dst.as_path(), &current_dir_path).unwrap_or(dst);
// ignore when source file is not newer than target file // ignore when source file is not newer than target file
if update_mode && super::util::is_older(&src, &dst) { if update_mode && super::util::is_older(&src, &dst).unwrap_or(false) {
continue; continue;
} }

View file

@ -313,7 +313,7 @@ fn move_file(
} }
} }
if update_mode && super::util::is_older(&from, &to) { if update_mode && super::util::is_older(&from, &to).unwrap_or(false) {
Ok(false) Ok(false)
} else { } else {
match move_item(&from, from_span, &to) { match move_item(&from, from_span, &to) {

View file

@ -133,9 +133,11 @@ fn get_interactive_confirmation(prompt: String) -> Result<bool, Box<dyn Error>>
} }
} }
pub fn is_older(src: &Path, dst: &Path) -> bool { /// Return `Some(true)` if the last change time of the `src` old than the `dst`,
if !dst.exists() { /// otherwisie return `Some(false)`. Return `None` if the `src` or `dst` doesn't exist.
return true; pub fn is_older(src: &Path, dst: &Path) -> Option<bool> {
if !dst.exists() || !src.exists() {
return None;
} }
#[cfg(unix)] #[cfg(unix)]
{ {
@ -146,7 +148,7 @@ pub fn is_older(src: &Path, dst: &Path) -> bool {
let dst_ctime = std::fs::metadata(dst) let dst_ctime = std::fs::metadata(dst)
.map(|m| m.ctime()) .map(|m| m.ctime())
.unwrap_or(i64::MAX); .unwrap_or(i64::MAX);
src_ctime <= dst_ctime Some(src_ctime <= dst_ctime)
} }
#[cfg(windows)] #[cfg(windows)]
{ {
@ -157,7 +159,7 @@ pub fn is_older(src: &Path, dst: &Path) -> bool {
let dst_ctime = std::fs::metadata(dst) let dst_ctime = std::fs::metadata(dst)
.map(|m| m.last_write_time()) .map(|m| m.last_write_time())
.unwrap_or(u64::MAX); .unwrap_or(u64::MAX);
src_ctime <= dst_ctime Some(src_ctime <= dst_ctime)
} }
} }

View file

@ -607,5 +607,9 @@ fn copy_file_with_update_flag_impl(progress: bool) {
sandbox.with_files(vec![FileWithContent("newest_valid.txt", "newest_body")]); sandbox.with_files(vec![FileWithContent("newest_valid.txt", "newest_body")]);
let actual = nu!(cwd: sandbox.cwd(), "cp {} -u newest_valid.txt valid.txt; open valid.txt", progress_flag); let actual = nu!(cwd: sandbox.cwd(), "cp {} -u newest_valid.txt valid.txt; open valid.txt", progress_flag);
assert_eq!(actual.out, "newest_body"); assert_eq!(actual.out, "newest_body");
// when destination doesn't exist
let actual = nu!(cwd: sandbox.cwd(), "cp {} -u newest_valid.txt des_missing.txt; open des_missing.txt", progress_flag);
assert_eq!(actual.out, "newest_body");
}); });
} }

View file

@ -484,5 +484,10 @@ fn mv_with_update_flag() {
sandbox.with_files(vec![FileWithContent("newest_valid.txt", "newest_body")]); sandbox.with_files(vec![FileWithContent("newest_valid.txt", "newest_body")]);
let actual = nu!(cwd: sandbox.cwd(), "mv -uf newest_valid.txt valid.txt; open valid.txt"); let actual = nu!(cwd: sandbox.cwd(), "mv -uf newest_valid.txt valid.txt; open valid.txt");
assert_eq!(actual.out, "newest_body"); assert_eq!(actual.out, "newest_body");
// when destination doesn't exist
sandbox.with_files(vec![FileWithContent("newest_valid.txt", "newest_body")]);
let actual = nu!(cwd: sandbox.cwd(), "mv -uf newest_valid.txt des_missing.txt; open des_missing.txt");
assert_eq!(actual.out, "newest_body");
}); });
} }