tgupdate: merge t/blob/no-read-failure into top-bases/gitweb-additions
[git/gitweb.git] / t / t5526-fetch-submodules.sh
blobf3b0a8d30afcb472398bef8623a49ba6bac7dc24
1 #!/bin/sh
2 # Copyright (c) 2010, Jens Lehmann
4 test_description='Recursive "git fetch" for submodules'
6 . ./test-lib.sh
8 pwd=$(pwd)
10 add_upstream_commit() {
12 cd submodule &&
13 head1=$(git rev-parse --short HEAD) &&
14 echo new >> subfile &&
15 test_tick &&
16 git add subfile &&
17 git commit -m new subfile &&
18 head2=$(git rev-parse --short HEAD) &&
19 echo "Fetching submodule submodule" > ../expect.err &&
20 echo "From $pwd/submodule" >> ../expect.err &&
21 echo " $head1..$head2 master -> origin/master" >> ../expect.err
22 ) &&
24 cd deepsubmodule &&
25 head1=$(git rev-parse --short HEAD) &&
26 echo new >> deepsubfile &&
27 test_tick &&
28 git add deepsubfile &&
29 git commit -m new deepsubfile &&
30 head2=$(git rev-parse --short HEAD) &&
31 echo "Fetching submodule submodule/subdir/deepsubmodule" >> ../expect.err
32 echo "From $pwd/deepsubmodule" >> ../expect.err &&
33 echo " $head1..$head2 master -> origin/master" >> ../expect.err
37 test_expect_success setup '
38 mkdir deepsubmodule &&
40 cd deepsubmodule &&
41 git init &&
42 echo deepsubcontent > deepsubfile &&
43 git add deepsubfile &&
44 git commit -m new deepsubfile
45 ) &&
46 mkdir submodule &&
48 cd submodule &&
49 git init &&
50 echo subcontent > subfile &&
51 git add subfile &&
52 git submodule add "$pwd/deepsubmodule" subdir/deepsubmodule &&
53 git commit -a -m new
54 ) &&
55 git submodule add "$pwd/submodule" submodule &&
56 git commit -am initial &&
57 git clone . downstream &&
59 cd downstream &&
60 git submodule update --init --recursive
64 test_expect_success "fetch --recurse-submodules recurses into submodules" '
65 add_upstream_commit &&
67 cd downstream &&
68 git fetch --recurse-submodules >../actual.out 2>../actual.err
69 ) &&
70 test_must_be_empty actual.out &&
71 test_i18ncmp expect.err actual.err
74 test_expect_success "fetch --recurse-submodules -j2 has the same output behaviour" '
75 add_upstream_commit &&
77 cd downstream &&
78 GIT_TRACE=$(pwd)/../trace.out git fetch --recurse-submodules -j2 2>../actual.err
79 ) &&
80 test_must_be_empty actual.out &&
81 test_i18ncmp expect.err actual.err &&
82 grep "2 tasks" trace.out
85 test_expect_success "fetch alone only fetches superproject" '
86 add_upstream_commit &&
88 cd downstream &&
89 git fetch >../actual.out 2>../actual.err
90 ) &&
91 ! test -s actual.out &&
92 ! test -s actual.err
95 test_expect_success "fetch --no-recurse-submodules only fetches superproject" '
97 cd downstream &&
98 git fetch --no-recurse-submodules >../actual.out 2>../actual.err
99 ) &&
100 ! test -s actual.out &&
101 ! test -s actual.err
104 test_expect_success "using fetchRecurseSubmodules=true in .gitmodules recurses into submodules" '
106 cd downstream &&
107 git config -f .gitmodules submodule.submodule.fetchRecurseSubmodules true &&
108 git fetch >../actual.out 2>../actual.err
109 ) &&
110 test_must_be_empty actual.out &&
111 test_i18ncmp expect.err actual.err
114 test_expect_success "--no-recurse-submodules overrides .gitmodules config" '
115 add_upstream_commit &&
117 cd downstream &&
118 git fetch --no-recurse-submodules >../actual.out 2>../actual.err
119 ) &&
120 ! test -s actual.out &&
121 ! test -s actual.err
124 test_expect_success "using fetchRecurseSubmodules=false in .git/config overrides setting in .gitmodules" '
126 cd downstream &&
127 git config submodule.submodule.fetchRecurseSubmodules false &&
128 git fetch >../actual.out 2>../actual.err
129 ) &&
130 ! test -s actual.out &&
131 ! test -s actual.err
134 test_expect_success "--recurse-submodules overrides fetchRecurseSubmodules setting from .git/config" '
136 cd downstream &&
137 git fetch --recurse-submodules >../actual.out 2>../actual.err &&
138 git config --unset -f .gitmodules submodule.submodule.fetchRecurseSubmodules &&
139 git config --unset submodule.submodule.fetchRecurseSubmodules
140 ) &&
141 test_must_be_empty actual.out &&
142 test_i18ncmp expect.err actual.err
145 test_expect_success "--quiet propagates to submodules" '
147 cd downstream &&
148 git fetch --recurse-submodules --quiet >../actual.out 2>../actual.err
149 ) &&
150 ! test -s actual.out &&
151 ! test -s actual.err
154 test_expect_success "--quiet propagates to parallel submodules" '
156 cd downstream &&
157 git fetch --recurse-submodules -j 2 --quiet >../actual.out 2>../actual.err
158 ) &&
159 ! test -s actual.out &&
160 ! test -s actual.err
163 test_expect_success "--dry-run propagates to submodules" '
164 add_upstream_commit &&
166 cd downstream &&
167 git fetch --recurse-submodules --dry-run >../actual.out 2>../actual.err
168 ) &&
169 test_must_be_empty actual.out &&
170 test_i18ncmp expect.err actual.err
173 test_expect_success "Without --dry-run propagates to submodules" '
175 cd downstream &&
176 git fetch --recurse-submodules >../actual.out 2>../actual.err
177 ) &&
178 test_must_be_empty actual.out &&
179 test_i18ncmp expect.err actual.err
182 test_expect_success "recurseSubmodules=true propagates into submodules" '
183 add_upstream_commit &&
185 cd downstream &&
186 git config fetch.recurseSubmodules true
187 git fetch >../actual.out 2>../actual.err
188 ) &&
189 test_must_be_empty actual.out &&
190 test_i18ncmp expect.err actual.err
193 test_expect_success "--recurse-submodules overrides config in submodule" '
194 add_upstream_commit &&
196 cd downstream &&
198 cd submodule &&
199 git config fetch.recurseSubmodules false
200 ) &&
201 git fetch --recurse-submodules >../actual.out 2>../actual.err
202 ) &&
203 test_must_be_empty actual.out &&
204 test_i18ncmp expect.err actual.err
207 test_expect_success "--no-recurse-submodules overrides config setting" '
208 add_upstream_commit &&
210 cd downstream &&
211 git config fetch.recurseSubmodules true
212 git fetch --no-recurse-submodules >../actual.out 2>../actual.err
213 ) &&
214 ! test -s actual.out &&
215 ! test -s actual.err
218 test_expect_success "Recursion doesn't happen when no new commits are fetched in the superproject" '
220 cd downstream &&
222 cd submodule &&
223 git config --unset fetch.recurseSubmodules
224 ) &&
225 git config --unset fetch.recurseSubmodules
226 git fetch >../actual.out 2>../actual.err
227 ) &&
228 ! test -s actual.out &&
229 ! test -s actual.err
232 test_expect_success "Recursion stops when no new submodule commits are fetched" '
233 head1=$(git rev-parse --short HEAD) &&
234 git add submodule &&
235 git commit -m "new submodule" &&
236 head2=$(git rev-parse --short HEAD) &&
237 echo "From $pwd/." > expect.err.sub &&
238 echo " $head1..$head2 master -> origin/master" >>expect.err.sub &&
239 head -3 expect.err >> expect.err.sub &&
241 cd downstream &&
242 git fetch >../actual.out 2>../actual.err
243 ) &&
244 test_i18ncmp expect.err.sub actual.err &&
245 test_must_be_empty actual.out
248 test_expect_success "Recursion doesn't happen when new superproject commits don't change any submodules" '
249 add_upstream_commit &&
250 head1=$(git rev-parse --short HEAD) &&
251 echo a > file &&
252 git add file &&
253 git commit -m "new file" &&
254 head2=$(git rev-parse --short HEAD) &&
255 echo "From $pwd/." > expect.err.file &&
256 echo " $head1..$head2 master -> origin/master" >> expect.err.file &&
258 cd downstream &&
259 git fetch >../actual.out 2>../actual.err
260 ) &&
261 ! test -s actual.out &&
262 test_i18ncmp expect.err.file actual.err
265 test_expect_success "Recursion picks up config in submodule" '
267 cd downstream &&
268 git fetch --recurse-submodules &&
270 cd submodule &&
271 git config fetch.recurseSubmodules true
273 ) &&
274 add_upstream_commit &&
275 head1=$(git rev-parse --short HEAD) &&
276 git add submodule &&
277 git commit -m "new submodule" &&
278 head2=$(git rev-parse --short HEAD) &&
279 echo "From $pwd/." > expect.err.sub &&
280 echo " $head1..$head2 master -> origin/master" >> expect.err.sub &&
281 cat expect.err >> expect.err.sub &&
283 cd downstream &&
284 git fetch >../actual.out 2>../actual.err &&
286 cd submodule &&
287 git config --unset fetch.recurseSubmodules
289 ) &&
290 test_i18ncmp expect.err.sub actual.err &&
291 test_must_be_empty actual.out
294 test_expect_success "Recursion picks up all submodules when necessary" '
295 add_upstream_commit &&
297 cd submodule &&
299 cd subdir/deepsubmodule &&
300 git fetch &&
301 git checkout -q FETCH_HEAD
302 ) &&
303 head1=$(git rev-parse --short HEAD^) &&
304 git add subdir/deepsubmodule &&
305 git commit -m "new deepsubmodule"
306 head2=$(git rev-parse --short HEAD) &&
307 echo "Fetching submodule submodule" > ../expect.err.sub &&
308 echo "From $pwd/submodule" >> ../expect.err.sub &&
309 echo " $head1..$head2 master -> origin/master" >> ../expect.err.sub
310 ) &&
311 head1=$(git rev-parse --short HEAD) &&
312 git add submodule &&
313 git commit -m "new submodule" &&
314 head2=$(git rev-parse --short HEAD) &&
315 echo "From $pwd/." > expect.err.2 &&
316 echo " $head1..$head2 master -> origin/master" >> expect.err.2 &&
317 cat expect.err.sub >> expect.err.2 &&
318 tail -3 expect.err >> expect.err.2 &&
320 cd downstream &&
321 git fetch >../actual.out 2>../actual.err
322 ) &&
323 test_i18ncmp expect.err.2 actual.err &&
324 test_must_be_empty actual.out
327 test_expect_success "'--recurse-submodules=on-demand' doesn't recurse when no new commits are fetched in the superproject (and ignores config)" '
328 add_upstream_commit &&
330 cd submodule &&
332 cd subdir/deepsubmodule &&
333 git fetch &&
334 git checkout -q FETCH_HEAD
335 ) &&
336 head1=$(git rev-parse --short HEAD^) &&
337 git add subdir/deepsubmodule &&
338 git commit -m "new deepsubmodule" &&
339 head2=$(git rev-parse --short HEAD) &&
340 echo Fetching submodule submodule > ../expect.err.sub &&
341 echo "From $pwd/submodule" >> ../expect.err.sub &&
342 echo " $head1..$head2 master -> origin/master" >> ../expect.err.sub
343 ) &&
345 cd downstream &&
346 git config fetch.recurseSubmodules true &&
347 git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err &&
348 git config --unset fetch.recurseSubmodules
349 ) &&
350 ! test -s actual.out &&
351 ! test -s actual.err
354 test_expect_success "'--recurse-submodules=on-demand' recurses as deep as necessary (and ignores config)" '
355 head1=$(git rev-parse --short HEAD) &&
356 git add submodule &&
357 git commit -m "new submodule" &&
358 head2=$(git rev-parse --short HEAD) &&
359 tail -3 expect.err > expect.err.deepsub &&
360 echo "From $pwd/." > expect.err &&
361 echo " $head1..$head2 master -> origin/master" >>expect.err &&
362 cat expect.err.sub >> expect.err &&
363 cat expect.err.deepsub >> expect.err &&
365 cd downstream &&
366 git config fetch.recurseSubmodules false &&
368 cd submodule &&
369 git config -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive false
370 ) &&
371 git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err &&
372 git config --unset fetch.recurseSubmodules
374 cd submodule &&
375 git config --unset -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive
377 ) &&
378 test_must_be_empty actual.out &&
379 test_i18ncmp expect.err actual.err
382 test_expect_success "'--recurse-submodules=on-demand' stops when no new submodule commits are found in the superproject (and ignores config)" '
383 add_upstream_commit &&
384 head1=$(git rev-parse --short HEAD) &&
385 echo a >> file &&
386 git add file &&
387 git commit -m "new file" &&
388 head2=$(git rev-parse --short HEAD) &&
389 echo "From $pwd/." > expect.err.file &&
390 echo " $head1..$head2 master -> origin/master" >> expect.err.file &&
392 cd downstream &&
393 git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err
394 ) &&
395 ! test -s actual.out &&
396 test_i18ncmp expect.err.file actual.err
399 test_expect_success "'fetch.recurseSubmodules=on-demand' overrides global config" '
401 cd downstream &&
402 git fetch --recurse-submodules
403 ) &&
404 add_upstream_commit &&
405 git config --global fetch.recurseSubmodules false &&
406 head1=$(git rev-parse --short HEAD) &&
407 git add submodule &&
408 git commit -m "new submodule" &&
409 head2=$(git rev-parse --short HEAD) &&
410 echo "From $pwd/." > expect.err.2 &&
411 echo " $head1..$head2 master -> origin/master" >>expect.err.2 &&
412 head -3 expect.err >> expect.err.2 &&
414 cd downstream &&
415 git config fetch.recurseSubmodules on-demand &&
416 git fetch >../actual.out 2>../actual.err
417 ) &&
418 git config --global --unset fetch.recurseSubmodules &&
420 cd downstream &&
421 git config --unset fetch.recurseSubmodules
422 ) &&
423 test_must_be_empty actual.out &&
424 test_i18ncmp expect.err.2 actual.err
427 test_expect_success "'submodule.<sub>.fetchRecurseSubmodules=on-demand' overrides fetch.recurseSubmodules" '
429 cd downstream &&
430 git fetch --recurse-submodules
431 ) &&
432 add_upstream_commit &&
433 git config fetch.recurseSubmodules false &&
434 head1=$(git rev-parse --short HEAD) &&
435 git add submodule &&
436 git commit -m "new submodule" &&
437 head2=$(git rev-parse --short HEAD) &&
438 echo "From $pwd/." > expect.err.2 &&
439 echo " $head1..$head2 master -> origin/master" >>expect.err.2 &&
440 head -3 expect.err >> expect.err.2 &&
442 cd downstream &&
443 git config submodule.submodule.fetchRecurseSubmodules on-demand &&
444 git fetch >../actual.out 2>../actual.err
445 ) &&
446 git config --unset fetch.recurseSubmodules &&
448 cd downstream &&
449 git config --unset submodule.submodule.fetchRecurseSubmodules
450 ) &&
451 test_must_be_empty actual.out &&
452 test_i18ncmp expect.err.2 actual.err
455 test_expect_success "don't fetch submodule when newly recorded commits are already present" '
457 cd submodule &&
458 git checkout -q HEAD^^
459 ) &&
460 head1=$(git rev-parse --short HEAD) &&
461 git add submodule &&
462 git commit -m "submodule rewound" &&
463 head2=$(git rev-parse --short HEAD) &&
464 echo "From $pwd/." > expect.err &&
465 echo " $head1..$head2 master -> origin/master" >> expect.err &&
467 cd downstream &&
468 git fetch >../actual.out 2>../actual.err
469 ) &&
470 ! test -s actual.out &&
471 test_i18ncmp expect.err actual.err
474 test_expect_success 'fetching submodules respects parallel settings' '
475 git config fetch.recurseSubmodules true &&
477 cd downstream &&
478 GIT_TRACE=$(pwd)/trace.out git fetch --jobs 7 &&
479 grep "7 tasks" trace.out &&
480 git config submodule.fetchJobs 8 &&
481 GIT_TRACE=$(pwd)/trace.out git fetch &&
482 grep "8 tasks" trace.out &&
483 GIT_TRACE=$(pwd)/trace.out git fetch --jobs 9 &&
484 grep "9 tasks" trace.out
488 test_expect_success 'fetching submodule into a broken repository' '
489 # Prepare src and src/sub nested in it
490 git init src &&
492 cd src &&
493 git init sub &&
494 git -C sub commit --allow-empty -m "initial in sub" &&
495 git submodule add -- ./sub sub &&
496 git commit -m "initial in top"
497 ) &&
499 # Clone the old-fashoned way
500 git clone src dst &&
501 git -C dst clone ../src/sub sub &&
503 # Make sure that old-fashoned layout is still supported
504 git -C dst status &&
506 # "diff" would find no change
507 git -C dst diff --exit-code &&
509 # Recursive-fetch works fine
510 git -C dst fetch --recurse-submodules &&
512 # Break the receiving submodule
513 rm -f dst/sub/.git/HEAD &&
515 # NOTE: without the fix the following tests will recurse forever!
516 # They should terminate with an error.
518 test_must_fail git -C dst status &&
519 test_must_fail git -C dst diff &&
520 test_must_fail git -C dst fetch --recurse-submodules
523 test_done