1 This patches adds the --backup-deleted option, as proposed by Jonathan
4 To use this patch, run these commands for a successful build:
6 patch -p1 <patches/backup-deleted.diff
7 ./configure (optional if already run)
10 based-on: 035a13f7e483efa47847c5d77a8b0dd30ebd8925
11 diff --git a/generator.c b/generator.c
14 @@ -1806,7 +1806,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
17 if (read_batch || whole_file) {
18 - if (inplace && make_backups > 0 && fnamecmp_type == FNAMECMP_FNAME) {
19 + if (inplace && make_backups > 1 && fnamecmp_type == FNAMECMP_FNAME) {
20 if (!(backupptr = get_backup_name(fname)))
22 if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
23 @@ -1842,7 +1842,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
27 - if (inplace && make_backups > 0 && fnamecmp_type == FNAMECMP_FNAME) {
28 + if (inplace && make_backups > 1 && fnamecmp_type == FNAMECMP_FNAME) {
29 if (!(backupptr = get_backup_name(fname))) {
32 @@ -1966,7 +1966,7 @@ int atomic_create(struct file_struct *file, char *fname, const char *slnk, const
36 - if (make_backups > 0 && !dir_in_the_way) {
37 + if (make_backups > 1 && !dir_in_the_way) {
38 if (!make_backup(fname, skip_atomic))
40 } else if (skip_atomic) {
41 diff --git a/options.c b/options.c
44 @@ -683,6 +683,7 @@ void usage(enum logcode F)
45 rprintf(F," -R, --relative use relative path names\n");
46 rprintf(F," --no-implied-dirs don't send implied dirs with --relative\n");
47 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
48 + rprintf(F," --backup-deleted make backups only of deleted files\n");
49 rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
50 rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
51 rprintf(F," -u, --update skip files that are newer on the receiver\n");
52 @@ -1010,7 +1011,8 @@ static struct poptOption long_options[] = {
53 {"no-i", 0, POPT_ARG_VAL, &itemize_changes, 0, 0, 0 },
54 {"bwlimit", 0, POPT_ARG_STRING, &bwlimit_arg, OPT_BWLIMIT, 0, 0 },
55 {"no-bwlimit", 0, POPT_ARG_VAL, &bwlimit, 0, 0, 0 },
56 - {"backup", 'b', POPT_ARG_VAL, &make_backups, 1, 0, 0 },
57 + {"backup", 'b', POPT_ARG_VAL, &make_backups, 2, 0, 0 },
58 + {"backup-deleted", 0, POPT_ARG_VAL, &make_backups, 1, 0, 0 },
59 {"no-backup", 0, POPT_ARG_VAL, &make_backups, 0, 0, 0 },
60 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
61 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
62 @@ -2679,6 +2681,10 @@ void server_options(char **args, int *argc_p)
66 + /* A remote sender just needs the above -b option.
67 + * A remote receiver will override that with this option. */
68 + if (make_backups == 1)
69 + args[ac++] = "--backup-deleted";
71 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
73 diff --git a/receiver.c b/receiver.c
76 @@ -419,7 +419,7 @@ static void handle_delayed_updates(char *local_name)
77 struct file_struct *file = cur_flist->files[ndx];
78 fname = local_name ? local_name : f_name(file, NULL);
79 if ((partialptr = partial_dir_fname(fname)) != NULL) {
80 - if (make_backups > 0 && !make_backup(fname, False))
81 + if (make_backups > 1 && !make_backup(fname, False))
83 if (DEBUG_GTE(RECV, 1)) {
84 rprintf(FINFO, "renaming %s to %s\n",
85 @@ -735,7 +735,7 @@ int recv_files(int f_in, int f_out, char *local_name)
87 /* Reminder: --inplace && --partial-dir are never
88 * enabled at the same time. */
89 - if (inplace && make_backups > 0) {
90 + if (inplace && make_backups > 1) {
91 if (!(fnamecmp = get_backup_name(fname)))
94 diff --git a/rsync.c b/rsync.c
97 @@ -699,7 +699,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
98 goto do_set_file_attrs;
101 - if (make_backups > 0 && overwriting_basis) {
102 + if (make_backups > 1 && overwriting_basis) {
103 int ok = make_backup(fname, False);
105 exit_cleanup(RERR_FILEIO);
106 diff --git a/rsync.yo b/rsync.yo
109 @@ -352,6 +352,7 @@ to the detailed description below for a complete description. verb(
110 -R, --relative use relative path names
111 --no-implied-dirs don't send implied dirs with --relative
112 -b, --backup make backups (see --suffix & --backup-dir)
113 + --backup-deleted make backups only of deleted files
114 --backup-dir=DIR make backups into hierarchy based in DIR
115 --suffix=SUFFIX backup suffix (default ~ w/o --backup-dir)
116 -u, --update skip files that are newer on the receiver
117 @@ -800,6 +801,11 @@ in the list so that it has a high enough priority to be effective (e.g., if
118 your rules specify a trailing inclusion/exclusion of '*', the auto-added
119 rule would never be reached).
121 +dit(bf(--backup-deleted)) With this option, deleted destination files are
122 +renamed, while modified destination files are not. Otherwise, this option
123 +behaves the same as bf(--backup), described above. Note that if bf(--backup)
124 +is also specified, whichever option is specified last takes precedence.
126 dit(bf(--backup-dir=DIR)) In combination with the bf(--backup) option, this
127 tells rsync to store all backups in the specified directory on the receiving
128 side. This can be used for incremental backups. You can additionally