mailmap: plug memory leak in read_mailmap_blob()
[git/gitster.git] / t / t6402-merge-rename.sh
blob729aac9842d1f7679da2c187bbb857f85ec3a131
1 #!/bin/sh
3 test_description='Merge-recursive merging renames'
4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7 TEST_PASSES_SANITIZE_LEAK=true
8 . ./test-lib.sh
10 modify () {
11 sed -e "$1" <"$2" >"$2.x" &&
12 mv "$2.x" "$2"
15 test_expect_success 'setup' '
16 cat >A <<-\EOF &&
17 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
18 b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
19 c cccccccccccccccccccccccccccccccccccccccccccccccc
20 d dddddddddddddddddddddddddddddddddddddddddddddddd
21 e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
22 f ffffffffffffffffffffffffffffffffffffffffffffffff
23 g gggggggggggggggggggggggggggggggggggggggggggggggg
24 h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
25 i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
26 j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
27 k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
28 l llllllllllllllllllllllllllllllllllllllllllllllll
29 m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
30 n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
31 o oooooooooooooooooooooooooooooooooooooooooooooooo
32 EOF
34 cat >M <<-\EOF &&
35 A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
36 B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
37 C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
38 D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
39 E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
40 F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
41 G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
42 H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
43 I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
44 J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
45 K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
46 L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
47 M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
48 N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
49 O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
50 EOF
52 git add A M &&
53 git commit -m "initial has A and M" &&
54 git branch white &&
55 git branch red &&
56 git branch blue &&
57 git branch yellow &&
58 git branch change &&
59 git branch change+rename &&
61 sed -e "/^g /s/.*/g : main changes a line/" <A >A+ &&
62 mv A+ A &&
63 git commit -a -m "main updates A" &&
65 git checkout yellow &&
66 rm -f M &&
67 git commit -a -m "yellow removes M" &&
69 git checkout white &&
70 sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
71 sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
72 rm -f A M &&
73 git update-index --add --remove A B M N &&
74 git commit -m "white renames A->B, M->N" &&
76 git checkout red &&
77 sed -e "/^g /s/.*/g : red changes a line/" <A >B &&
78 sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
79 rm -f A M &&
80 git update-index --add --remove A B M N &&
81 git commit -m "red renames A->B, M->N" &&
83 git checkout blue &&
84 sed -e "/^g /s/.*/g : blue changes a line/" <A >C &&
85 sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
86 rm -f A M &&
87 git update-index --add --remove A C M N &&
88 git commit -m "blue renames A->C, M->N" &&
90 git checkout change &&
91 sed -e "/^g /s/.*/g : changed line/" <A >A+ &&
92 mv A+ A &&
93 git commit -q -a -m "changed" &&
95 git checkout change+rename &&
96 sed -e "/^g /s/.*/g : changed line/" <A >B &&
97 rm A &&
98 git update-index --add B &&
99 git commit -q -a -m "changed and renamed" &&
101 git checkout main
104 test_expect_success 'pull renaming branch into unrenaming one' \
106 git show-branch &&
107 test_expect_code 1 git pull --no-rebase . white &&
108 git ls-files -s &&
109 test_stdout_line_count = 3 git ls-files -u B &&
110 test_stdout_line_count = 1 git ls-files -s N &&
111 sed -ne "/^g/{
114 }" B | grep main &&
115 git diff --exit-code white N
118 test_expect_success 'pull renaming branch into another renaming one' \
120 rm -f B &&
121 git reset --hard &&
122 git checkout red &&
123 test_expect_code 1 git pull --no-rebase . white &&
124 test_stdout_line_count = 3 git ls-files -u B &&
125 test_stdout_line_count = 1 git ls-files -s N &&
126 sed -ne "/^g/{
129 }" B | grep red &&
130 git diff --exit-code white N
133 test_expect_success 'pull unrenaming branch into renaming one' \
135 git reset --hard &&
136 git show-branch &&
137 test_expect_code 1 git pull --no-rebase . main &&
138 test_stdout_line_count = 3 git ls-files -u B &&
139 test_stdout_line_count = 1 git ls-files -s N &&
140 sed -ne "/^g/{
143 }" B | grep red &&
144 git diff --exit-code white N
147 test_expect_success 'pull conflicting renames' \
149 git reset --hard &&
150 git show-branch &&
151 test_expect_code 1 git pull --no-rebase . blue &&
152 test_stdout_line_count = 1 git ls-files -u A &&
153 test_stdout_line_count = 1 git ls-files -u B &&
154 test_stdout_line_count = 1 git ls-files -u C &&
155 test_stdout_line_count = 1 git ls-files -s N &&
156 sed -ne "/^g/{
159 }" B | grep red &&
160 git diff --exit-code white N
163 test_expect_success 'interference with untracked working tree file' '
164 git reset --hard &&
165 git show-branch &&
166 echo >A this file should not matter &&
167 test_expect_code 1 git pull --no-rebase . white &&
168 test_path_is_file A
171 test_expect_success 'interference with untracked working tree file' '
172 git reset --hard &&
173 git checkout white &&
174 git show-branch &&
175 rm -f A &&
176 echo >A this file should not matter &&
177 test_expect_code 1 git pull --no-rebase . red &&
178 test_path_is_file A
181 test_expect_success 'interference with untracked working tree file' '
182 git reset --hard &&
183 rm -f A M &&
184 git checkout -f main &&
185 git tag -f anchor &&
186 git show-branch &&
187 git pull --no-rebase . yellow &&
188 test_path_is_missing M &&
189 git reset --hard anchor
192 test_expect_success 'updated working tree file should prevent the merge' '
193 git reset --hard &&
194 rm -f A M &&
195 git checkout -f main &&
196 git tag -f anchor &&
197 git show-branch &&
198 echo >>M one line addition &&
199 cat M >M.saved &&
200 test_expect_code 128 git pull . yellow &&
201 test_cmp M M.saved &&
202 rm -f M.saved
205 test_expect_success 'updated working tree file should prevent the merge' '
206 git reset --hard &&
207 rm -f A M &&
208 git checkout -f main &&
209 git tag -f anchor &&
210 git show-branch &&
211 echo >>M one line addition &&
212 cat M >M.saved &&
213 git update-index M &&
214 test_expect_code 2 git pull --no-rebase . yellow &&
215 test_cmp M M.saved &&
216 rm -f M.saved
219 test_expect_success 'interference with untracked working tree file' '
220 git reset --hard &&
221 rm -f A M &&
222 git checkout -f yellow &&
223 git tag -f anchor &&
224 git show-branch &&
225 echo >M this file should not matter &&
226 git pull --no-rebase . main &&
227 test_path_is_file M &&
229 git ls-files -s |
230 grep M
231 } &&
232 git reset --hard anchor
235 test_expect_success 'merge of identical changes in a renamed file' '
236 rm -f A M N &&
237 git reset --hard &&
238 git checkout change+rename &&
240 test-tool chmtime --get -3600 B >old-mtime &&
241 GIT_MERGE_VERBOSITY=3 git merge change >out &&
243 test-tool chmtime --get B >new-mtime &&
244 test_cmp old-mtime new-mtime &&
246 git reset --hard HEAD^ &&
247 git checkout change &&
249 # A will be renamed to B; we check mtimes and file presence
250 test_path_is_missing B &&
251 test-tool chmtime --get -3600 A >old-mtime &&
252 GIT_MERGE_VERBOSITY=3 git merge change+rename >out &&
254 test_path_is_missing A &&
255 test-tool chmtime --get B >new-mtime &&
256 test $(cat old-mtime) -lt $(cat new-mtime)
259 test_expect_success 'setup for rename + d/f conflicts' '
260 git reset --hard &&
261 git checkout --orphan dir-in-way &&
262 git rm -rf . &&
263 git clean -fdqx &&
265 mkdir sub &&
266 mkdir dir &&
267 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >sub/file &&
268 echo foo >dir/file-in-the-way &&
269 git add -A &&
270 git commit -m "Common commit" &&
272 echo 11 >>sub/file &&
273 echo more >>dir/file-in-the-way &&
274 git add -u &&
275 git commit -m "Commit to merge, with dir in the way" &&
277 git checkout -b dir-not-in-way &&
278 git reset --soft HEAD^ &&
279 git rm -rf dir &&
280 git commit -m "Commit to merge, with dir removed" -- dir sub/file &&
282 git checkout -b renamed-file-has-no-conflicts dir-in-way~1 &&
283 git rm -rf dir &&
284 git rm sub/file &&
285 printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n" >dir &&
286 git add dir &&
287 git commit -m "Independent change" &&
289 git checkout -b renamed-file-has-conflicts dir-in-way~1 &&
290 git rm -rf dir &&
291 git mv sub/file dir &&
292 echo 12 >>dir &&
293 git add dir &&
294 git commit -m "Conflicting change"
297 test_expect_success 'Rename+D/F conflict; renamed file merges + dir not in way' '
298 git reset --hard &&
299 git checkout -q renamed-file-has-no-conflicts^0 &&
301 git merge --strategy=recursive dir-not-in-way &&
303 git diff --quiet &&
304 test_path_is_file dir &&
305 test_write_lines 1 2 3 4 5555 6 7 8 9 10 11 >expected &&
306 test_cmp expected dir
309 test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' '
310 git reset --hard &&
311 rm -rf dir~* &&
312 git checkout -q renamed-file-has-no-conflicts^0 &&
313 test_must_fail git merge --strategy=recursive dir-in-way >output &&
315 test_grep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
316 test_grep "Auto-merging dir" output &&
317 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
318 then
319 test_grep "moving it to dir~HEAD instead" output
320 else
321 test_grep "Adding as dir~HEAD instead" output
322 fi &&
324 test_stdout_line_count = 3 git ls-files -u &&
325 test_stdout_line_count = 2 git ls-files -u dir/file-in-the-way &&
327 test_must_fail git diff --quiet &&
328 test_must_fail git diff --cached --quiet &&
330 test_path_is_file dir/file-in-the-way &&
331 test_path_is_file dir~HEAD &&
332 test_cmp expected dir~HEAD
335 test_expect_success 'Same as previous, but merged other way' '
336 git reset --hard &&
337 rm -rf dir~* &&
338 git checkout -q dir-in-way^0 &&
339 test_must_fail git merge --strategy=recursive renamed-file-has-no-conflicts >output 2>errors &&
341 ! grep "error: refusing to lose untracked file at" errors &&
342 test_grep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
343 test_grep "Auto-merging dir" output &&
344 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
345 then
346 test_grep "moving it to dir~renamed-file-has-no-conflicts instead" output
347 else
348 test_grep "Adding as dir~renamed-file-has-no-conflicts instead" output
349 fi &&
351 test_stdout_line_count = 3 git ls-files -u &&
352 test_stdout_line_count = 2 git ls-files -u dir/file-in-the-way &&
354 test_must_fail git diff --quiet &&
355 test_must_fail git diff --cached --quiet &&
357 test_path_is_file dir/file-in-the-way &&
358 test_path_is_file dir~renamed-file-has-no-conflicts &&
359 test_cmp expected dir~renamed-file-has-no-conflicts
362 test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in way' '
363 git reset --hard &&
364 rm -rf dir~* &&
365 git checkout -q renamed-file-has-conflicts^0 &&
366 test_must_fail git merge --strategy=recursive dir-not-in-way &&
368 test_stdout_line_count = 3 git ls-files -u &&
369 test_stdout_line_count = 3 git ls-files -u dir &&
371 test_must_fail git diff --quiet &&
372 test_must_fail git diff --cached --quiet &&
374 test_path_is_file dir &&
375 cat >expected <<-\EOF &&
386 <<<<<<< HEAD:dir
388 =======
390 >>>>>>> dir-not-in-way:sub/file
392 test_cmp expected dir
395 test_expect_success 'Rename+D/F conflict; renamed file cannot merge and dir in the way' '
396 modify s/dir-not-in-way/dir-in-way/ expected &&
398 git reset --hard &&
399 rm -rf dir~* &&
400 git checkout -q renamed-file-has-conflicts^0 &&
401 test_must_fail git merge --strategy=recursive dir-in-way &&
403 test_stdout_line_count = 5 git ls-files -u &&
404 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
405 then
406 test_stdout_line_count = 3 git ls-files -u dir~HEAD
407 else
408 git ls-files -u dir >out &&
409 test 3 -eq $(grep -v file-in-the-way out | wc -l) &&
410 rm -f out
411 fi &&
412 test_stdout_line_count = 2 git ls-files -u dir/file-in-the-way &&
414 test_must_fail git diff --quiet &&
415 test_must_fail git diff --cached --quiet &&
417 test_path_is_file dir/file-in-the-way &&
418 test_path_is_file dir~HEAD &&
419 test_cmp expected dir~HEAD
422 test_expect_success 'Same as previous, but merged other way' '
423 git reset --hard &&
424 rm -rf dir~* &&
425 git checkout -q dir-in-way^0 &&
426 test_must_fail git merge --strategy=recursive renamed-file-has-conflicts &&
428 test_stdout_line_count = 5 git ls-files -u &&
429 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
430 then
431 test_stdout_line_count = 3 git ls-files -u dir~renamed-file-has-conflicts
432 else
433 git ls-files -u dir >out &&
434 test 3 -eq $(grep -v file-in-the-way out | wc -l) &&
435 rm -f out
436 fi &&
437 test_stdout_line_count = 2 git ls-files -u dir/file-in-the-way &&
439 test_must_fail git diff --quiet &&
440 test_must_fail git diff --cached --quiet &&
442 test_path_is_file dir/file-in-the-way &&
443 test_path_is_file dir~renamed-file-has-conflicts &&
444 cat >expected <<-\EOF &&
455 <<<<<<< HEAD:sub/file
457 =======
459 >>>>>>> renamed-file-has-conflicts:dir
461 test_cmp expected dir~renamed-file-has-conflicts
464 test_expect_success 'setup both rename source and destination involved in D/F conflict' '
465 git reset --hard &&
466 git checkout --orphan rename-dest &&
467 git rm -rf . &&
468 git clean -fdqx &&
470 mkdir one &&
471 echo stuff >one/file &&
472 git add -A &&
473 git commit -m "Common commit" &&
475 git mv one/file destdir &&
476 git commit -m "Renamed to destdir" &&
478 git checkout -b source-conflict HEAD~1 &&
479 git rm -rf one &&
480 mkdir destdir &&
481 touch one destdir/foo &&
482 git add -A &&
483 git commit -m "Conflicts in the way"
486 test_expect_success 'both rename source and destination involved in D/F conflict' '
487 git reset --hard &&
488 rm -rf dir~* &&
489 git checkout -q rename-dest^0 &&
490 test_must_fail git merge --strategy=recursive source-conflict &&
492 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
493 then
494 test_stdout_line_count = 2 git ls-files -u
495 else
496 test_stdout_line_count = 1 git ls-files -u
497 fi &&
499 test_must_fail git diff --quiet &&
501 test_path_is_file destdir/foo &&
502 test_path_is_file one &&
503 test_path_is_file destdir~HEAD &&
504 test "stuff" = "$(cat destdir~HEAD)"
507 test_expect_success 'setup pair rename to parent of other (D/F conflicts)' '
508 git reset --hard &&
509 git checkout --orphan rename-two &&
510 git rm -rf . &&
511 git clean -fdqx &&
513 mkdir one &&
514 mkdir two &&
515 echo stuff >one/file &&
516 echo other >two/file &&
517 git add -A &&
518 git commit -m "Common commit" &&
520 git rm -rf one &&
521 git mv two/file one &&
522 git commit -m "Rename two/file -> one" &&
524 git checkout -b rename-one HEAD~1 &&
525 git rm -rf two &&
526 git mv one/file two &&
527 rm -r one &&
528 git commit -m "Rename one/file -> two"
531 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
532 then
533 test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' '
534 git checkout -q rename-one^0 &&
535 mkdir one &&
536 test_must_fail git merge --strategy=recursive rename-two &&
538 test_stdout_line_count = 4 git ls-files -u &&
539 test_stdout_line_count = 2 git ls-files -u one &&
540 test_stdout_line_count = 2 git ls-files -u two &&
542 test_must_fail git diff --quiet &&
544 test 3 -eq $(find . | grep -v .git | wc -l) &&
546 test_path_is_file one &&
547 test_path_is_file two &&
548 test "other" = $(cat one) &&
549 test "stuff" = $(cat two)
551 else
552 test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' '
553 git checkout -q rename-one^0 &&
554 mkdir one &&
555 test_must_fail git merge --strategy=recursive rename-two &&
557 test_stdout_line_count = 2 git ls-files -u &&
558 test_stdout_line_count = 1 git ls-files -u one &&
559 test_stdout_line_count = 1 git ls-files -u two &&
561 test_must_fail git diff --quiet &&
563 test 4 -eq $(find . | grep -v .git | wc -l) &&
565 test_path_is_dir one &&
566 test_path_is_file one~rename-two &&
567 test_path_is_file two &&
568 test "other" = $(cat one~rename-two) &&
569 test "stuff" = $(cat two)
573 test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean start' '
574 git reset --hard &&
575 git clean -fdqx &&
576 test_must_fail git merge --strategy=recursive rename-two &&
578 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
579 then
580 test_stdout_line_count = 4 git ls-files -u &&
581 test_stdout_line_count = 2 git ls-files -u one &&
582 test_stdout_line_count = 2 git ls-files -u two
583 else
584 test_stdout_line_count = 2 git ls-files -u &&
585 test_stdout_line_count = 1 git ls-files -u one &&
586 test_stdout_line_count = 1 git ls-files -u two
587 fi &&
589 test_must_fail git diff --quiet &&
591 test 3 -eq $(find . | grep -v .git | wc -l) &&
593 test_path_is_file one &&
594 test_path_is_file two &&
595 test "other" = $(cat one) &&
596 test "stuff" = $(cat two)
599 test_expect_success 'setup rename of one file to two, with directories in the way' '
600 git reset --hard &&
601 git checkout --orphan first-rename &&
602 git rm -rf . &&
603 git clean -fdqx &&
605 echo stuff >original &&
606 git add -A &&
607 git commit -m "Common commit" &&
609 mkdir two &&
610 >two/file &&
611 git add two/file &&
612 git mv original one &&
613 git commit -m "Put two/file in the way, rename to one" &&
615 git checkout -b second-rename HEAD~1 &&
616 mkdir one &&
617 >one/file &&
618 git add one/file &&
619 git mv original two &&
620 git commit -m "Put one/file in the way, rename to two"
623 test_expect_success 'check handling of differently renamed file with D/F conflicts' '
624 git checkout -q first-rename^0 &&
625 test_must_fail git merge --strategy=recursive second-rename &&
627 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
628 then
629 test_stdout_line_count = 5 git ls-files -s &&
630 test_stdout_line_count = 3 git ls-files -u &&
631 test_stdout_line_count = 1 git ls-files -u one~HEAD &&
632 test_stdout_line_count = 1 git ls-files -u two~second-rename &&
633 test_stdout_line_count = 1 git ls-files -u original &&
634 test_stdout_line_count = 0 git ls-files -o
635 else
636 test_stdout_line_count = 5 git ls-files -s &&
637 test_stdout_line_count = 3 git ls-files -u &&
638 test_stdout_line_count = 1 git ls-files -u one &&
639 test_stdout_line_count = 1 git ls-files -u two &&
640 test_stdout_line_count = 1 git ls-files -u original &&
641 test_stdout_line_count = 2 git ls-files -o
642 fi &&
644 test_path_is_file one/file &&
645 test_path_is_file two/file &&
646 test_path_is_file one~HEAD &&
647 test_path_is_file two~second-rename &&
648 test_path_is_missing original
651 test_expect_success 'setup rename one file to two; directories moving out of the way' '
652 git reset --hard &&
653 git checkout --orphan first-rename-redo &&
654 git rm -rf . &&
655 git clean -fdqx &&
657 echo stuff >original &&
658 mkdir one two &&
659 touch one/file two/file &&
660 git add -A &&
661 git commit -m "Common commit" &&
663 git rm -rf one &&
664 git mv original one &&
665 git commit -m "Rename to one" &&
667 git checkout -b second-rename-redo HEAD~1 &&
668 git rm -rf two &&
669 git mv original two &&
670 git commit -m "Rename to two"
673 test_expect_success 'check handling of differently renamed file with D/F conflicts' '
674 git checkout -q first-rename-redo^0 &&
675 test_must_fail git merge --strategy=recursive second-rename-redo &&
677 test_stdout_line_count = 3 git ls-files -u &&
678 test_stdout_line_count = 1 git ls-files -u one &&
679 test_stdout_line_count = 1 git ls-files -u two &&
680 test_stdout_line_count = 1 git ls-files -u original &&
681 test_stdout_line_count = 0 git ls-files -o &&
683 test_path_is_file one &&
684 test_path_is_file two &&
685 test_path_is_missing original
688 test_expect_success 'setup avoid unnecessary update, normal rename' '
689 git reset --hard &&
690 git checkout --orphan avoid-unnecessary-update-1 &&
691 git rm -rf . &&
692 git clean -fdqx &&
694 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >original &&
695 git add -A &&
696 git commit -m "Common commit" &&
698 git mv original rename &&
699 echo 11 >>rename &&
700 git add -u &&
701 git commit -m "Renamed and modified" &&
703 git checkout -b merge-branch-1 HEAD~1 &&
704 echo "random content" >random-file &&
705 git add -A &&
706 git commit -m "Random, unrelated changes"
709 test_expect_success 'avoid unnecessary update, normal rename' '
710 git checkout -q avoid-unnecessary-update-1^0 &&
711 test-tool chmtime --get -3600 rename >expect &&
712 git merge merge-branch-1 &&
713 test-tool chmtime --get rename >actual &&
714 test_cmp expect actual # "rename" should have stayed intact
717 test_expect_success 'setup to test avoiding unnecessary update, with D/F conflict' '
718 git reset --hard &&
719 git checkout --orphan avoid-unnecessary-update-2 &&
720 git rm -rf . &&
721 git clean -fdqx &&
723 mkdir df &&
724 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >df/file &&
725 git add -A &&
726 git commit -m "Common commit" &&
728 git mv df/file temp &&
729 rm -rf df &&
730 git mv temp df &&
731 echo 11 >>df &&
732 git add -u &&
733 git commit -m "Renamed and modified" &&
735 git checkout -b merge-branch-2 HEAD~1 &&
736 >unrelated-change &&
737 git add unrelated-change &&
738 git commit -m "Only unrelated changes"
741 test_expect_success 'avoid unnecessary update, with D/F conflict' '
742 git checkout -q avoid-unnecessary-update-2^0 &&
743 test-tool chmtime --get -3600 df >expect &&
744 git merge merge-branch-2 &&
745 test-tool chmtime --get df >actual &&
746 test_cmp expect actual # "df" should have stayed intact
749 test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' '
750 git rm -rf . &&
751 git clean -fdqx &&
752 rm -rf .git &&
753 git init &&
755 >irrelevant &&
756 mkdir df &&
757 >df/file &&
758 git add -A &&
759 git commit -mA &&
761 git checkout -b side &&
762 git rm -rf df &&
763 git commit -mB &&
765 git checkout main &&
766 git rm -rf df &&
767 echo bla >df &&
768 git add -A &&
769 git commit -m "Add a newfile"
772 test_expect_success 'avoid unnecessary update, dir->(file,nothing)' '
773 git checkout -q main^0 &&
774 test-tool chmtime --get -3600 df >expect &&
775 git merge side &&
776 test-tool chmtime --get df >actual &&
777 test_cmp expect actual # "df" should have stayed intact
780 test_expect_success 'setup avoid unnecessary update, modify/delete' '
781 git rm -rf . &&
782 git clean -fdqx &&
783 rm -rf .git &&
784 git init &&
786 >irrelevant &&
787 >file &&
788 git add -A &&
789 git commit -mA &&
791 git checkout -b side &&
792 git rm -f file &&
793 git commit -m "Delete file" &&
795 git checkout main &&
796 echo bla >file &&
797 git add -A &&
798 git commit -m "Modify file"
801 test_expect_success 'avoid unnecessary update, modify/delete' '
802 git checkout -q main^0 &&
803 test-tool chmtime --get -3600 file >expect &&
804 test_must_fail git merge side &&
805 test-tool chmtime --get file >actual &&
806 test_cmp expect actual # "file" should have stayed intact
809 test_expect_success 'setup avoid unnecessary update, rename/add-dest' '
810 git rm -rf . &&
811 git clean -fdqx &&
812 rm -rf .git &&
813 git init &&
815 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >file &&
816 git add -A &&
817 git commit -mA &&
819 git checkout -b side &&
820 cp file newfile &&
821 git add -A &&
822 git commit -m "Add file copy" &&
824 git checkout main &&
825 git mv file newfile &&
826 git commit -m "Rename file"
829 test_expect_success 'avoid unnecessary update, rename/add-dest' '
830 git checkout -q main^0 &&
831 test-tool chmtime --get -3600 newfile >expect &&
832 git merge side &&
833 test-tool chmtime --get newfile >actual &&
834 test_cmp expect actual # "file" should have stayed intact
837 test_expect_success 'setup merge of rename + small change' '
838 git reset --hard &&
839 git checkout --orphan rename-plus-small-change &&
840 git rm -rf . &&
841 git clean -fdqx &&
843 echo ORIGINAL >file &&
844 git add file &&
846 test_tick &&
847 git commit -m Initial &&
848 git checkout -b rename_branch &&
849 git mv file renamed_file &&
850 git commit -m Rename &&
851 git checkout rename-plus-small-change &&
852 echo NEW-VERSION >file &&
853 git commit -a -m Reformat
856 test_expect_success 'merge rename + small change' '
857 git merge rename_branch &&
859 test_stdout_line_count = 1 git ls-files -s &&
860 test_stdout_line_count = 0 git ls-files -o &&
861 newhash=$(git rev-parse HEAD:renamed_file) &&
862 oldhash=$(git rev-parse HEAD~1:file) &&
863 test $newhash = $oldhash
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 &&
872 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >original_file &&
873 git add original_file &&
874 git commit -mA &&
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 &&
882 git checkout main &&
883 echo 8.5 >>original_file &&
884 git add original_file &&
885 git commit -mC
888 test_expect_success 'merge main into rename has correct extended markers' '
889 git checkout rename^0 &&
890 test_must_fail git merge -s recursive main^0 &&
892 cat >expected <<-\EOF &&
901 <<<<<<< HEAD:renamed_file
903 =======
905 >>>>>>> main^0:original_file
907 test_cmp expected renamed_file
910 test_expect_success 'merge rename into main has correct extended markers' '
911 git reset --hard &&
912 git checkout main^0 &&
913 test_must_fail git merge -s recursive rename^0 &&
915 cat >expected <<-\EOF &&
924 <<<<<<< HEAD:original_file
926 =======
928 >>>>>>> rename^0:renamed_file
930 test_cmp expected renamed_file
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 &&
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 &&
944 git checkout -b rename &&
945 git mv original_file renamed_file &&
946 git commit -mB &&
948 git checkout main &&
949 git rm original_file &&
950 git commit -mC
953 test_expect_success 'no spurious "refusing to lose untracked" message' '
954 git checkout main^0 &&
955 test_must_fail git merge rename^0 2>errors.txt &&
956 ! grep "refusing to lose untracked file" errors.txt
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
974 test_done