Merge branch 'kg/gc-auto-windows-workaround'
[alt-git.git] / t / t3034-merge-recursive-rename-options.sh
blob3d9fae68c41c85b4393e618cfe3706212d5c2dce
1 #!/bin/sh
3 test_description='merge-recursive rename options
5 Test rename detection by examining rename/delete conflicts.
7 * (HEAD -> rename) rename
8 | * (master) delete
9 |/
10 * base
12 git diff --name-status base master
13 D 0-old
14 D 1-old
15 D 2-old
16 D 3-old
18 git diff --name-status -M01 base rename
19 R025 0-old 0-new
20 R050 1-old 1-new
21 R075 2-old 2-new
22 R100 3-old 3-new
24 Actual similarity indices are parsed from diff output. We rely on the fact that
25 they are rounded down (see, e.g., Documentation/diff-generate-patch.txt, which
26 mentions this in a different context).
29 . ./test-lib.sh
31 get_expected_stages () {
32 git checkout rename -- $1-new &&
33 git ls-files --stage $1-new >expected-stages-undetected-$1 &&
34 sed "s/ 0 / 2 /" <expected-stages-undetected-$1 \
35 >expected-stages-detected-$1 &&
36 git read-tree -u --reset HEAD
39 rename_detected () {
40 git ls-files --stage $1-old $1-new >stages-actual-$1 &&
41 test_cmp expected-stages-detected-$1 stages-actual-$1
44 rename_undetected () {
45 git ls-files --stage $1-old $1-new >stages-actual-$1 &&
46 test_cmp expected-stages-undetected-$1 stages-actual-$1
49 check_common () {
50 git ls-files --stage >stages-actual &&
51 test_line_count = 4 stages-actual
54 check_threshold_0 () {
55 check_common &&
56 rename_detected 0 &&
57 rename_detected 1 &&
58 rename_detected 2 &&
59 rename_detected 3
62 check_threshold_1 () {
63 check_common &&
64 rename_undetected 0 &&
65 rename_detected 1 &&
66 rename_detected 2 &&
67 rename_detected 3
70 check_threshold_2 () {
71 check_common &&
72 rename_undetected 0 &&
73 rename_undetected 1 &&
74 rename_detected 2 &&
75 rename_detected 3
78 check_exact_renames () {
79 check_common &&
80 rename_undetected 0 &&
81 rename_undetected 1 &&
82 rename_undetected 2 &&
83 rename_detected 3
86 check_no_renames () {
87 check_common &&
88 rename_undetected 0 &&
89 rename_undetected 1 &&
90 rename_undetected 2 &&
91 rename_undetected 3
94 test_expect_success 'setup repo' '
95 cat <<-\EOF >3-old &&
96 33a
97 33b
98 33c
99 33d
101 sed s/33/22/ <3-old >2-old &&
102 sed s/33/11/ <3-old >1-old &&
103 sed s/33/00/ <3-old >0-old &&
104 git add [0-3]-old &&
105 git commit -m base &&
106 git rm [0-3]-old &&
107 git commit -m delete &&
108 git checkout -b rename HEAD^ &&
109 cp 3-old 3-new &&
110 sed 1,1s/./x/ <2-old >2-new &&
111 sed 1,2s/./x/ <1-old >1-new &&
112 sed 1,3s/./x/ <0-old >0-new &&
113 git add [0-3]-new &&
114 git rm [0-3]-old &&
115 git commit -m rename &&
116 get_expected_stages 0 &&
117 get_expected_stages 1 &&
118 get_expected_stages 2 &&
119 get_expected_stages 3 &&
120 check_50="false" &&
121 tail="HEAD^ -- HEAD master"
124 test_expect_success 'setup thresholds' '
125 git diff --name-status -M01 HEAD^ HEAD >diff-output &&
126 test_debug "cat diff-output" &&
127 test_line_count = 4 diff-output &&
128 grep "R[0-9][0-9][0-9] \([0-3]\)-old \1-new" diff-output \
129 >grep-output &&
130 test_cmp diff-output grep-output &&
131 th0=$(sed -n "s/R\(...\) 0-old 0-new/\1/p" <diff-output) &&
132 th1=$(sed -n "s/R\(...\) 1-old 1-new/\1/p" <diff-output) &&
133 th2=$(sed -n "s/R\(...\) 2-old 2-new/\1/p" <diff-output) &&
134 th3=$(sed -n "s/R\(...\) 3-old 3-new/\1/p" <diff-output) &&
135 test "$th0" -lt "$th1" &&
136 test "$th1" -lt "$th2" &&
137 test "$th2" -lt "$th3" &&
138 test "$th3" = 100 &&
139 if test 50 -le "$th0"
140 then
141 check_50=check_threshold_0
142 elif test 50 -le "$th1"
143 then
144 check_50=check_threshold_1
145 elif test 50 -le "$th2"
146 then
147 check_50=check_threshold_2
148 fi &&
149 th0="$th0%" &&
150 th1="$th1%" &&
151 th2="$th2%" &&
152 th3="$th3%"
155 test_expect_success 'assumption for tests: rename detection with diff' '
156 git diff --name-status -M$th0 --diff-filter=R HEAD^ HEAD \
157 >diff-output-0 &&
158 git diff --name-status -M$th1 --diff-filter=R HEAD^ HEAD \
159 >diff-output-1 &&
160 git diff --name-status -M$th2 --diff-filter=R HEAD^ HEAD \
161 >diff-output-2 &&
162 git diff --name-status -M100% --diff-filter=R HEAD^ HEAD \
163 >diff-output-3 &&
164 test_line_count = 4 diff-output-0 &&
165 test_line_count = 3 diff-output-1 &&
166 test_line_count = 2 diff-output-2 &&
167 test_line_count = 1 diff-output-3
170 test_expect_success 'default similarity threshold is 50%' '
171 git read-tree --reset -u HEAD &&
172 test_must_fail git merge-recursive $tail &&
173 $check_50
176 test_expect_success 'low rename threshold' '
177 git read-tree --reset -u HEAD &&
178 test_must_fail git merge-recursive --find-renames=$th0 $tail &&
179 check_threshold_0
182 test_expect_success 'medium rename threshold' '
183 git read-tree --reset -u HEAD &&
184 test_must_fail git merge-recursive --find-renames=$th1 $tail &&
185 check_threshold_1
188 test_expect_success 'high rename threshold' '
189 git read-tree --reset -u HEAD &&
190 test_must_fail git merge-recursive --find-renames=$th2 $tail &&
191 check_threshold_2
194 test_expect_success 'exact renames only' '
195 git read-tree --reset -u HEAD &&
196 test_must_fail git merge-recursive --find-renames=100% $tail &&
197 check_exact_renames
200 test_expect_success 'rename threshold is truncated' '
201 git read-tree --reset -u HEAD &&
202 test_must_fail git merge-recursive --find-renames=200% $tail &&
203 check_exact_renames
206 test_expect_success 'disabled rename detection' '
207 git read-tree --reset -u HEAD &&
208 git merge-recursive --no-renames $tail &&
209 check_no_renames
212 test_expect_success 'last wins in --find-renames=<m> --find-renames=<n>' '
213 git read-tree --reset -u HEAD &&
214 test_must_fail git merge-recursive \
215 --find-renames=$th0 --find-renames=$th2 $tail &&
216 check_threshold_2
219 test_expect_success '--find-renames resets threshold' '
220 git read-tree --reset -u HEAD &&
221 test_must_fail git merge-recursive \
222 --find-renames=$th0 --find-renames $tail &&
223 $check_50
226 test_expect_success 'last wins in --no-renames --find-renames' '
227 git read-tree --reset -u HEAD &&
228 test_must_fail git merge-recursive --no-renames --find-renames $tail &&
229 $check_50
232 test_expect_success 'last wins in --find-renames --no-renames' '
233 git read-tree --reset -u HEAD &&
234 git merge-recursive --find-renames --no-renames $tail &&
235 check_no_renames
238 test_expect_success 'assumption for further tests: trivial merge succeeds' '
239 git read-tree --reset -u HEAD &&
240 git merge-recursive HEAD -- HEAD HEAD &&
241 git diff --quiet --cached &&
242 git merge-recursive --find-renames=$th0 HEAD -- HEAD HEAD &&
243 git diff --quiet --cached &&
244 git merge-recursive --find-renames=$th2 HEAD -- HEAD HEAD &&
245 git diff --quiet --cached &&
246 git merge-recursive --find-renames=100% HEAD -- HEAD HEAD &&
247 git diff --quiet --cached &&
248 git merge-recursive --no-renames HEAD -- HEAD HEAD &&
249 git diff --quiet --cached
252 test_expect_success '--find-renames rejects negative argument' '
253 git read-tree --reset -u HEAD &&
254 test_must_fail git merge-recursive --find-renames=-25 \
255 HEAD -- HEAD HEAD &&
256 git diff --quiet --cached
259 test_expect_success '--find-renames rejects non-numbers' '
260 git read-tree --reset -u HEAD &&
261 test_must_fail git merge-recursive --find-renames=0xf \
262 HEAD -- HEAD HEAD &&
263 git diff --quiet --cached
266 test_expect_success 'rename-threshold=<n> is a synonym for find-renames=<n>' '
267 git read-tree --reset -u HEAD &&
268 test_must_fail git merge-recursive --rename-threshold=$th0 $tail &&
269 check_threshold_0
272 test_expect_success 'last wins in --no-renames --rename-threshold=<n>' '
273 git read-tree --reset -u HEAD &&
274 test_must_fail git merge-recursive --no-renames --rename-threshold=$th0 $tail &&
275 check_threshold_0
278 test_expect_success 'last wins in --rename-threshold=<n> --no-renames' '
279 git read-tree --reset -u HEAD &&
280 git merge-recursive --rename-threshold=$th0 --no-renames $tail &&
281 check_no_renames
284 test_expect_success '--rename-threshold=<n> rejects negative argument' '
285 git read-tree --reset -u HEAD &&
286 test_must_fail git merge-recursive --rename-threshold=-25 \
287 HEAD -- HEAD HEAD &&
288 git diff --quiet --cached
291 test_expect_success '--rename-threshold=<n> rejects non-numbers' '
292 git read-tree --reset -u HEAD &&
293 test_must_fail git merge-recursive --rename-threshold=0xf \
294 HEAD -- HEAD HEAD &&
295 git diff --quiet --cached
298 test_expect_success 'last wins in --rename-threshold=<m> --find-renames=<n>' '
299 git read-tree --reset -u HEAD &&
300 test_must_fail git merge-recursive \
301 --rename-threshold=$th0 --find-renames=$th2 $tail &&
302 check_threshold_2
305 test_expect_success 'last wins in --find-renames=<m> --rename-threshold=<n>' '
306 git read-tree --reset -u HEAD &&
307 test_must_fail git merge-recursive \
308 --find-renames=$th2 --rename-threshold=$th0 $tail &&
309 check_threshold_0
312 test_expect_success 'merge.renames disables rename detection' '
313 git read-tree --reset -u HEAD &&
314 git -c merge.renames=false merge-recursive $tail &&
315 check_no_renames
318 test_expect_success 'merge.renames defaults to diff.renames' '
319 git read-tree --reset -u HEAD &&
320 git -c diff.renames=false merge-recursive $tail &&
321 check_no_renames
324 test_expect_success 'merge.renames overrides diff.renames' '
325 git read-tree --reset -u HEAD &&
326 test_must_fail git -c diff.renames=false -c merge.renames=true merge-recursive $tail &&
327 $check_50
330 test_done