submodule.c: write "Fetching submodule <foo>" to stderr
[git] / t / t5526-fetch-submodules.sh
1 #!/bin/sh
2 # Copyright (c) 2010, Jens Lehmann
3
4 test_description='Recursive "git fetch" for submodules'
5
6 . ./test-lib.sh
7
8 pwd=$(pwd)
9
10 add_upstream_commit() {
11         (
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         ) &&
23         (
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
34         )
35 }
36
37 test_expect_success setup '
38         mkdir deepsubmodule &&
39         (
40                 cd deepsubmodule &&
41                 git init &&
42                 echo deepsubcontent > deepsubfile &&
43                 git add deepsubfile &&
44                 git commit -m new deepsubfile
45         ) &&
46         mkdir submodule &&
47         (
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 &&
58         (
59                 cd downstream &&
60                 git submodule update --init --recursive
61         )
62 '
63
64 test_expect_success "fetch --recurse-submodules recurses into submodules" '
65         add_upstream_commit &&
66         (
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
72 '
73
74 test_expect_success "fetch alone only fetches superproject" '
75         add_upstream_commit &&
76         (
77                 cd downstream &&
78                 git fetch >../actual.out 2>../actual.err
79         ) &&
80         ! test -s actual.out &&
81         ! test -s actual.err
82 '
83
84 test_expect_success "fetch --no-recurse-submodules only fetches superproject" '
85         (
86                 cd downstream &&
87                 git fetch --no-recurse-submodules >../actual.out 2>../actual.err
88         ) &&
89         ! test -s actual.out &&
90         ! test -s actual.err
91 '
92
93 test_expect_success "using fetchRecurseSubmodules=true in .gitmodules recurses into submodules" '
94         (
95                 cd downstream &&
96                 git config -f .gitmodules submodule.submodule.fetchRecurseSubmodules true &&
97                 git fetch >../actual.out 2>../actual.err
98         ) &&
99         test_must_be_empty actual.out &&
100         test_i18ncmp expect.err actual.err
101 '
102
103 test_expect_success "--no-recurse-submodules overrides .gitmodules config" '
104         add_upstream_commit &&
105         (
106                 cd downstream &&
107                 git fetch --no-recurse-submodules >../actual.out 2>../actual.err
108         ) &&
109         ! test -s actual.out &&
110         ! test -s actual.err
111 '
112
113 test_expect_success "using fetchRecurseSubmodules=false in .git/config overrides setting in .gitmodules" '
114         (
115                 cd downstream &&
116                 git config submodule.submodule.fetchRecurseSubmodules false &&
117                 git fetch >../actual.out 2>../actual.err
118         ) &&
119         ! test -s actual.out &&
120         ! test -s actual.err
121 '
122
123 test_expect_success "--recurse-submodules overrides fetchRecurseSubmodules setting from .git/config" '
124         (
125                 cd downstream &&
126                 git fetch --recurse-submodules >../actual.out 2>../actual.err &&
127                 git config --unset -f .gitmodules submodule.submodule.fetchRecurseSubmodules &&
128                 git config --unset submodule.submodule.fetchRecurseSubmodules
129         ) &&
130         test_must_be_empty actual.out &&
131         test_i18ncmp expect.err actual.err
132 '
133
134 test_expect_success "--quiet propagates to submodules" '
135         (
136                 cd downstream &&
137                 git fetch --recurse-submodules --quiet >../actual.out 2>../actual.err
138         ) &&
139         ! test -s actual.out &&
140         ! test -s actual.err
141 '
142
143 test_expect_success "--dry-run propagates to submodules" '
144         add_upstream_commit &&
145         (
146                 cd downstream &&
147                 git fetch --recurse-submodules --dry-run >../actual.out 2>../actual.err
148         ) &&
149         test_must_be_empty actual.out &&
150         test_i18ncmp expect.err actual.err
151 '
152
153 test_expect_success "Without --dry-run propagates to submodules" '
154         (
155                 cd downstream &&
156                 git fetch --recurse-submodules >../actual.out 2>../actual.err
157         ) &&
158         test_must_be_empty actual.out &&
159         test_i18ncmp expect.err actual.err
160 '
161
162 test_expect_success "recurseSubmodules=true propagates into submodules" '
163         add_upstream_commit &&
164         (
165                 cd downstream &&
166                 git config fetch.recurseSubmodules true
167                 git fetch >../actual.out 2>../actual.err
168         ) &&
169         test_must_be_empty actual.out &&
170         test_i18ncmp expect.err actual.err
171 '
172
173 test_expect_success "--recurse-submodules overrides config in submodule" '
174         add_upstream_commit &&
175         (
176                 cd downstream &&
177                 (
178                         cd submodule &&
179                         git config fetch.recurseSubmodules false
180                 ) &&
181                 git fetch --recurse-submodules >../actual.out 2>../actual.err
182         ) &&
183         test_must_be_empty actual.out &&
184         test_i18ncmp expect.err actual.err
185 '
186
187 test_expect_success "--no-recurse-submodules overrides config setting" '
188         add_upstream_commit &&
189         (
190                 cd downstream &&
191                 git config fetch.recurseSubmodules true
192                 git fetch --no-recurse-submodules >../actual.out 2>../actual.err
193         ) &&
194         ! test -s actual.out &&
195         ! test -s actual.err
196 '
197
198 test_expect_success "Recursion doesn't happen when no new commits are fetched in the superproject" '
199         (
200                 cd downstream &&
201                 (
202                         cd submodule &&
203                         git config --unset fetch.recurseSubmodules
204                 ) &&
205                 git config --unset fetch.recurseSubmodules
206                 git fetch >../actual.out 2>../actual.err
207         ) &&
208         ! test -s actual.out &&
209         ! test -s actual.err
210 '
211
212 test_expect_success "Recursion stops when no new submodule commits are fetched" '
213         head1=$(git rev-parse --short HEAD) &&
214         git add submodule &&
215         git commit -m "new submodule" &&
216         head2=$(git rev-parse --short HEAD) &&
217         echo "From $pwd/." > expect.err.sub &&
218         echo "   $head1..$head2  master     -> origin/master" >>expect.err.sub &&
219         head -3 expect.err >> expect.err.sub &&
220         (
221                 cd downstream &&
222                 git fetch >../actual.out 2>../actual.err
223         ) &&
224         test_i18ncmp expect.err.sub actual.err &&
225         test_must_be_empty actual.out
226 '
227
228 test_expect_success "Recursion doesn't happen when new superproject commits don't change any submodules" '
229         add_upstream_commit &&
230         head1=$(git rev-parse --short HEAD) &&
231         echo a > file &&
232         git add file &&
233         git commit -m "new file" &&
234         head2=$(git rev-parse --short HEAD) &&
235         echo "From $pwd/." > expect.err.file &&
236         echo "   $head1..$head2  master     -> origin/master" >> expect.err.file &&
237         (
238                 cd downstream &&
239                 git fetch >../actual.out 2>../actual.err
240         ) &&
241         ! test -s actual.out &&
242         test_i18ncmp expect.err.file actual.err
243 '
244
245 test_expect_success "Recursion picks up config in submodule" '
246         (
247                 cd downstream &&
248                 git fetch --recurse-submodules &&
249                 (
250                         cd submodule &&
251                         git config fetch.recurseSubmodules true
252                 )
253         ) &&
254         add_upstream_commit &&
255         head1=$(git rev-parse --short HEAD) &&
256         git add submodule &&
257         git commit -m "new submodule" &&
258         head2=$(git rev-parse --short HEAD) &&
259         echo "From $pwd/." > expect.err.sub &&
260         echo "   $head1..$head2  master     -> origin/master" >> expect.err.sub &&
261         cat expect.err >> expect.err.sub &&
262         (
263                 cd downstream &&
264                 git fetch >../actual.out 2>../actual.err &&
265                 (
266                         cd submodule &&
267                         git config --unset fetch.recurseSubmodules
268                 )
269         ) &&
270         test_i18ncmp expect.err.sub actual.err &&
271         test_must_be_empty actual.out
272 '
273
274 test_expect_success "Recursion picks up all submodules when necessary" '
275         add_upstream_commit &&
276         (
277                 cd submodule &&
278                 (
279                         cd subdir/deepsubmodule &&
280                         git fetch &&
281                         git checkout -q FETCH_HEAD
282                 ) &&
283                 head1=$(git rev-parse --short HEAD^) &&
284                 git add subdir/deepsubmodule &&
285                 git commit -m "new deepsubmodule"
286                 head2=$(git rev-parse --short HEAD) &&
287                 echo "Fetching submodule submodule" > ../expect.err.sub &&
288                 echo "From $pwd/submodule" >> ../expect.err.sub &&
289                 echo "   $head1..$head2  master     -> origin/master" >> ../expect.err.sub
290         ) &&
291         head1=$(git rev-parse --short HEAD) &&
292         git add submodule &&
293         git commit -m "new submodule" &&
294         head2=$(git rev-parse --short HEAD) &&
295         echo "From $pwd/." > expect.err.2 &&
296         echo "   $head1..$head2  master     -> origin/master" >> expect.err.2 &&
297         cat expect.err.sub >> expect.err.2 &&
298         tail -3 expect.err >> expect.err.2 &&
299         (
300                 cd downstream &&
301                 git fetch >../actual.out 2>../actual.err
302         ) &&
303         test_i18ncmp expect.err.2 actual.err &&
304         test_must_be_empty actual.out
305 '
306
307 test_expect_success "'--recurse-submodules=on-demand' doesn't recurse when no new commits are fetched in the superproject (and ignores config)" '
308         add_upstream_commit &&
309         (
310                 cd submodule &&
311                 (
312                         cd subdir/deepsubmodule &&
313                         git fetch &&
314                         git checkout -q FETCH_HEAD
315                 ) &&
316                 head1=$(git rev-parse --short HEAD^) &&
317                 git add subdir/deepsubmodule &&
318                 git commit -m "new deepsubmodule" &&
319                 head2=$(git rev-parse --short HEAD) &&
320                 echo Fetching submodule submodule > ../expect.err.sub &&
321                 echo "From $pwd/submodule" >> ../expect.err.sub &&
322                 echo "   $head1..$head2  master     -> origin/master" >> ../expect.err.sub
323         ) &&
324         (
325                 cd downstream &&
326                 git config fetch.recurseSubmodules true &&
327                 git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err &&
328                 git config --unset fetch.recurseSubmodules
329         ) &&
330         ! test -s actual.out &&
331         ! test -s actual.err
332 '
333
334 test_expect_success "'--recurse-submodules=on-demand' recurses as deep as necessary (and ignores config)" '
335         head1=$(git rev-parse --short HEAD) &&
336         git add submodule &&
337         git commit -m "new submodule" &&
338         head2=$(git rev-parse --short HEAD) &&
339         tail -3 expect.err > expect.err.deepsub &&
340         echo "From $pwd/." > expect.err &&
341         echo "   $head1..$head2  master     -> origin/master" >>expect.err &&
342         cat expect.err.sub >> expect.err &&
343         cat expect.err.deepsub >> expect.err &&
344         (
345                 cd downstream &&
346                 git config fetch.recurseSubmodules false &&
347                 (
348                         cd submodule &&
349                         git config -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive false
350                 ) &&
351                 git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err &&
352                 git config --unset fetch.recurseSubmodules
353                 (
354                         cd submodule &&
355                         git config --unset -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive
356                 )
357         ) &&
358         test_must_be_empty actual.out &&
359         test_i18ncmp expect.err actual.err
360 '
361
362 test_expect_success "'--recurse-submodules=on-demand' stops when no new submodule commits are found in the superproject (and ignores config)" '
363         add_upstream_commit &&
364         head1=$(git rev-parse --short HEAD) &&
365         echo a >> file &&
366         git add file &&
367         git commit -m "new file" &&
368         head2=$(git rev-parse --short HEAD) &&
369         echo "From $pwd/." > expect.err.file &&
370         echo "   $head1..$head2  master     -> origin/master" >> expect.err.file &&
371         (
372                 cd downstream &&
373                 git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err
374         ) &&
375         ! test -s actual.out &&
376         test_i18ncmp expect.err.file actual.err
377 '
378
379 test_expect_success "'fetch.recurseSubmodules=on-demand' overrides global config" '
380         (
381                 cd downstream &&
382                 git fetch --recurse-submodules
383         ) &&
384         add_upstream_commit &&
385         git config --global fetch.recurseSubmodules false &&
386         head1=$(git rev-parse --short HEAD) &&
387         git add submodule &&
388         git commit -m "new submodule" &&
389         head2=$(git rev-parse --short HEAD) &&
390         echo "From $pwd/." > expect.err.2 &&
391         echo "   $head1..$head2  master     -> origin/master" >>expect.err.2 &&
392         head -3 expect.err >> expect.err.2 &&
393         (
394                 cd downstream &&
395                 git config fetch.recurseSubmodules on-demand &&
396                 git fetch >../actual.out 2>../actual.err
397         ) &&
398         git config --global --unset fetch.recurseSubmodules &&
399         (
400                 cd downstream &&
401                 git config --unset fetch.recurseSubmodules
402         ) &&
403         test_must_be_empty actual.out &&
404         test_i18ncmp expect.err.2 actual.err
405 '
406
407 test_expect_success "'submodule.<sub>.fetchRecurseSubmodules=on-demand' overrides fetch.recurseSubmodules" '
408         (
409                 cd downstream &&
410                 git fetch --recurse-submodules
411         ) &&
412         add_upstream_commit &&
413         git config fetch.recurseSubmodules false &&
414         head1=$(git rev-parse --short HEAD) &&
415         git add submodule &&
416         git commit -m "new submodule" &&
417         head2=$(git rev-parse --short HEAD) &&
418         echo "From $pwd/." > expect.err.2 &&
419         echo "   $head1..$head2  master     -> origin/master" >>expect.err.2 &&
420         head -3 expect.err >> expect.err.2 &&
421         (
422                 cd downstream &&
423                 git config submodule.submodule.fetchRecurseSubmodules on-demand &&
424                 git fetch >../actual.out 2>../actual.err
425         ) &&
426         git config --unset fetch.recurseSubmodules &&
427         (
428                 cd downstream &&
429                 git config --unset submodule.submodule.fetchRecurseSubmodules
430         ) &&
431         test_must_be_empty actual.out &&
432         test_i18ncmp expect.err.2 actual.err
433 '
434
435 test_expect_success "don't fetch submodule when newly recorded commits are already present" '
436         (
437                 cd submodule &&
438                 git checkout -q HEAD^^
439         ) &&
440         head1=$(git rev-parse --short HEAD) &&
441         git add submodule &&
442         git commit -m "submodule rewound" &&
443         head2=$(git rev-parse --short HEAD) &&
444         echo "From $pwd/." > expect.err &&
445         echo "   $head1..$head2  master     -> origin/master" >> expect.err &&
446         (
447                 cd downstream &&
448                 git fetch >../actual.out 2>../actual.err
449         ) &&
450         ! test -s actual.out &&
451         test_i18ncmp expect.err actual.err
452 '
453
454 test_done