t/lib-httpd: load mod_unixd
[git] / t / t5505-remote.sh
1 #!/bin/sh
2
3 test_description='git remote porcelain-ish'
4
5 . ./test-lib.sh
6
7 setup_repository () {
8         mkdir "$1" && (
9         cd "$1" &&
10         git init &&
11         >file &&
12         git add file &&
13         test_tick &&
14         git commit -m "Initial" &&
15         git checkout -b side &&
16         >elif &&
17         git add elif &&
18         test_tick &&
19         git commit -m "Second" &&
20         git checkout master
21         )
22 }
23
24 tokens_match () {
25         echo "$1" | tr ' ' '\012' | sort | sed -e '/^$/d' >expect &&
26         echo "$2" | tr ' ' '\012' | sort | sed -e '/^$/d' >actual &&
27         test_cmp expect actual
28 }
29
30 check_remote_track () {
31         actual=$(git remote show "$1" | sed -ne 's|^    \(.*\) tracked$|\1|p')
32         shift &&
33         tokens_match "$*" "$actual"
34 }
35
36 check_tracking_branch () {
37         f="" &&
38         r=$(git for-each-ref "--format=%(refname)" |
39                 sed -ne "s|^refs/remotes/$1/||p") &&
40         shift &&
41         tokens_match "$*" "$r"
42 }
43
44 test_expect_success setup '
45         setup_repository one &&
46         setup_repository two &&
47         (
48                 cd two &&
49                 git branch another
50         ) &&
51         git clone one test
52 '
53
54 test_expect_success 'add remote whose URL agrees with url.<...>.insteadOf' '
55         test_config url.git@host.com:team/repo.git.insteadOf myremote &&
56         git remote add myremote git@host.com:team/repo.git
57 '
58
59 test_expect_success C_LOCALE_OUTPUT 'remote information for the origin' '
60         (
61                 cd test &&
62                 tokens_match origin "$(git remote)" &&
63                 check_remote_track origin master side &&
64                 check_tracking_branch origin HEAD master side
65         )
66 '
67
68 test_expect_success 'add another remote' '
69         (
70                 cd test &&
71                 git remote add -f second ../two &&
72                 tokens_match "origin second" "$(git remote)" &&
73                 check_tracking_branch second master side another &&
74                 git for-each-ref "--format=%(refname)" refs/remotes |
75                 sed -e "/^refs\/remotes\/origin\//d" \
76                     -e "/^refs\/remotes\/second\//d" >actual &&
77                 >expect &&
78                 test_cmp expect actual
79         )
80 '
81
82 test_expect_success C_LOCALE_OUTPUT 'check remote-tracking' '
83         (
84                 cd test &&
85                 check_remote_track origin master side &&
86                 check_remote_track second master side another
87         )
88 '
89
90 test_expect_success 'remote forces tracking branches' '
91         (
92                 cd test &&
93                 case $(git config remote.second.fetch) in
94                 +*) true ;;
95                  *) false ;;
96                 esac
97         )
98 '
99
100 test_expect_success 'remove remote' '
101         (
102                 cd test &&
103                 git symbolic-ref refs/remotes/second/HEAD refs/remotes/second/master &&
104                 git remote rm second
105         )
106 '
107
108 test_expect_success C_LOCALE_OUTPUT 'remove remote' '
109         (
110                 cd test &&
111                 tokens_match origin "$(git remote)" &&
112                 check_remote_track origin master side &&
113                 git for-each-ref "--format=%(refname)" refs/remotes |
114                 sed -e "/^refs\/remotes\/origin\//d" >actual &&
115                 >expect &&
116                 test_cmp expect actual
117         )
118 '
119
120 test_expect_success 'remove remote protects local branches' '
121         (
122                 cd test &&
123                 cat >expect1 <<-\EOF &&
124                 Note: A branch outside the refs/remotes/ hierarchy was not removed;
125                 to delete it, use:
126                   git branch -d master
127                 EOF
128                 cat >expect2 <<-\EOF &&
129                 Note: Some branches outside the refs/remotes/ hierarchy were not removed;
130                 to delete them, use:
131                   git branch -d foobranch
132                   git branch -d master
133                 EOF
134                 git tag footag &&
135                 git config --add remote.oops.fetch "+refs/*:refs/*" &&
136                 git remote remove oops 2>actual1 &&
137                 git branch foobranch &&
138                 git config --add remote.oops.fetch "+refs/*:refs/*" &&
139                 git remote rm oops 2>actual2 &&
140                 git branch -d foobranch &&
141                 git tag -d footag &&
142                 test_i18ncmp expect1 actual1 &&
143                 test_i18ncmp expect2 actual2
144         )
145 '
146
147 cat >test/expect <<EOF
148 * remote origin
149   Fetch URL: $(pwd)/one
150   Push  URL: $(pwd)/one
151   HEAD branch: master
152   Remote branches:
153     master new (next fetch will store in remotes/origin)
154     side   tracked
155   Local branches configured for 'git pull':
156     ahead    merges with remote master
157     master   merges with remote master
158     octopus  merges with remote topic-a
159                 and with remote topic-b
160                 and with remote topic-c
161     rebase  rebases onto remote master
162   Local refs configured for 'git push':
163     master pushes to master   (local out of date)
164     master pushes to upstream (create)
165 * remote two
166   Fetch URL: ../two
167   Push  URL: ../three
168   HEAD branch: master
169   Local refs configured for 'git push':
170     ahead  forces to master  (fast-forwardable)
171     master pushes to another (up to date)
172 EOF
173
174 test_expect_success 'show' '
175         (
176                 cd test &&
177                 git config --add remote.origin.fetch refs/heads/master:refs/heads/upstream &&
178                 git fetch &&
179                 git checkout -b ahead origin/master &&
180                 echo 1 >>file &&
181                 test_tick &&
182                 git commit -m update file &&
183                 git checkout master &&
184                 git branch --track octopus origin/master &&
185                 git branch --track rebase origin/master &&
186                 git branch -d -r origin/master &&
187                 git config --add remote.two.url ../two &&
188                 git config --add remote.two.pushurl ../three &&
189                 git config branch.rebase.rebase true &&
190                 git config branch.octopus.merge "topic-a topic-b topic-c" &&
191                 (
192                         cd ../one &&
193                         echo 1 >file &&
194                         test_tick &&
195                         git commit -m update file
196                 ) &&
197                 git config --add remote.origin.push : &&
198                 git config --add remote.origin.push refs/heads/master:refs/heads/upstream &&
199                 git config --add remote.origin.push +refs/tags/lastbackup &&
200                 git config --add remote.two.push +refs/heads/ahead:refs/heads/master &&
201                 git config --add remote.two.push refs/heads/master:refs/heads/another &&
202                 git remote show origin two >output &&
203                 git branch -d rebase octopus &&
204                 test_i18ncmp expect output
205         )
206 '
207
208 cat >test/expect <<EOF
209 * remote origin
210   Fetch URL: $(pwd)/one
211   Push  URL: $(pwd)/one
212   HEAD branch: (not queried)
213   Remote branches: (status not queried)
214     master
215     side
216   Local branches configured for 'git pull':
217     ahead  merges with remote master
218     master merges with remote master
219   Local refs configured for 'git push' (status not queried):
220     (matching)           pushes to (matching)
221     refs/heads/master    pushes to refs/heads/upstream
222     refs/tags/lastbackup forces to refs/tags/lastbackup
223 EOF
224
225 test_expect_success 'show -n' '
226         mv one one.unreachable &&
227         (
228                 cd test &&
229                 git remote show -n origin >output &&
230                 mv ../one.unreachable ../one &&
231                 test_i18ncmp expect output
232         )
233 '
234
235 test_expect_success 'prune' '
236         (
237                 cd one &&
238                 git branch -m side side2
239         ) &&
240         (
241                 cd test &&
242                 git fetch origin &&
243                 git remote prune origin &&
244                 git rev-parse refs/remotes/origin/side2 &&
245                 test_must_fail git rev-parse refs/remotes/origin/side
246         )
247 '
248
249 test_expect_success 'set-head --delete' '
250         (
251                 cd test &&
252                 git symbolic-ref refs/remotes/origin/HEAD &&
253                 git remote set-head --delete origin &&
254                 test_must_fail git symbolic-ref refs/remotes/origin/HEAD
255         )
256 '
257
258 test_expect_success 'set-head --auto' '
259         (
260                 cd test &&
261                 git remote set-head --auto origin &&
262                 echo refs/remotes/origin/master >expect &&
263                 git symbolic-ref refs/remotes/origin/HEAD >output &&
264                 test_cmp expect output
265         )
266 '
267
268 test_expect_success 'set-head --auto has no problem w/multiple HEADs' '
269         (
270                 cd test &&
271                 git fetch two "refs/heads/*:refs/remotes/two/*" &&
272                 git remote set-head --auto two >output 2>&1 &&
273                 echo "two/HEAD set to master" >expect &&
274                 test_i18ncmp expect output
275         )
276 '
277
278 cat >test/expect <<\EOF
279 refs/remotes/origin/side2
280 EOF
281
282 test_expect_success 'set-head explicit' '
283         (
284                 cd test &&
285                 git remote set-head origin side2 &&
286                 git symbolic-ref refs/remotes/origin/HEAD >output &&
287                 git remote set-head origin master &&
288                 test_cmp expect output
289         )
290 '
291
292 cat >test/expect <<EOF
293 Pruning origin
294 URL: $(pwd)/one
295  * [would prune] origin/side2
296 EOF
297
298 test_expect_success 'prune --dry-run' '
299         (
300                 cd one &&
301                 git branch -m side2 side) &&
302         (
303                 cd test &&
304                 git remote prune --dry-run origin >output &&
305                 git rev-parse refs/remotes/origin/side2 &&
306                 test_must_fail git rev-parse refs/remotes/origin/side &&
307         (
308                 cd ../one &&
309                 git branch -m side side2) &&
310                 test_i18ncmp expect output
311         )
312 '
313
314 test_expect_success 'add --mirror && prune' '
315         mkdir mirror &&
316         (
317                 cd mirror &&
318                 git init --bare &&
319                 git remote add --mirror -f origin ../one
320         ) &&
321         (
322                 cd one &&
323                 git branch -m side2 side
324         ) &&
325         (
326                 cd mirror &&
327                 git rev-parse --verify refs/heads/side2 &&
328                 test_must_fail git rev-parse --verify refs/heads/side &&
329                 git fetch origin &&
330                 git remote prune origin &&
331                 test_must_fail git rev-parse --verify refs/heads/side2 &&
332                 git rev-parse --verify refs/heads/side
333         )
334 '
335
336 test_expect_success 'add --mirror=fetch' '
337         mkdir mirror-fetch &&
338         git init mirror-fetch/parent &&
339         (
340                 cd mirror-fetch/parent &&
341                 test_commit one
342         ) &&
343         git init --bare mirror-fetch/child &&
344         (
345                 cd mirror-fetch/child &&
346                 git remote add --mirror=fetch -f parent ../parent
347         )
348 '
349
350 test_expect_success 'fetch mirrors act as mirrors during fetch' '
351         (
352                 cd mirror-fetch/parent &&
353                 git branch new &&
354                 git branch -m master renamed
355         ) &&
356         (
357                 cd mirror-fetch/child &&
358                 git fetch parent &&
359                 git rev-parse --verify refs/heads/new &&
360                 git rev-parse --verify refs/heads/renamed
361         )
362 '
363
364 test_expect_success 'fetch mirrors can prune' '
365         (
366                 cd mirror-fetch/child &&
367                 git remote prune parent &&
368                 test_must_fail git rev-parse --verify refs/heads/master
369         )
370 '
371
372 test_expect_success 'fetch mirrors do not act as mirrors during push' '
373         (
374                 cd mirror-fetch/parent &&
375                 git checkout HEAD^0
376         ) &&
377         (
378                 cd mirror-fetch/child &&
379                 git branch -m renamed renamed2 &&
380                 git push parent :
381         ) &&
382         (
383                 cd mirror-fetch/parent &&
384                 git rev-parse --verify renamed &&
385                 test_must_fail git rev-parse --verify refs/heads/renamed2
386         )
387 '
388
389 test_expect_success 'add fetch mirror with specific branches' '
390         git init --bare mirror-fetch/track &&
391         (
392                 cd mirror-fetch/track &&
393                 git remote add --mirror=fetch -t heads/new parent ../parent
394         )
395 '
396
397 test_expect_success 'fetch mirror respects specific branches' '
398         (
399                 cd mirror-fetch/track &&
400                 git fetch parent &&
401                 git rev-parse --verify refs/heads/new &&
402                 test_must_fail git rev-parse --verify refs/heads/renamed
403         )
404 '
405
406 test_expect_success 'add --mirror=push' '
407         mkdir mirror-push &&
408         git init --bare mirror-push/public &&
409         git init mirror-push/private &&
410         (
411                 cd mirror-push/private &&
412                 test_commit one &&
413                 git remote add --mirror=push public ../public
414         )
415 '
416
417 test_expect_success 'push mirrors act as mirrors during push' '
418         (
419                 cd mirror-push/private &&
420                 git branch new &&
421                 git branch -m master renamed &&
422                 git push public
423         ) &&
424         (
425                 cd mirror-push/private &&
426                 git rev-parse --verify refs/heads/new &&
427                 git rev-parse --verify refs/heads/renamed &&
428                 test_must_fail git rev-parse --verify refs/heads/master
429         )
430 '
431
432 test_expect_success 'push mirrors do not act as mirrors during fetch' '
433         (
434                 cd mirror-push/public &&
435                 git branch -m renamed renamed2 &&
436                 git symbolic-ref HEAD refs/heads/renamed2
437         ) &&
438         (
439                 cd mirror-push/private &&
440                 git fetch public &&
441                 git rev-parse --verify refs/heads/renamed &&
442                 test_must_fail git rev-parse --verify refs/heads/renamed2
443         )
444 '
445
446 test_expect_success 'push mirrors do not allow you to specify refs' '
447         git init mirror-push/track &&
448         (
449                 cd mirror-push/track &&
450                 test_must_fail git remote add --mirror=push -t new public ../public
451         )
452 '
453
454 test_expect_success 'add alt && prune' '
455         mkdir alttst &&
456         (
457                 cd alttst &&
458                 git init &&
459                 git remote add -f origin ../one &&
460                 git config remote.alt.url ../one &&
461                 git config remote.alt.fetch "+refs/heads/*:refs/remotes/origin/*"
462         ) &&
463         (
464                 cd one &&
465                 git branch -m side side2
466         ) &&
467         (
468                 cd alttst &&
469                 git rev-parse --verify refs/remotes/origin/side &&
470                 test_must_fail git rev-parse --verify refs/remotes/origin/side2 &&
471                 git fetch alt &&
472                 git remote prune alt &&
473                 test_must_fail git rev-parse --verify refs/remotes/origin/side &&
474                 git rev-parse --verify refs/remotes/origin/side2
475         )
476 '
477
478 cat >test/expect <<\EOF
479 some-tag
480 EOF
481
482 test_expect_success 'add with reachable tags (default)' '
483         (
484                 cd one &&
485                 >foobar &&
486                 git add foobar &&
487                 git commit -m "Foobar" &&
488                 git tag -a -m "Foobar tag" foobar-tag &&
489                 git reset --hard HEAD~1 &&
490                 git tag -a -m "Some tag" some-tag
491         ) &&
492         mkdir add-tags &&
493         (
494                 cd add-tags &&
495                 git init &&
496                 git remote add -f origin ../one &&
497                 git tag -l some-tag >../test/output &&
498                 git tag -l foobar-tag >>../test/output &&
499                 test_must_fail git config remote.origin.tagopt
500         ) &&
501         test_cmp test/expect test/output
502 '
503
504 cat >test/expect <<\EOF
505 some-tag
506 foobar-tag
507 --tags
508 EOF
509
510 test_expect_success 'add --tags' '
511         rm -rf add-tags &&
512         (
513                 mkdir add-tags &&
514                 cd add-tags &&
515                 git init &&
516                 git remote add -f --tags origin ../one &&
517                 git tag -l some-tag >../test/output &&
518                 git tag -l foobar-tag >>../test/output &&
519                 git config remote.origin.tagopt >>../test/output
520         ) &&
521         test_cmp test/expect test/output
522 '
523
524 cat >test/expect <<\EOF
525 --no-tags
526 EOF
527
528 test_expect_success 'add --no-tags' '
529         rm -rf add-tags &&
530         (
531                 mkdir add-no-tags &&
532                 cd add-no-tags &&
533                 git init &&
534                 git remote add -f --no-tags origin ../one &&
535                 git tag -l some-tag >../test/output &&
536                 git tag -l foobar-tag >../test/output &&
537                 git config remote.origin.tagopt >>../test/output
538         ) &&
539         (
540                 cd one &&
541                 git tag -d some-tag foobar-tag
542         ) &&
543         test_cmp test/expect test/output
544 '
545
546 test_expect_success 'reject --no-no-tags' '
547         (
548                 cd add-no-tags &&
549                 test_must_fail git remote add -f --no-no-tags neworigin ../one
550         )
551 '
552
553 cat >one/expect <<\EOF
554   apis/master
555   apis/side
556   drosophila/another
557   drosophila/master
558   drosophila/side
559 EOF
560
561 test_expect_success 'update' '
562         (
563                 cd one &&
564                 git remote add drosophila ../two &&
565                 git remote add apis ../mirror &&
566                 git remote update &&
567                 git branch -r >output &&
568                 test_cmp expect output
569         )
570 '
571
572 cat >one/expect <<\EOF
573   drosophila/another
574   drosophila/master
575   drosophila/side
576   manduca/master
577   manduca/side
578   megaloprepus/master
579   megaloprepus/side
580 EOF
581
582 test_expect_success 'update with arguments' '
583         (
584                 cd one &&
585                 for b in $(git branch -r)
586                 do
587                 git branch -r -d $b || exit 1
588                 done &&
589                 git remote add manduca ../mirror &&
590                 git remote add megaloprepus ../mirror &&
591                 git config remotes.phobaeticus "drosophila megaloprepus" &&
592                 git config remotes.titanus manduca &&
593                 git remote update phobaeticus titanus &&
594                 git branch -r >output &&
595                 test_cmp expect output
596         )
597 '
598
599 test_expect_success 'update --prune' '
600         (
601                 cd one &&
602                 git branch -m side2 side3
603         ) &&
604         (
605                 cd test &&
606                 git remote update --prune &&
607                 (
608                         cd ../one &&
609                         git branch -m side3 side2
610                 ) &&
611                 git rev-parse refs/remotes/origin/side3 &&
612                 test_must_fail git rev-parse refs/remotes/origin/side2
613         )
614 '
615
616 cat >one/expect <<-\EOF
617   apis/master
618   apis/side
619   manduca/master
620   manduca/side
621   megaloprepus/master
622   megaloprepus/side
623 EOF
624
625 test_expect_success 'update default' '
626         (
627                 cd one &&
628                 for b in $(git branch -r)
629                 do
630                 git branch -r -d $b || exit 1
631                 done &&
632                 git config remote.drosophila.skipDefaultUpdate true &&
633                 git remote update default &&
634                 git branch -r >output &&
635                 test_cmp expect output
636         )
637 '
638
639 cat >one/expect <<\EOF
640   drosophila/another
641   drosophila/master
642   drosophila/side
643 EOF
644
645 test_expect_success 'update default (overridden, with funny whitespace)' '
646         (
647                 cd one &&
648                 for b in $(git branch -r)
649                 do
650                 git branch -r -d $b || exit 1
651                 done &&
652                 git config remotes.default "$(printf "\t drosophila  \n")" &&
653                 git remote update default &&
654                 git branch -r >output &&
655                 test_cmp expect output
656         )
657 '
658
659 test_expect_success 'update (with remotes.default defined)' '
660         (
661                 cd one &&
662                 for b in $(git branch -r)
663                 do
664                 git branch -r -d $b || exit 1
665                 done &&
666                 git config remotes.default "drosophila" &&
667                 git remote update &&
668                 git branch -r >output &&
669                 test_cmp expect output
670         )
671 '
672
673 test_expect_success '"remote show" does not show symbolic refs' '
674         git clone one three &&
675         (
676                 cd three &&
677                 git remote show origin >output &&
678                 ! grep "^ *HEAD$" < output &&
679                 ! grep -i stale < output
680         )
681 '
682
683 test_expect_success 'reject adding remote with an invalid name' '
684         test_must_fail git remote add some:url desired-name
685 '
686
687 # The first three test if the tracking branches are properly renamed,
688 # the last two ones check if the config is updated.
689
690 test_expect_success 'rename a remote' '
691         git clone one four &&
692         (
693                 cd four &&
694                 git remote rename origin upstream &&
695                 rmdir .git/refs/remotes/origin &&
696                 test "$(git symbolic-ref refs/remotes/upstream/HEAD)" = "refs/remotes/upstream/master" &&
697                 test "$(git rev-parse upstream/master)" = "$(git rev-parse master)" &&
698                 test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*" &&
699                 test "$(git config branch.master.remote)" = "upstream"
700         )
701 '
702
703 test_expect_success 'rename does not update a non-default fetch refspec' '
704         git clone one four.one &&
705         (
706                 cd four.one &&
707                 git config remote.origin.fetch +refs/heads/*:refs/heads/origin/* &&
708                 git remote rename origin upstream &&
709                 test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/heads/origin/*" &&
710                 git rev-parse -q origin/master
711         )
712 '
713
714 test_expect_success 'rename a remote with name part of fetch spec' '
715         git clone one four.two &&
716         (
717                 cd four.two &&
718                 git remote rename origin remote &&
719                 git remote rename remote upstream &&
720                 test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*"
721         )
722 '
723
724 test_expect_success 'rename a remote with name prefix of other remote' '
725         git clone one four.three &&
726         (
727                 cd four.three &&
728                 git remote add o git://example.com/repo.git &&
729                 git remote rename o upstream &&
730                 test "$(git rev-parse origin/master)" = "$(git rev-parse master)"
731         )
732 '
733
734 cat >remotes_origin <<EOF
735 URL: $(pwd)/one
736 Push: refs/heads/master:refs/heads/upstream
737 Push: refs/heads/next:refs/heads/upstream2
738 Pull: refs/heads/master:refs/heads/origin
739 Pull: refs/heads/next:refs/heads/origin2
740 EOF
741
742 test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
743         git clone one five &&
744         origin_url=$(pwd)/one &&
745         (
746                 cd five &&
747                 git remote remove origin &&
748                 mkdir -p .git/remotes &&
749                 cat ../remotes_origin >.git/remotes/origin &&
750                 git remote rename origin origin &&
751                 test_path_is_missing .git/remotes/origin &&
752                 test "$(git config remote.origin.url)" = "$origin_url" &&
753                 cat >push_expected <<-\EOF &&
754                 refs/heads/master:refs/heads/upstream
755                 refs/heads/next:refs/heads/upstream2
756                 EOF
757                 cat >fetch_expected <<-\EOF &&
758                 refs/heads/master:refs/heads/origin
759                 refs/heads/next:refs/heads/origin2
760                 EOF
761                 git config --get-all remote.origin.push >push_actual &&
762                 git config --get-all remote.origin.fetch >fetch_actual &&
763                 test_cmp push_expected push_actual &&
764                 test_cmp fetch_expected fetch_actual
765         )
766 '
767
768 test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '
769         git clone one six &&
770         origin_url=$(pwd)/one &&
771         (
772                 cd six &&
773                 git remote rm origin &&
774                 echo "$origin_url" >.git/branches/origin &&
775                 git remote rename origin origin &&
776                 test_path_is_missing .git/branches/origin &&
777                 test "$(git config remote.origin.url)" = "$origin_url" &&
778                 test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin" &&
779                 test "$(git config remote.origin.push)" = "HEAD:refs/heads/master"
780         )
781 '
782
783 test_expect_success 'migrate a remote from named file in $GIT_DIR/branches (2)' '
784         git clone one seven &&
785         (
786                 cd seven &&
787                 git remote rm origin &&
788                 echo "quux#foom" > .git/branches/origin &&
789                 git remote rename origin origin &&
790                 test_path_is_missing .git/branches/origin &&
791                 test "$(git config remote.origin.url)" = "quux" &&
792                 test "$(git config remote.origin.fetch)" = "refs/heads/foom:refs/heads/origin"
793                 test "$(git config remote.origin.push)" = "HEAD:refs/heads/foom"
794         )
795 '
796
797 test_expect_success 'remote prune to cause a dangling symref' '
798         git clone one eight &&
799         (
800                 cd one &&
801                 git checkout side2 &&
802                 git branch -D master
803         ) &&
804         (
805                 cd eight &&
806                 git remote prune origin
807         ) >err 2>&1 &&
808         test_i18ngrep "has become dangling" err &&
809
810         : And the dangling symref will not cause other annoying errors &&
811         (
812                 cd eight &&
813                 git branch -a
814         ) 2>err &&
815         ! grep "points nowhere" err &&
816         (
817                 cd eight &&
818                 test_must_fail git branch nomore origin
819         ) 2>err &&
820         grep "dangling symref" err
821 '
822
823 test_expect_success 'show empty remote' '
824         test_create_repo empty &&
825         git clone empty empty-clone &&
826         (
827                 cd empty-clone &&
828                 git remote show origin
829         )
830 '
831
832 test_expect_success 'remote set-branches requires a remote' '
833         test_must_fail git remote set-branches &&
834         test_must_fail git remote set-branches --add
835 '
836
837 test_expect_success 'remote set-branches' '
838         echo "+refs/heads/*:refs/remotes/scratch/*" >expect.initial &&
839         sort <<-\EOF >expect.add &&
840         +refs/heads/*:refs/remotes/scratch/*
841         +refs/heads/other:refs/remotes/scratch/other
842         EOF
843         sort <<-\EOF >expect.replace &&
844         +refs/heads/maint:refs/remotes/scratch/maint
845         +refs/heads/master:refs/remotes/scratch/master
846         +refs/heads/next:refs/remotes/scratch/next
847         EOF
848         sort <<-\EOF >expect.add-two &&
849         +refs/heads/maint:refs/remotes/scratch/maint
850         +refs/heads/master:refs/remotes/scratch/master
851         +refs/heads/next:refs/remotes/scratch/next
852         +refs/heads/pu:refs/remotes/scratch/pu
853         +refs/heads/t/topic:refs/remotes/scratch/t/topic
854         EOF
855         sort <<-\EOF >expect.setup-ffonly &&
856         refs/heads/master:refs/remotes/scratch/master
857         +refs/heads/next:refs/remotes/scratch/next
858         EOF
859         sort <<-\EOF >expect.respect-ffonly &&
860         refs/heads/master:refs/remotes/scratch/master
861         +refs/heads/next:refs/remotes/scratch/next
862         +refs/heads/pu:refs/remotes/scratch/pu
863         EOF
864
865         git clone .git/ setbranches &&
866         (
867                 cd setbranches &&
868                 git remote rename origin scratch &&
869                 git config --get-all remote.scratch.fetch >config-result &&
870                 sort <config-result >../actual.initial &&
871
872                 git remote set-branches scratch --add other &&
873                 git config --get-all remote.scratch.fetch >config-result &&
874                 sort <config-result >../actual.add &&
875
876                 git remote set-branches scratch maint master next &&
877                 git config --get-all remote.scratch.fetch >config-result &&
878                 sort <config-result >../actual.replace &&
879
880                 git remote set-branches --add scratch pu t/topic &&
881                 git config --get-all remote.scratch.fetch >config-result &&
882                 sort <config-result >../actual.add-two &&
883
884                 git config --unset-all remote.scratch.fetch &&
885                 git config remote.scratch.fetch \
886                         refs/heads/master:refs/remotes/scratch/master &&
887                 git config --add remote.scratch.fetch \
888                         +refs/heads/next:refs/remotes/scratch/next &&
889                 git config --get-all remote.scratch.fetch >config-result &&
890                 sort <config-result >../actual.setup-ffonly &&
891
892                 git remote set-branches --add scratch pu &&
893                 git config --get-all remote.scratch.fetch >config-result &&
894                 sort <config-result >../actual.respect-ffonly
895         ) &&
896         test_cmp expect.initial actual.initial &&
897         test_cmp expect.add actual.add &&
898         test_cmp expect.replace actual.replace &&
899         test_cmp expect.add-two actual.add-two &&
900         test_cmp expect.setup-ffonly actual.setup-ffonly &&
901         test_cmp expect.respect-ffonly actual.respect-ffonly
902 '
903
904 test_expect_success 'remote set-branches with --mirror' '
905         echo "+refs/*:refs/*" >expect.initial &&
906         echo "+refs/heads/master:refs/heads/master" >expect.replace &&
907         git clone --mirror .git/ setbranches-mirror &&
908         (
909                 cd setbranches-mirror &&
910                 git remote rename origin scratch &&
911                 git config --get-all remote.scratch.fetch >../actual.initial &&
912
913                 git remote set-branches scratch heads/master &&
914                 git config --get-all remote.scratch.fetch >../actual.replace
915         ) &&
916         test_cmp expect.initial actual.initial &&
917         test_cmp expect.replace actual.replace
918 '
919
920 test_expect_success 'new remote' '
921         git remote add someremote foo &&
922         echo foo >expect &&
923         git config --get-all remote.someremote.url >actual &&
924         cmp expect actual
925 '
926
927 get_url_test () {
928         cat >expect &&
929         git remote get-url "$@" >actual &&
930         test_cmp expect actual
931 }
932
933 test_expect_success 'get-url on new remote' '
934         echo foo | get_url_test someremote &&
935         echo foo | get_url_test --all someremote &&
936         echo foo | get_url_test --push someremote &&
937         echo foo | get_url_test --push --all someremote
938 '
939
940 test_expect_success 'remote set-url bar' '
941         git remote set-url someremote bar &&
942         echo bar >expect &&
943         git config --get-all remote.someremote.url >actual &&
944         cmp expect actual
945 '
946
947 test_expect_success 'remote set-url baz bar' '
948         git remote set-url someremote baz bar &&
949         echo baz >expect &&
950         git config --get-all remote.someremote.url >actual &&
951         cmp expect actual
952 '
953
954 test_expect_success 'remote set-url zot bar' '
955         test_must_fail git remote set-url someremote zot bar &&
956         echo baz >expect &&
957         git config --get-all remote.someremote.url >actual &&
958         cmp expect actual
959 '
960
961 test_expect_success 'remote set-url --push zot baz' '
962         test_must_fail git remote set-url --push someremote zot baz &&
963         echo "YYY" >expect &&
964         echo baz >>expect &&
965         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
966         echo "YYY" >>actual &&
967         git config --get-all remote.someremote.url >>actual &&
968         cmp expect actual
969 '
970
971 test_expect_success 'remote set-url --push zot' '
972         git remote set-url --push someremote zot &&
973         echo zot >expect &&
974         echo "YYY" >>expect &&
975         echo baz >>expect &&
976         git config --get-all remote.someremote.pushurl >actual &&
977         echo "YYY" >>actual &&
978         git config --get-all remote.someremote.url >>actual &&
979         cmp expect actual
980 '
981
982 test_expect_success 'get-url with different urls' '
983         echo baz | get_url_test someremote &&
984         echo baz | get_url_test --all someremote &&
985         echo zot | get_url_test --push someremote &&
986         echo zot | get_url_test --push --all someremote
987 '
988
989 test_expect_success 'remote set-url --push qux zot' '
990         git remote set-url --push someremote qux zot &&
991         echo qux >expect &&
992         echo "YYY" >>expect &&
993         echo baz >>expect &&
994         git config --get-all remote.someremote.pushurl >actual &&
995         echo "YYY" >>actual &&
996         git config --get-all remote.someremote.url >>actual &&
997         cmp expect actual
998 '
999
1000 test_expect_success 'remote set-url --push foo qu+x' '
1001         git remote set-url --push someremote foo qu+x &&
1002         echo foo >expect &&
1003         echo "YYY" >>expect &&
1004         echo baz >>expect &&
1005         git config --get-all remote.someremote.pushurl >actual &&
1006         echo "YYY" >>actual &&
1007         git config --get-all remote.someremote.url >>actual &&
1008         cmp expect actual
1009 '
1010
1011 test_expect_success 'remote set-url --push --add aaa' '
1012         git remote set-url --push --add someremote aaa &&
1013         echo foo >expect &&
1014         echo aaa >>expect &&
1015         echo "YYY" >>expect &&
1016         echo baz >>expect &&
1017         git config --get-all remote.someremote.pushurl >actual &&
1018         echo "YYY" >>actual &&
1019         git config --get-all remote.someremote.url >>actual &&
1020         cmp expect actual
1021 '
1022
1023 test_expect_success 'get-url on multi push remote' '
1024         echo foo | get_url_test --push someremote &&
1025         get_url_test --push --all someremote <<-\EOF
1026         foo
1027         aaa
1028         EOF
1029 '
1030
1031 test_expect_success 'remote set-url --push bar aaa' '
1032         git remote set-url --push someremote bar aaa &&
1033         echo foo >expect &&
1034         echo bar >>expect &&
1035         echo "YYY" >>expect &&
1036         echo baz >>expect &&
1037         git config --get-all remote.someremote.pushurl >actual &&
1038         echo "YYY" >>actual &&
1039         git config --get-all remote.someremote.url >>actual &&
1040         cmp expect actual
1041 '
1042
1043 test_expect_success 'remote set-url --push --delete bar' '
1044         git remote set-url --push --delete someremote bar &&
1045         echo foo >expect &&
1046         echo "YYY" >>expect &&
1047         echo baz >>expect &&
1048         git config --get-all remote.someremote.pushurl >actual &&
1049         echo "YYY" >>actual &&
1050         git config --get-all remote.someremote.url >>actual &&
1051         cmp expect actual
1052 '
1053
1054 test_expect_success 'remote set-url --push --delete foo' '
1055         git remote set-url --push --delete someremote foo &&
1056         echo "YYY" >expect &&
1057         echo baz >>expect &&
1058         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1059         echo "YYY" >>actual &&
1060         git config --get-all remote.someremote.url >>actual &&
1061         cmp expect actual
1062 '
1063
1064 test_expect_success 'remote set-url --add bbb' '
1065         git remote set-url --add someremote bbb &&
1066         echo "YYY" >expect &&
1067         echo baz >>expect &&
1068         echo bbb >>expect &&
1069         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1070         echo "YYY" >>actual &&
1071         git config --get-all remote.someremote.url >>actual &&
1072         cmp expect actual
1073 '
1074
1075 test_expect_success 'get-url on multi fetch remote' '
1076         echo baz | get_url_test someremote &&
1077         get_url_test --all someremote <<-\EOF
1078         baz
1079         bbb
1080         EOF
1081 '
1082
1083 test_expect_success 'remote set-url --delete .*' '
1084         test_must_fail git remote set-url --delete someremote .\* &&
1085         echo "YYY" >expect &&
1086         echo baz >>expect &&
1087         echo bbb >>expect &&
1088         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1089         echo "YYY" >>actual &&
1090         git config --get-all remote.someremote.url >>actual &&
1091         cmp expect actual
1092 '
1093
1094 test_expect_success 'remote set-url --delete bbb' '
1095         git remote set-url --delete someremote bbb &&
1096         echo "YYY" >expect &&
1097         echo baz >>expect &&
1098         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1099         echo "YYY" >>actual &&
1100         git config --get-all remote.someremote.url >>actual &&
1101         cmp expect actual
1102 '
1103
1104 test_expect_success 'remote set-url --delete baz' '
1105         test_must_fail git remote set-url --delete someremote baz &&
1106         echo "YYY" >expect &&
1107         echo baz >>expect &&
1108         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1109         echo "YYY" >>actual &&
1110         git config --get-all remote.someremote.url >>actual &&
1111         cmp expect actual
1112 '
1113
1114 test_expect_success 'remote set-url --add ccc' '
1115         git remote set-url --add someremote ccc &&
1116         echo "YYY" >expect &&
1117         echo baz >>expect &&
1118         echo ccc >>expect &&
1119         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1120         echo "YYY" >>actual &&
1121         git config --get-all remote.someremote.url >>actual &&
1122         cmp expect actual
1123 '
1124
1125 test_expect_success 'remote set-url --delete baz' '
1126         git remote set-url --delete someremote baz &&
1127         echo "YYY" >expect &&
1128         echo ccc >>expect &&
1129         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1130         echo "YYY" >>actual &&
1131         git config --get-all remote.someremote.url >>actual &&
1132         cmp expect actual
1133 '
1134
1135 test_expect_success 'extra args: setup' '
1136         # add a dummy origin so that this does not trigger failure
1137         git remote add origin .
1138 '
1139
1140 test_extra_arg () {
1141         test_expect_success "extra args: $*" "
1142                 test_must_fail git remote $* bogus_extra_arg 2>actual &&
1143                 grep '^usage:' actual
1144         "
1145 }
1146
1147 test_extra_arg add nick url
1148 test_extra_arg rename origin newname
1149 test_extra_arg remove origin
1150 test_extra_arg set-head origin master
1151 # set-branches takes any number of args
1152 test_extra_arg get-url origin newurl
1153 test_extra_arg set-url origin newurl oldurl
1154 # show takes any number of args
1155 # prune takes any number of args
1156 # update takes any number of args
1157
1158 test_expect_success 'add remote matching the "insteadOf" URL' '
1159         git config url.xyz@example.com.insteadOf backup &&
1160         git remote add backup xyz@example.com
1161 '
1162
1163 test_done