Robin H. Johnson
2016-Jan-16 08:32 UTC
[PATCH v2, resend] ignore-non-existing-directory: add variant of ignore-non-existing
Add new option --ignore-non-existing-directory, that is a variant of --ignore-non-existing, but applies ONLY to directories. This was previously proposed in bug #8366, but I independently had a use case for it in the Gentoo infrastructure. X-URL: https://bugzilla.samba.org/show_bug.cgi?id=8366 X-URL: http://superuser.com/questions/316561/rsync-synchronizing-files-only-without-creating-folders-on-destination Signed-off-by: Robin H. Johnson <robbat2 at gentoo.org> --- generator.c | 21 +++++++++---- options.c | 5 +++ rsync.yo | 8 +++++ testsuite/ignore-non-existing-directory.test | 47 ++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 testsuite/ignore-non-existing-directory.test diff --git a/generator.c b/generator.c index 3a4504f..6cafce6 100644 --- a/generator.c +++ b/generator.c @@ -57,6 +57,7 @@ extern int update_only; extern int human_readable; extern int ignore_existing; extern int ignore_non_existing; +extern int ignore_non_existing_dirs; extern int want_xattr_optim; extern int inplace; extern int append_mode; @@ -1323,22 +1324,28 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, return; } - if (ignore_non_existing > 0 && statret == -1 && stat_errno == ENOENT) { + if ((ignore_non_existing > 0 || ignore_non_existing_dirs > 0) && statret == -1 && stat_errno == ENOENT) { + int actually_ignore = 0; if (is_dir) { if (is_dir < 0) return; + actually_ignore = 1; skip_dir = file; file->flags |= FLAG_MISSING_DIR; } #ifdef SUPPORT_HARD_LINKS - else if (F_IS_HLINKED(file)) + else if (ignore_non_existing > 0 && F_IS_HLINKED(file)) { + actually_ignore = 1; handle_skipped_hlink(file, itemizing, code, f_out); + } #endif - if (INFO_GTE(SKIP, 1)) { - rprintf(FINFO, "not creating new %s \"%s\"\n", - is_dir ? "directory" : "file", fname); + if(actually_ignore == 1) { + if (INFO_GTE(SKIP, 1)) { + rprintf(FINFO, "not creating new %s \"%s\"\n", + is_dir ? "directory" : "file", fname); + } + return; } - return; } if (statret == 0 && !(sx.st.st_mode & S_IWUSR) @@ -2109,6 +2116,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) min_size = -1; ignore_existing = -ignore_existing; ignore_non_existing = -ignore_non_existing; + ignore_non_existing_dirs = -ignore_non_existing_dirs; update_only = -update_only; always_checksum = -always_checksum; size_only = -size_only; @@ -2134,6 +2142,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) min_size = save_min_size; ignore_existing = -ignore_existing; ignore_non_existing = -ignore_non_existing; + ignore_non_existing_dirs = -ignore_non_existing_dirs; update_only = -update_only; always_checksum = -always_checksum; size_only = -size_only; diff --git a/options.c b/options.c index 7e93ea1..7c5c53b 100644 --- a/options.c +++ b/options.c @@ -114,6 +114,7 @@ int fuzzy_basis = 0; size_t bwlimit_writemax = 0; int ignore_existing = 0; int ignore_non_existing = 0; +int ignore_non_existing_dirs = 0; int need_messages_from_generator = 0; int max_delete = INT_MIN; OFF_T max_size = -1; @@ -916,6 +917,7 @@ static struct poptOption long_options[] = { {"no-one-file-system",0, POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, {"no-x", 0, POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 }, + {"ignore-non-existing-directory",0,POPT_ARG_NONE, &ignore_non_existing_dirs, 0, 0, 0 }, {"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 }, {"ignore-non-existing",0,POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 }, {"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 }, @@ -2708,6 +2710,9 @@ void server_options(char **args, int *argc_p) if (ignore_non_existing) args[ac++] = "--existing"; + if (ignore_non_existing_dirs) + args[ac++] = "--ignore-non-existing-directory"; + if (tmpdir) { args[ac++] = "--temp-dir"; args[ac++] = tmpdir; diff --git a/rsync.yo b/rsync.yo index 88479f3..722849f 100644 --- a/rsync.yo +++ b/rsync.yo @@ -1306,6 +1306,14 @@ This option is a transfer rule, not an exclude, so it doesn't affect the data that goes into the file-lists, and thus it doesn't affect deletions. It just limits the files that the receiver requests to be transferred. +dit(bf(--ignore-non-existing-directory)) This tells rsync to skip creating +directories that do not exist yet on the destination. It is a variation on +bf(--ignore-non-existing) that is applied only for directories. + +This option is a transfer rule, not an exclude, so it doesn't affect the +data that goes into the file-lists, and thus it doesn't affect deletions. +It just limits the files that the receiver requests to be transferred. + dit(bf(--ignore-existing)) This tells rsync to skip updating files that already exist on the destination (this does em(not) ignore existing directories, or nothing would get done). See also bf(--existing). diff --git a/testsuite/ignore-non-existing-directory.test b/testsuite/ignore-non-existing-directory.test new file mode 100644 index 0000000..971ee20 --- /dev/null +++ b/testsuite/ignore-non-existing-directory.test @@ -0,0 +1,47 @@ +#! /bin/sh + +# This program is distributable under the terms of the GNU GPL (see +# COPYING). + +. $suitedir/rsync.fns + +makepath "$fromdir/subdir1" "$fromdir/subdir2" "$todir/subdir1" +echo data >"$fromdir/subdir1/file" +echo data >"$todir/subdir1/file2" +echo data >"$fromdir/subdir2/file" + +# Test 1: Ensure subdir2 and content under it are not created +$RSYNC -r --ignore-non-existing-directory -vv "$fromdir/" "$todir/" | tee "$scratchdir/out" +if [ ! -d "$todir/subdir1" ]; then + test_fail 'test 1 failed: subdir1 should have been created' +fi +if [ ! -f "$todir/subdir1/file" ]; then + test_fail 'test 1 failed: subdir1/file should have been created' +fi +if [ ! -f "$todir/subdir1/file2" ]; then + test_fail 'test 1 failed: subdir1/file2 should not have been removed' +fi +if [ -d "$todir/subdir2" ]; then + test_fail 'test 1 failed: subdir2 should not have been created' +fi +if [ -f "$todir/subdir2/file" ]; then + test_fail 'test 1 failed: subdir2/file should not have been created' +fi + +# Test 2: Also ensure that other delete handling was not impacted +$RSYNC -r --delete --ignore-non-existing-directory -vv "$fromdir/" "$todir/" | tee "$scratchdir/out" +if [ ! -d "$todir/subdir1" ]; then + test_fail 'test 2 failed: subdir1 should have been created' +fi +if [ ! -f "$todir/subdir1/file" ]; then + test_fail 'test 2 failed: subdir1/file should have been created' +fi +if [ -f "$todir/subdir1/file2" ]; then + test_fail 'test 2 failed: subdir1/file2 should have been removed' +fi +if [ -d "$todir/subdir2" ]; then + test_fail 'test 2 failed: subdir2 should not have been created' +fi +if [ -f "$todir/subdir2/file" ]; then + test_fail 'test 2 failed: subdir2/file should not have been created' +fi -- 2.3.0
Possibly Parallel Threads
- [PATCH v2] ignore-non-existing-directory: add variant of ignore-non-existing
- [PATCH] ignore-non-existing-directory: add variant of ignore-non-existing
- [PATCH] add option to skip files based on age/mtime
- [PATCH] Unsnarl missing_below/dry_run logic.
- [PATCH] Fix itemize test for objdir != srcdir builds