de1d0fcf438c7c366642c46d78e983df57ca8a59
1#!/bin/sh
2
3test_description='git remote porcelain-ish'
4
5. ./test-lib.sh
6
7setup_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
24tokens_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
30check_remote_track () {
31 actual=$(git remote show "$1" | sed -e '1,/Tracked/d') &&
32 shift &&
33 tokens_match "$*" "$actual"
34}
35
36check_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
44test_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
55test_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
64test_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
80test_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
90test_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
98test_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
110test_expect_success 'remove remote protects non-remote branches' '
111(
112 cd test &&
113 (cat >expect1 <<EOF
114Note: A non-remote branch was not removed; to delete it, use:
115 git branch -d master
116EOF
117 cat >expect2 <<EOF
118Note: Non-remote branches were not removed; to delete them, use:
119 git branch -d foobranch
120 git branch -d master
121EOF
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
136cat > test/expect << EOF
137* remote origin
138 URL: $(pwd)/one
139 HEAD branch: master
140 Remote branch merged with 'git pull' while on branch master
141 master
142 New remote branch (next fetch will store in remotes/origin)
143 master
144 Tracked remote branches
145 master
146 side
147 Local branches pushed with 'git push'
148 master:upstream
149 +refs/tags/lastbackup
150* remote two
151 URL: ../two
152 HEAD branch (remote HEAD is ambiguous, may be one of the following):
153 another
154 master
155EOF
156
157test_expect_success 'show' '
158 (cd test &&
159 git config --add remote.origin.fetch \
160 refs/heads/master:refs/heads/upstream &&
161 git fetch &&
162 git branch -d -r origin/master &&
163 git config --add remote.two.url ../two &&
164 (cd ../one &&
165 echo 1 > file &&
166 test_tick &&
167 git commit -m update file) &&
168 git config remote.origin.push \
169 refs/heads/master:refs/heads/upstream &&
170 git config --add remote.origin.push \
171 +refs/tags/lastbackup &&
172 git remote show origin two > output &&
173 test_cmp expect output)
174'
175
176cat > test/expect << EOF
177* remote origin
178 URL: $(pwd)/one
179 HEAD branch: (not queried)
180 Remote branch merged with 'git pull' while on branch master
181 master
182 Tracked remote branches
183 master
184 side
185 Local branches pushed with 'git push'
186 master:upstream
187 +refs/tags/lastbackup
188EOF
189
190test_expect_success 'show -n' '
191 (mv one one.unreachable &&
192 cd test &&
193 git remote show -n origin > output &&
194 mv ../one.unreachable ../one &&
195 test_cmp expect output)
196'
197
198test_expect_success 'prune' '
199 (cd one &&
200 git branch -m side side2) &&
201 (cd test &&
202 git fetch origin &&
203 git remote prune origin &&
204 git rev-parse refs/remotes/origin/side2 &&
205 test_must_fail git rev-parse refs/remotes/origin/side)
206'
207
208test_expect_success 'set-head --delete' '
209 (cd test &&
210 git symbolic-ref refs/remotes/origin/HEAD &&
211 git remote set-head --delete origin &&
212 test_must_fail git symbolic-ref refs/remotes/origin/HEAD)
213'
214
215test_expect_success 'set-head --auto' '
216 (cd test &&
217 git remote set-head --auto origin &&
218 echo refs/remotes/origin/master >expect &&
219 git symbolic-ref refs/remotes/origin/HEAD >output &&
220 test_cmp expect output
221 )
222'
223
224cat >test/expect <<EOF
225error: Multiple remote HEAD branches. Please choose one explicitly with:
226 git remote set-head two another
227 git remote set-head two master
228EOF
229
230test_expect_success 'set-head --auto fails w/multiple HEADs' '
231 (cd test &&
232 test_must_fail git remote set-head --auto two >output 2>&1 &&
233 test_cmp expect output)
234'
235
236cat >test/expect <<EOF
237refs/remotes/origin/side2
238EOF
239
240test_expect_success 'set-head explicit' '
241 (cd test &&
242 git remote set-head origin side2 &&
243 git symbolic-ref refs/remotes/origin/HEAD >output &&
244 git remote set-head origin master &&
245 test_cmp expect output)
246'
247
248cat > test/expect << EOF
249Pruning origin
250URL: $(pwd)/one
251 * [would prune] origin/side2
252EOF
253
254test_expect_success 'prune --dry-run' '
255 (cd one &&
256 git branch -m side2 side) &&
257 (cd test &&
258 git remote prune --dry-run origin > output &&
259 git rev-parse refs/remotes/origin/side2 &&
260 test_must_fail git rev-parse refs/remotes/origin/side &&
261 (cd ../one &&
262 git branch -m side side2) &&
263 test_cmp expect output)
264'
265
266test_expect_success 'add --mirror && prune' '
267 (mkdir mirror &&
268 cd mirror &&
269 git init --bare &&
270 git remote add --mirror -f origin ../one) &&
271 (cd one &&
272 git branch -m side2 side) &&
273 (cd mirror &&
274 git rev-parse --verify refs/heads/side2 &&
275 test_must_fail git rev-parse --verify refs/heads/side &&
276 git fetch origin &&
277 git remote prune origin &&
278 test_must_fail git rev-parse --verify refs/heads/side2 &&
279 git rev-parse --verify refs/heads/side)
280'
281
282test_expect_success 'add alt && prune' '
283 (mkdir alttst &&
284 cd alttst &&
285 git init &&
286 git remote add -f origin ../one &&
287 git config remote.alt.url ../one &&
288 git config remote.alt.fetch "+refs/heads/*:refs/remotes/origin/*") &&
289 (cd one &&
290 git branch -m side side2) &&
291 (cd alttst &&
292 git rev-parse --verify refs/remotes/origin/side &&
293 test_must_fail git rev-parse --verify refs/remotes/origin/side2 &&
294 git fetch alt &&
295 git remote prune alt &&
296 test_must_fail git rev-parse --verify refs/remotes/origin/side &&
297 git rev-parse --verify refs/remotes/origin/side2)
298'
299
300cat > one/expect << EOF
301 apis/master
302 apis/side
303 drosophila/another
304 drosophila/master
305 drosophila/side
306EOF
307
308test_expect_success 'update' '
309
310 (cd one &&
311 git remote add drosophila ../two &&
312 git remote add apis ../mirror &&
313 git remote update &&
314 git branch -r > output &&
315 test_cmp expect output)
316
317'
318
319cat > one/expect << EOF
320 drosophila/another
321 drosophila/master
322 drosophila/side
323 manduca/master
324 manduca/side
325 megaloprepus/master
326 megaloprepus/side
327EOF
328
329test_expect_success 'update with arguments' '
330
331 (cd one &&
332 for b in $(git branch -r)
333 do
334 git branch -r -d $b || break
335 done &&
336 git remote add manduca ../mirror &&
337 git remote add megaloprepus ../mirror &&
338 git config remotes.phobaeticus "drosophila megaloprepus" &&
339 git config remotes.titanus manduca &&
340 git remote update phobaeticus titanus &&
341 git branch -r > output &&
342 test_cmp expect output)
343
344'
345
346cat > one/expect << EOF
347 apis/master
348 apis/side
349 manduca/master
350 manduca/side
351 megaloprepus/master
352 megaloprepus/side
353EOF
354
355test_expect_success 'update default' '
356
357 (cd one &&
358 for b in $(git branch -r)
359 do
360 git branch -r -d $b || break
361 done &&
362 git config remote.drosophila.skipDefaultUpdate true &&
363 git remote update default &&
364 git branch -r > output &&
365 test_cmp expect output)
366
367'
368
369cat > one/expect << EOF
370 drosophila/another
371 drosophila/master
372 drosophila/side
373EOF
374
375test_expect_success 'update default (overridden, with funny whitespace)' '
376
377 (cd one &&
378 for b in $(git branch -r)
379 do
380 git branch -r -d $b || break
381 done &&
382 git config remotes.default "$(printf "\t drosophila \n")" &&
383 git remote update default &&
384 git branch -r > output &&
385 test_cmp expect output)
386
387'
388
389test_expect_success '"remote show" does not show symbolic refs' '
390
391 git clone one three &&
392 (cd three &&
393 git remote show origin > output &&
394 ! grep "^ *HEAD$" < output &&
395 ! grep -i stale < output)
396
397'
398
399test_expect_success 'reject adding remote with an invalid name' '
400
401 test_must_fail git remote add some:url desired-name
402
403'
404
405# The first three test if the tracking branches are properly renamed,
406# the last two ones check if the config is updated.
407
408test_expect_success 'rename a remote' '
409
410 git clone one four &&
411 (cd four &&
412 git remote rename origin upstream &&
413 rmdir .git/refs/remotes/origin &&
414 test "$(git symbolic-ref refs/remotes/upstream/HEAD)" = "refs/remotes/upstream/master" &&
415 test "$(git rev-parse upstream/master)" = "$(git rev-parse master)" &&
416 test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*" &&
417 test "$(git config branch.master.remote)" = "upstream")
418
419'
420
421cat > remotes_origin << EOF
422URL: $(pwd)/one
423Push: refs/heads/master:refs/heads/upstream
424Pull: refs/heads/master:refs/heads/origin
425EOF
426
427test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
428 git clone one five &&
429 origin_url=$(pwd)/one &&
430 (cd five &&
431 git remote rm origin &&
432 mkdir -p .git/remotes &&
433 cat ../remotes_origin > .git/remotes/origin &&
434 git remote rename origin origin &&
435 ! test -f .git/remotes/origin &&
436 test "$(git config remote.origin.url)" = "$origin_url" &&
437 test "$(git config remote.origin.push)" = "refs/heads/master:refs/heads/upstream" &&
438 test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
439'
440
441test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '
442 git clone one six &&
443 origin_url=$(pwd)/one &&
444 (cd six &&
445 git remote rm origin &&
446 echo "$origin_url" > .git/branches/origin &&
447 git remote rename origin origin &&
448 ! test -f .git/branches/origin &&
449 test "$(git config remote.origin.url)" = "$origin_url" &&
450 test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
451'
452
453test_expect_success 'remote prune to cause a dangling symref' '
454 git clone one seven &&
455 (
456 cd one &&
457 git checkout side2 &&
458 git branch -D master
459 ) &&
460 (
461 cd seven &&
462 git remote prune origin
463 ) 2>err &&
464 grep "has become dangling" err &&
465
466 : And the dangling symref will not cause other annoying errors
467 (
468 cd seven &&
469 git branch -a
470 ) 2>err &&
471 ! grep "points nowhere" err
472 (
473 cd seven &&
474 test_must_fail git branch nomore origin
475 ) 2>err &&
476 grep "dangling symref" err
477'
478
479test_done
480