Commit | Line | Data |
---|---|---|
9ff55583 WD |
1 | This patch adds the options --detect-renamed-lax and --detect-moved. |
2 | These modify the --detect-renamed algorithm to adopt a matching file | |
3 | without verifying that the content is as expected. The former blindly | |
4 | accepts a file that matches in size and modified time. The latter | |
5 | requires that the filename also match (ignoring any renamed files). | |
6 | ||
7 | This patch is EXPERIMENTAL, though it did work correctly in my light | |
8 | testing. | |
9 | ||
10 | To use this patch, run these commands for a successful build: | |
11 | ||
12 | patch -p1 <patches/detect-renamed.diff | |
13 | patch -p1 <patches/detect-renamed-lax.diff | |
14 | ./configure (optional if already run) | |
15 | make | |
16 | ||
17 | FIXME: If a run with --detect-renamed-lax stages a different-basename | |
18 | destination file and then gets interrupted, a subsequent run that | |
19 | switches to --detect-moved blindly accepts the staged file. | |
20 | ||
21 | -- Matt McCutchen <hashproduct+rsync@gmail.com> | |
22 | ||
cc3e685d | 23 | diff --git a/generator.c b/generator.c |
fc557362 | 24 | index 35ba203..ac844ac 100644 |
cc3e685d WD |
25 | --- a/generator.c |
26 | +++ b/generator.c | |
fc557362 | 27 | @@ -469,7 +469,9 @@ static int fattr_find(struct file_struct *f, char *fname) |
9ff55583 WD |
28 | continue; |
29 | } | |
30 | } | |
31 | - ok_match = mid; | |
32 | + /* --detect-moved doesn't allow non-basename matches */ | |
33 | + if (detect_renamed != 3) | |
34 | + ok_match = mid; | |
35 | diff = u_strcmp(fmid->basename, f->basename); | |
36 | if (diff == 0) { | |
37 | good_match = mid; | |
fc557362 | 38 | @@ -1796,6 +1798,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, |
9ff55583 WD |
39 | fnamecmp = partialptr; |
40 | fnamecmp_type = FNAMECMP_PARTIAL_DIR; | |
41 | statret = 0; | |
42 | + if (detect_renamed > 1 && unchanged_file(fnamecmp, file, &sx.st)) { | |
43 | + /* Adopt the partial file. */ | |
44 | + finish_transfer(fname, fnamecmp, NULL, NULL, file, 1, 1); | |
45 | + handle_partial_dir(partialptr, PDIR_DELETE); | |
46 | + if (itemizing) | |
47 | + itemize(fnamecmp, file, ndx, -1, &sx, | |
48 | + ITEM_LOCAL_CHANGE, fnamecmp_type, NULL); | |
49 | +#ifdef SUPPORT_HARD_LINKS | |
50 | + if (preserve_hard_links && F_IS_HLINKED(file)) | |
51 | + finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1); | |
52 | +#endif | |
53 | + if (remove_source_files == 1) | |
54 | + goto return_with_success; | |
55 | + goto cleanup; | |
56 | + } | |
57 | } | |
58 | ||
59 | if (!do_xfers) | |
cc3e685d | 60 | diff --git a/options.c b/options.c |
fc557362 | 61 | index 7e454b3..1da38cb 100644 |
cc3e685d WD |
62 | --- a/options.c |
63 | +++ b/options.c | |
fc557362 | 64 | @@ -744,6 +744,8 @@ void usage(enum logcode F) |
9ff55583 WD |
65 | rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n"); |
66 | rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n"); | |
67 | rprintf(F," --detect-renamed try to find renamed files to speed up the transfer\n"); | |
68 | + rprintf(F," --detect-renamed-lax ... and assume identical to source files (risky!)\n"); | |
69 | + rprintf(F," --detect-moved ... only if basenames match (less risky)\n"); | |
70 | rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n"); | |
71 | rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n"); | |
72 | rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n"); | |
fc557362 | 73 | @@ -939,7 +941,9 @@ static struct poptOption long_options[] = { |
9ff55583 WD |
74 | {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 }, |
75 | {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 }, | |
76 | {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 }, | |
77 | - {"detect-renamed", 0, POPT_ARG_NONE, &detect_renamed, 0, 0, 0 }, | |
78 | + {"detect-renamed", 0, POPT_ARG_VAL, &detect_renamed, 1, 0, 0 }, | |
79 | + {"detect-renamed-lax",0, POPT_ARG_VAL, &detect_renamed, 2, 0, 0 }, | |
80 | + {"detect-moved", 0, POPT_ARG_VAL, &detect_renamed, 3, 0, 0 }, | |
c0c7984e WD |
81 | {"fuzzy", 'y', POPT_ARG_VAL, &fuzzy_basis, 1, 0, 0 }, |
82 | {"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 }, | |
83 | {"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 }, | |
fc557362 | 84 | @@ -2480,8 +2484,14 @@ void server_options(char **args, int *argc_p) |
7c4c2959 WD |
85 | args[ac++] = "--super"; |
86 | if (size_only) | |
87 | args[ac++] = "--size-only"; | |
88 | - if (detect_renamed) | |
89 | - args[ac++] = "--detect-renamed"; | |
90 | + if (detect_renamed) { | |
91 | + if (detect_renamed == 1) | |
92 | + args[ac++] = "--detect-renamed"; | |
93 | + else if (detect_renamed == 2) | |
94 | + args[ac++] = "--detect-renamed-lax"; | |
95 | + else | |
96 | + args[ac++] = "--detect-moved"; | |
97 | + } | |
fc557362 WD |
98 | if (do_stats) |
99 | args[ac++] = "--stats"; | |
7c4c2959 | 100 | } else { |
cc3e685d | 101 | diff --git a/rsync.yo b/rsync.yo |
fc557362 | 102 | index 4df39b0..e254152 100644 |
cc3e685d WD |
103 | --- a/rsync.yo |
104 | +++ b/rsync.yo | |
fc557362 | 105 | @@ -398,6 +398,8 @@ to the detailed description below for a complete description. verb( |
9ff55583 WD |
106 | -T, --temp-dir=DIR create temporary files in directory DIR |
107 | -y, --fuzzy find similar file for basis if no dest file | |
108 | --detect-renamed try to find renamed files to speed the xfer | |
109 | + --detect-renamed-lax ...& assume identical to src files (risky!) | |
110 | + --detect-moved ... only if basenames match (less risky) | |
111 | --compare-dest=DIR also compare received files relative to DIR | |
112 | --copy-dest=DIR ... and include copies of unchanged files | |
113 | --link-dest=DIR hardlink to files in DIR when unchanged | |
fc557362 | 114 | @@ -1621,6 +1623,17 @@ the bf(--partial-dir) option, that directory will be used instead. These |
9ff55583 WD |
115 | potential alternate-basis files will be removed as the transfer progresses. |
116 | This option conflicts with bf(--inplace) and bf(--append). | |
117 | ||
118 | +dit(bf(--detect-renamed-lax)) This version of bf(--detect-renamed) | |
119 | +makes rsync hard-link em(dest/D) to em(dest/S) without verifying that | |
120 | +em(src/S) and em(dest/S) have the same data. This poses a significant risk | |
121 | +of corrupting the destination by representing a new source file by an | |
122 | +unrelated destination file that coincidentally passes the quick check with the | |
123 | +source file. Use this option only if you accept the risk and disk I/O is a | |
124 | +bottleneck. | |
125 | + | |
126 | +dit(bf(--detect-moved)) A less risky variant of bf(--detect-renamed-lax) that | |
127 | +only uses a destination file that has the same basename as the new source file. | |
128 | + | |
129 | dit(bf(--compare-dest=DIR)) This option instructs rsync to use em(DIR) on | |
130 | the destination machine as an additional hierarchy to compare destination | |
131 | files against doing transfers (if the files are missing in the destination |