The local copy we do for --compare-dest simplifies the logic near
[rsync/rsync-patches.git] / copy-dest.diff
CommitLineData
4afbc050
WD
1This adds the option --copy-dest, which works just like --link-dest
2except that identical files are copied into the destination instead
3of hard-linked.
4
d195b286
WD
5--- orig/generator.c 2005-03-03 00:14:56
6+++ generator.c 2005-03-03 00:25:59
4afbc050
WD
7@@ -65,6 +65,7 @@ extern int always_checksum;
8 extern char *partial_dir;
9 extern char *basis_dir[];
10 extern int compare_dest;
11+extern int copy_dest;
12 extern int link_dest;
13 extern int whole_file;
14 extern int local_server;
d195b286 15@@ -824,6 +825,8 @@ static void recv_generator(char *fname,
251c8a01
WD
16 continue;
17 best_match = i;
18 match_level = 2;
19+ if (copy_dest)
20+ break;
21 /* FALL THROUGH */
22 case 2:
23 if (!unchanged_attrs(file, &st))
d195b286 24@@ -857,7 +860,20 @@ static void recv_generator(char *fname,
b25262e2 25 match_level = 2;
4afbc050 26 }
e5718e56 27 #endif
b25262e2 28- if (compare_dest || (match_level && match_level < 3)) {
e5718e56 29+ if (match_level == 2) {
4afbc050
WD
30+ /* Copy the file locally. */
31+ if (copy_file(fnamecmpbuf, fname, file->mode) < 0) {
251c8a01
WD
32+ if (verbose) {
33+ rsyserr(FINFO, errno,
34+ "copy_file %s => %s",
35+ full_fname(fnamecmpbuf),
36+ safe_fname(fname));
37+ }
e5718e56 38+ match_level = 0;
251c8a01 39+ statret = -1;
4afbc050
WD
40+ } else
41+ set_perms(fname, file, NULL, 0);
b25262e2 42+ } else if (compare_dest || match_level == 1) {
4afbc050
WD
43 fnamecmp = fnamecmpbuf;
44 fnamecmp_type = i;
45 }
d195b286
WD
46@@ -935,11 +951,9 @@ static void recv_generator(char *fname,
47 return;
48 }
49 /* Only --compare-dest gets here. */
50- if (unchanged_attrs(file, &st)) {
51- itemize(file, statret, &st, ITEM_NO_DEST_AND_NO_UPDATE,
52- f_out, ndx);
53- return;
54- }
55+ itemize(file, statret, &st, ITEM_NO_DEST_AND_NO_UPDATE,
56+ f_out, ndx);
57+ return;
58 }
59
60 prepare_to_open:
e5718e56 61--- orig/options.c 2005-03-02 09:52:06
251c8a01 62+++ options.c 2005-03-02 10:05:21
4afbc050
WD
63@@ -143,6 +143,7 @@ char *backup_dir = NULL;
64 char backup_dir_buf[MAXPATHLEN];
65 int rsync_port = 0;
66 int compare_dest = 0;
67+int copy_dest = 0;
68 int link_dest = 0;
69 int basis_dir_cnt = 0;
70
71@@ -317,6 +318,7 @@ void usage(enum logcode F)
72 rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
73 rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n");
74 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
75+ rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
76 rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
77 rprintf(F," -z, --compress compress file data during the transfer\n");
78 rprintf(F," -C, --cvs-exclude auto-ignore files the same way CVS does\n");
79@@ -355,7 +357,7 @@ void usage(enum logcode F)
80 }
81
82 enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
83- OPT_FILTER, OPT_COMPARE_DEST, OPT_LINK_DEST,
84+ OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
85 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
86 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
87 OPT_REFUSED_BASE = 9000};
88@@ -424,6 +426,7 @@ static struct poptOption long_options[]
89 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
90 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
91 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
92+ {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
93 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
94 {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
95 /* TODO: Should this take an optional int giving the compression level? */
96@@ -838,6 +841,11 @@ int parse_arguments(int *argc, const cha
97 return 0;
98 #endif
99
100+ case OPT_COPY_DEST:
101+ copy_dest = 1;
102+ dest_option = "--copy-dest";
103+ goto set_dest_dir;
104+
105 case OPT_COMPARE_DEST:
106 compare_dest = 1;
107 dest_option = "--compare-dest";
108@@ -928,9 +936,9 @@ int parse_arguments(int *argc, const cha
109 return 0;
110 }
111
112- if (compare_dest + link_dest > 1) {
113+ if (compare_dest + copy_dest + link_dest > 1) {
114 snprintf(err_buf, sizeof err_buf,
115- "You may not mix --compare-dest and --link-dest.\n");
116+ "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
117 return 0;
118 }
119
d195b286 120--- orig/rsync.yo 2005-03-02 18:01:33
4afbc050
WD
121+++ rsync.yo 2005-02-23 02:05:34
122@@ -353,6 +353,7 @@ to the detailed description below for a
123 -T, --temp-dir=DIR create temporary files in directory DIR
124 -y, --fuzzy find similar file for basis if no dest file
125 --compare-dest=DIR also compare received files relative to DIR
126+ --copy-dest=DIR ... and include copies of unchanged files
127 --link-dest=DIR hardlink to files in DIR when unchanged
128 -z, --compress compress file data during the transfer
129 -C, --cvs-exclude auto-ignore files in the same way CVS does
130@@ -554,8 +555,8 @@ bound.
131
132 The option implies bf(--partial) (since an interrupted transfer does not delete
133 the file), but conflicts with bf(--partial-dir) and bf(--delay-updates).
134-Prior to rsync 2.6.4 bf(--inplace) was also incompatible with bf(--compare-dest)
135-and bf(--link-dest).
136+Prior to rsync 2.6.4 bf(--inplace) was also incompatible with bf(--compare-dest),
137+bf(--copy-dest), and bf(--link-dest).
138
139 WARNING: The file's data will be in an inconsistent state during the
140 transfer (and possibly afterward if the transfer gets interrupted), so you
d195b286
WD
141@@ -957,9 +958,19 @@ the list in the order specified), and if
142 of the em(DIR)s will be selected to try to speed up the transfer.
4afbc050
WD
143
144 If em(DIR) is a relative path, it is relative to the destination directory.
145-See also bf(--link-dest).
146+See also bf(--copy-dest) and bf(--link-dest).
147
148-dit(bf(--link-dest=DIR)) This option behaves like bf(--compare-dest), but
149+dit(bf(--copy-dest=DIR)) This option behaves like bf(--compare-dest), but
150+rsync will also copy unchanged files found in em(DIR) to the destination
151+directory (using the data in the em(DIR) for an efficient copy). This is
152+useful for doing transfers to a new destination while leaving existing
153+files intact, and then doing a flash-cutover when all files have been
154+successfully transferred.
155+
156+If em(DIR) is a relative path, it is relative to the destination directory.
157+See also bf(--compare-dest) and bf(--link-dest).
158+
159+dit(bf(--link-dest=DIR)) This option behaves like bf(--copy-dest), but
160 unchanged files are hard linked from em(DIR) to the destination directory.
161 The files must be identical in all preserved attributes (e.g. permissions,
162 possibly ownership) in order for the files to be linked together.
251c8a01 163@@ -973,7 +984,7 @@ the list in the order specified), and if
4afbc050
WD
164 of the em(DIR)s will be selected to try to speed up the transfer.
165
166 If em(DIR) is a relative path, it is relative to the destination directory.
167-See also bf(--compare-dest).
168+See also bf(--compare-dest) and bf(--copy-dest).
169
170 Note that rsync versions prior to 2.6.1 had a bug that could prevent
171 bf(--link-dest) from working properly for a non-root user when bf(-o) was specified
172--- orig/testsuite/compare-dest.test 2005-02-26 19:51:27
173+++ testsuite/compare-dest.test 2005-03-01 15:57:27
174@@ -31,9 +31,9 @@ $RSYNC -av --exclude=/text --exclude=etc
175 checkit "$RSYNC -avv --no-whole-file \
176 --compare-dest=\"$alt1dir\" --compare-dest=\"$alt2dir\" \
177 \"$fromdir/\" \"$todir/\"" "$chkdir" "$todir"
178-#checkit "$RSYNC -avv --no-whole-file \
179-# --copy-dest=\"$alt1dir\" --copy-dest=\"$alt2dir\" \
180-# \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
181+checkit "$RSYNC -avv --no-whole-file \
182+ --copy-dest=\"$alt1dir\" --copy-dest=\"$alt2dir\" \
183+ \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
184
185 # The script would have aborted on error, so getting here means we've won.
186 exit 0