t7102,t7201: remove whitespace after redirect operator
[git] / t / t7201-co.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Junio C Hamano
4 #
5
6 test_description='git checkout tests.
7
8 Creates master, forks renamer and side branches from it.
9 Test switching across them.
10
11   ! [master] 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   +*++ [master] Initial A one, A two
20
21 '
22
23 . ./test-lib.sh
24
25 test_tick
26
27 fill () {
28         for i
29         do
30                 echo "$i"
31         done
32 }
33
34
35 test_expect_success setup '
36         fill x y z >same &&
37         fill 1 2 3 4 5 6 7 8 >one &&
38         fill a b c d e >two &&
39         git add same one two &&
40         git commit -m "Initial A one, A two" &&
41
42         git checkout -b renamer &&
43         rm -f one &&
44         fill 1 3 4 5 6 7 8 >uno &&
45         git add uno &&
46         fill a b c d e f >two &&
47         git commit -a -m "Renamer R one->uno, M two" &&
48
49         git checkout -b side master &&
50         fill 1 2 3 4 5 6 7 >one &&
51         fill A B C D E >three &&
52         rm -f two &&
53         git update-index --add --remove one two three &&
54         git commit -m "Side M one, D two, A three" &&
55
56         git checkout -b simple master &&
57         rm -f one &&
58         fill a c e >two &&
59         git commit -a -m "Simple D one, M two" &&
60
61         git checkout master
62 '
63
64 test_expect_success 'checkout from non-existing branch' '
65         git checkout -b delete-me master &&
66         git update-ref -d --no-deref refs/heads/delete-me &&
67         test refs/heads/delete-me = "$(git symbolic-ref HEAD)" &&
68         git checkout master &&
69         test refs/heads/master = "$(git symbolic-ref HEAD)"
70 '
71
72 test_expect_success 'checkout with dirty tree without -m' '
73         fill 0 1 2 3 4 5 6 7 8 >one &&
74         if git checkout side
75         then
76                 echo Not happy
77                 false
78         else
79                 echo "happy - failed correctly"
80         fi
81 '
82
83 test_expect_success 'checkout with unrelated dirty tree without -m' '
84         git checkout -f master &&
85         fill 0 1 2 3 4 5 6 7 8 >same &&
86         cp same kept &&
87         git checkout side >messages &&
88         test_cmp same kept &&
89         printf "M\t%s\n" same >messages.expect &&
90         test_cmp messages.expect messages
91 '
92
93 test_expect_success 'checkout -m with dirty tree' '
94         git checkout -f master &&
95         git clean -f &&
96
97         fill 0 1 2 3 4 5 6 7 8 >one &&
98         git checkout -m side >messages &&
99
100         test "$(git symbolic-ref HEAD)" = "refs/heads/side" &&
101
102         printf "M\t%s\n" one >expect.messages &&
103         test_cmp expect.messages messages &&
104
105         fill "M one" "A three" "D       two" >expect.master &&
106         git diff --name-status master >current.master &&
107         test_cmp expect.master current.master &&
108
109         fill "M one" >expect.side &&
110         git diff --name-status side >current.side &&
111         test_cmp expect.side current.side &&
112
113         git diff --cached >current.index &&
114         test_must_be_empty current.index
115 '
116
117 test_expect_success 'checkout -m with dirty tree, renamed' '
118         git checkout -f master && git clean -f &&
119
120         fill 1 2 3 4 5 7 8 >one &&
121         if git checkout renamer
122         then
123                 echo Not happy
124                 false
125         else
126                 echo "happy - failed correctly"
127         fi &&
128
129         git checkout -m renamer &&
130         fill 1 3 4 5 7 8 >expect &&
131         test_cmp expect uno &&
132         ! test -f one &&
133         git diff --cached >current &&
134         test_must_be_empty current
135 '
136
137 test_expect_success 'checkout -m with merge conflict' '
138         git checkout -f master && git clean -f &&
139
140         fill 1 T 3 4 5 6 S 8 >one &&
141         if git checkout renamer
142         then
143                 echo Not happy
144                 false
145         else
146                 echo "happy - failed correctly"
147         fi &&
148
149         git checkout -m renamer &&
150
151         git diff master:one :3:uno |
152         sed -e "1,/^@@/d" -e "/^ /d" -e "s/^-/d/" -e "s/^+/a/" >current &&
153         fill d2 aT d7 aS >expect &&
154         test_cmp expect current &&
155         git diff --cached two >current &&
156         test_must_be_empty current
157 '
158
159 test_expect_success 'format of merge conflict from checkout -m' '
160         git checkout -f master && git clean -f &&
161
162         fill b d >two &&
163         git checkout -m simple &&
164
165         git ls-files >current &&
166         fill same two two two >expect &&
167         test_cmp expect current &&
168
169         cat <<-EOF >expect &&
170         <<<<<<< simple
171         a
172         c
173         e
174         =======
175         b
176         d
177         >>>>>>> local
178         EOF
179         test_cmp expect two
180 '
181
182 test_expect_success 'checkout --merge --conflict=diff3 <branch>' '
183         git checkout -f master && git reset --hard && git clean -f &&
184
185         fill b d >two &&
186         git checkout --merge --conflict=diff3 simple &&
187
188         cat <<-EOF >expect &&
189         <<<<<<< simple
190         a
191         c
192         e
193         ||||||| master
194         a
195         b
196         c
197         d
198         e
199         =======
200         b
201         d
202         >>>>>>> local
203         EOF
204         test_cmp expect two
205 '
206
207 test_expect_success 'switch to another branch while carrying a deletion' '
208         git checkout -f master && git reset --hard && git clean -f &&
209         git rm two &&
210
211         test_must_fail git checkout simple 2>errs &&
212         test_i18ngrep overwritten errs &&
213
214         test_must_fail git read-tree --quiet -m -u HEAD simple 2>errs &&
215         test_must_be_empty errs
216 '
217
218 test_expect_success 'checkout to detach HEAD (with advice declined)' '
219         git config advice.detachedHead false &&
220         rev=$(git rev-parse --short renamer^) &&
221         git checkout -f renamer && git clean -f &&
222         git checkout renamer^ 2>messages &&
223         test_i18ngrep "HEAD is now at $rev" messages &&
224         test_line_count = 1 messages &&
225         H=$(git rev-parse --verify HEAD) &&
226         M=$(git show-ref -s --verify refs/heads/master) &&
227         test "z$H" = "z$M" &&
228         if git symbolic-ref HEAD >/dev/null 2>&1
229         then
230                 echo "OOPS, HEAD is still symbolic???"
231                 false
232         else
233                 : happy
234         fi
235 '
236
237 test_expect_success 'checkout to detach HEAD' '
238         git config advice.detachedHead true &&
239         rev=$(git rev-parse --short renamer^) &&
240         git checkout -f renamer && git clean -f &&
241         GIT_TEST_GETTEXT_POISON=false git checkout renamer^ 2>messages &&
242         grep "HEAD is now at $rev" messages &&
243         test_line_count -gt 1 messages &&
244         H=$(git rev-parse --verify HEAD) &&
245         M=$(git show-ref -s --verify refs/heads/master) &&
246         test "z$H" = "z$M" &&
247         if git symbolic-ref HEAD >/dev/null 2>&1
248         then
249                 echo "OOPS, HEAD is still symbolic???"
250                 false
251         else
252                 : happy
253         fi
254 '
255
256 test_expect_success 'checkout to detach HEAD with branchname^' '
257         git checkout -f master && git clean -f &&
258         git checkout renamer^ &&
259         H=$(git rev-parse --verify HEAD) &&
260         M=$(git show-ref -s --verify refs/heads/master) &&
261         test "z$H" = "z$M" &&
262         if git symbolic-ref HEAD >/dev/null 2>&1
263         then
264                 echo "OOPS, HEAD is still symbolic???"
265                 false
266         else
267                 : happy
268         fi
269 '
270
271 test_expect_success 'checkout to detach HEAD with :/message' '
272         git checkout -f master && git clean -f &&
273         git checkout ":/Initial" &&
274         H=$(git rev-parse --verify HEAD) &&
275         M=$(git show-ref -s --verify refs/heads/master) &&
276         test "z$H" = "z$M" &&
277         if git symbolic-ref HEAD >/dev/null 2>&1
278         then
279                 echo "OOPS, HEAD is still symbolic???"
280                 false
281         else
282                 : happy
283         fi
284 '
285
286 test_expect_success 'checkout to detach HEAD with HEAD^0' '
287         git checkout -f master && git clean -f &&
288         git checkout HEAD^0 &&
289         H=$(git rev-parse --verify HEAD) &&
290         M=$(git show-ref -s --verify refs/heads/master) &&
291         test "z$H" = "z$M" &&
292         if git symbolic-ref HEAD >/dev/null 2>&1
293         then
294                 echo "OOPS, HEAD is still symbolic???"
295                 false
296         else
297                 : happy
298         fi
299 '
300
301 test_expect_success 'checkout with ambiguous tag/branch names' '
302         git tag both side &&
303         git branch both master &&
304         git reset --hard &&
305         git checkout master &&
306
307         git checkout both &&
308         H=$(git rev-parse --verify HEAD) &&
309         M=$(git show-ref -s --verify refs/heads/master) &&
310         test "z$H" = "z$M" &&
311         name=$(git symbolic-ref HEAD 2>/dev/null) &&
312         test "z$name" = zrefs/heads/both
313 '
314
315 test_expect_success 'checkout with ambiguous tag/branch names' '
316         git reset --hard &&
317         git checkout master &&
318
319         git tag frotz side &&
320         git branch frotz master &&
321         git reset --hard &&
322         git checkout master &&
323
324         git checkout tags/frotz &&
325         H=$(git rev-parse --verify HEAD) &&
326         S=$(git show-ref -s --verify refs/heads/side) &&
327         test "z$H" = "z$S" &&
328         if name=$(git symbolic-ref HEAD 2>/dev/null)
329         then
330                 echo "Bad -- should have detached"
331                 false
332         else
333                 : happy
334         fi
335 '
336
337 test_expect_success 'switch branches while in subdirectory' '
338         git reset --hard &&
339         git checkout master &&
340
341         mkdir subs &&
342         (
343                 cd subs &&
344                 git checkout side
345         ) &&
346         ! test -f subs/one &&
347         rm -fr subs
348 '
349
350 test_expect_success 'checkout specific path while in subdirectory' '
351         git reset --hard &&
352         git checkout side &&
353         mkdir subs &&
354         >subs/bero &&
355         git add subs/bero &&
356         git commit -m "add subs/bero" &&
357
358         git checkout master &&
359         mkdir -p subs &&
360         (
361                 cd subs &&
362                 git checkout side -- bero
363         ) &&
364         test -f subs/bero
365 '
366
367 test_expect_success 'checkout w/--track sets up tracking' '
368     git config branch.autosetupmerge false &&
369     git checkout master &&
370     git checkout --track -b track1 &&
371     test "$(git config branch.track1.remote)" &&
372     test "$(git config branch.track1.merge)"
373 '
374
375 test_expect_success 'checkout w/autosetupmerge=always sets up tracking' '
376     test_when_finished git config branch.autosetupmerge false &&
377     git config branch.autosetupmerge always &&
378     git checkout master &&
379     git checkout -b track2 &&
380     test "$(git config branch.track2.remote)" &&
381     test "$(git config branch.track2.merge)"
382 '
383
384 test_expect_success 'checkout w/--track from non-branch HEAD fails' '
385     git checkout master^0 &&
386     test_must_fail git symbolic-ref HEAD &&
387     test_must_fail git checkout --track -b track &&
388     test_must_fail git rev-parse --verify track &&
389     test_must_fail git symbolic-ref HEAD &&
390     test "z$(git rev-parse master^0)" = "z$(git rev-parse HEAD)"
391 '
392
393 test_expect_success 'checkout w/--track from tag fails' '
394     git checkout master^0 &&
395     test_must_fail git symbolic-ref HEAD &&
396     test_must_fail git checkout --track -b track frotz &&
397     test_must_fail git rev-parse --verify track &&
398     test_must_fail git symbolic-ref HEAD &&
399     test "z$(git rev-parse master^0)" = "z$(git rev-parse HEAD)"
400 '
401
402 test_expect_success 'detach a symbolic link HEAD' '
403     git checkout master &&
404     git config --bool core.prefersymlinkrefs yes &&
405     git checkout side &&
406     git checkout master &&
407     it=$(git symbolic-ref HEAD) &&
408     test "z$it" = zrefs/heads/master &&
409     here=$(git rev-parse --verify refs/heads/master) &&
410     git checkout side^ &&
411     test "z$(git rev-parse --verify refs/heads/master)" = "z$here"
412 '
413
414 test_expect_success 'checkout with --track fakes a sensible -b <name>' '
415     git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" &&
416     git update-ref refs/remotes/origin/koala/bear renamer &&
417
418     git checkout --track origin/koala/bear &&
419     test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
420     test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
421
422     git checkout master && git branch -D koala/bear &&
423
424     git checkout --track refs/remotes/origin/koala/bear &&
425     test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
426     test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
427
428     git checkout master && git branch -D koala/bear &&
429
430     git checkout --track remotes/origin/koala/bear &&
431     test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
432     test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"
433 '
434
435 test_expect_success 'checkout with --track, but without -b, fails with too short tracked name' '
436     test_must_fail git checkout --track renamer
437 '
438
439 setup_conflicting_index () {
440         rm -f .git/index &&
441         O=$(echo original | git hash-object -w --stdin) &&
442         A=$(echo ourside | git hash-object -w --stdin) &&
443         B=$(echo theirside | git hash-object -w --stdin) &&
444         (
445                 echo "100644 $A 0       fild" &&
446                 echo "100644 $O 1       file" &&
447                 echo "100644 $A 2       file" &&
448                 echo "100644 $B 3       file" &&
449                 echo "100644 $A 0       filf"
450         ) | git update-index --index-info
451 }
452
453 test_expect_success 'checkout an unmerged path should fail' '
454         setup_conflicting_index &&
455         echo "none of the above" >sample &&
456         cat sample >fild &&
457         cat sample >file &&
458         cat sample >filf &&
459         test_must_fail git checkout fild file filf &&
460         test_cmp sample fild &&
461         test_cmp sample filf &&
462         test_cmp sample file
463 '
464
465 test_expect_success 'checkout with an unmerged path can be ignored' '
466         setup_conflicting_index &&
467         echo "none of the above" >sample &&
468         echo ourside >expect &&
469         cat sample >fild &&
470         cat sample >file &&
471         cat sample >filf &&
472         git checkout -f fild file filf &&
473         test_cmp expect fild &&
474         test_cmp expect filf &&
475         test_cmp sample file
476 '
477
478 test_expect_success 'checkout unmerged stage' '
479         setup_conflicting_index &&
480         echo "none of the above" >sample &&
481         echo ourside >expect &&
482         cat sample >fild &&
483         cat sample >file &&
484         cat sample >filf &&
485         git checkout --ours . &&
486         test_cmp expect fild &&
487         test_cmp expect filf &&
488         test_cmp expect file &&
489         git checkout --theirs file &&
490         test ztheirside = "z$(cat file)"
491 '
492
493 test_expect_success 'checkout with --merge' '
494         setup_conflicting_index &&
495         echo "none of the above" >sample &&
496         echo ourside >expect &&
497         cat sample >fild &&
498         cat sample >file &&
499         cat sample >filf &&
500         git checkout -m -- fild file filf &&
501         (
502                 echo "<<<<<<< ours" &&
503                 echo ourside &&
504                 echo "=======" &&
505                 echo theirside &&
506                 echo ">>>>>>> theirs"
507         ) >merged &&
508         test_cmp expect fild &&
509         test_cmp expect filf &&
510         test_cmp merged file
511 '
512
513 test_expect_success 'checkout with --merge, in diff3 -m style' '
514         git config merge.conflictstyle diff3 &&
515         setup_conflicting_index &&
516         echo "none of the above" >sample &&
517         echo ourside >expect &&
518         cat sample >fild &&
519         cat sample >file &&
520         cat sample >filf &&
521         git checkout -m -- fild file filf &&
522         (
523                 echo "<<<<<<< ours" &&
524                 echo ourside &&
525                 echo "||||||| base" &&
526                 echo original &&
527                 echo "=======" &&
528                 echo theirside &&
529                 echo ">>>>>>> theirs"
530         ) >merged &&
531         test_cmp expect fild &&
532         test_cmp expect filf &&
533         test_cmp merged file
534 '
535
536 test_expect_success 'checkout --conflict=merge, overriding config' '
537         git config merge.conflictstyle diff3 &&
538         setup_conflicting_index &&
539         echo "none of the above" >sample &&
540         echo ourside >expect &&
541         cat sample >fild &&
542         cat sample >file &&
543         cat sample >filf &&
544         git checkout --conflict=merge -- fild file filf &&
545         (
546                 echo "<<<<<<< ours" &&
547                 echo ourside &&
548                 echo "=======" &&
549                 echo theirside &&
550                 echo ">>>>>>> theirs"
551         ) >merged &&
552         test_cmp expect fild &&
553         test_cmp expect filf &&
554         test_cmp merged file
555 '
556
557 test_expect_success 'checkout --conflict=diff3' '
558         test_unconfig merge.conflictstyle &&
559         setup_conflicting_index &&
560         echo "none of the above" >sample &&
561         echo ourside >expect &&
562         cat sample >fild &&
563         cat sample >file &&
564         cat sample >filf &&
565         git checkout --conflict=diff3 -- fild file filf &&
566         (
567                 echo "<<<<<<< ours" &&
568                 echo ourside &&
569                 echo "||||||| base" &&
570                 echo original &&
571                 echo "=======" &&
572                 echo theirside &&
573                 echo ">>>>>>> theirs"
574         ) >merged &&
575         test_cmp expect fild &&
576         test_cmp expect filf &&
577         test_cmp merged file
578 '
579
580 test_expect_success 'failing checkout -b should not break working tree' '
581         git reset --hard master &&
582         git symbolic-ref HEAD refs/heads/master &&
583         test_must_fail git checkout -b renamer side^ &&
584         test $(git symbolic-ref HEAD) = refs/heads/master &&
585         git diff --exit-code &&
586         git diff --cached --exit-code
587 '
588
589 test_expect_success 'switch out of non-branch' '
590         git reset --hard master &&
591         git checkout master^0 &&
592         echo modified >one &&
593         test_must_fail git checkout renamer 2>error.log &&
594         ! grep "^Previous HEAD" error.log
595 '
596
597 (
598  echo "#!$SHELL_PATH"
599  cat <<\EOF
600 O=$1 A=$2 B=$3
601 cat "$A" >.tmp
602 exec >"$A"
603 echo '<<<<<<< filfre-theirs'
604 cat "$B"
605 echo '||||||| filfre-common'
606 cat "$O"
607 echo '======='
608 cat ".tmp"
609 echo '>>>>>>> filfre-ours'
610 rm -f .tmp
611 exit 1
612 EOF
613 ) >filfre.sh
614 chmod +x filfre.sh
615
616 test_expect_success 'custom merge driver with checkout -m' '
617         git reset --hard &&
618
619         git config merge.filfre.driver "./filfre.sh %O %A %B" &&
620         git config merge.filfre.name "Feel-free merge driver" &&
621         git config merge.filfre.recursive binary &&
622         echo "arm merge=filfre" >.gitattributes &&
623
624         git checkout -b left &&
625         echo neutral >arm &&
626         git add arm .gitattributes &&
627         test_tick &&
628         git commit -m neutral &&
629         git branch right &&
630
631         echo left >arm &&
632         test_tick &&
633         git commit -a -m left &&
634         git checkout right &&
635
636         echo right >arm &&
637         test_tick &&
638         git commit -a -m right &&
639
640         test_must_fail git merge left &&
641         (
642                 for t in filfre-common left right
643                 do
644                         grep $t arm || exit 1
645                 done
646         ) &&
647
648         mv arm expect &&
649         git checkout -m arm &&
650         test_cmp expect arm
651 '
652
653 test_done