Add the --backup-whole-dirs option to add the --suffix to deleted dirs as well hacks/backup-whole-dirs
authorMatt McCutchen <matt@mattmccutchen.net>
Fri, 5 Sep 2008 19:39:58 +0000 (15:39 -0400)
committerMatt McCutchen <matt@mattmccutchen.net>
Fri, 5 Sep 2008 19:40:23 +0000 (15:40 -0400)
as the files inside.

generator.c
options.c
rsync.yo

index 8557740..a97ce20 100644 (file)
@@ -182,7 +182,9 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
                        --file_extra_cnt;
                        uid_ndx = 0;
                }
-               if (ret == DR_NOT_EMPTY || ret == DR_AT_LIMIT)
+               /* In Peach's use case, we want to move a deleted directory
+                * even if it contains (protected) previous backup files. */
+               if (make_backups < 2 && (ret == DR_NOT_EMPTY || ret == DR_AT_LIMIT))
                        goto check_ret;
                /* OK: try to delete the directory. */
        }
@@ -190,12 +192,14 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
        if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && ++deletion_count > max_delete)
                return DR_AT_LIMIT;
 
-       if (S_ISDIR(mode)) {
-               what = "rmdir";
-               ok = do_rmdir(fbuf) == 0;
-       } else if (make_backups > 0 && (backup_dir || !is_backup_file(fbuf))) {
+       if (make_backups > 0 && (backup_dir || !is_backup_file(fbuf))
+               /* Allow a dir to be backed up as a whole? */
+               && (make_backups >= 2 || !S_ISDIR(mode))) {
                what = "make_backup";
                ok = make_backup(fbuf);
+       } else if (S_ISDIR(mode)) {
+               what = "rmdir";
+               ok = do_rmdir(fbuf) == 0;
        } else {
                what = "unlink";
                ok = robust_unlink(fbuf) == 0;
index 2d04974..5422e20 100644 (file)
--- a/options.c
+++ b/options.c
@@ -661,6 +661,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-whole-dirs     move deleted dirs as a whole (see caveat)\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");
@@ -953,6 +954,7 @@ static struct poptOption long_options[] = {
   {"no-bwlimit",       0,  POPT_ARG_VAL,    &bwlimit, 0, 0, 0 },
   {"backup",          'b', POPT_ARG_VAL,    &make_backups, 1, 0, 0 },
   {"no-backup",        0,  POPT_ARG_VAL,    &make_backups, 0, 0, 0 },
+  {"backup-whole-dirs",0,  POPT_ARG_VAL,    &make_backups, 2, 0, 0 },
   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
   {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
   {"list-only",        0,  POPT_ARG_VAL,    &list_only, 2, 0, 0 },
@@ -2386,6 +2388,8 @@ void server_options(char **args, int *argc_p)
                        args[ac++] = "--super";
                if (size_only)
                        args[ac++] = "--size-only";
+               if (make_backups > 1)
+                       args[ac++] = "--backup-whole-dirs";
        } else {
                if (skip_compress) {
                        if (asprintf(&arg, "--skip-compress=%s", skip_compress) < 0)
index 79cbf07..ac31942 100644 (file)
--- a/rsync.yo
+++ b/rsync.yo
@@ -325,6 +325,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-whole-dirs     move deleted dirs as a whole (see caveat)
      --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
@@ -717,6 +718,12 @@ 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-whole-dirs)) This option makes rsync back up a destination
+directory that no longer exists on the source as a whole by renaming it with
+the suffix, in addition to renaming the files inside.  Warning: this happens
+irrespective of any non-perishably protected descendants of the directory.
+This is a hack for Matteo "Peach" Pescarin's use case.
+
 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