-- Matt McCutchen <hashproduct@gmail.com>
-based-on: d64bda1c1e79dc385f194d74f7957ce7cd118654
+based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
/**
* If 1, send the whole file as literal data rather than trying to
-@@ -715,6 +716,7 @@ void usage(enum logcode F)
+@@ -728,6 +729,7 @@ void usage(enum logcode F)
rprintf(F," --existing skip creating new files on receiver\n");
rprintf(F," --ignore-existing skip updating files that already exist on receiver\n");
rprintf(F," --remove-source-files sender removes synchronized files (non-dirs)\n");
rprintf(F," --del an alias for --delete-during\n");
rprintf(F," --delete delete extraneous files from destination dirs\n");
rprintf(F," --delete-before receiver deletes before transfer, not during\n");
-@@ -972,6 +974,7 @@ static struct poptOption long_options[] = {
+@@ -990,6 +992,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 },
{"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 },
-@@ -2549,6 +2552,8 @@ void server_options(char **args, int *argc_p)
+@@ -2617,6 +2620,8 @@ void server_options(char **args, int *argc_p)
goto oom;
args[ac++] = arg;
}
diff --git a/rsync.yo b/rsync.yo
--- a/rsync.yo
+++ b/rsync.yo
-@@ -369,6 +369,7 @@ to the detailed description below for a complete description. verb(
+@@ -384,6 +384,7 @@ to the detailed description below for a complete description. verb(
--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)
--del an alias for --delete-during
--delete delete extraneous files from dest dirs
--delete-before receiver deletes before xfer, not during
-@@ -1238,6 +1239,14 @@ dit(bf(--remove-source-files)) This tells rsync to remove from the sending
- side the files (meaning non-directories) that are a part of the transfer
- and have been successfully duplicated on the receiving side.
+@@ -1310,6 +1311,14 @@ bf(--exclude='*.new') for the rsync transfer).
+ 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.
+dit(bf(--source-backup)) Makes the sender back up the source files it removes
+due to bf(--remove-source-files). This option is independent of
extern int inplace;
extern int batch_fd;
extern int write_batch;
-@@ -125,6 +126,7 @@ void successful_send(int ndx)
- char fname[MAXPATHLEN];
+@@ -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;
-@@ -135,7 +137,11 @@ void successful_send(int ndx)
+@@ -151,7 +153,11 @@ void successful_send(int ndx)
return;
- f_name(file, fname);
+ }
-- if (do_unlink(fname) == 0) {
+- if (do_unlink(fname) < 0) {
+ if (make_source_backups)
+ result = !make_backup(fname, True);
+ else
+ result = do_unlink(fname);
-+ if (result == 0) {
- if (INFO_GTE(REMOVE, 1))
- rprintf(FINFO, "sender removed %s\n", fname);
- } else
++ if (result < 0) {
+ failed_op = "remove";
+ failed:
+ if (errno == ENOENT)