On Fri, 2008-09-05 at 20:29 +0200, The Peach wrote:
> Right now: 
> if the directory in the source is deleted, in the destination the files
> contained in the directory are renamed, while the directory itself
> is not.
> 
> So... is it possible to have both renamed instead of only the files?

Yes.  I hacked up a patch to do this for you with a --backup-whole-dirs
option; the patch is attached.  The patched version of rsync is also
available in branch hacks/backup-whole-dirs of my repository.

Matt
diff --git a/generator.c b/generator.c
index 8557740..a97ce20 100644
--- a/generator.c
+++ b/generator.c
@@ -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;
diff --git a/options.c b/options.c
index 2d04974..5422e20 100644
--- 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)
diff --git a/rsync.yo b/rsync.yo
index 79cbf07..ac31942 100644
--- 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
-- 
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