http-push.c::remote_exists(): use the new http API
[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
46         setup_repository one &&
47         setup_repository two &&
48         (
49                 cd two && git branch another
50         ) &&
51         git clone one test
52
53 '
54
55 test_expect_success 'remote information for the origin' '
56 (
57         cd test &&
58         tokens_match origin "$(git remote)" &&
59         check_remote_track origin master side &&
60         check_tracking_branch origin HEAD master side
61 )
62 '
63
64 test_expect_success 'add another remote' '
65 (
66         cd test &&
67         git remote add -f second ../two &&
68         tokens_match "origin second" "$(git remote)" &&
69         check_remote_track origin master side &&
70         check_remote_track second master side another &&
71         check_tracking_branch second master side another &&
72         git for-each-ref "--format=%(refname)" refs/remotes |
73         sed -e "/^refs\/remotes\/origin\//d" \
74             -e "/^refs\/remotes\/second\//d" >actual &&
75         >expect &&
76         test_cmp expect actual
77 )
78 '
79
80 test_expect_success 'remote forces tracking branches' '
81 (
82         cd test &&
83         case `git config remote.second.fetch` in
84         +*) true ;;
85          *) false ;;
86         esac
87 )
88 '
89
90 test_expect_success 'remove remote' '
91 (
92         cd test &&
93         git symbolic-ref refs/remotes/second/HEAD refs/remotes/second/master &&
94         git remote rm second
95 )
96 '
97
98 test_expect_success 'remove remote' '
99 (
100         cd test &&
101         tokens_match origin "$(git remote)" &&
102         check_remote_track origin master side &&
103         git for-each-ref "--format=%(refname)" refs/remotes |
104         sed -e "/^refs\/remotes\/origin\//d" >actual &&
105         >expect &&
106         test_cmp expect actual
107 )
108 '
109
110 test_expect_success 'remove remote protects non-remote branches' '
111 (
112         cd test &&
113         (cat >expect1 <<EOF
114 Note: A non-remote branch was not removed; to delete it, use:
115   git branch -d master
116 EOF
117     cat >expect2 <<EOF
118 Note: Non-remote branches were not removed; to delete them, use:
119   git branch -d foobranch
120   git branch -d master
121 EOF
122 ) &&
123         git tag footag
124         git config --add remote.oops.fetch "+refs/*:refs/*" &&
125         git remote rm oops 2>actual1 &&
126         git branch foobranch &&
127         git config --add remote.oops.fetch "+refs/*:refs/*" &&
128         git remote rm oops 2>actual2 &&
129         git branch -d foobranch &&
130         git tag -d footag &&
131         test_cmp expect1 actual1 &&
132         test_cmp expect2 actual2
133 )
134 '
135
136 cat > test/expect << EOF
137 * remote origin
138   URL: $(pwd)/one
139   HEAD branch: master
140   Remote branches:
141     master new (next fetch will store in remotes/origin)
142     side   tracked
143   Local branches configured for 'git pull':
144     ahead    merges with remote master
145     master   merges with remote master
146     octopus  merges with remote topic-a
147                 and with remote topic-b
148                 and with remote topic-c
149     rebase  rebases onto remote master
150   Local refs configured for 'git push':
151     master pushes to master   (local out of date)
152     master pushes to upstream (create)
153 * remote two
154   URL: ../two
155   HEAD branch (remote HEAD is ambiguous, may be one of the following):
156     another
157     master
158   Local refs configured for 'git push':
159     ahead  forces to master  (fast forwardable)
160     master pushes to another (up to date)
161 EOF
162
163 test_expect_success 'show' '
164         (cd test &&
165          git config --add remote.origin.fetch refs/heads/master:refs/heads/upstream &&
166          git fetch &&
167          git checkout -b ahead origin/master &&
168          echo 1 >> file &&
169          test_tick &&
170          git commit -m update file &&
171          git checkout master &&
172          git branch --track octopus origin/master &&
173          git branch --track rebase origin/master &&
174          git branch -d -r origin/master &&
175          git config --add remote.two.url ../two &&
176          git config branch.rebase.rebase true &&
177          git config branch.octopus.merge "topic-a topic-b topic-c" &&
178          (cd ../one &&
179           echo 1 > file &&
180           test_tick &&
181           git commit -m update file) &&
182          git config --add remote.origin.push : &&
183          git config --add remote.origin.push refs/heads/master:refs/heads/upstream &&
184          git config --add remote.origin.push +refs/tags/lastbackup &&
185          git config --add remote.two.push +refs/heads/ahead:refs/heads/master &&
186          git config --add remote.two.push refs/heads/master:refs/heads/another &&
187          git remote show origin two > output &&
188          git branch -d rebase octopus &&
189          test_cmp expect output)
190 '
191
192 cat > test/expect << EOF
193 * remote origin
194   URL: $(pwd)/one
195   HEAD branch: (not queried)
196   Remote branches: (status not queried)
197     master
198     side
199   Local branches configured for 'git pull':
200     ahead  merges with remote master
201     master merges with remote master
202   Local refs configured for 'git push' (status not queried):
203     (matching)           pushes to (matching)
204     refs/heads/master    pushes to refs/heads/upstream
205     refs/tags/lastbackup forces to refs/tags/lastbackup
206 EOF
207
208 test_expect_success 'show -n' '
209         (mv one one.unreachable &&
210          cd test &&
211          git remote show -n origin > output &&
212          mv ../one.unreachable ../one &&
213          test_cmp expect output)
214 '
215
216 test_expect_success 'prune' '
217         (cd one &&
218          git branch -m side side2) &&
219         (cd test &&
220          git fetch origin &&
221          git remote prune origin &&
222          git rev-parse refs/remotes/origin/side2 &&
223          test_must_fail git rev-parse refs/remotes/origin/side)
224 '
225
226 test_expect_success 'set-head --delete' '
227         (cd test &&
228          git symbolic-ref refs/remotes/origin/HEAD &&
229          git remote set-head --delete origin &&
230          test_must_fail git symbolic-ref refs/remotes/origin/HEAD)
231 '
232
233 test_expect_success 'set-head --auto' '
234         (cd test &&
235          git remote set-head --auto origin &&
236          echo refs/remotes/origin/master >expect &&
237          git symbolic-ref refs/remotes/origin/HEAD >output &&
238          test_cmp expect output
239         )
240 '
241
242 cat >test/expect <<EOF
243 error: Multiple remote HEAD branches. Please choose one explicitly with:
244   git remote set-head two another
245   git remote set-head two master
246 EOF
247
248 test_expect_success 'set-head --auto fails w/multiple HEADs' '
249         (cd test &&
250          test_must_fail git remote set-head --auto two >output 2>&1 &&
251         test_cmp expect output)
252 '
253
254 cat >test/expect <<EOF
255 refs/remotes/origin/side2
256 EOF
257
258 test_expect_success 'set-head explicit' '
259         (cd test &&
260          git remote set-head origin side2 &&
261          git symbolic-ref refs/remotes/origin/HEAD >output &&
262          git remote set-head origin master &&
263          test_cmp expect output)
264 '
265
266 cat > test/expect << EOF
267 Pruning origin
268 URL: $(pwd)/one
269  * [would prune] origin/side2
270 EOF
271
272 test_expect_success 'prune --dry-run' '
273         (cd one &&
274          git branch -m side2 side) &&
275         (cd test &&
276          git remote prune --dry-run origin > output &&
277          git rev-parse refs/remotes/origin/side2 &&
278          test_must_fail git rev-parse refs/remotes/origin/side &&
279         (cd ../one &&
280          git branch -m side side2) &&
281          test_cmp expect output)
282 '
283
284 test_expect_success 'add --mirror && prune' '
285         (mkdir mirror &&
286          cd mirror &&
287          git init --bare &&
288          git remote add --mirror -f origin ../one) &&
289         (cd one &&
290          git branch -m side2 side) &&
291         (cd mirror &&
292          git rev-parse --verify refs/heads/side2 &&
293          test_must_fail git rev-parse --verify refs/heads/side &&
294          git fetch origin &&
295          git remote prune origin &&
296          test_must_fail git rev-parse --verify refs/heads/side2 &&
297          git rev-parse --verify refs/heads/side)
298 '
299
300 test_expect_success 'add alt && prune' '
301         (mkdir alttst &&
302          cd alttst &&
303          git init &&
304          git remote add -f origin ../one &&
305          git config remote.alt.url ../one &&
306          git config remote.alt.fetch "+refs/heads/*:refs/remotes/origin/*") &&
307         (cd one &&
308          git branch -m side side2) &&
309         (cd alttst &&
310          git rev-parse --verify refs/remotes/origin/side &&
311          test_must_fail git rev-parse --verify refs/remotes/origin/side2 &&
312          git fetch alt &&
313          git remote prune alt &&
314          test_must_fail git rev-parse --verify refs/remotes/origin/side &&
315          git rev-parse --verify refs/remotes/origin/side2)
316 '
317
318 cat > one/expect << EOF
319   apis/master
320   apis/side
321   drosophila/another
322   drosophila/master
323   drosophila/side
324 EOF
325
326 test_expect_success 'update' '
327
328         (cd one &&
329          git remote add drosophila ../two &&
330          git remote add apis ../mirror &&
331          git remote update &&
332          git branch -r > output &&
333          test_cmp expect output)
334
335 '
336
337 cat > one/expect << EOF
338   drosophila/another
339   drosophila/master
340   drosophila/side
341   manduca/master
342   manduca/side
343   megaloprepus/master
344   megaloprepus/side
345 EOF
346
347 test_expect_success 'update with arguments' '
348
349         (cd one &&
350          for b in $(git branch -r)
351          do
352                 git branch -r -d $b || break
353          done &&
354          git remote add manduca ../mirror &&
355          git remote add megaloprepus ../mirror &&
356          git config remotes.phobaeticus "drosophila megaloprepus" &&
357          git config remotes.titanus manduca &&
358          git remote update phobaeticus titanus &&
359          git branch -r > output &&
360          test_cmp expect output)
361
362 '
363
364 cat > one/expect << EOF
365   apis/master
366   apis/side
367   manduca/master
368   manduca/side
369   megaloprepus/master
370   megaloprepus/side
371 EOF
372
373 test_expect_success 'update default' '
374
375         (cd one &&
376          for b in $(git branch -r)
377          do
378                 git branch -r -d $b || break
379          done &&
380          git config remote.drosophila.skipDefaultUpdate true &&
381          git remote update default &&
382          git branch -r > output &&
383          test_cmp expect output)
384
385 '
386
387 cat > one/expect << EOF
388   drosophila/another
389   drosophila/master
390   drosophila/side
391 EOF
392
393 test_expect_success 'update default (overridden, with funny whitespace)' '
394
395         (cd one &&
396          for b in $(git branch -r)
397          do
398                 git branch -r -d $b || break
399          done &&
400          git config remotes.default "$(printf "\t drosophila  \n")" &&
401          git remote update default &&
402          git branch -r > output &&
403          test_cmp expect output)
404
405 '
406
407 test_expect_success '"remote show" does not show symbolic refs' '
408
409         git clone one three &&
410         (cd three &&
411          git remote show origin > output &&
412          ! grep "^ *HEAD$" < output &&
413          ! grep -i stale < output)
414
415 '
416
417 test_expect_success 'reject adding remote with an invalid name' '
418
419         test_must_fail git remote add some:url desired-name
420
421 '
422
423 # The first three test if the tracking branches are properly renamed,
424 # the last two ones check if the config is updated.
425
426 test_expect_success 'rename a remote' '
427
428         git clone one four &&
429         (cd four &&
430          git remote rename origin upstream &&
431          rmdir .git/refs/remotes/origin &&
432          test "$(git symbolic-ref refs/remotes/upstream/HEAD)" = "refs/remotes/upstream/master" &&
433          test "$(git rev-parse upstream/master)" = "$(git rev-parse master)" &&
434          test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*" &&
435          test "$(git config branch.master.remote)" = "upstream")
436
437 '
438
439 cat > remotes_origin << EOF
440 URL: $(pwd)/one
441 Push: refs/heads/master:refs/heads/upstream
442 Pull: refs/heads/master:refs/heads/origin
443 EOF
444
445 test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
446         git clone one five &&
447         origin_url=$(pwd)/one &&
448         (cd five &&
449          git remote rm origin &&
450          mkdir -p .git/remotes &&
451          cat ../remotes_origin > .git/remotes/origin &&
452          git remote rename origin origin &&
453          ! test -f .git/remotes/origin &&
454          test "$(git config remote.origin.url)" = "$origin_url" &&
455          test "$(git config remote.origin.push)" = "refs/heads/master:refs/heads/upstream" &&
456          test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
457 '
458
459 test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '
460         git clone one six &&
461         origin_url=$(pwd)/one &&
462         (cd six &&
463          git remote rm origin &&
464          echo "$origin_url" > .git/branches/origin &&
465          git remote rename origin origin &&
466          ! test -f .git/branches/origin &&
467          test "$(git config remote.origin.url)" = "$origin_url" &&
468          test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
469 '
470
471 test_expect_success 'remote prune to cause a dangling symref' '
472         git clone one seven &&
473         (
474                 cd one &&
475                 git checkout side2 &&
476                 git branch -D master
477         ) &&
478         (
479                 cd seven &&
480                 git remote prune origin
481         ) 2>err &&
482         grep "has become dangling" err &&
483
484         : And the dangling symref will not cause other annoying errors
485         (
486                 cd seven &&
487                 git branch -a
488         ) 2>err &&
489         ! grep "points nowhere" err
490         (
491                 cd seven &&
492                 test_must_fail git branch nomore origin
493         ) 2>err &&
494         grep "dangling symref" err
495 '
496
497 test_done
498