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