This patch adds a --source-backup option that backs up source files removed due to --remove-source-files. To use this patch, run these commands for a successful build: patch -p1 based-on: e94bad1c156fc3910f24e2b3b71a81b0b0bdeb70 diff --git a/options.c b/options.c --- a/options.c +++ b/options.c @@ -32,6 +32,7 @@ extern filter_rule_list filter_list; extern filter_rule_list daemon_filter_list; int make_backups = 0; +int make_source_backups = 0; /** * If 1, send the whole file as literal data rather than trying to @@ -767,6 +768,7 @@ static struct poptOption long_options[] = { {"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 }, + {"source-backup", 0, POPT_ARG_NONE, &make_source_backups, 0, 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 }, @@ -2768,6 +2770,8 @@ void server_options(char **args, int *argc_p) goto oom; args[ac++] = arg; } + if (make_source_backups) + args[ac++] = "--source-backup"; } if (max_alloc_arg && max_alloc != DEFAULT_MAX_ALLOC) { diff --git a/rsync.1.md b/rsync.1.md --- a/rsync.1.md +++ b/rsync.1.md @@ -391,6 +391,7 @@ detailed description below for a complete description. --existing skip creating new files on receiver --ignore-existing skip updating files that exist on receiver --remove-source-files sender removes synchronized files (non-dir) +--source-backup ... and backs up those files --del an alias for --delete-during --delete delete extraneous files from dest dirs --delete-before receiver deletes before xfer, not during @@ -1620,6 +1621,16 @@ your home directory (remove the '=' for that). Starting with 3.1.0, rsync will skip the sender-side removal (and output an error) if the file's size or modify time has not stayed unchanged. +0. `--source-backup` + + Makes the sender back up the source files it removes due to + `--remove-source-files`. This option is independent of `--backup` but uses + the same `--backup-dir` and `--suffix` settings, if any. With + `--backup-dir`, rsync looks for each file's backup dir relative to the + source argument the file came from. Consequently, if the `--backup-dir` + path is relative, each source argument gets a separate backup dir at that + path relative to the argument. + 0. `--delete` This tells rsync to delete extraneous files from the receiving side (ones diff --git a/sender.c b/sender.c --- a/sender.c +++ b/sender.c @@ -41,6 +41,7 @@ extern int protocol_version; extern int remove_source_files; extern int updating_basis_file; extern int make_backups; +extern int make_source_backups; extern int inplace; extern int inplace_partial; extern int batch_fd; @@ -127,6 +128,7 @@ void successful_send(int ndx) struct file_struct *file; struct file_list *flist; STRUCT_STAT st; + int result; if (!remove_source_files) return; @@ -151,7 +153,11 @@ void successful_send(int ndx) return; } - if (do_unlink(fname) < 0) { + if (make_source_backups) + result = !make_backup(fname, True); + else + result = do_unlink(fname); + if (result < 0) { failed_op = "remove"; failed: if (errno == ENOENT) diff -Nurp a/rsync.1 b/rsync.1 --- a/rsync.1 +++ b/rsync.1 @@ -467,6 +467,7 @@ detailed description below for a complet --existing skip creating new files on receiver --ignore-existing skip updating files that exist on receiver --remove-source-files sender removes synchronized files (non-dir) +--source-backup ... and backs up those files --del an alias for --delete-during --delete delete extraneous files from dest dirs --delete-before receiver deletes before xfer, not during @@ -1679,6 +1680,14 @@ rsync transfer). .IP Starting with 3.1.0, rsync will skip the sender-side removal (and output an error) if the file's size or modify time has not stayed unchanged. +.IP "\fB\-\-source-backup\fP" +Makes the sender back up the source files it removes due to +\fB\-\-remove-source-files\fP. This option is independent of \fB\-\-backup\fP but uses +the same \fB\-\-backup-dir\fP and \fB\-\-suffix\fP settings, if any. With +\fB\-\-backup-dir\fP, rsync looks for each file's backup dir relative to the +source argument the file came from. Consequently, if the \fB\-\-backup-dir\fP +path is relative, each source argument gets a separate backup dir at that +path relative to the argument. .IP "\fB\-\-delete\fP" This tells rsync to delete extraneous files from the receiving side (ones that aren't on the sending side), but only for the directories that are diff -Nurp a/rsync.1.html b/rsync.1.html --- a/rsync.1.html +++ b/rsync.1.html @@ -382,6 +382,7 @@ detailed description below for a complet --existing skip creating new files on receiver --ignore-existing skip updating files that exist on receiver --remove-source-files sender removes synchronized files (non-dir) +--source-backup ... and backs up those files --del an alias for --delete-during --delete delete extraneous files from dest dirs --delete-before receiver deletes before xfer, not during @@ -1549,6 +1550,16 @@ rsync transfer).

error) if the file's size or modify time has not stayed unchanged.

+
--source-backup
+

Makes the sender back up the source files it removes due to +--remove-source-files. This option is independent of --backup but uses +the same --backup-dir and --suffix settings, if any. With +--backup-dir, rsync looks for each file's backup dir relative to the +source argument the file came from. Consequently, if the --backup-dir +path is relative, each source argument gets a separate backup dir at that +path relative to the argument.

+
+
--delete

This tells rsync to delete extraneous files from the receiving side (ones that aren't on the sending side), but only for the directories that are