Merge branch 'js/maint-1.6.0-exec-path-env' into maint-1.6.1
[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 -e '1,/Tracked/d') &&
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   Remote branch merged with 'git pull' while on branch master
140     master
141   New remote branch (next fetch will store in remotes/origin)
142     master
143   Tracked remote branches
144     side
145     master
146   Local branches pushed with 'git push'
147     master:upstream
148     +refs/tags/lastbackup
149 EOF
150
151 test_expect_success 'show' '
152         (cd test &&
153          git config --add remote.origin.fetch \
154                 refs/heads/master:refs/heads/upstream &&
155          git fetch &&
156          git branch -d -r origin/master &&
157          (cd ../one &&
158           echo 1 > file &&
159           test_tick &&
160           git commit -m update file) &&
161          git config remote.origin.push \
162                 refs/heads/master:refs/heads/upstream &&
163          git config --add remote.origin.push \
164                 +refs/tags/lastbackup &&
165          git remote show origin > output &&
166          test_cmp expect output)
167 '
168
169 cat > test/expect << EOF
170 * remote origin
171   URL: $(pwd)/one
172   Remote branch merged with 'git pull' while on branch master
173     master
174   Tracked remote branches
175     master
176     side
177   Local branches pushed with 'git push'
178     master:upstream
179     +refs/tags/lastbackup
180 EOF
181
182 test_expect_success 'show -n' '
183         (mv one one.unreachable &&
184          cd test &&
185          git remote show -n origin > output &&
186          mv ../one.unreachable ../one &&
187          test_cmp expect output)
188 '
189
190 test_expect_success 'prune' '
191         (cd one &&
192          git branch -m side side2) &&
193         (cd test &&
194          git fetch origin &&
195          git remote prune origin &&
196          git rev-parse refs/remotes/origin/side2 &&
197          test_must_fail git rev-parse refs/remotes/origin/side)
198 '
199
200 cat > test/expect << EOF
201 Pruning origin
202 URL: $(pwd)/one
203  * [would prune] origin/side2
204 EOF
205
206 test_expect_success 'prune --dry-run' '
207         (cd one &&
208          git branch -m side2 side) &&
209         (cd test &&
210          git remote prune --dry-run origin > output &&
211          git rev-parse refs/remotes/origin/side2 &&
212          test_must_fail git rev-parse refs/remotes/origin/side &&
213         (cd ../one &&
214          git branch -m side side2) &&
215          test_cmp expect output)
216 '
217
218 test_expect_success 'add --mirror && prune' '
219         (mkdir mirror &&
220          cd mirror &&
221          git init --bare &&
222          git remote add --mirror -f origin ../one) &&
223         (cd one &&
224          git branch -m side2 side) &&
225         (cd mirror &&
226          git rev-parse --verify refs/heads/side2 &&
227          test_must_fail git rev-parse --verify refs/heads/side &&
228          git fetch origin &&
229          git remote prune origin &&
230          test_must_fail git rev-parse --verify refs/heads/side2 &&
231          git rev-parse --verify refs/heads/side)
232 '
233
234 test_expect_success 'add alt && prune' '
235         (mkdir alttst &&
236          cd alttst &&
237          git init &&
238          git remote add -f origin ../one &&
239          git config remote.alt.url ../one &&
240          git config remote.alt.fetch "+refs/heads/*:refs/remotes/origin/*") &&
241         (cd one &&
242          git branch -m side side2) &&
243         (cd alttst &&
244          git rev-parse --verify refs/remotes/origin/side &&
245          test_must_fail git rev-parse --verify refs/remotes/origin/side2 &&
246          git fetch alt &&
247          git remote prune alt &&
248          test_must_fail git rev-parse --verify refs/remotes/origin/side &&
249          git rev-parse --verify refs/remotes/origin/side2)
250 '
251
252 cat > one/expect << EOF
253   apis/master
254   apis/side
255   drosophila/another
256   drosophila/master
257   drosophila/side
258 EOF
259
260 test_expect_success 'update' '
261
262         (cd one &&
263          git remote add drosophila ../two &&
264          git remote add apis ../mirror &&
265          git remote update &&
266          git branch -r > output &&
267          test_cmp expect output)
268
269 '
270
271 cat > one/expect << EOF
272   drosophila/another
273   drosophila/master
274   drosophila/side
275   manduca/master
276   manduca/side
277   megaloprepus/master
278   megaloprepus/side
279 EOF
280
281 test_expect_success 'update with arguments' '
282
283         (cd one &&
284          for b in $(git branch -r)
285          do
286                 git branch -r -d $b || break
287          done &&
288          git remote add manduca ../mirror &&
289          git remote add megaloprepus ../mirror &&
290          git config remotes.phobaeticus "drosophila megaloprepus" &&
291          git config remotes.titanus manduca &&
292          git remote update phobaeticus titanus &&
293          git branch -r > output &&
294          test_cmp expect output)
295
296 '
297
298 cat > one/expect << EOF
299   apis/master
300   apis/side
301   manduca/master
302   manduca/side
303   megaloprepus/master
304   megaloprepus/side
305 EOF
306
307 test_expect_success 'update default' '
308
309         (cd one &&
310          for b in $(git branch -r)
311          do
312                 git branch -r -d $b || break
313          done &&
314          git config remote.drosophila.skipDefaultUpdate true &&
315          git remote update default &&
316          git branch -r > output &&
317          test_cmp expect output)
318
319 '
320
321 cat > one/expect << EOF
322   drosophila/another
323   drosophila/master
324   drosophila/side
325 EOF
326
327 test_expect_success 'update default (overridden, with funny whitespace)' '
328
329         (cd one &&
330          for b in $(git branch -r)
331          do
332                 git branch -r -d $b || break
333          done &&
334          git config remotes.default "$(printf "\t drosophila  \n")" &&
335          git remote update default &&
336          git branch -r > output &&
337          test_cmp expect output)
338
339 '
340
341 test_expect_success '"remote show" does not show symbolic refs' '
342
343         git clone one three &&
344         (cd three &&
345          git remote show origin > output &&
346          ! grep HEAD < output &&
347          ! grep -i stale < output)
348
349 '
350
351 test_expect_success 'reject adding remote with an invalid name' '
352
353         test_must_fail git remote add some:url desired-name
354
355 '
356
357 # The first three test if the tracking branches are properly renamed,
358 # the last two ones check if the config is updated.
359
360 test_expect_success 'rename a remote' '
361
362         git clone one four &&
363         (cd four &&
364          git remote rename origin upstream &&
365          rmdir .git/refs/remotes/origin &&
366          test "$(git symbolic-ref refs/remotes/upstream/HEAD)" = "refs/remotes/upstream/master" &&
367          test "$(git rev-parse upstream/master)" = "$(git rev-parse master)" &&
368          test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*" &&
369          test "$(git config branch.master.remote)" = "upstream")
370
371 '
372
373 cat > remotes_origin << EOF
374 URL: $(pwd)/one
375 Push: refs/heads/master:refs/heads/upstream
376 Pull: refs/heads/master:refs/heads/origin
377 EOF
378
379 test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
380         git clone one five &&
381         origin_url=$(pwd)/one &&
382         (cd five &&
383          git remote rm origin &&
384          mkdir -p .git/remotes &&
385          cat ../remotes_origin > .git/remotes/origin &&
386          git remote rename origin origin &&
387          ! test -f .git/remotes/origin &&
388          test "$(git config remote.origin.url)" = "$origin_url" &&
389          test "$(git config remote.origin.push)" = "refs/heads/master:refs/heads/upstream" &&
390          test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
391 '
392
393 test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '
394         git clone one six &&
395         origin_url=$(pwd)/one &&
396         (cd six &&
397          git remote rm origin &&
398          echo "$origin_url" > .git/branches/origin &&
399          git remote rename origin origin &&
400          ! test -f .git/branches/origin &&
401          test "$(git config remote.origin.url)" = "$origin_url" &&
402          test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
403 '
404
405 test_done