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