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