builtin-remote: add set-head subcommand
[git/dscho.git] / t / t5505-remote.sh
blobde1d0fcf438c7c366642c46d78e983df57ca8a59
1 #!/bin/sh
3 test_description='git remote porcelain-ish'
5 . ./test-lib.sh
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
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
30 check_remote_track () {
31 actual=$(git remote show "$1" | sed -e '1,/Tracked/d') &&
32 shift &&
33 tokens_match "$*" "$actual"
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"
44 test_expect_success setup '
46 setup_repository one &&
47 setup_repository two &&
49 cd two && git branch another
50 ) &&
51 git clone one test
55 test_expect_success 'remote information for the origin' '
57 cd test &&
58 tokens_match origin "$(git remote)" &&
59 check_remote_track origin master side &&
60 check_tracking_branch origin HEAD master side
64 test_expect_success 'add another remote' '
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
80 test_expect_success 'remote forces tracking branches' '
82 cd test &&
83 case `git config remote.second.fetch` in
84 +*) true ;;
85 *) false ;;
86 esac
90 test_expect_success 'remove remote' '
92 cd test &&
93 git symbolic-ref refs/remotes/second/HEAD refs/remotes/second/master &&
94 git remote rm second
98 test_expect_success 'remove remote' '
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
110 test_expect_success 'remove remote protects non-remote branches' '
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
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
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
136 cat > 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
157 test_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)
176 cat > 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
190 test_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)
198 test_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)
208 test_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)
215 test_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
224 cat >test/expect <<EOF
225 error: Multiple remote HEAD branches. Please choose one explicitly with:
226 git remote set-head two another
227 git remote set-head two master
230 test_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)
236 cat >test/expect <<EOF
237 refs/remotes/origin/side2
240 test_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)
248 cat > test/expect << EOF
249 Pruning origin
250 URL: $(pwd)/one
251 * [would prune] origin/side2
254 test_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)
266 test_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)
282 test_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)
300 cat > one/expect << EOF
301 apis/master
302 apis/side
303 drosophila/another
304 drosophila/master
305 drosophila/side
308 test_expect_success 'update' '
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)
319 cat > one/expect << EOF
320 drosophila/another
321 drosophila/master
322 drosophila/side
323 manduca/master
324 manduca/side
325 megaloprepus/master
326 megaloprepus/side
329 test_expect_success 'update with arguments' '
331 (cd one &&
332 for b in $(git branch -r)
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)
346 cat > one/expect << EOF
347 apis/master
348 apis/side
349 manduca/master
350 manduca/side
351 megaloprepus/master
352 megaloprepus/side
355 test_expect_success 'update default' '
357 (cd one &&
358 for b in $(git branch -r)
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)
369 cat > one/expect << EOF
370 drosophila/another
371 drosophila/master
372 drosophila/side
375 test_expect_success 'update default (overridden, with funny whitespace)' '
377 (cd one &&
378 for b in $(git branch -r)
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)
389 test_expect_success '"remote show" does not show symbolic refs' '
391 git clone one three &&
392 (cd three &&
393 git remote show origin > output &&
394 ! grep "^ *HEAD$" < output &&
395 ! grep -i stale < output)
399 test_expect_success 'reject adding remote with an invalid name' '
401 test_must_fail git remote add some:url desired-name
405 # The first three test if the tracking branches are properly renamed,
406 # the last two ones check if the config is updated.
408 test_expect_success 'rename a remote' '
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")
421 cat > remotes_origin << EOF
422 URL: $(pwd)/one
423 Push: refs/heads/master:refs/heads/upstream
424 Pull: refs/heads/master:refs/heads/origin
427 test_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")
441 test_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")
453 test_expect_success 'remote prune to cause a dangling symref' '
454 git clone one seven &&
456 cd one &&
457 git checkout side2 &&
458 git branch -D master
459 ) &&
461 cd seven &&
462 git remote prune origin
463 ) 2>err &&
464 grep "has become dangling" err &&
466 : And the dangling symref will not cause other annoying errors
468 cd seven &&
469 git branch -a
470 ) 2>err &&
471 ! grep "points nowhere" err
473 cd seven &&
474 test_must_fail git branch nomore origin
475 ) 2>err &&
476 grep "dangling symref" err
479 test_done