Updated patches to work with the current trunk.
[rsync/rsync-patches.git] / detect-renamed-lax.diff
CommitLineData
9ff55583
WD
1This patch adds the options --detect-renamed-lax and --detect-moved.
2These modify the --detect-renamed algorithm to adopt a matching file
3without verifying that the content is as expected. The former blindly
4accepts a file that matches in size and modified time. The latter
5requires that the filename also match (ignoring any renamed files).
6
7This patch is EXPERIMENTAL, though it did work correctly in my light
8testing.
9
10To 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
17FIXME: If a run with --detect-renamed-lax stages a different-basename
18destination file and then gets interrupted, a subsequent run that
19switches to --detect-moved blindly accepts the staged file.
20
21-- Matt McCutchen <hashproduct+rsync@gmail.com>
22
cc3e685d 23diff --git a/generator.c b/generator.c
fc557362 24index 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 60diff --git a/options.c b/options.c
fc557362 61index 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 101diff --git a/rsync.yo b/rsync.yo
fc557362 102index 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