]>
Commit | Line | Data |
---|---|---|
1 | #!/bin/sh | |
2 | ||
3 | test_description='Merge-recursive merging renames' | |
4 | . ./test-lib.sh | |
5 | ||
6 | modify () { | |
7 | sed -e "$1" <"$2" >"$2.x" && | |
8 | mv "$2.x" "$2" | |
9 | } | |
10 | ||
11 | test_expect_success 'setup' ' | |
12 | cat >A <<-\EOF && | |
13 | a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | |
14 | b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | |
15 | c cccccccccccccccccccccccccccccccccccccccccccccccc | |
16 | d dddddddddddddddddddddddddddddddddddddddddddddddd | |
17 | e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee | |
18 | f ffffffffffffffffffffffffffffffffffffffffffffffff | |
19 | g gggggggggggggggggggggggggggggggggggggggggggggggg | |
20 | h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh | |
21 | i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii | |
22 | j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj | |
23 | k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk | |
24 | l llllllllllllllllllllllllllllllllllllllllllllllll | |
25 | m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm | |
26 | n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn | |
27 | o oooooooooooooooooooooooooooooooooooooooooooooooo | |
28 | EOF | |
29 | ||
30 | cat >M <<-\EOF && | |
31 | A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | |
32 | B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB | |
33 | C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC | |
34 | D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD | |
35 | E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE | |
36 | F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | |
37 | G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG | |
38 | H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH | |
39 | I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII | |
40 | J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ | |
41 | K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK | |
42 | L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL | |
43 | M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM | |
44 | N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN | |
45 | O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO | |
46 | EOF | |
47 | ||
48 | git add A M && | |
49 | git commit -m "initial has A and M" && | |
50 | git branch white && | |
51 | git branch red && | |
52 | git branch blue && | |
53 | git branch yellow && | |
54 | git branch change && | |
55 | git branch change+rename && | |
56 | ||
57 | sed -e "/^g /s/.*/g : master changes a line/" <A >A+ && | |
58 | mv A+ A && | |
59 | git commit -a -m "master updates A" && | |
60 | ||
61 | git checkout yellow && | |
62 | rm -f M && | |
63 | git commit -a -m "yellow removes M" && | |
64 | ||
65 | git checkout white && | |
66 | sed -e "/^g /s/.*/g : white changes a line/" <A >B && | |
67 | sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N && | |
68 | rm -f A M && | |
69 | git update-index --add --remove A B M N && | |
70 | git commit -m "white renames A->B, M->N" && | |
71 | ||
72 | git checkout red && | |
73 | sed -e "/^g /s/.*/g : red changes a line/" <A >B && | |
74 | sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N && | |
75 | rm -f A M && | |
76 | git update-index --add --remove A B M N && | |
77 | git commit -m "red renames A->B, M->N" && | |
78 | ||
79 | git checkout blue && | |
80 | sed -e "/^g /s/.*/g : blue changes a line/" <A >C && | |
81 | sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N && | |
82 | rm -f A M && | |
83 | git update-index --add --remove A C M N && | |
84 | git commit -m "blue renames A->C, M->N" && | |
85 | ||
86 | git checkout change && | |
87 | sed -e "/^g /s/.*/g : changed line/" <A >A+ && | |
88 | mv A+ A && | |
89 | git commit -q -a -m "changed" && | |
90 | ||
91 | git checkout change+rename && | |
92 | sed -e "/^g /s/.*/g : changed line/" <A >B && | |
93 | rm A && | |
94 | git update-index --add B && | |
95 | git commit -q -a -m "changed and renamed" && | |
96 | ||
97 | git checkout master | |
98 | ' | |
99 | ||
100 | test_expect_success 'pull renaming branch into unrenaming one' \ | |
101 | ' | |
102 | git show-branch && | |
103 | test_expect_code 1 git pull . white && | |
104 | git ls-files -s && | |
105 | git ls-files -u B >b.stages && | |
106 | test_line_count = 3 b.stages && | |
107 | git ls-files -s N >n.stages && | |
108 | test_line_count = 1 n.stages && | |
109 | sed -ne "/^g/{ | |
110 | p | |
111 | q | |
112 | }" B | grep master && | |
113 | git diff --exit-code white N | |
114 | ' | |
115 | ||
116 | test_expect_success 'pull renaming branch into another renaming one' \ | |
117 | ' | |
118 | rm -f B && | |
119 | git reset --hard && | |
120 | git checkout red && | |
121 | test_expect_code 1 git pull . white && | |
122 | git ls-files -u B >b.stages && | |
123 | test_line_count = 3 b.stages && | |
124 | git ls-files -s N >n.stages && | |
125 | test_line_count = 1 n.stages && | |
126 | sed -ne "/^g/{ | |
127 | p | |
128 | q | |
129 | }" B | grep red && | |
130 | git diff --exit-code white N | |
131 | ' | |
132 | ||
133 | test_expect_success 'pull unrenaming branch into renaming one' \ | |
134 | ' | |
135 | git reset --hard && | |
136 | git show-branch && | |
137 | test_expect_code 1 git pull . master && | |
138 | git ls-files -u B >b.stages && | |
139 | test_line_count = 3 b.stages && | |
140 | git ls-files -s N >n.stages && | |
141 | test_line_count = 1 n.stages && | |
142 | sed -ne "/^g/{ | |
143 | p | |
144 | q | |
145 | }" B | grep red && | |
146 | git diff --exit-code white N | |
147 | ' | |
148 | ||
149 | test_expect_success 'pull conflicting renames' \ | |
150 | ' | |
151 | git reset --hard && | |
152 | git show-branch && | |
153 | test_expect_code 1 git pull . blue && | |
154 | git ls-files -u A >a.stages && | |
155 | test_line_count = 1 a.stages && | |
156 | git ls-files -u B >b.stages && | |
157 | test_line_count = 1 b.stages && | |
158 | git ls-files -u C >c.stages && | |
159 | test_line_count = 1 c.stages && | |
160 | git ls-files -s N >n.stages && | |
161 | test_line_count = 1 n.stages && | |
162 | sed -ne "/^g/{ | |
163 | p | |
164 | q | |
165 | }" B | grep red && | |
166 | git diff --exit-code white N | |
167 | ' | |
168 | ||
169 | test_expect_success 'interference with untracked working tree file' ' | |
170 | git reset --hard && | |
171 | git show-branch && | |
172 | echo >A this file should not matter && | |
173 | test_expect_code 1 git pull . white && | |
174 | test_path_is_file A | |
175 | ' | |
176 | ||
177 | test_expect_success 'interference with untracked working tree file' ' | |
178 | git reset --hard && | |
179 | git checkout white && | |
180 | git show-branch && | |
181 | rm -f A && | |
182 | echo >A this file should not matter && | |
183 | test_expect_code 1 git pull . red && | |
184 | test_path_is_file A | |
185 | ' | |
186 | ||
187 | test_expect_success 'interference with untracked working tree file' ' | |
188 | git reset --hard && | |
189 | rm -f A M && | |
190 | git checkout -f master && | |
191 | git tag -f anchor && | |
192 | git show-branch && | |
193 | git pull . yellow && | |
194 | test_path_is_missing M && | |
195 | git reset --hard anchor | |
196 | ' | |
197 | ||
198 | test_expect_success 'updated working tree file should prevent the merge' ' | |
199 | git reset --hard && | |
200 | rm -f A M && | |
201 | git checkout -f master && | |
202 | git tag -f anchor && | |
203 | git show-branch && | |
204 | echo >>M one line addition && | |
205 | cat M >M.saved && | |
206 | test_expect_code 128 git pull . yellow && | |
207 | test_cmp M M.saved && | |
208 | rm -f M.saved | |
209 | ' | |
210 | ||
211 | test_expect_success 'updated working tree file should prevent the merge' ' | |
212 | git reset --hard && | |
213 | rm -f A M && | |
214 | git checkout -f master && | |
215 | git tag -f anchor && | |
216 | git show-branch && | |
217 | echo >>M one line addition && | |
218 | cat M >M.saved && | |
219 | git update-index M && | |
220 | test_expect_code 128 git pull . yellow && | |
221 | test_cmp M M.saved && | |
222 | rm -f M.saved | |
223 | ' | |
224 | ||
225 | test_expect_success 'interference with untracked working tree file' ' | |
226 | git reset --hard && | |
227 | rm -f A M && | |
228 | git checkout -f yellow && | |
229 | git tag -f anchor && | |
230 | git show-branch && | |
231 | echo >M this file should not matter && | |
232 | git pull . master && | |
233 | test_path_is_file M && | |
234 | ! { | |
235 | git ls-files -s | | |
236 | grep M | |
237 | } && | |
238 | git reset --hard anchor | |
239 | ' | |
240 | ||
241 | test_expect_success 'merge of identical changes in a renamed file' ' | |
242 | rm -f A M N && | |
243 | git reset --hard && | |
244 | git checkout change+rename && | |
245 | ||
246 | test-tool chmtime --get -3600 B >old-mtime && | |
247 | GIT_MERGE_VERBOSITY=3 git merge change >out && | |
248 | ||
249 | test-tool chmtime --get B >new-mtime && | |
250 | test_cmp old-mtime new-mtime && | |
251 | ||
252 | git reset --hard HEAD^ && | |
253 | git checkout change && | |
254 | ||
255 | # A will be renamed to B; we check mtimes and file presence | |
256 | test_path_is_missing B && | |
257 | test-tool chmtime --get -3600 A >old-mtime && | |
258 | GIT_MERGE_VERBOSITY=3 git merge change+rename >out && | |
259 | ||
260 | test_path_is_missing A && | |
261 | test-tool chmtime --get B >new-mtime && | |
262 | test $(cat old-mtime) -lt $(cat new-mtime) | |
263 | ' | |
264 | ||
265 | test_expect_success 'setup for rename + d/f conflicts' ' | |
266 | git reset --hard && | |
267 | git checkout --orphan dir-in-way && | |
268 | git rm -rf . && | |
269 | git clean -fdqx && | |
270 | ||
271 | mkdir sub && | |
272 | mkdir dir && | |
273 | printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >sub/file && | |
274 | echo foo >dir/file-in-the-way && | |
275 | git add -A && | |
276 | git commit -m "Common commit" && | |
277 | ||
278 | echo 11 >>sub/file && | |
279 | echo more >>dir/file-in-the-way && | |
280 | git add -u && | |
281 | git commit -m "Commit to merge, with dir in the way" && | |
282 | ||
283 | git checkout -b dir-not-in-way && | |
284 | git reset --soft HEAD^ && | |
285 | git rm -rf dir && | |
286 | git commit -m "Commit to merge, with dir removed" -- dir sub/file && | |
287 | ||
288 | git checkout -b renamed-file-has-no-conflicts dir-in-way~1 && | |
289 | git rm -rf dir && | |
290 | git rm sub/file && | |
291 | printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n" >dir && | |
292 | git add dir && | |
293 | git commit -m "Independent change" && | |
294 | ||
295 | git checkout -b renamed-file-has-conflicts dir-in-way~1 && | |
296 | git rm -rf dir && | |
297 | git mv sub/file dir && | |
298 | echo 12 >>dir && | |
299 | git add dir && | |
300 | git commit -m "Conflicting change" | |
301 | ' | |
302 | ||
303 | test_expect_success 'Rename+D/F conflict; renamed file merges + dir not in way' ' | |
304 | git reset --hard && | |
305 | git checkout -q renamed-file-has-no-conflicts^0 && | |
306 | ||
307 | git merge --strategy=recursive dir-not-in-way && | |
308 | ||
309 | git diff --quiet && | |
310 | test_path_is_file dir && | |
311 | test_write_lines 1 2 3 4 5555 6 7 8 9 10 11 >expected && | |
312 | test_cmp expected dir | |
313 | ' | |
314 | ||
315 | test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' ' | |
316 | git reset --hard && | |
317 | rm -rf dir~* && | |
318 | git checkout -q renamed-file-has-no-conflicts^0 && | |
319 | test_must_fail git merge --strategy=recursive dir-in-way >output && | |
320 | ||
321 | test_i18ngrep "CONFLICT (modify/delete): dir/file-in-the-way" output && | |
322 | test_i18ngrep "Auto-merging dir" output && | |
323 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort | |
324 | then | |
325 | test_i18ngrep "moving it to dir~HEAD instead" output | |
326 | else | |
327 | test_i18ngrep "Adding as dir~HEAD instead" output | |
328 | fi && | |
329 | ||
330 | test 3 -eq "$(git ls-files -u | wc -l)" && | |
331 | test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && | |
332 | ||
333 | test_must_fail git diff --quiet && | |
334 | test_must_fail git diff --cached --quiet && | |
335 | ||
336 | test_path_is_file dir/file-in-the-way && | |
337 | test_path_is_file dir~HEAD && | |
338 | test_cmp expected dir~HEAD | |
339 | ' | |
340 | ||
341 | test_expect_success 'Same as previous, but merged other way' ' | |
342 | git reset --hard && | |
343 | rm -rf dir~* && | |
344 | git checkout -q dir-in-way^0 && | |
345 | test_must_fail git merge --strategy=recursive renamed-file-has-no-conflicts >output 2>errors && | |
346 | ||
347 | ! grep "error: refusing to lose untracked file at" errors && | |
348 | test_i18ngrep "CONFLICT (modify/delete): dir/file-in-the-way" output && | |
349 | test_i18ngrep "Auto-merging dir" output && | |
350 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort | |
351 | then | |
352 | test_i18ngrep "moving it to dir~renamed-file-has-no-conflicts instead" output | |
353 | else | |
354 | test_i18ngrep "Adding as dir~renamed-file-has-no-conflicts instead" output | |
355 | fi && | |
356 | ||
357 | test 3 -eq "$(git ls-files -u | wc -l)" && | |
358 | test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && | |
359 | ||
360 | test_must_fail git diff --quiet && | |
361 | test_must_fail git diff --cached --quiet && | |
362 | ||
363 | test_path_is_file dir/file-in-the-way && | |
364 | test_path_is_file dir~renamed-file-has-no-conflicts && | |
365 | test_cmp expected dir~renamed-file-has-no-conflicts | |
366 | ' | |
367 | ||
368 | test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in way' ' | |
369 | git reset --hard && | |
370 | rm -rf dir~* && | |
371 | git checkout -q renamed-file-has-conflicts^0 && | |
372 | test_must_fail git merge --strategy=recursive dir-not-in-way && | |
373 | ||
374 | test 3 -eq "$(git ls-files -u | wc -l)" && | |
375 | test 3 -eq "$(git ls-files -u dir | wc -l)" && | |
376 | ||
377 | test_must_fail git diff --quiet && | |
378 | test_must_fail git diff --cached --quiet && | |
379 | ||
380 | test_path_is_file dir && | |
381 | cat >expected <<-\EOF && | |
382 | 1 | |
383 | 2 | |
384 | 3 | |
385 | 4 | |
386 | 5 | |
387 | 6 | |
388 | 7 | |
389 | 8 | |
390 | 9 | |
391 | 10 | |
392 | <<<<<<< HEAD:dir | |
393 | 12 | |
394 | ======= | |
395 | 11 | |
396 | >>>>>>> dir-not-in-way:sub/file | |
397 | EOF | |
398 | test_cmp expected dir | |
399 | ' | |
400 | ||
401 | test_expect_success 'Rename+D/F conflict; renamed file cannot merge and dir in the way' ' | |
402 | modify s/dir-not-in-way/dir-in-way/ expected && | |
403 | ||
404 | git reset --hard && | |
405 | rm -rf dir~* && | |
406 | git checkout -q renamed-file-has-conflicts^0 && | |
407 | test_must_fail git merge --strategy=recursive dir-in-way && | |
408 | ||
409 | test 5 -eq "$(git ls-files -u | wc -l)" && | |
410 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort | |
411 | then | |
412 | test 3 -eq "$(git ls-files -u dir~HEAD | wc -l)" | |
413 | else | |
414 | test 3 -eq "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" | |
415 | fi && | |
416 | test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && | |
417 | ||
418 | test_must_fail git diff --quiet && | |
419 | test_must_fail git diff --cached --quiet && | |
420 | ||
421 | test_path_is_file dir/file-in-the-way && | |
422 | test_path_is_file dir~HEAD && | |
423 | test_cmp expected dir~HEAD | |
424 | ' | |
425 | ||
426 | test_expect_success 'Same as previous, but merged other way' ' | |
427 | git reset --hard && | |
428 | rm -rf dir~* && | |
429 | git checkout -q dir-in-way^0 && | |
430 | test_must_fail git merge --strategy=recursive renamed-file-has-conflicts && | |
431 | ||
432 | test 5 -eq "$(git ls-files -u | wc -l)" && | |
433 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort | |
434 | then | |
435 | test 3 -eq "$(git ls-files -u dir~renamed-file-has-conflicts | wc -l)" | |
436 | else | |
437 | test 3 -eq "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" | |
438 | fi && | |
439 | test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && | |
440 | ||
441 | test_must_fail git diff --quiet && | |
442 | test_must_fail git diff --cached --quiet && | |
443 | ||
444 | test_path_is_file dir/file-in-the-way && | |
445 | test_path_is_file dir~renamed-file-has-conflicts && | |
446 | cat >expected <<-\EOF && | |
447 | 1 | |
448 | 2 | |
449 | 3 | |
450 | 4 | |
451 | 5 | |
452 | 6 | |
453 | 7 | |
454 | 8 | |
455 | 9 | |
456 | 10 | |
457 | <<<<<<< HEAD:sub/file | |
458 | 11 | |
459 | ======= | |
460 | 12 | |
461 | >>>>>>> renamed-file-has-conflicts:dir | |
462 | EOF | |
463 | test_cmp expected dir~renamed-file-has-conflicts | |
464 | ' | |
465 | ||
466 | test_expect_success 'setup both rename source and destination involved in D/F conflict' ' | |
467 | git reset --hard && | |
468 | git checkout --orphan rename-dest && | |
469 | git rm -rf . && | |
470 | git clean -fdqx && | |
471 | ||
472 | mkdir one && | |
473 | echo stuff >one/file && | |
474 | git add -A && | |
475 | git commit -m "Common commit" && | |
476 | ||
477 | git mv one/file destdir && | |
478 | git commit -m "Renamed to destdir" && | |
479 | ||
480 | git checkout -b source-conflict HEAD~1 && | |
481 | git rm -rf one && | |
482 | mkdir destdir && | |
483 | touch one destdir/foo && | |
484 | git add -A && | |
485 | git commit -m "Conflicts in the way" | |
486 | ' | |
487 | ||
488 | test_expect_success 'both rename source and destination involved in D/F conflict' ' | |
489 | git reset --hard && | |
490 | rm -rf dir~* && | |
491 | git checkout -q rename-dest^0 && | |
492 | test_must_fail git merge --strategy=recursive source-conflict && | |
493 | ||
494 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort | |
495 | then | |
496 | test 2 -eq "$(git ls-files -u | wc -l)" | |
497 | else | |
498 | test 1 -eq "$(git ls-files -u | wc -l)" | |
499 | fi && | |
500 | ||
501 | test_must_fail git diff --quiet && | |
502 | ||
503 | test_path_is_file destdir/foo && | |
504 | test_path_is_file one && | |
505 | test_path_is_file destdir~HEAD && | |
506 | test "stuff" = "$(cat destdir~HEAD)" | |
507 | ' | |
508 | ||
509 | test_expect_success 'setup pair rename to parent of other (D/F conflicts)' ' | |
510 | git reset --hard && | |
511 | git checkout --orphan rename-two && | |
512 | git rm -rf . && | |
513 | git clean -fdqx && | |
514 | ||
515 | mkdir one && | |
516 | mkdir two && | |
517 | echo stuff >one/file && | |
518 | echo other >two/file && | |
519 | git add -A && | |
520 | git commit -m "Common commit" && | |
521 | ||
522 | git rm -rf one && | |
523 | git mv two/file one && | |
524 | git commit -m "Rename two/file -> one" && | |
525 | ||
526 | git checkout -b rename-one HEAD~1 && | |
527 | git rm -rf two && | |
528 | git mv one/file two && | |
529 | rm -r one && | |
530 | git commit -m "Rename one/file -> two" | |
531 | ' | |
532 | ||
533 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort | |
534 | then | |
535 | test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' ' | |
536 | git checkout -q rename-one^0 && | |
537 | mkdir one && | |
538 | test_must_fail git merge --strategy=recursive rename-two && | |
539 | ||
540 | test 4 -eq "$(git ls-files -u | wc -l)" && | |
541 | test 2 -eq "$(git ls-files -u one | wc -l)" && | |
542 | test 2 -eq "$(git ls-files -u two | wc -l)" && | |
543 | ||
544 | test_must_fail git diff --quiet && | |
545 | ||
546 | test 3 -eq $(find . | grep -v .git | wc -l) && | |
547 | ||
548 | test_path_is_file one && | |
549 | test_path_is_file two && | |
550 | test "other" = $(cat one) && | |
551 | test "stuff" = $(cat two) | |
552 | ' | |
553 | else | |
554 | test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' ' | |
555 | git checkout -q rename-one^0 && | |
556 | mkdir one && | |
557 | test_must_fail git merge --strategy=recursive rename-two && | |
558 | ||
559 | test 2 -eq "$(git ls-files -u | wc -l)" && | |
560 | test 1 -eq "$(git ls-files -u one | wc -l)" && | |
561 | test 1 -eq "$(git ls-files -u two | wc -l)" && | |
562 | ||
563 | test_must_fail git diff --quiet && | |
564 | ||
565 | test 4 -eq $(find . | grep -v .git | wc -l) && | |
566 | ||
567 | test_path_is_dir one && | |
568 | test_path_is_file one~rename-two && | |
569 | test_path_is_file two && | |
570 | test "other" = $(cat one~rename-two) && | |
571 | test "stuff" = $(cat two) | |
572 | ' | |
573 | fi | |
574 | ||
575 | test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean start' ' | |
576 | git reset --hard && | |
577 | git clean -fdqx && | |
578 | test_must_fail git merge --strategy=recursive rename-two && | |
579 | ||
580 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort | |
581 | then | |
582 | test 4 -eq "$(git ls-files -u | wc -l)" && | |
583 | test 2 -eq "$(git ls-files -u one | wc -l)" && | |
584 | test 2 -eq "$(git ls-files -u two | wc -l)" | |
585 | else | |
586 | test 2 -eq "$(git ls-files -u | wc -l)" && | |
587 | test 1 -eq "$(git ls-files -u one | wc -l)" && | |
588 | test 1 -eq "$(git ls-files -u two | wc -l)" | |
589 | fi && | |
590 | ||
591 | test_must_fail git diff --quiet && | |
592 | ||
593 | test 3 -eq $(find . | grep -v .git | wc -l) && | |
594 | ||
595 | test_path_is_file one && | |
596 | test_path_is_file two && | |
597 | test "other" = $(cat one) && | |
598 | test "stuff" = $(cat two) | |
599 | ' | |
600 | ||
601 | test_expect_success 'setup rename of one file to two, with directories in the way' ' | |
602 | git reset --hard && | |
603 | git checkout --orphan first-rename && | |
604 | git rm -rf . && | |
605 | git clean -fdqx && | |
606 | ||
607 | echo stuff >original && | |
608 | git add -A && | |
609 | git commit -m "Common commit" && | |
610 | ||
611 | mkdir two && | |
612 | >two/file && | |
613 | git add two/file && | |
614 | git mv original one && | |
615 | git commit -m "Put two/file in the way, rename to one" && | |
616 | ||
617 | git checkout -b second-rename HEAD~1 && | |
618 | mkdir one && | |
619 | >one/file && | |
620 | git add one/file && | |
621 | git mv original two && | |
622 | git commit -m "Put one/file in the way, rename to two" | |
623 | ' | |
624 | ||
625 | test_expect_success 'check handling of differently renamed file with D/F conflicts' ' | |
626 | git checkout -q first-rename^0 && | |
627 | test_must_fail git merge --strategy=recursive second-rename && | |
628 | ||
629 | if test "$GIT_TEST_MERGE_ALGORITHM" = ort | |
630 | then | |
631 | test 5 -eq "$(git ls-files -s | wc -l)" && | |
632 | test 3 -eq "$(git ls-files -u | wc -l)" && | |
633 | test 1 -eq "$(git ls-files -u one~HEAD | wc -l)" && | |
634 | test 1 -eq "$(git ls-files -u two~second-rename | wc -l)" && | |
635 | test 1 -eq "$(git ls-files -u original | wc -l)" && | |
636 | test 0 -eq "$(git ls-files -o | wc -l)" | |
637 | else | |
638 | test 5 -eq "$(git ls-files -s | wc -l)" && | |
639 | test 3 -eq "$(git ls-files -u | wc -l)" && | |
640 | test 1 -eq "$(git ls-files -u one | wc -l)" && | |
641 | test 1 -eq "$(git ls-files -u two | wc -l)" && | |
642 | test 1 -eq "$(git ls-files -u original | wc -l)" && | |
643 | test 2 -eq "$(git ls-files -o | wc -l)" | |
644 | fi && | |
645 | ||
646 | test_path_is_file one/file && | |
647 | test_path_is_file two/file && | |
648 | test_path_is_file one~HEAD && | |
649 | test_path_is_file two~second-rename && | |
650 | test_path_is_missing original | |
651 | ' | |
652 | ||
653 | test_expect_success 'setup rename one file to two; directories moving out of the way' ' | |
654 | git reset --hard && | |
655 | git checkout --orphan first-rename-redo && | |
656 | git rm -rf . && | |
657 | git clean -fdqx && | |
658 | ||
659 | echo stuff >original && | |
660 | mkdir one two && | |
661 | touch one/file two/file && | |
662 | git add -A && | |
663 | git commit -m "Common commit" && | |
664 | ||
665 | git rm -rf one && | |
666 | git mv original one && | |
667 | git commit -m "Rename to one" && | |
668 | ||
669 | git checkout -b second-rename-redo HEAD~1 && | |
670 | git rm -rf two && | |
671 | git mv original two && | |
672 | git commit -m "Rename to two" | |
673 | ' | |
674 | ||
675 | test_expect_success 'check handling of differently renamed file with D/F conflicts' ' | |
676 | git checkout -q first-rename-redo^0 && | |
677 | test_must_fail git merge --strategy=recursive second-rename-redo && | |
678 | ||
679 | test 3 -eq "$(git ls-files -u | wc -l)" && | |
680 | test 1 -eq "$(git ls-files -u one | wc -l)" && | |
681 | test 1 -eq "$(git ls-files -u two | wc -l)" && | |
682 | test 1 -eq "$(git ls-files -u original | wc -l)" && | |
683 | test 0 -eq "$(git ls-files -o | wc -l)" && | |
684 | ||
685 | test_path_is_file one && | |
686 | test_path_is_file two && | |
687 | test_path_is_missing original | |
688 | ' | |
689 | ||
690 | test_expect_success 'setup avoid unnecessary update, normal rename' ' | |
691 | git reset --hard && | |
692 | git checkout --orphan avoid-unnecessary-update-1 && | |
693 | git rm -rf . && | |
694 | git clean -fdqx && | |
695 | ||
696 | printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >original && | |
697 | git add -A && | |
698 | git commit -m "Common commit" && | |
699 | ||
700 | git mv original rename && | |
701 | echo 11 >>rename && | |
702 | git add -u && | |
703 | git commit -m "Renamed and modified" && | |
704 | ||
705 | git checkout -b merge-branch-1 HEAD~1 && | |
706 | echo "random content" >random-file && | |
707 | git add -A && | |
708 | git commit -m "Random, unrelated changes" | |
709 | ' | |
710 | ||
711 | test_expect_success 'avoid unnecessary update, normal rename' ' | |
712 | git checkout -q avoid-unnecessary-update-1^0 && | |
713 | test-tool chmtime --get -3600 rename >expect && | |
714 | git merge merge-branch-1 && | |
715 | test-tool chmtime --get rename >actual && | |
716 | test_cmp expect actual # "rename" should have stayed intact | |
717 | ' | |
718 | ||
719 | test_expect_success 'setup to test avoiding unnecessary update, with D/F conflict' ' | |
720 | git reset --hard && | |
721 | git checkout --orphan avoid-unnecessary-update-2 && | |
722 | git rm -rf . && | |
723 | git clean -fdqx && | |
724 | ||
725 | mkdir df && | |
726 | printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >df/file && | |
727 | git add -A && | |
728 | git commit -m "Common commit" && | |
729 | ||
730 | git mv df/file temp && | |
731 | rm -rf df && | |
732 | git mv temp df && | |
733 | echo 11 >>df && | |
734 | git add -u && | |
735 | git commit -m "Renamed and modified" && | |
736 | ||
737 | git checkout -b merge-branch-2 HEAD~1 && | |
738 | >unrelated-change && | |
739 | git add unrelated-change && | |
740 | git commit -m "Only unrelated changes" | |
741 | ' | |
742 | ||
743 | test_expect_success 'avoid unnecessary update, with D/F conflict' ' | |
744 | git checkout -q avoid-unnecessary-update-2^0 && | |
745 | test-tool chmtime --get -3600 df >expect && | |
746 | git merge merge-branch-2 && | |
747 | test-tool chmtime --get df >actual && | |
748 | test_cmp expect actual # "df" should have stayed intact | |
749 | ' | |
750 | ||
751 | test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' ' | |
752 | git rm -rf . && | |
753 | git clean -fdqx && | |
754 | rm -rf .git && | |
755 | git init && | |
756 | ||
757 | >irrelevant && | |
758 | mkdir df && | |
759 | >df/file && | |
760 | git add -A && | |
761 | git commit -mA && | |
762 | ||
763 | git checkout -b side && | |
764 | git rm -rf df && | |
765 | git commit -mB && | |
766 | ||
767 | git checkout master && | |
768 | git rm -rf df && | |
769 | echo bla >df && | |
770 | git add -A && | |
771 | git commit -m "Add a newfile" | |
772 | ' | |
773 | ||
774 | test_expect_success 'avoid unnecessary update, dir->(file,nothing)' ' | |
775 | git checkout -q master^0 && | |
776 | test-tool chmtime --get -3600 df >expect && | |
777 | git merge side && | |
778 | test-tool chmtime --get df >actual && | |
779 | test_cmp expect actual # "df" should have stayed intact | |
780 | ' | |
781 | ||
782 | test_expect_success 'setup avoid unnecessary update, modify/delete' ' | |
783 | git rm -rf . && | |
784 | git clean -fdqx && | |
785 | rm -rf .git && | |
786 | git init && | |
787 | ||
788 | >irrelevant && | |
789 | >file && | |
790 | git add -A && | |
791 | git commit -mA && | |
792 | ||
793 | git checkout -b side && | |
794 | git rm -f file && | |
795 | git commit -m "Delete file" && | |
796 | ||
797 | git checkout master && | |
798 | echo bla >file && | |
799 | git add -A && | |
800 | git commit -m "Modify file" | |
801 | ' | |
802 | ||
803 | test_expect_success 'avoid unnecessary update, modify/delete' ' | |
804 | git checkout -q master^0 && | |
805 | test-tool chmtime --get -3600 file >expect && | |
806 | test_must_fail git merge side && | |
807 | test-tool chmtime --get file >actual && | |
808 | test_cmp expect actual # "file" should have stayed intact | |
809 | ' | |
810 | ||
811 | test_expect_success 'setup avoid unnecessary update, rename/add-dest' ' | |
812 | git rm -rf . && | |
813 | git clean -fdqx && | |
814 | rm -rf .git && | |
815 | git init && | |
816 | ||
817 | printf "1\n2\n3\n4\n5\n6\n7\n8\n" >file && | |
818 | git add -A && | |
819 | git commit -mA && | |
820 | ||
821 | git checkout -b side && | |
822 | cp file newfile && | |
823 | git add -A && | |
824 | git commit -m "Add file copy" && | |
825 | ||
826 | git checkout master && | |
827 | git mv file newfile && | |
828 | git commit -m "Rename file" | |
829 | ' | |
830 | ||
831 | test_expect_success 'avoid unnecessary update, rename/add-dest' ' | |
832 | git checkout -q master^0 && | |
833 | test-tool chmtime --get -3600 newfile >expect && | |
834 | git merge side && | |
835 | test-tool chmtime --get newfile >actual && | |
836 | test_cmp expect actual # "file" should have stayed intact | |
837 | ' | |
838 | ||
839 | test_expect_success 'setup merge of rename + small change' ' | |
840 | git reset --hard && | |
841 | git checkout --orphan rename-plus-small-change && | |
842 | git rm -rf . && | |
843 | git clean -fdqx && | |
844 | ||
845 | echo ORIGINAL >file && | |
846 | git add file && | |
847 | ||
848 | test_tick && | |
849 | git commit -m Initial && | |
850 | git checkout -b rename_branch && | |
851 | git mv file renamed_file && | |
852 | git commit -m Rename && | |
853 | git checkout rename-plus-small-change && | |
854 | echo NEW-VERSION >file && | |
855 | git commit -a -m Reformat | |
856 | ' | |
857 | ||
858 | test_expect_success 'merge rename + small change' ' | |
859 | git merge rename_branch && | |
860 | ||
861 | test 1 -eq $(git ls-files -s | wc -l) && | |
862 | test 0 -eq $(git ls-files -o | wc -l) && | |
863 | test $(git rev-parse HEAD:renamed_file) = $(git rev-parse HEAD~1:file) | |
864 | ' | |
865 | ||
866 | test_expect_success 'setup for use of extended merge markers' ' | |
867 | git rm -rf . && | |
868 | git clean -fdqx && | |
869 | rm -rf .git && | |
870 | git init && | |
871 | ||
872 | printf "1\n2\n3\n4\n5\n6\n7\n8\n" >original_file && | |
873 | git add original_file && | |
874 | git commit -mA && | |
875 | ||
876 | git checkout -b rename && | |
877 | echo 9 >>original_file && | |
878 | git add original_file && | |
879 | git mv original_file renamed_file && | |
880 | git commit -mB && | |
881 | ||
882 | git checkout master && | |
883 | echo 8.5 >>original_file && | |
884 | git add original_file && | |
885 | git commit -mC | |
886 | ' | |
887 | ||
888 | test_expect_success 'merge master into rename has correct extended markers' ' | |
889 | git checkout rename^0 && | |
890 | test_must_fail git merge -s recursive master^0 && | |
891 | ||
892 | cat >expected <<-\EOF && | |
893 | 1 | |
894 | 2 | |
895 | 3 | |
896 | 4 | |
897 | 5 | |
898 | 6 | |
899 | 7 | |
900 | 8 | |
901 | <<<<<<< HEAD:renamed_file | |
902 | 9 | |
903 | ======= | |
904 | 8.5 | |
905 | >>>>>>> master^0:original_file | |
906 | EOF | |
907 | test_cmp expected renamed_file | |
908 | ' | |
909 | ||
910 | test_expect_success 'merge rename into master has correct extended markers' ' | |
911 | git reset --hard && | |
912 | git checkout master^0 && | |
913 | test_must_fail git merge -s recursive rename^0 && | |
914 | ||
915 | cat >expected <<-\EOF && | |
916 | 1 | |
917 | 2 | |
918 | 3 | |
919 | 4 | |
920 | 5 | |
921 | 6 | |
922 | 7 | |
923 | 8 | |
924 | <<<<<<< HEAD:original_file | |
925 | 8.5 | |
926 | ======= | |
927 | 9 | |
928 | >>>>>>> rename^0:renamed_file | |
929 | EOF | |
930 | test_cmp expected renamed_file | |
931 | ' | |
932 | ||
933 | test_expect_success 'setup spurious "refusing to lose untracked" message' ' | |
934 | git rm -rf . && | |
935 | git clean -fdqx && | |
936 | rm -rf .git && | |
937 | git init && | |
938 | ||
939 | > irrelevant_file && | |
940 | printf "1\n2\n3\n4\n5\n6\n7\n8\n" >original_file && | |
941 | git add irrelevant_file original_file && | |
942 | git commit -mA && | |
943 | ||
944 | git checkout -b rename && | |
945 | git mv original_file renamed_file && | |
946 | git commit -mB && | |
947 | ||
948 | git checkout master && | |
949 | git rm original_file && | |
950 | git commit -mC | |
951 | ' | |
952 | ||
953 | test_expect_success 'no spurious "refusing to lose untracked" message' ' | |
954 | git checkout master^0 && | |
955 | test_must_fail git merge rename^0 2>errors.txt && | |
956 | ! grep "refusing to lose untracked file" errors.txt | |
957 | ' | |
958 | ||
959 | test_expect_success 'do not follow renames for empty files' ' | |
960 | git checkout -f -b empty-base && | |
961 | >empty1 && | |
962 | git add empty1 && | |
963 | git commit -m base && | |
964 | echo content >empty1 && | |
965 | git add empty1 && | |
966 | git commit -m fill && | |
967 | git checkout -b empty-topic HEAD^ && | |
968 | git mv empty1 empty2 && | |
969 | git commit -m rename && | |
970 | test_must_fail git merge empty-base && | |
971 | test_must_be_empty empty2 | |
972 | ' | |
973 | ||
974 | test_done |