diff -rup rsync-3.0.7/generator.c rsync-3.0.7.new/generator.c --- rsync-3.0.7/generator.c 2010-12-26 17:39:55.896647045 -0500 +++ rsync-3.0.7.new/generator.c 2010-12-26 17:24:37.351867543 -0500 @@ -1841,7 +1841,7 @@ static void recv_generator(char *fname, 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))) @@ -1877,7 +1877,7 @@ static void recv_generator(char *fname, 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; diff -rup rsync-3.0.7/hlink.c rsync-3.0.7.new/hlink.c --- rsync-3.0.7/hlink.c 2009-12-12 20:22:55.000000000 -0500 +++ rsync-3.0.7.new/hlink.c 2010-12-26 17:25:18.683140222 -0500 @@ -222,7 +222,7 @@ static int maybe_hard_link(struct file_s file->flags |= FLAG_HLINK_DONE; return 0; } - if (make_backups > 0) { + if (make_backups > 1) { if (!make_backup(fname)) return -1; } else if (robust_unlink(fname)) { diff -rup rsync-3.0.7/options.c rsync-3.0.7.new/options.c --- rsync-3.0.7/options.c 2010-12-26 17:39:55.897647028 -0500 +++ rsync-3.0.7.new/options.c 2010-12-26 17:37:40.917032945 -0500 @@ -324,6 +324,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 (see --suffix & --backup-dir)\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"); @@ -609,7 +610,8 @@ static struct poptOption long_options[] {"no-i", 0, POPT_ARG_VAL, &itemize_changes, 0, 0, 0 }, {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 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 }, @@ -1738,8 +1740,11 @@ void server_options(char **args, int *ar argstr[x++] = 'v'; /* the -q option is intentionally left out */ - if (make_backups) + if (make_backups > 1) argstr[x++] = 'b'; + else if (make_backups) + /* XXX Protocol incompatibility! */ + args[ac++] = "--backup-deleted"; if (update_only) argstr[x++] = 'u'; if (!do_xfers) /* Note: NOT "dry_run"! */ diff -rup rsync-3.0.7/receiver.c rsync-3.0.7.new/receiver.c --- rsync-3.0.7/receiver.c 2009-04-12 15:48:59.000000000 -0400 +++ rsync-3.0.7.new/receiver.c 2010-12-26 17:36:28.464313455 -0500 @@ -330,7 +330,7 @@ static void handle_delayed_updates(char 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)) + if (make_backups > 1 && !make_backup(fname)) continue; if (verbose > 2) { rprintf(FINFO, "renaming %s to %s\n", @@ -606,7 +606,7 @@ int recv_files(int f_in, char *local_nam } 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 -rup rsync-3.0.7/rsync.1 rsync-3.0.7.new/rsync.1 --- rsync-3.0.7/rsync.1 2009-12-31 16:18:50.000000000 -0500 +++ rsync-3.0.7.new/rsync.1 2010-12-26 17:44:59.966270941 -0500 @@ -402,6 +402,7 @@ to the detailed description below for a \-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 (see \-\-suffix & \-\-backup-dir) \-\-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 @@ -791,6 +792,11 @@ in the list so that it has a high enough your rules specify a trailing inclusion/exclusion of \(cq\&*\(cq\&, the auto-added rule would never be reached). .IP +.IP "\fB\-\-backup\-deleted\fP" +With this option, deleted destination files are renamed, while +modified destination files are not. Otherwise, this option behaves the +same as \fB\-\-backup\fP, described above. +.IP .IP "\fB\-\-backup\-dir=DIR\fP" In combination with the \fB\-\-backup\fP option, this tells rsync to store all backups in the specified directory on the receiving diff -rup rsync-3.0.7/rsync.c rsync-3.0.7.new/rsync.c --- rsync-3.0.7/rsync.c 2010-12-26 17:39:55.897647028 -0500 +++ rsync-3.0.7.new/rsync.c 2010-12-26 17:37:01.211734700 -0500 @@ -565,7 +565,7 @@ int finish_transfer(const char *fname, c goto do_set_file_attrs; } - if (make_backups > 0 && overwriting_basis) { + if (make_backups > 1 && overwriting_basis) { if (!make_backup(fname)) return 1; if (fnamecmp == fname)