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