Raw
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Junio C Hamano
4 #
5
6 test_description='git checkout tests.
7
8 Creates main, forks renamer and side branches from it.
9 Test switching across them.
10
11 ! [main] Initial A one, A two
12 * [renamer] Renamer R one->uno, M two
13 ! [side] Side M one, D two, A three
14 ! [simple] Simple D one, M two
15 ----
16 + [simple] Simple D one, M two
17 + [side] Side M one, D two, A three
18 * [renamer] Renamer R one->uno, M two
19 +*++ [main] Initial A one, A two
20
21 '
22
23 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
24 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
25
26 . ./test-lib.sh
27
28 test_tick
29
30 fill () {
31 for i
32 do
33 echo "$i"
34 done
35 }
36
37
38 test_expect_success setup '
39 fill x y z >same &&
40 fill 1 2 3 4 5 6 7 8 >one &&
41 fill a b c d e >two &&
42 git add same one two &&
43 git commit -m "Initial A one, A two" &&
44
45 git checkout -b renamer &&
46 rm -f one &&
47 fill 1 3 4 5 6 7 8 >uno &&
48 git add uno &&
49 fill a b c d e f >two &&
50 git commit -a -m "Renamer R one->uno, M two" &&
51
52 git checkout -b side main &&
53 fill 1 2 3 4 5 6 7 >one &&
54 fill A B C D E >three &&
55 rm -f two &&
56 git update-index --add --remove one two three &&
57 git commit -m "Side M one, D two, A three" &&
58
59 git checkout -b simple main &&
60 rm -f one &&
61 fill a c e >two &&
62 git commit -a -m "Simple D one, M two" &&
63
64 git checkout main
65 '
66
67 test_expect_success 'checkout from non-existing branch' '
68 git checkout -b delete-me main &&
69 git update-ref -d --no-deref refs/heads/delete-me &&
70 test refs/heads/delete-me = "$(git symbolic-ref HEAD)" &&
71 git checkout main &&
72 test refs/heads/main = "$(git symbolic-ref HEAD)"
73 '
74
75 test_expect_success 'checkout with dirty tree without -m' '
76 fill 0 1 2 3 4 5 6 7 8 >one &&
77 if git checkout side
78 then
79 echo Not happy
80 false
81 else
82 echo "happy - failed correctly"
83 fi
84 '
85
86 test_expect_success 'checkout with unrelated dirty tree without -m' '
87 git checkout -f main &&
88 fill 0 1 2 3 4 5 6 7 8 >same &&
89 cp same kept &&
90 git checkout side >messages &&
91 test_cmp same kept &&
92 printf "M\t%s\n" same >messages.expect &&
93 test_cmp messages.expect messages
94 '
95
96 test_expect_success 'checkout -m with dirty tree' '
97 git checkout -f main &&
98 git clean -f &&
99
100 fill 0 1 2 3 4 5 6 7 8 >one &&
101 git checkout -m side >messages &&
102
103 test "$(git symbolic-ref HEAD)" = "refs/heads/side" &&
104
105 cat >expect.messages <<-\EOF &&
106 The following paths have local changes:
107 M one
108 EOF
109 test_cmp expect.messages messages &&
110
111 fill "M one" "A three" "D two" >expect.main &&
112 git diff --name-status main >current.main &&
113 test_cmp expect.main current.main &&
114
115 fill "M one" >expect.side &&
116 git diff --name-status side >current.side &&
117 test_cmp expect.side current.side &&
118
119 git diff --cached >current.index &&
120 test_must_be_empty current.index
121 '
122
123 test_expect_success 'checkout -m with dirty tree, renamed' '
124 git checkout -f main && git clean -f &&
125
126 fill 1 2 3 4 5 7 8 >one &&
127 if git checkout renamer
128 then
129 echo Not happy
130 false
131 else
132 echo "happy - failed correctly"
133 fi &&
134
135 git checkout -m renamer &&
136 fill 1 3 4 5 7 8 >expect &&
137 test_cmp expect uno &&
138 ! test -f one &&
139 git diff --cached >current &&
140 test_must_be_empty current
141 '
142
143 test_expect_success 'checkout -m with merge conflict' '
144 git checkout -f main && git clean -f &&
145
146 fill 1 T 3 4 5 6 S 8 >one &&
147 if git checkout renamer
148 then
149 echo Not happy
150 false
151 else
152 echo "happy - failed correctly"
153 fi &&
154
155 git checkout -m renamer &&
156
157 git diff main:one :3:uno |
158 sed -e "1,/^@@/d" -e "/^ /d" -e "s/^-/d/" -e "s/^+/a/" >current &&
159 fill d2 aT d7 aS >expect &&
160 test_cmp expect current &&
161 git diff --cached two >current &&
162 test_must_be_empty current
163 '
164
165 test_expect_success 'format of merge conflict from checkout -m' '
166 git checkout -f main &&
167 git clean -f &&
168
169 fill b d >two &&
170 git checkout -m simple &&
171
172 git ls-files >current &&
173 fill same two two two >expect &&
174 test_cmp expect current &&
175
176 cat <<-EOF >expect &&
177 <<<<<<< simple
178 a
179 c
180 e
181 =======
182 b
183 d
184 >>>>>>> local
185 EOF
186 test_cmp expect two
187 '
188
189 test_expect_success 'checkout --merge --conflict=diff3 <branch>' '
190 git checkout -f main &&
191 git reset --hard &&
192 git clean -f &&
193
194 fill b d >two &&
195 git checkout --merge --conflict=diff3 simple &&
196
197 cat <<-EOF >expect &&
198 <<<<<<< simple
199 a
200 c
201 e
202 ||||||| main
203 a
204 b
205 c
206 d
207 e
208 =======
209 b
210 d
211 >>>>>>> local
212 EOF
213 test_cmp expect two
214 '
215
216 test_expect_success 'checkout -m with mixed staged and unstaged changes' '
217 git checkout -f main &&
218 git clean -f &&
219
220 fill 0 x y z >same &&
221 git add same &&
222 fill 1 2 3 4 5 6 7 >one &&
223 git checkout -m side >actual 2>&1 &&
224 test_grep "Applied autostash" actual &&
225 fill 0 x y z >expect &&
226 test_cmp expect same &&
227 fill 1 2 3 4 5 6 7 >expect &&
228 test_cmp expect one
229 '
230
231 test_expect_success 'checkout -m creates a recoverable stash on conflict' '
232 git checkout -f main &&
233 git clean -f &&
234
235 fill 1 2 3 4 5 >one &&
236 test_must_fail git checkout side 2>stderr &&
237 test_grep "Your local changes" stderr &&
238 git checkout -m side >actual 2>&1 &&
239 test_grep "resulted in conflicts" actual &&
240 test_grep "git stash drop" actual &&
241 test_grep "git stash pop" actual &&
242 test_grep "The following paths have local changes" actual &&
243 git log -p -1 --format="%gs%n%B" -g --diff-merges=1 refs/stash >actual &&
244 sed /^index/d actual >actual.trimmed &&
245 cat >expect <<-EOF &&
246 autostash while switching to ${SQ}side${SQ}
247 On main: autostash while switching to ${SQ}side${SQ}
248
249 diff --git a/one b/one
250 --- a/one
251 +++ b/one
252 @@ -3,6 +3,3 @@
253 3
254 4
255 5
256 -6
257 -7
258 -8
259 EOF
260 test_cmp expect actual.trimmed &&
261 git stash drop &&
262 git reset --hard
263 '
264
265 test_expect_success 'checkout -m which would overwrite untracked file' '
266 git checkout -f --detach main &&
267 test_commit another-file &&
268 git checkout HEAD^ &&
269 >another-file.t &&
270 fill 1 2 3 4 5 >one &&
271 test_must_fail git checkout -m @{-1} 2>err &&
272 q_to_tab >expect <<-\EOF &&
273 error: The following untracked working tree files would be overwritten by checkout:
274 Qanother-file.t
275 Please move or remove them before you switch branches.
276 Aborting
277 Applied autostash.
278 EOF
279 test_cmp expect err
280 '
281
282 test_expect_success 'switch to another branch while carrying a deletion' '
283 git checkout -f main &&
284 git reset --hard &&
285 git clean -f &&
286 git rm two &&
287
288 test_must_fail git checkout simple 2>errs &&
289 test_grep overwritten errs &&
290
291 test_must_fail git read-tree --quiet -m -u HEAD simple 2>errs &&
292 test_must_be_empty errs
293 '
294
295 test_expect_success 'checkout to detach HEAD (with advice declined)' '
296 git config set advice.detachedHead false &&
297 rev=$(git rev-parse --short renamer^) &&
298 git checkout -f renamer &&
299 git clean -f &&
300 git checkout renamer^ 2>messages &&
301 test_grep "HEAD is now at $rev" messages &&
302 test_line_count = 1 messages &&
303 H=$(git rev-parse --verify HEAD) &&
304 M=$(git show-ref -s --verify refs/heads/main) &&
305 test "z$H" = "z$M" &&
306 if git symbolic-ref HEAD >/dev/null 2>&1
307 then
308 echo "OOPS, HEAD is still symbolic???"
309 false
310 else
311 : happy
312 fi
313 '
314
315 test_expect_success 'checkout to detach HEAD' '
316 git config set advice.detachedHead true &&
317 rev=$(git rev-parse --short renamer^) &&
318 git checkout -f renamer &&
319 git clean -f &&
320 git checkout renamer^ 2>messages &&
321 test_grep "HEAD is now at $rev" messages &&
322 test_line_count -gt 1 messages &&
323 H=$(git rev-parse --verify HEAD) &&
324 M=$(git show-ref -s --verify refs/heads/main) &&
325 test "z$H" = "z$M" &&
326 if git symbolic-ref HEAD >/dev/null 2>&1
327 then
328 echo "OOPS, HEAD is still symbolic???"
329 false
330 else
331 : happy
332 fi
333 '
334
335 test_expect_success 'checkout to detach HEAD with branchname^' '
336 git checkout -f main &&
337 git clean -f &&
338 git checkout renamer^ &&
339 H=$(git rev-parse --verify HEAD) &&
340 M=$(git show-ref -s --verify refs/heads/main) &&
341 test "z$H" = "z$M" &&
342 if git symbolic-ref HEAD >/dev/null 2>&1
343 then
344 echo "OOPS, HEAD is still symbolic???"
345 false
346 else
347 : happy
348 fi
349 '
350
351 test_expect_success 'checkout to detach HEAD with :/message' '
352 git checkout -f main &&
353 git clean -f &&
354 git checkout ":/Initial" &&
355 H=$(git rev-parse --verify HEAD) &&
356 M=$(git show-ref -s --verify refs/heads/main) &&
357 test "z$H" = "z$M" &&
358 if git symbolic-ref HEAD >/dev/null 2>&1
359 then
360 echo "OOPS, HEAD is still symbolic???"
361 false
362 else
363 : happy
364 fi
365 '
366
367 test_expect_success 'checkout to detach HEAD with HEAD^0' '
368 git checkout -f main &&
369 git clean -f &&
370 git checkout HEAD^0 &&
371 H=$(git rev-parse --verify HEAD) &&
372 M=$(git show-ref -s --verify refs/heads/main) &&
373 test "z$H" = "z$M" &&
374 if git symbolic-ref HEAD >/dev/null 2>&1
375 then
376 echo "OOPS, HEAD is still symbolic???"
377 false
378 else
379 : happy
380 fi
381 '
382
383 test_expect_success 'checkout with ambiguous tag/branch names' '
384 git tag both side &&
385 git branch both main &&
386 git reset --hard &&
387 git checkout main &&
388
389 git checkout both &&
390 H=$(git rev-parse --verify HEAD) &&
391 M=$(git show-ref -s --verify refs/heads/main) &&
392 test "z$H" = "z$M" &&
393 name=$(git symbolic-ref HEAD 2>/dev/null) &&
394 test "z$name" = zrefs/heads/both
395 '
396
397 test_expect_success 'checkout with ambiguous tag/branch names' '
398 git reset --hard &&
399 git checkout main &&
400
401 git tag frotz side &&
402 git branch frotz main &&
403 git reset --hard &&
404 git checkout main &&
405
406 git checkout tags/frotz &&
407 H=$(git rev-parse --verify HEAD) &&
408 S=$(git show-ref -s --verify refs/heads/side) &&
409 test "z$H" = "z$S" &&
410 if name=$(git symbolic-ref HEAD 2>/dev/null)
411 then
412 echo "Bad -- should have detached"
413 false
414 else
415 : happy
416 fi
417 '
418
419 test_expect_success 'switch branches while in subdirectory' '
420 git reset --hard &&
421 git checkout main &&
422
423 mkdir subs &&
424 git -C subs checkout side &&
425 ! test -f subs/one &&
426 rm -fr subs
427 '
428
429 test_expect_success 'checkout specific path while in subdirectory' '
430 git reset --hard &&
431 git checkout side &&
432 mkdir subs &&
433 >subs/bero &&
434 git add subs/bero &&
435 git commit -m "add subs/bero" &&
436
437 git checkout main &&
438 mkdir -p subs &&
439 git -C subs checkout side -- bero &&
440 test -f subs/bero
441 '
442
443 test_expect_success 'checkout w/--track sets up tracking' '
444 git config branch.autosetupmerge false &&
445 git checkout main &&
446 git checkout --track -b track1 &&
447 test "$(git config branch.track1.remote)" &&
448 test "$(git config branch.track1.merge)"
449 '
450
451 test_expect_success 'checkout w/autosetupmerge=always sets up tracking' '
452 test_when_finished git config branch.autosetupmerge false &&
453 git config branch.autosetupmerge always &&
454 git checkout main &&
455 git checkout -b track2 &&
456 test "$(git config branch.track2.remote)" &&
457 test "$(git config branch.track2.merge)"
458 '
459
460 test_expect_success 'checkout w/--track from non-branch HEAD fails' '
461 git checkout main^0 &&
462 test_must_fail git symbolic-ref HEAD &&
463 test_must_fail git checkout --track -b track &&
464 test_must_fail git rev-parse --verify track &&
465 test_must_fail git symbolic-ref HEAD &&
466 test "z$(git rev-parse main^0)" = "z$(git rev-parse HEAD)"
467 '
468
469 test_expect_success 'checkout w/--track from tag fails' '
470 git checkout main^0 &&
471 test_must_fail git symbolic-ref HEAD &&
472 test_must_fail git checkout --track -b track frotz &&
473 test_must_fail git rev-parse --verify track &&
474 test_must_fail git symbolic-ref HEAD &&
475 test "z$(git rev-parse main^0)" = "z$(git rev-parse HEAD)"
476 '
477
478 test_expect_success 'detach a symbolic link HEAD' '
479 git checkout main &&
480 git config --bool core.prefersymlinkrefs yes &&
481 git checkout side &&
482 git checkout main &&
483 it=$(git symbolic-ref HEAD) &&
484 test "z$it" = zrefs/heads/main &&
485 here=$(git rev-parse --verify refs/heads/main) &&
486 git checkout side^ &&
487 test "z$(git rev-parse --verify refs/heads/main)" = "z$here"
488 '
489
490 test_expect_success 'checkout with --track fakes a sensible -b <name>' '
491 git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" &&
492 git update-ref refs/remotes/origin/koala/bear renamer &&
493
494 git checkout --track origin/koala/bear &&
495 test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
496 test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
497
498 git checkout main && git branch -D koala/bear &&
499
500 git checkout --track refs/remotes/origin/koala/bear &&
501 test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
502 test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
503
504 git checkout main && git branch -D koala/bear &&
505
506 git checkout --track remotes/origin/koala/bear &&
507 test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
508 test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"
509 '
510
511 test_expect_success 'checkout with --track, but without -b, fails with too short tracked name' '
512 test_must_fail git checkout --track renamer
513 '
514
515 setup_conflicting_index () {
516 rm -f .git/index &&
517 O=$(echo original | git hash-object -w --stdin) &&
518 A=$(echo ourside | git hash-object -w --stdin) &&
519 B=$(echo theirside | git hash-object -w --stdin) &&
520 (
521 echo "100644 $A 0 fild" &&
522 echo "100644 $O 1 file" &&
523 echo "100644 $A 2 file" &&
524 echo "100644 $B 3 file" &&
525 echo "100644 $A 0 filf"
526 ) | git update-index --index-info
527 }
528
529 test_expect_success 'checkout an unmerged path should fail' '
530 setup_conflicting_index &&
531 echo "none of the above" >sample &&
532 cat sample >fild &&
533 cat sample >file &&
534 cat sample >filf &&
535 test_must_fail git checkout fild file filf &&
536 test_cmp sample fild &&
537 test_cmp sample filf &&
538 test_cmp sample file
539 '
540
541 test_expect_success 'checkout with an unmerged path can be ignored' '
542 setup_conflicting_index &&
543 echo "none of the above" >sample &&
544 echo ourside >expect &&
545 cat sample >fild &&
546 cat sample >file &&
547 cat sample >filf &&
548 git checkout -f fild file filf &&
549 test_cmp expect fild &&
550 test_cmp expect filf &&
551 test_cmp sample file
552 '
553
554 test_expect_success 'checkout unmerged stage' '
555 setup_conflicting_index &&
556 echo "none of the above" >sample &&
557 echo ourside >expect &&
558 cat sample >fild &&
559 cat sample >file &&
560 cat sample >filf &&
561 git checkout --ours . &&
562 test_cmp expect fild &&
563 test_cmp expect filf &&
564 test_cmp expect file &&
565 git checkout --theirs file &&
566 test ztheirside = "z$(cat file)"
567 '
568
569 test_expect_success 'checkout --ours is incompatible with switching' '
570 test_must_fail git checkout --ours 2>error &&
571 test_grep "needs the paths to check out" error &&
572
573 test_must_fail git checkout --ours HEAD 2>error &&
574 test_grep "cannot be used with switching" error &&
575
576 test_must_fail git checkout --ours main 2>error &&
577 test_grep "cannot be used with switching" error &&
578
579 git checkout --ours file
580 '
581
582 test_expect_success 'checkout path with --merge from tree-ish is a no-no' '
583 setup_conflicting_index &&
584 test_must_fail git checkout -m HEAD -- file
585 '
586
587 test_expect_success 'checkout with --merge' '
588 setup_conflicting_index &&
589 echo "none of the above" >sample &&
590 echo ourside >expect &&
591 cat sample >fild &&
592 cat sample >file &&
593 cat sample >filf &&
594 git checkout -m -- fild file filf &&
595 (
596 echo "<<<<<<< ours" &&
597 echo ourside &&
598 echo "=======" &&
599 echo theirside &&
600 echo ">>>>>>> theirs"
601 ) >merged &&
602 test_cmp expect fild &&
603 test_cmp expect filf &&
604 test_cmp merged file
605 '
606
607 test_expect_success 'checkout -m works after (mistaken) resolution' '
608 setup_conflicting_index &&
609 echo "none of the above" >sample &&
610 cat sample >fild &&
611 cat sample >file &&
612 cat sample >filf &&
613 # resolve to something
614 git add file &&
615 git checkout --merge -- fild file filf &&
616 {
617 echo "<<<<<<< ours" &&
618 echo ourside &&
619 echo "=======" &&
620 echo theirside &&
621 echo ">>>>>>> theirs"
622 } >merged &&
623 test_cmp expect fild &&
624 test_cmp expect filf &&
625 test_cmp merged file
626 '
627
628 test_expect_success 'checkout -m works after (mistaken) resolution to remove' '
629 setup_conflicting_index &&
630 echo "none of the above" >sample &&
631 cat sample >fild &&
632 cat sample >file &&
633 cat sample >filf &&
634 # resolve to remove
635 git rm file &&
636 git checkout --merge -- fild file filf &&
637 {
638 echo "<<<<<<< ours" &&
639 echo ourside &&
640 echo "=======" &&
641 echo theirside &&
642 echo ">>>>>>> theirs"
643 } >merged &&
644 test_cmp expect fild &&
645 test_cmp expect filf &&
646 test_cmp merged file
647 '
648
649 test_expect_success 'checkout with --merge, in diff3 -m style' '
650 git config merge.conflictstyle diff3 &&
651 setup_conflicting_index &&
652 echo "none of the above" >sample &&
653 echo ourside >expect &&
654 cat sample >fild &&
655 cat sample >file &&
656 cat sample >filf &&
657 git checkout -m -- fild file filf &&
658 (
659 echo "<<<<<<< ours" &&
660 echo ourside &&
661 echo "||||||| base" &&
662 echo original &&
663 echo "=======" &&
664 echo theirside &&
665 echo ">>>>>>> theirs"
666 ) >merged &&
667 test_cmp expect fild &&
668 test_cmp expect filf &&
669 test_cmp merged file
670 '
671
672 test_expect_success 'checkout --conflict=merge, overriding config' '
673 git config merge.conflictstyle diff3 &&
674 setup_conflicting_index &&
675 echo "none of the above" >sample &&
676 echo ourside >expect &&
677 cat sample >fild &&
678 cat sample >file &&
679 cat sample >filf &&
680 git checkout --conflict=merge -- fild file filf &&
681 (
682 echo "<<<<<<< ours" &&
683 echo ourside &&
684 echo "=======" &&
685 echo theirside &&
686 echo ">>>>>>> theirs"
687 ) >merged &&
688 test_cmp expect fild &&
689 test_cmp expect filf &&
690 test_cmp merged file
691 '
692
693 test_expect_success 'checkout --conflict=diff3' '
694 test_unconfig merge.conflictstyle &&
695 setup_conflicting_index &&
696 echo "none of the above" >sample &&
697 echo ourside >expect &&
698 cat sample >fild &&
699 cat sample >file &&
700 cat sample >filf &&
701 git checkout --conflict=diff3 -- fild file filf &&
702 (
703 echo "<<<<<<< ours" &&
704 echo ourside &&
705 echo "||||||| base" &&
706 echo original &&
707 echo "=======" &&
708 echo theirside &&
709 echo ">>>>>>> theirs"
710 ) >merged &&
711 test_cmp expect fild &&
712 test_cmp expect filf &&
713 test_cmp merged file
714 '
715
716 test_expect_success 'checkout --conflict=diff3 --no-conflict does not merge' '
717 setup_conflicting_index &&
718 echo "none of the above" >expect &&
719 cat expect >fild &&
720 cat expect >file &&
721 test_must_fail git checkout --conflict=diff3 --no-conflict -- fild file 2>err &&
722 test_cmp expect file &&
723 test_cmp expect fild &&
724 echo "error: path ${SQ}file${SQ} is unmerged" >expect &&
725 test_cmp expect err
726 '
727
728 test_expect_success 'checkout --conflict=diff3 --no-merge does not merge' '
729 setup_conflicting_index &&
730 echo "none of the above" >expect &&
731 cat expect >fild &&
732 cat expect >file &&
733 test_must_fail git checkout --conflict=diff3 --no-merge -- fild file 2>err &&
734 test_cmp expect file &&
735 test_cmp expect fild &&
736 echo "error: path ${SQ}file${SQ} is unmerged" >expect &&
737 test_cmp expect err
738 '
739
740 test_expect_success 'checkout --no-merge --conflict=diff3 does merge' '
741 setup_conflicting_index &&
742 echo "none of the above" >fild &&
743 echo "none of the above" >file &&
744 git checkout --no-merge --conflict=diff3 -- fild file &&
745 echo "ourside" >expect &&
746 test_cmp expect fild &&
747 cat >expect <<-\EOF &&
748 <<<<<<< ours
749 ourside
750 ||||||| base
751 original
752 =======
753 theirside
754 >>>>>>> theirs
755 EOF
756 test_cmp expect file
757 '
758
759 test_expect_success 'checkout --merge --conflict=diff3 --no-conflict does merge' '
760 setup_conflicting_index &&
761 echo "none of the above" >fild &&
762 echo "none of the above" >file &&
763 git checkout --merge --conflict=diff3 --no-conflict -- fild file &&
764 echo "ourside" >expect &&
765 test_cmp expect fild &&
766 cat >expect <<-\EOF &&
767 <<<<<<< ours
768 ourside
769 =======
770 theirside
771 >>>>>>> theirs
772 EOF
773 test_cmp expect file
774 '
775
776 test_expect_success 'checkout with invalid conflict style' '
777 test_must_fail git checkout --conflict=bad 2>actual -- file &&
778 echo "error: unknown conflict style ${SQ}bad${SQ}" >expect &&
779 test_cmp expect actual
780 '
781
782 test_expect_success 'failing checkout -b should not break working tree' '
783 git clean -fd && # Remove untracked files in the way
784 git reset --hard main &&
785 git symbolic-ref HEAD refs/heads/main &&
786 test_must_fail git checkout -b renamer side^ &&
787 test $(git symbolic-ref HEAD) = refs/heads/main &&
788 git diff --exit-code &&
789 git diff --cached --exit-code
790 '
791
792 test_expect_success 'switch out of non-branch' '
793 git reset --hard main &&
794 git checkout main^0 &&
795 echo modified >one &&
796 test_must_fail git checkout renamer 2>error.log &&
797 test_grep ! "^Previous HEAD" error.log
798 '
799
800 (
801 echo "#!$SHELL_PATH"
802 cat <<\EOF
803 O=$1 A=$2 B=$3
804 cat "$A" >.tmp
805 exec >"$A"
806 echo '<<<<<<< filfre-theirs'
807 cat "$B"
808 echo '||||||| filfre-common'
809 cat "$O"
810 echo '======='
811 cat ".tmp"
812 echo '>>>>>>> filfre-ours'
813 rm -f .tmp
814 exit 1
815 EOF
816 ) >filfre.sh
817 chmod +x filfre.sh
818
819 test_expect_success 'custom merge driver with checkout -m' '
820 git reset --hard &&
821
822 git config merge.filfre.driver "./filfre.sh %O %A %B" &&
823 git config merge.filfre.name "Feel-free merge driver" &&
824 git config merge.filfre.recursive binary &&
825 echo "arm merge=filfre" >.gitattributes &&
826
827 git checkout -b left &&
828 echo neutral >arm &&
829 git add arm .gitattributes &&
830 test_tick &&
831 git commit -m neutral &&
832 git branch right &&
833
834 echo left >arm &&
835 test_tick &&
836 git commit -a -m left &&
837 git checkout right &&
838
839 echo right >arm &&
840 test_tick &&
841 git commit -a -m right &&
842
843 test_must_fail git merge left &&
844 (
845 for t in filfre-common left right
846 do
847 test_grep $t arm || exit 1
848 done
849 ) &&
850
851 mv arm expect &&
852 git checkout -m arm &&
853 test_cmp expect arm
854 '
855
856 test_expect_success 'tracking info copied with autoSetupMerge=inherit' '
857 git reset --hard main &&
858 # default config does not copy tracking info
859 git checkout -b foo-no-inherit koala/bear &&
860 test_cmp_config "" --default "" branch.foo-no-inherit.remote &&
861 test_cmp_config "" --default "" branch.foo-no-inherit.merge &&
862 # with autoSetupMerge=inherit, we copy tracking info from koala/bear
863 test_config branch.autoSetupMerge inherit &&
864 git checkout -b foo koala/bear &&
865 test_cmp_config origin branch.foo.remote &&
866 test_cmp_config refs/heads/koala/bear branch.foo.merge &&
867 # no tracking info to inherit from main
868 git checkout -b main2 main &&
869 test_cmp_config "" --default "" branch.main2.remote &&
870 test_cmp_config "" --default "" branch.main2.merge
871 '
872
873 test_done