From: "Robin H. Johnson" <robb...@gentoo.org>

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 indepentantly 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 <robb...@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


-- 
Please use reply-all for most replies to avoid omitting the mailing list.
To unsubscribe or change options: https://lists.samba.org/mailman/listinfo/rsync
Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html

Reply via email to