Merge branch 'jt/upload-pack-error-report' into maint
[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 test_expect_success 'rename succeeds with existing remote.<target>.prune' '
768         git clone one four.four &&
769         test_when_finished git config --global --unset remote.upstream.prune &&
770         git config --global remote.upstream.prune true &&
771         git -C four.four remote rename origin upstream
772 '
773
774 cat >remotes_origin <<EOF
775 URL: $(pwd)/one
776 Push: refs/heads/master:refs/heads/upstream
777 Push: refs/heads/next:refs/heads/upstream2
778 Pull: refs/heads/master:refs/heads/origin
779 Pull: refs/heads/next:refs/heads/origin2
780 EOF
781
782 test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
783         git clone one five &&
784         origin_url=$(pwd)/one &&
785         (
786                 cd five &&
787                 git remote remove origin &&
788                 mkdir -p .git/remotes &&
789                 cat ../remotes_origin >.git/remotes/origin &&
790                 git remote rename origin origin &&
791                 test_path_is_missing .git/remotes/origin &&
792                 test "$(git config remote.origin.url)" = "$origin_url" &&
793                 cat >push_expected <<-\EOF &&
794                 refs/heads/master:refs/heads/upstream
795                 refs/heads/next:refs/heads/upstream2
796                 EOF
797                 cat >fetch_expected <<-\EOF &&
798                 refs/heads/master:refs/heads/origin
799                 refs/heads/next:refs/heads/origin2
800                 EOF
801                 git config --get-all remote.origin.push >push_actual &&
802                 git config --get-all remote.origin.fetch >fetch_actual &&
803                 test_cmp push_expected push_actual &&
804                 test_cmp fetch_expected fetch_actual
805         )
806 '
807
808 test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '
809         git clone one six &&
810         origin_url=$(pwd)/one &&
811         (
812                 cd six &&
813                 git remote rm origin &&
814                 echo "$origin_url" >.git/branches/origin &&
815                 git remote rename origin origin &&
816                 test_path_is_missing .git/branches/origin &&
817                 test "$(git config remote.origin.url)" = "$origin_url" &&
818                 test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin" &&
819                 test "$(git config remote.origin.push)" = "HEAD:refs/heads/master"
820         )
821 '
822
823 test_expect_success 'migrate a remote from named file in $GIT_DIR/branches (2)' '
824         git clone one seven &&
825         (
826                 cd seven &&
827                 git remote rm origin &&
828                 echo "quux#foom" > .git/branches/origin &&
829                 git remote rename origin origin &&
830                 test_path_is_missing .git/branches/origin &&
831                 test "$(git config remote.origin.url)" = "quux" &&
832                 test "$(git config remote.origin.fetch)" = "refs/heads/foom:refs/heads/origin"
833                 test "$(git config remote.origin.push)" = "HEAD:refs/heads/foom"
834         )
835 '
836
837 test_expect_success 'remote prune to cause a dangling symref' '
838         git clone one eight &&
839         (
840                 cd one &&
841                 git checkout side2 &&
842                 git branch -D master
843         ) &&
844         (
845                 cd eight &&
846                 git remote prune origin
847         ) >err 2>&1 &&
848         test_i18ngrep "has become dangling" err &&
849
850         : And the dangling symref will not cause other annoying errors &&
851         (
852                 cd eight &&
853                 git branch -a
854         ) 2>err &&
855         ! grep "points nowhere" err &&
856         (
857                 cd eight &&
858                 test_must_fail git branch nomore origin
859         ) 2>err &&
860         grep "dangling symref" err
861 '
862
863 test_expect_success 'show empty remote' '
864         test_create_repo empty &&
865         git clone empty empty-clone &&
866         (
867                 cd empty-clone &&
868                 git remote show origin
869         )
870 '
871
872 test_expect_success 'remote set-branches requires a remote' '
873         test_must_fail git remote set-branches &&
874         test_must_fail git remote set-branches --add
875 '
876
877 test_expect_success 'remote set-branches' '
878         echo "+refs/heads/*:refs/remotes/scratch/*" >expect.initial &&
879         sort <<-\EOF >expect.add &&
880         +refs/heads/*:refs/remotes/scratch/*
881         +refs/heads/other:refs/remotes/scratch/other
882         EOF
883         sort <<-\EOF >expect.replace &&
884         +refs/heads/maint:refs/remotes/scratch/maint
885         +refs/heads/master:refs/remotes/scratch/master
886         +refs/heads/next:refs/remotes/scratch/next
887         EOF
888         sort <<-\EOF >expect.add-two &&
889         +refs/heads/maint:refs/remotes/scratch/maint
890         +refs/heads/master:refs/remotes/scratch/master
891         +refs/heads/next:refs/remotes/scratch/next
892         +refs/heads/pu:refs/remotes/scratch/pu
893         +refs/heads/t/topic:refs/remotes/scratch/t/topic
894         EOF
895         sort <<-\EOF >expect.setup-ffonly &&
896         refs/heads/master:refs/remotes/scratch/master
897         +refs/heads/next:refs/remotes/scratch/next
898         EOF
899         sort <<-\EOF >expect.respect-ffonly &&
900         refs/heads/master:refs/remotes/scratch/master
901         +refs/heads/next:refs/remotes/scratch/next
902         +refs/heads/pu:refs/remotes/scratch/pu
903         EOF
904
905         git clone .git/ setbranches &&
906         (
907                 cd setbranches &&
908                 git remote rename origin scratch &&
909                 git config --get-all remote.scratch.fetch >config-result &&
910                 sort <config-result >../actual.initial &&
911
912                 git remote set-branches scratch --add other &&
913                 git config --get-all remote.scratch.fetch >config-result &&
914                 sort <config-result >../actual.add &&
915
916                 git remote set-branches scratch maint master next &&
917                 git config --get-all remote.scratch.fetch >config-result &&
918                 sort <config-result >../actual.replace &&
919
920                 git remote set-branches --add scratch pu t/topic &&
921                 git config --get-all remote.scratch.fetch >config-result &&
922                 sort <config-result >../actual.add-two &&
923
924                 git config --unset-all remote.scratch.fetch &&
925                 git config remote.scratch.fetch \
926                         refs/heads/master:refs/remotes/scratch/master &&
927                 git config --add remote.scratch.fetch \
928                         +refs/heads/next:refs/remotes/scratch/next &&
929                 git config --get-all remote.scratch.fetch >config-result &&
930                 sort <config-result >../actual.setup-ffonly &&
931
932                 git remote set-branches --add scratch pu &&
933                 git config --get-all remote.scratch.fetch >config-result &&
934                 sort <config-result >../actual.respect-ffonly
935         ) &&
936         test_cmp expect.initial actual.initial &&
937         test_cmp expect.add actual.add &&
938         test_cmp expect.replace actual.replace &&
939         test_cmp expect.add-two actual.add-two &&
940         test_cmp expect.setup-ffonly actual.setup-ffonly &&
941         test_cmp expect.respect-ffonly actual.respect-ffonly
942 '
943
944 test_expect_success 'remote set-branches with --mirror' '
945         echo "+refs/*:refs/*" >expect.initial &&
946         echo "+refs/heads/master:refs/heads/master" >expect.replace &&
947         git clone --mirror .git/ setbranches-mirror &&
948         (
949                 cd setbranches-mirror &&
950                 git remote rename origin scratch &&
951                 git config --get-all remote.scratch.fetch >../actual.initial &&
952
953                 git remote set-branches scratch heads/master &&
954                 git config --get-all remote.scratch.fetch >../actual.replace
955         ) &&
956         test_cmp expect.initial actual.initial &&
957         test_cmp expect.replace actual.replace
958 '
959
960 test_expect_success 'new remote' '
961         git remote add someremote foo &&
962         echo foo >expect &&
963         git config --get-all remote.someremote.url >actual &&
964         cmp expect actual
965 '
966
967 get_url_test () {
968         cat >expect &&
969         git remote get-url "$@" >actual &&
970         test_cmp expect actual
971 }
972
973 test_expect_success 'get-url on new remote' '
974         echo foo | get_url_test someremote &&
975         echo foo | get_url_test --all someremote &&
976         echo foo | get_url_test --push someremote &&
977         echo foo | get_url_test --push --all someremote
978 '
979
980 test_expect_success 'remote set-url with locked config' '
981         test_when_finished "rm -f .git/config.lock" &&
982         git config --get-all remote.someremote.url >expect &&
983         >.git/config.lock &&
984         test_must_fail git remote set-url someremote baz &&
985         git config --get-all remote.someremote.url >actual &&
986         cmp expect actual
987 '
988
989 test_expect_success 'remote set-url bar' '
990         git remote set-url someremote bar &&
991         echo bar >expect &&
992         git config --get-all remote.someremote.url >actual &&
993         cmp expect actual
994 '
995
996 test_expect_success 'remote set-url baz bar' '
997         git remote set-url someremote baz 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 zot bar' '
1004         test_must_fail git remote set-url someremote zot bar &&
1005         echo baz >expect &&
1006         git config --get-all remote.someremote.url >actual &&
1007         cmp expect actual
1008 '
1009
1010 test_expect_success 'remote set-url --push zot baz' '
1011         test_must_fail git remote set-url --push someremote zot baz &&
1012         echo "YYY" >expect &&
1013         echo baz >>expect &&
1014         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1015         echo "YYY" >>actual &&
1016         git config --get-all remote.someremote.url >>actual &&
1017         cmp expect actual
1018 '
1019
1020 test_expect_success 'remote set-url --push zot' '
1021         git remote set-url --push someremote zot &&
1022         echo zot >expect &&
1023         echo "YYY" >>expect &&
1024         echo baz >>expect &&
1025         git config --get-all remote.someremote.pushurl >actual &&
1026         echo "YYY" >>actual &&
1027         git config --get-all remote.someremote.url >>actual &&
1028         cmp expect actual
1029 '
1030
1031 test_expect_success 'get-url with different urls' '
1032         echo baz | get_url_test someremote &&
1033         echo baz | get_url_test --all someremote &&
1034         echo zot | get_url_test --push someremote &&
1035         echo zot | get_url_test --push --all someremote
1036 '
1037
1038 test_expect_success 'remote set-url --push qux zot' '
1039         git remote set-url --push someremote qux zot &&
1040         echo qux >expect &&
1041         echo "YYY" >>expect &&
1042         echo baz >>expect &&
1043         git config --get-all remote.someremote.pushurl >actual &&
1044         echo "YYY" >>actual &&
1045         git config --get-all remote.someremote.url >>actual &&
1046         cmp expect actual
1047 '
1048
1049 test_expect_success 'remote set-url --push foo qu+x' '
1050         git remote set-url --push someremote foo qu+x &&
1051         echo foo >expect &&
1052         echo "YYY" >>expect &&
1053         echo baz >>expect &&
1054         git config --get-all remote.someremote.pushurl >actual &&
1055         echo "YYY" >>actual &&
1056         git config --get-all remote.someremote.url >>actual &&
1057         cmp expect actual
1058 '
1059
1060 test_expect_success 'remote set-url --push --add aaa' '
1061         git remote set-url --push --add someremote aaa &&
1062         echo foo >expect &&
1063         echo aaa >>expect &&
1064         echo "YYY" >>expect &&
1065         echo baz >>expect &&
1066         git config --get-all remote.someremote.pushurl >actual &&
1067         echo "YYY" >>actual &&
1068         git config --get-all remote.someremote.url >>actual &&
1069         cmp expect actual
1070 '
1071
1072 test_expect_success 'get-url on multi push remote' '
1073         echo foo | get_url_test --push someremote &&
1074         get_url_test --push --all someremote <<-\EOF
1075         foo
1076         aaa
1077         EOF
1078 '
1079
1080 test_expect_success 'remote set-url --push bar aaa' '
1081         git remote set-url --push someremote bar aaa &&
1082         echo foo >expect &&
1083         echo bar >>expect &&
1084         echo "YYY" >>expect &&
1085         echo baz >>expect &&
1086         git config --get-all remote.someremote.pushurl >actual &&
1087         echo "YYY" >>actual &&
1088         git config --get-all remote.someremote.url >>actual &&
1089         cmp expect actual
1090 '
1091
1092 test_expect_success 'remote set-url --push --delete bar' '
1093         git remote set-url --push --delete someremote bar &&
1094         echo foo >expect &&
1095         echo "YYY" >>expect &&
1096         echo baz >>expect &&
1097         git config --get-all remote.someremote.pushurl >actual &&
1098         echo "YYY" >>actual &&
1099         git config --get-all remote.someremote.url >>actual &&
1100         cmp expect actual
1101 '
1102
1103 test_expect_success 'remote set-url --push --delete foo' '
1104         git remote set-url --push --delete someremote foo &&
1105         echo "YYY" >expect &&
1106         echo baz >>expect &&
1107         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1108         echo "YYY" >>actual &&
1109         git config --get-all remote.someremote.url >>actual &&
1110         cmp expect actual
1111 '
1112
1113 test_expect_success 'remote set-url --add bbb' '
1114         git remote set-url --add someremote bbb &&
1115         echo "YYY" >expect &&
1116         echo baz >>expect &&
1117         echo bbb >>expect &&
1118         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1119         echo "YYY" >>actual &&
1120         git config --get-all remote.someremote.url >>actual &&
1121         cmp expect actual
1122 '
1123
1124 test_expect_success 'get-url on multi fetch remote' '
1125         echo baz | get_url_test someremote &&
1126         get_url_test --all someremote <<-\EOF
1127         baz
1128         bbb
1129         EOF
1130 '
1131
1132 test_expect_success 'remote set-url --delete .*' '
1133         test_must_fail git remote set-url --delete someremote .\* &&
1134         echo "YYY" >expect &&
1135         echo baz >>expect &&
1136         echo bbb >>expect &&
1137         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1138         echo "YYY" >>actual &&
1139         git config --get-all remote.someremote.url >>actual &&
1140         cmp expect actual
1141 '
1142
1143 test_expect_success 'remote set-url --delete bbb' '
1144         git remote set-url --delete someremote bbb &&
1145         echo "YYY" >expect &&
1146         echo baz >>expect &&
1147         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1148         echo "YYY" >>actual &&
1149         git config --get-all remote.someremote.url >>actual &&
1150         cmp expect actual
1151 '
1152
1153 test_expect_success 'remote set-url --delete baz' '
1154         test_must_fail git remote set-url --delete someremote baz &&
1155         echo "YYY" >expect &&
1156         echo baz >>expect &&
1157         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1158         echo "YYY" >>actual &&
1159         git config --get-all remote.someremote.url >>actual &&
1160         cmp expect actual
1161 '
1162
1163 test_expect_success 'remote set-url --add ccc' '
1164         git remote set-url --add someremote ccc &&
1165         echo "YYY" >expect &&
1166         echo baz >>expect &&
1167         echo ccc >>expect &&
1168         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1169         echo "YYY" >>actual &&
1170         git config --get-all remote.someremote.url >>actual &&
1171         cmp expect actual
1172 '
1173
1174 test_expect_success 'remote set-url --delete baz' '
1175         git remote set-url --delete someremote baz &&
1176         echo "YYY" >expect &&
1177         echo ccc >>expect &&
1178         test_must_fail git config --get-all remote.someremote.pushurl >actual &&
1179         echo "YYY" >>actual &&
1180         git config --get-all remote.someremote.url >>actual &&
1181         cmp expect actual
1182 '
1183
1184 test_expect_success 'extra args: setup' '
1185         # add a dummy origin so that this does not trigger failure
1186         git remote add origin .
1187 '
1188
1189 test_extra_arg () {
1190         test_expect_success "extra args: $*" "
1191                 test_must_fail git remote $* bogus_extra_arg 2>actual &&
1192                 test_i18ngrep '^usage:' actual
1193         "
1194 }
1195
1196 test_extra_arg add nick url
1197 test_extra_arg rename origin newname
1198 test_extra_arg remove origin
1199 test_extra_arg set-head origin master
1200 # set-branches takes any number of args
1201 test_extra_arg get-url origin newurl
1202 test_extra_arg set-url origin newurl oldurl
1203 # show takes any number of args
1204 # prune takes any number of args
1205 # update takes any number of args
1206
1207 test_expect_success 'add remote matching the "insteadOf" URL' '
1208         git config url.xyz@example.com.insteadOf backup &&
1209         git remote add backup xyz@example.com
1210 '
1211
1212 test_done