bisect: move argument parsing before state modification.
[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 "From $pwd/submodule" > ../expect.err &&
20                 echo "   $head1..$head2  master     -> origin/master" >> ../expect.err
21         ) &&
22         (
23                 cd deepsubmodule &&
24                 head1=$(git rev-parse --short HEAD) &&
25                 echo new >> deepsubfile &&
26                 test_tick &&
27                 git add deepsubfile &&
28                 git commit -m new deepsubfile &&
29                 head2=$(git rev-parse --short HEAD) &&
30                 echo "From $pwd/deepsubmodule" >> ../expect.err &&
31                 echo "   $head1..$head2  master     -> origin/master" >> ../expect.err
32         )
33 }
34
35 test_expect_success setup '
36         mkdir deepsubmodule &&
37         (
38                 cd deepsubmodule &&
39                 git init &&
40                 echo deepsubcontent > deepsubfile &&
41                 git add deepsubfile &&
42                 git commit -m new deepsubfile
43         ) &&
44         mkdir submodule &&
45         (
46                 cd submodule &&
47                 git init &&
48                 echo subcontent > subfile &&
49                 git add subfile &&
50                 git submodule add "$pwd/deepsubmodule" subdir/deepsubmodule &&
51                 git commit -a -m new
52         ) &&
53         git submodule add "$pwd/submodule" submodule &&
54         git commit -am initial &&
55         git clone . downstream &&
56         (
57                 cd downstream &&
58                 git submodule update --init --recursive
59         ) &&
60         echo "Fetching submodule submodule" > expect.out &&
61         echo "Fetching submodule submodule/subdir/deepsubmodule" >> expect.out
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_i18ncmp expect.out 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_i18ncmp expect.out 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_i18ncmp expect.out 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_i18ncmp expect.out 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_i18ncmp expect.out 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_i18ncmp expect.out 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_i18ncmp expect.out 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 "Fetching submodule submodule" > expect.out.sub &&
218         echo "From $pwd/." > expect.err.sub &&
219         echo "   $head1..$head2  master     -> origin/master" >> expect.err.sub
220         head -2 expect.err >> expect.err.sub &&
221         (
222                 cd downstream &&
223                 git fetch >../actual.out 2>../actual.err
224         ) &&
225         test_i18ncmp expect.err.sub actual.err &&
226         test_i18ncmp expect.out.sub actual.out
227 '
228
229 test_expect_success "Recursion doesn't happen when new superproject commits don't change any submodules" '
230         add_upstream_commit &&
231         head1=$(git rev-parse --short HEAD) &&
232         echo a > file &&
233         git add file &&
234         git commit -m "new file" &&
235         head2=$(git rev-parse --short HEAD) &&
236         echo "From $pwd/." > expect.err.file &&
237         echo "   $head1..$head2  master     -> origin/master" >> expect.err.file &&
238         (
239                 cd downstream &&
240                 git fetch >../actual.out 2>../actual.err
241         ) &&
242         ! test -s actual.out &&
243         test_i18ncmp expect.err.file actual.err
244 '
245
246 test_expect_success "Recursion picks up config in submodule" '
247         (
248                 cd downstream &&
249                 git fetch --recurse-submodules &&
250                 (
251                         cd submodule &&
252                         git config fetch.recurseSubmodules true
253                 )
254         ) &&
255         add_upstream_commit &&
256         head1=$(git rev-parse --short HEAD) &&
257         git add submodule &&
258         git commit -m "new submodule" &&
259         head2=$(git rev-parse --short HEAD) &&
260         echo "From $pwd/." > expect.err.sub &&
261         echo "   $head1..$head2  master     -> origin/master" >> expect.err.sub &&
262         cat expect.err >> expect.err.sub &&
263         (
264                 cd downstream &&
265                 git fetch >../actual.out 2>../actual.err &&
266                 (
267                         cd submodule &&
268                         git config --unset fetch.recurseSubmodules
269                 )
270         ) &&
271         test_i18ncmp expect.err.sub actual.err &&
272         test_i18ncmp expect.out actual.out
273 '
274
275 test_expect_success "Recursion picks up all submodules when necessary" '
276         add_upstream_commit &&
277         (
278                 cd submodule &&
279                 (
280                         cd subdir/deepsubmodule &&
281                         git fetch &&
282                         git checkout -q FETCH_HEAD
283                 ) &&
284                 head1=$(git rev-parse --short HEAD^) &&
285                 git add subdir/deepsubmodule &&
286                 git commit -m "new deepsubmodule"
287                 head2=$(git rev-parse --short HEAD) &&
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 -2 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_i18ncmp expect.out 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 "From $pwd/submodule" > ../expect.err.sub &&
321                 echo "   $head1..$head2  master     -> origin/master" >> ../expect.err.sub
322         ) &&
323         (
324                 cd downstream &&
325                 git config fetch.recurseSubmodules true &&
326                 git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err &&
327                 git config --unset fetch.recurseSubmodules
328         ) &&
329         ! test -s actual.out &&
330         ! test -s actual.err
331 '
332
333 test_expect_success "'--recurse-submodules=on-demand' recurses as deep as necessary (and ignores config)" '
334         head1=$(git rev-parse --short HEAD) &&
335         git add submodule &&
336         git commit -m "new submodule" &&
337         head2=$(git rev-parse --short HEAD) &&
338         tail -2 expect.err > expect.err.deepsub &&
339         echo "From $pwd/." > expect.err &&
340         echo "   $head1..$head2  master     -> origin/master" >> expect.err
341         cat expect.err.sub >> expect.err &&
342         cat expect.err.deepsub >> expect.err &&
343         (
344                 cd downstream &&
345                 git config fetch.recurseSubmodules false &&
346                 (
347                         cd submodule &&
348                         git config -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive false
349                 ) &&
350                 git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err &&
351                 git config --unset fetch.recurseSubmodules
352                 (
353                         cd submodule &&
354                         git config --unset -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive
355                 )
356         ) &&
357         test_i18ncmp expect.out actual.out &&
358         test_i18ncmp expect.err actual.err
359 '
360
361 test_expect_success "'--recurse-submodules=on-demand' stops when no new submodule commits are found in the superproject (and ignores config)" '
362         add_upstream_commit &&
363         head1=$(git rev-parse --short HEAD) &&
364         echo a >> file &&
365         git add file &&
366         git commit -m "new file" &&
367         head2=$(git rev-parse --short HEAD) &&
368         echo "From $pwd/." > expect.err.file &&
369         echo "   $head1..$head2  master     -> origin/master" >> expect.err.file &&
370         (
371                 cd downstream &&
372                 git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err
373         ) &&
374         ! test -s actual.out &&
375         test_i18ncmp expect.err.file actual.err
376 '
377
378 test_expect_success "'fetch.recurseSubmodules=on-demand' overrides global config" '
379         (
380                 cd downstream &&
381                 git fetch --recurse-submodules
382         ) &&
383         add_upstream_commit &&
384         git config --global fetch.recurseSubmodules false &&
385         head1=$(git rev-parse --short HEAD) &&
386         git add submodule &&
387         git commit -m "new submodule" &&
388         head2=$(git rev-parse --short HEAD) &&
389         echo "From $pwd/." > expect.err.2 &&
390         echo "   $head1..$head2  master     -> origin/master" >> expect.err.2
391         head -2 expect.err >> expect.err.2 &&
392         (
393                 cd downstream &&
394                 git config fetch.recurseSubmodules on-demand &&
395                 git fetch >../actual.out 2>../actual.err
396         ) &&
397         git config --global --unset fetch.recurseSubmodules &&
398         (
399                 cd downstream &&
400                 git config --unset fetch.recurseSubmodules
401         ) &&
402         test_i18ncmp expect.out.sub actual.out &&
403         test_i18ncmp expect.err.2 actual.err
404 '
405
406 test_expect_success "'submodule.<sub>.fetchRecurseSubmodules=on-demand' overrides fetch.recurseSubmodules" '
407         (
408                 cd downstream &&
409                 git fetch --recurse-submodules
410         ) &&
411         add_upstream_commit &&
412         git config fetch.recurseSubmodules false &&
413         head1=$(git rev-parse --short HEAD) &&
414         git add submodule &&
415         git commit -m "new submodule" &&
416         head2=$(git rev-parse --short HEAD) &&
417         echo "From $pwd/." > expect.err.2 &&
418         echo "   $head1..$head2  master     -> origin/master" >> expect.err.2
419         head -2 expect.err >> expect.err.2 &&
420         (
421                 cd downstream &&
422                 git config submodule.submodule.fetchRecurseSubmodules on-demand &&
423                 git fetch >../actual.out 2>../actual.err
424         ) &&
425         git config --unset fetch.recurseSubmodules &&
426         (
427                 cd downstream &&
428                 git config --unset submodule.submodule.fetchRecurseSubmodules
429         ) &&
430         test_i18ncmp expect.out.sub actual.out &&
431         test_i18ncmp expect.err.2 actual.err
432 '
433
434 test_expect_success "don't fetch submodule when newly recorded commits are already present" '
435         (
436                 cd submodule &&
437                 git checkout -q HEAD^^
438         ) &&
439         head1=$(git rev-parse --short HEAD) &&
440         git add submodule &&
441         git commit -m "submodule rewound" &&
442         head2=$(git rev-parse --short HEAD) &&
443         echo "From $pwd/." > expect.err &&
444         echo "   $head1..$head2  master     -> origin/master" >> expect.err &&
445         (
446                 cd downstream &&
447                 git fetch >../actual.out 2>../actual.err
448         ) &&
449         ! test -s actual.out &&
450         test_i18ncmp expect.err actual.err
451 '
452
453 test_done