This patches adds the --backup-deleted option, as proposed by Jonathan
Kames in bug 7889.
To use this patch, run these commands for a successful build:
patch -p1 <patches/backup-deleted.diff
./configure (optional if already run)
make
based-on: d73762eea3f15f2c56bb3fa9394ad1883c25c949
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
@@ -1800,7 +1800,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
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)))
@@ -1836,7 +1836,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
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;
@@ -1960,7 +1960,7 @@ int atomic_create(struct file_struct *file, char *fname, const char *slnk, const
skip_atomic = 0;
if (del_for_flag) {
- if (make_backups > 0 && !dir_in_the_way) {
+ if (make_backups > 1 && !dir_in_the_way) {
if (!make_backup(fname, skip_atomic))
return 0;
} else if (skip_atomic) {
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
@@ -678,6 +678,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\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");
@@ -994,7 +995,8 @@ static struct poptOption long_options[] = {
{"no-i", 0, POPT_ARG_VAL, &itemize_changes, 0, 0, 0 },
{"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 },
+ {"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 },
@@ -2632,6 +2634,10 @@ void server_options(char **args, int *argc_p)
}
if (am_sender) {
+ /* A remote sender just needs the above -b option.
+ * A remote receiver will override that with this option. */
+ if (make_backups == 1)
+ args[ac++] = "--backup-deleted";
if (max_delete > 0) {
if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
goto oom;
diff --git a/receiver.c b/receiver.c
--- a/receiver.c
+++ b/receiver.c
@@ -416,7 +416,7 @@ static void handle_delayed_updates(char *local_name)
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, False))
+ if (make_backups > 1 && !make_backup(fname, False))
continue;
if (DEBUG_GTE(RECV, 1)) {
rprintf(FINFO, "renaming %s to %s\n",
@@ -729,7 +729,7 @@ int recv_files(int f_in, int f_out, char *local_name)
} 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 --git a/rsync.c b/rsync.c
--- a/rsync.c
+++ b/rsync.c
@@ -662,7 +662,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
goto do_set_file_attrs;
}
- if (make_backups > 0 && overwriting_basis) {
+ if (make_backups > 1 && overwriting_basis) {
int ok = make_backup(fname, False);
if (!ok)
exit_cleanup(RERR_FILEIO);
diff --git a/rsync.yo b/rsync.yo
--- a/rsync.yo
+++ b/rsync.yo
@@ -346,6 +346,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-deleted make backups only of deleted files
--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
@@ -792,6 +793,11 @@ 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-deleted)) With this option, deleted destination files are
+renamed, while modified destination files are not. Otherwise, this option
+behaves the same as bf(--backup), described above. Note that if bf(--backup)
+is also specified, whichever option is specified last takes precedence.
+
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
diff -Nurp a/rsync.1 b/rsync.1
--- a/rsync.1
+++ b/rsync.1
@@ -422,6 +422,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
\-\-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
@@ -914,6 +915,12 @@ 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. Note that if \fB\-\-backup\fP
+is also specified, whichever option is specified last takes precedence.
+.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