mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-06-08 06:05:57 -04:00
main: fix --mkpath + --dry-run file-to-file copy (#880)
A single-file --mkpath copy whose destination parent does not exist failed under --dry-run: make_path() only *reports* the directories it would create in a dry run, so change_dir#3 then tried to chdir into a parent that isn't there and aborted with "change_dir#3 ... failed". When the parent is genuinely missing in a dry run, skip the chdir and mark the destination as not-yet-present (dry_run++), exactly as the multi-file/dir-creation path already does, so the generator doesn't probe the missing tree. Gating it on the missing-parent case keeps an ordinary file-to-file dry run chdir'ing into and itemizing against an existing destination. Fixes: #880 Co-authored-by: Stiliyan Tonev (Bark) <stiliyan21@gmail.com>
This commit is contained in:
11
main.c
11
main.c
@@ -832,7 +832,16 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
dest_path = "/";
|
||||
|
||||
*cp = '\0';
|
||||
if (!change_dir(dest_path, CD_NORMAL)) {
|
||||
if (dry_run && mkpath_dest_arg && do_stat(dest_path, &st) < 0) {
|
||||
/* --mkpath would have created this parent dir, but a dry run did
|
||||
* not, so don't chdir into it; flag the destination as not yet
|
||||
* present (as the dir-creation path above does) so the generator
|
||||
* doesn't try to compare against the missing tree (#880). Only
|
||||
* the missing-parent case is touched, so an ordinary file-to-file
|
||||
* dry run still itemizes against an existing destination. */
|
||||
dry_run++;
|
||||
change_dir(dest_path, CD_SKIP_CHDIR);
|
||||
} else if (!change_dir(dest_path, CD_NORMAL)) {
|
||||
rsyserr(FERROR, errno, "change_dir#3 %s failed",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
|
||||
Reference in New Issue
Block a user