Adding backup-deleted patch adapted from bug 7889
authorWayne Davison <wayned@samba.org>
Sat, 9 Apr 2011 16:15:56 +0000 (09:15 -0700)
committerWayne Davison <wayned@samba.org>
Sat, 9 Apr 2011 16:36:32 +0000 (09:36 -0700)
by Jonathan Kamens.

backup-deleted.diff [new file with mode: 0644]

diff --git a/backup-deleted.diff b/backup-deleted.diff
new file mode 100644 (file)
index 0000000..380067a
--- /dev/null
@@ -0,0 +1,128 @@
+This patches adds the --backup-deleted option, as proposed by Jonathan
+Kames in bug 7889.
+
+To use this patch, run these commands for a successful build:
+
+    patch -p1 <patches/backup-deleted.diff
+    ./configure                                 (optional if already run)
+    make
+
+based-on: 591c224584c04e0d6f58ece969946bd5472f7c89
+diff --git a/generator.c b/generator.c
+--- a/generator.c
++++ b/generator.c
+@@ -1702,7 +1702,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+               goto notify_others;
+       if (read_batch || whole_file) {
+-              if (inplace && make_backups > 0 && fnamecmp_type == FNAMECMP_FNAME) {
++              if (inplace && make_backups > 1 && fnamecmp_type == FNAMECMP_FNAME) {
+                       if (!(backupptr = get_backup_name(fname)))
+                               goto cleanup;
+                       if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
+@@ -1738,7 +1738,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+               goto notify_others;
+       }
+-      if (inplace && make_backups > 0 && fnamecmp_type == FNAMECMP_FNAME) {
++      if (inplace && make_backups > 1 && fnamecmp_type == FNAMECMP_FNAME) {
+               if (!(backupptr = get_backup_name(fname))) {
+                       close(fd);
+                       goto cleanup;
+@@ -1877,7 +1877,7 @@ int atomic_create(struct file_struct *file, char *fname, const char *lnk,
+               skip_atomic = 0;
+       if (del_for_flag) {
+-              if (make_backups > 0 && !dir_in_the_way) {
++              if (make_backups > 1 && !dir_in_the_way) {
+                       if (!make_backup(fname, skip_atomic))
+                               return 0;
+               } else if (skip_atomic) {
+diff --git a/options.c b/options.c
+--- a/options.c
++++ b/options.c
+@@ -674,6 +674,7 @@ void usage(enum logcode F)
+   rprintf(F," -R, --relative              use relative path names\n");
+   rprintf(F,"     --no-implied-dirs       don't send implied dirs with --relative\n");
+   rprintf(F," -b, --backup                make backups (see --suffix & --backup-dir)\n");
++  rprintf(F,"     --backup-deleted        make backups only of deleted files\n");
+   rprintf(F,"     --backup-dir=DIR        make backups into hierarchy based in DIR\n");
+   rprintf(F,"     --suffix=SUFFIX         set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
+   rprintf(F," -u, --update                skip files that are newer on the receiver\n");
+@@ -982,7 +983,8 @@ static struct poptOption long_options[] = {
+   {"no-i",             0,  POPT_ARG_VAL,    &itemize_changes, 0, 0, 0 },
+   {"bwlimit",          0,  POPT_ARG_STRING, &bwlimit_arg, OPT_BWLIMIT, 0, 0 },
+   {"no-bwlimit",       0,  POPT_ARG_VAL,    &bwlimit, 0, 0, 0 },
+-  {"backup",          'b', POPT_ARG_VAL,    &make_backups, 1, 0, 0 },
++  {"backup",          'b', POPT_ARG_VAL,    &make_backups, 2, 0, 0 },
++  {"backup-deleted",   0,  POPT_ARG_VAL,    &make_backups, 1, 0, 0 },
+   {"no-backup",        0,  POPT_ARG_VAL,    &make_backups, 0, 0, 0 },
+   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
+   {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
+@@ -2520,6 +2522,10 @@ void server_options(char **args, int *argc_p)
+       }
+       if (am_sender) {
++              /* A remote sender just needs the above -b option.
++               * A remote receiver will override that with this option. */
++              if (make_backups == 1)
++                      args[ac++] = "--backup-deleted";
+               if (max_delete > 0) {
+                       if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
+                               goto oom;
+diff --git a/receiver.c b/receiver.c
+--- a/receiver.c
++++ b/receiver.c
+@@ -418,7 +418,7 @@ static void handle_delayed_updates(char *local_name)
+               struct file_struct *file = cur_flist->files[ndx];
+               fname = local_name ? local_name : f_name(file, NULL);
+               if ((partialptr = partial_dir_fname(fname)) != NULL) {
+-                      if (make_backups > 0 && !make_backup(fname, False))
++                      if (make_backups > 1 && !make_backup(fname, False))
+                               continue;
+                       if (DEBUG_GTE(RECV, 1)) {
+                               rprintf(FINFO, "renaming %s to %s\n",
+@@ -725,7 +725,7 @@ int recv_files(int f_in, int f_out, char *local_name)
+               } else {
+                       /* Reminder: --inplace && --partial-dir are never
+                        * enabled at the same time. */
+-                      if (inplace && make_backups > 0) {
++                      if (inplace && make_backups > 1) {
+                               if (!(fnamecmp = get_backup_name(fname)))
+                                       fnamecmp = fname;
+                               else
+diff --git a/rsync.c b/rsync.c
+--- a/rsync.c
++++ b/rsync.c
+@@ -633,7 +633,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+               goto do_set_file_attrs;
+       }
+-      if (make_backups > 0 && overwriting_basis) {
++      if (make_backups > 1 && overwriting_basis) {
+               int ok = make_backup(fname, False);
+               if (!ok)
+                       return 1;
+diff --git a/rsync.yo b/rsync.yo
+--- a/rsync.yo
++++ b/rsync.yo
+@@ -329,6 +329,7 @@ to the detailed description below for a complete description.  verb(
+  -R, --relative              use relative path names
+      --no-implied-dirs       don't send implied dirs with --relative
+  -b, --backup                make backups (see --suffix & --backup-dir)
++     --backup-deleted        make backups only of deleted files
+      --backup-dir=DIR        make backups into hierarchy based in DIR
+      --suffix=SUFFIX         backup suffix (default ~ w/o --backup-dir)
+  -u, --update                skip files that are newer on the receiver
+@@ -731,6 +732,11 @@ in the list so that it has a high enough priority to be effective (e.g., if
+ your rules specify a trailing inclusion/exclusion of '*', the auto-added
+ rule would never be reached).
++dit(bf(--backup-deleted)) With this option, deleted destination files are
++renamed, while modified destination files are not. Otherwise, this option
++behaves the same as bf(--backup), described above.  Note that if bf(--backup)
++is also specified, whichever option is specified last takes precedence.
++
+ dit(bf(--backup-dir=DIR)) In combination with the bf(--backup) option, this
+ tells rsync to store all backups in the specified directory on the receiving
+ side.  This can be used for incremental backups.  You can additionally