1This patch from Antti Tapaninen added the --omit-dir-changes option, which 2tells rsync to not affect any attributes on the directories in the transfer. 3 4To use this patch, run these commands for a successful build: 5 6 patch -p1 <patches/omit-dir-changes.diff 7 ./configure (optional if already run) 8 make 9 10--- old/generator.c 11+++ new/generator.c 12@@ -44,6 +44,7 @@ extern int preserve_uid; 13 extern int preserve_gid; 14 extern int preserve_times; 15 extern int omit_dir_times; 16+extern int omit_dir_changes; 17 extern int delete_mode; 18 extern int delete_before; 19 extern int delete_during; 20@@ -348,10 +349,11 @@ void itemize(struct file_struct *file, i 21 iflags |= ITEM_REPORT_TIME; 22 if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS)) 23 iflags |= ITEM_REPORT_PERMS; 24- if (preserve_uid && am_root && file->uid != st->st_uid) 25+ if (preserve_uid && am_root && file->uid != st->st_uid 26+ && !(omit_dir_changes && S_ISDIR(st->st_mode))) 27 iflags |= ITEM_REPORT_OWNER; 28- if (preserve_gid && file->gid != GID_NONE 29- && st->st_gid != file->gid) 30+ if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid 31+ && !(omit_dir_changes && S_ISDIR(st->st_mode))) 32 iflags |= ITEM_REPORT_GROUP; 33 } else 34 iflags |= ITEM_IS_NEW; 35@@ -892,7 +894,7 @@ static void recv_generator(char *fname, 36 37 /* If we're not preserving permissions, change the file-list's 38 * mode based on the local permissions and some heuristics. */ 39- if (!preserve_perms) { 40+ if (!preserve_perms || (omit_dir_changes && S_ISDIR(st.st_mode))) { 41 int exists = statret == 0 42 && S_ISDIR(st.st_mode) == S_ISDIR(file->mode); 43 file->mode = dest_mode(file->mode, st.st_mode, exists); 44--- old/options.c 45+++ new/options.c 46@@ -55,6 +55,7 @@ int preserve_uid = 0; 47 int preserve_gid = 0; 48 int preserve_times = 0; 49 int omit_dir_times = 0; 50+int omit_dir_changes = 0; 51 int update_only = 0; 52 int cvs_exclude = 0; 53 int dry_run = 0; 54@@ -313,6 +314,7 @@ void usage(enum logcode F) 55 rprintf(F," -D same as --devices --specials\n"); 56 rprintf(F," -t, --times preserve times\n"); 57 rprintf(F," -O, --omit-dir-times omit directories when preserving times\n"); 58+ rprintf(F," --omit-dir-changes omit directories when preserving any attributes\n"); 59 rprintf(F," --super receiver attempts super-user activities\n"); 60 rprintf(F," -S, --sparse handle sparse files efficiently\n"); 61 rprintf(F," -n, --dry-run show what would have been transferred\n"); 62@@ -429,6 +431,7 @@ static struct poptOption long_options[] 63 {"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 }, 64 {"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 }, 65 {"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 2, 0, 0 }, 66+ {"omit-dir-changes", 0, POPT_ARG_NONE, &omit_dir_changes, 0, 0, 0 }, 67 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 }, 68 {"super", 0, POPT_ARG_VAL, &am_root, 2, 0, 0 }, 69 {"no-super", 0, POPT_ARG_VAL, &am_root, 0, 0, 0 }, 70@@ -1287,6 +1290,9 @@ int parse_arguments(int *argc, const cha 71 "P *%s", backup_suffix); 72 parse_rule(&filter_list, backup_dir_buf, 0, 0); 73 } 74+ 75+ if (omit_dir_changes) 76+ omit_dir_times = 2; 77 if (make_backups && !backup_dir) 78 omit_dir_times = 1; 79 80@@ -1515,6 +1521,8 @@ void server_options(char **args,int *arg 81 argstr[x++] = 'm'; 82 if (omit_dir_times == 2) 83 argstr[x++] = 'O'; 84+ if (omit_dir_changes == 1) 85+ args[ac++] = "--omit-dir-changes"; 86 } else { 87 if (copy_links) 88 argstr[x++] = 'L'; 89--- old/receiver.c 90+++ new/receiver.c 91@@ -37,6 +37,7 @@ extern int protocol_version; 92 extern int relative_paths; 93 extern int preserve_hard_links; 94 extern int preserve_perms; 95+extern int omit_dir_changes; 96 extern int basis_dir_cnt; 97 extern int make_backups; 98 extern int cleanup_got_literal; 99@@ -551,7 +552,7 @@ int recv_files(int f_in, struct file_lis 100 101 /* If we're not preserving permissions, change the file-list's 102 * mode based on the local permissions and some heuristics. */ 103- if (!preserve_perms) { 104+ if (!preserve_perms || (omit_dir_changes && S_ISDIR(st.st_mode))) { 105 int exists = fd1 != -1; 106 file->mode = dest_mode(file->mode, st.st_mode, exists); 107 } 108--- old/rsync.c 109+++ new/rsync.c 110@@ -36,6 +36,7 @@ extern int preserve_perms; 111 extern int preserve_executability; 112 extern int preserve_times; 113 extern int omit_dir_times; 114+extern int omit_dir_changes; 115 extern int am_root; 116 extern int am_server; 117 extern int am_sender; 118@@ -162,9 +163,11 @@ int set_file_attrs(char *fname, struct f 119 updated = 1; 120 } 121 122- change_uid = am_root && preserve_uid && st->st_uid != file->uid; 123+ change_uid = am_root && preserve_uid && st->st_uid != file->uid 124+ && !(omit_dir_changes && S_ISDIR(st->st_mode)); 125 change_gid = preserve_gid && file->gid != GID_NONE 126- && st->st_gid != file->gid; 127+ && st->st_gid != file->gid 128+ && !(omit_dir_changes && S_ISDIR(st->st_mode)); 129 #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK 130 if (S_ISLNK(st->st_mode)) 131 ; 132