fixup! refs/refs-internal.h: avoid forward declaration of an enum
[git] / t / t5531-deep-submodule-push.sh
1 #!/bin/sh
2
3 test_description='test push with submodules'
4
5 . ./test-lib.sh
6
7 test_expect_success setup '
8         mkdir pub.git &&
9         GIT_DIR=pub.git git init --bare &&
10         GIT_DIR=pub.git git config receive.fsckobjects true &&
11         mkdir work &&
12         (
13                 cd work &&
14                 git init &&
15                 git config push.default matching &&
16                 mkdir -p gar/bage &&
17                 (
18                         cd gar/bage &&
19                         git init &&
20                         git config push.default matching &&
21                         >junk &&
22                         git add junk &&
23                         git commit -m "Initial junk"
24                 ) &&
25                 git add gar/bage &&
26                 git commit -m "Initial superproject"
27         )
28 '
29
30 test_expect_success 'push works with recorded gitlink' '
31         (
32                 cd work &&
33                 git push ../pub.git master
34         )
35 '
36
37 test_expect_success 'push if submodule has no remote' '
38         (
39                 cd work/gar/bage &&
40                 >junk2 &&
41                 git add junk2 &&
42                 git commit -m "Second junk"
43         ) &&
44         (
45                 cd work &&
46                 git add gar/bage &&
47                 git commit -m "Second commit for gar/bage" &&
48                 git push --recurse-submodules=check ../pub.git master
49         )
50 '
51
52 test_expect_success 'push fails if submodule commit not on remote' '
53         (
54                 cd work/gar &&
55                 git clone --bare bage ../../submodule.git &&
56                 cd bage &&
57                 git remote add origin ../../../submodule.git &&
58                 git fetch &&
59                 >junk3 &&
60                 git add junk3 &&
61                 git commit -m "Third junk"
62         ) &&
63         (
64                 cd work &&
65                 git add gar/bage &&
66                 git commit -m "Third commit for gar/bage" &&
67                 # the push should fail with --recurse-submodules=check
68                 # on the command line...
69                 test_must_fail git push --recurse-submodules=check ../pub.git master &&
70
71                 # ...or if specified in the configuration..
72                 test_must_fail git -c push.recurseSubmodules=check push ../pub.git master
73         )
74 '
75
76 test_expect_success 'push succeeds after commit was pushed to remote' '
77         (
78                 cd work/gar/bage &&
79                 git push origin master
80         ) &&
81         (
82                 cd work &&
83                 git push --recurse-submodules=check ../pub.git master
84         )
85 '
86
87 test_expect_success 'push succeeds if submodule commit not on remote but using on-demand on command line' '
88         (
89                 cd work/gar/bage &&
90                 >recurse-on-demand-on-command-line &&
91                 git add recurse-on-demand-on-command-line &&
92                 git commit -m "Recurse on-demand on command line junk"
93         ) &&
94         (
95                 cd work &&
96                 git add gar/bage &&
97                 git commit -m "Recurse on-demand on command line for gar/bage" &&
98                 git push --recurse-submodules=on-demand ../pub.git master &&
99                 # Check that the supermodule commit got there
100                 git fetch ../pub.git &&
101                 git diff --quiet FETCH_HEAD master &&
102                 # Check that the submodule commit got there too
103                 cd gar/bage &&
104                 git diff --quiet origin/master master
105         )
106 '
107
108 test_expect_success 'push succeeds if submodule commit not on remote but using on-demand from config' '
109         (
110                 cd work/gar/bage &&
111                 >recurse-on-demand-from-config &&
112                 git add recurse-on-demand-from-config &&
113                 git commit -m "Recurse on-demand from config junk"
114         ) &&
115         (
116                 cd work &&
117                 git add gar/bage &&
118                 git commit -m "Recurse on-demand from config for gar/bage" &&
119                 git -c push.recurseSubmodules=on-demand push ../pub.git master &&
120                 # Check that the supermodule commit got there
121                 git fetch ../pub.git &&
122                 git diff --quiet FETCH_HEAD master &&
123                 # Check that the submodule commit got there too
124                 cd gar/bage &&
125                 git diff --quiet origin/master master
126         )
127 '
128
129 test_expect_success 'push succeeds if submodule commit not on remote but using auto-on-demand via submodule.recurse config' '
130         (
131                 cd work/gar/bage &&
132                 >recurse-on-demand-from-submodule-recurse-config &&
133                 git add recurse-on-demand-from-submodule-recurse-config &&
134                 git commit -m "Recurse submodule.recurse from config junk"
135         ) &&
136         (
137                 cd work &&
138                 git add gar/bage &&
139                 git commit -m "Recurse submodule.recurse from config for gar/bage" &&
140                 git -c submodule.recurse push ../pub.git master &&
141                 # Check that the supermodule commit got there
142                 git fetch ../pub.git &&
143                 git diff --quiet FETCH_HEAD master &&
144                 # Check that the submodule commit got there too
145                 cd gar/bage &&
146                 git diff --quiet origin/master master
147         )
148 '
149
150 test_expect_success 'push recurse-submodules on command line overrides config' '
151         (
152                 cd work/gar/bage &&
153                 >recurse-check-on-command-line-overriding-config &&
154                 git add recurse-check-on-command-line-overriding-config &&
155                 git commit -m "Recurse on command-line overriding config junk"
156         ) &&
157         (
158                 cd work &&
159                 git add gar/bage &&
160                 git commit -m "Recurse on command-line overriding config for gar/bage" &&
161
162                 # Ensure that we can override on-demand in the config
163                 # to just check submodules
164                 test_must_fail git -c push.recurseSubmodules=on-demand push --recurse-submodules=check ../pub.git master &&
165                 # Check that the supermodule commit did not get there
166                 git fetch ../pub.git &&
167                 git diff --quiet FETCH_HEAD master^ &&
168                 # Check that the submodule commit did not get there
169                 (cd gar/bage && git diff --quiet origin/master master^) &&
170
171                 # Ensure that we can override check in the config to
172                 # disable submodule recursion entirely
173                 (cd gar/bage && git diff --quiet origin/master master^) &&
174                 git -c push.recurseSubmodules=on-demand push --recurse-submodules=no ../pub.git master &&
175                 git fetch ../pub.git &&
176                 git diff --quiet FETCH_HEAD master &&
177                 (cd gar/bage && git diff --quiet origin/master master^) &&
178
179                 # Ensure that we can override check in the config to
180                 # disable submodule recursion entirely (alternative form)
181                 git -c push.recurseSubmodules=on-demand push --no-recurse-submodules ../pub.git master &&
182                 git fetch ../pub.git &&
183                 git diff --quiet FETCH_HEAD master &&
184                 (cd gar/bage && git diff --quiet origin/master master^) &&
185
186                 # Ensure that we can override check in the config to
187                 # push the submodule too
188                 git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git master &&
189                 git fetch ../pub.git &&
190                 git diff --quiet FETCH_HEAD master &&
191                 (cd gar/bage && git diff --quiet origin/master master)
192         )
193 '
194
195 test_expect_success 'push recurse-submodules last one wins on command line' '
196         (
197                 cd work/gar/bage &&
198                 >recurse-check-on-command-line-overriding-earlier-command-line &&
199                 git add recurse-check-on-command-line-overriding-earlier-command-line &&
200                 git commit -m "Recurse on command-line overridiing earlier command-line junk"
201         ) &&
202         (
203                 cd work &&
204                 git add gar/bage &&
205                 git commit -m "Recurse on command-line overriding earlier command-line for gar/bage" &&
206
207                 # should result in "check"
208                 test_must_fail git push --recurse-submodules=on-demand --recurse-submodules=check ../pub.git master &&
209                 # Check that the supermodule commit did not get there
210                 git fetch ../pub.git &&
211                 git diff --quiet FETCH_HEAD master^ &&
212                 # Check that the submodule commit did not get there
213                 (cd gar/bage && git diff --quiet origin/master master^) &&
214
215                 # should result in "no"
216                 git push --recurse-submodules=on-demand --recurse-submodules=no ../pub.git master &&
217                 # Check that the supermodule commit did get there
218                 git fetch ../pub.git &&
219                 git diff --quiet FETCH_HEAD master &&
220                 # Check that the submodule commit did not get there
221                 (cd gar/bage && git diff --quiet origin/master master^) &&
222
223                 # should result in "no"
224                 git push --recurse-submodules=on-demand --no-recurse-submodules ../pub.git master &&
225                 # Check that the submodule commit did not get there
226                 (cd gar/bage && git diff --quiet origin/master master^) &&
227
228                 # But the options in the other order should push the submodule
229                 git push --recurse-submodules=check --recurse-submodules=on-demand ../pub.git master &&
230                 # Check that the submodule commit did get there
231                 git fetch ../pub.git &&
232                 (cd gar/bage && git diff --quiet origin/master master)
233         )
234 '
235
236 test_expect_success 'push succeeds if submodule commit not on remote using on-demand from cmdline overriding config' '
237         (
238                 cd work/gar/bage &&
239                 >recurse-on-demand-on-command-line-overriding-config &&
240                 git add recurse-on-demand-on-command-line-overriding-config &&
241                 git commit -m "Recurse on-demand on command-line overriding config junk"
242         ) &&
243         (
244                 cd work &&
245                 git add gar/bage &&
246                 git commit -m "Recurse on-demand on command-line overriding config for gar/bage" &&
247                 git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git master &&
248                 # Check that the supermodule commit got there
249                 git fetch ../pub.git &&
250                 git diff --quiet FETCH_HEAD master &&
251                 # Check that the submodule commit got there
252                 cd gar/bage &&
253                 git diff --quiet origin/master master
254         )
255 '
256
257 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline overriding config' '
258         (
259                 cd work/gar/bage &&
260                 >recurse-disable-on-command-line-overriding-config &&
261                 git add recurse-disable-on-command-line-overriding-config &&
262                 git commit -m "Recurse disable on command-line overriding config junk"
263         ) &&
264         (
265                 cd work &&
266                 git add gar/bage &&
267                 git commit -m "Recurse disable on command-line overriding config for gar/bage" &&
268                 git -c push.recurseSubmodules=check push --recurse-submodules=no ../pub.git master &&
269                 # Check that the supermodule commit got there
270                 git fetch ../pub.git &&
271                 git diff --quiet FETCH_HEAD master &&
272                 # But that the submodule commit did not
273                 ( cd gar/bage && git diff --quiet origin/master master^ ) &&
274                 # Now push it to avoid confusing future tests
275                 git push --recurse-submodules=on-demand ../pub.git master
276         )
277 '
278
279 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline (alternative form) overriding config' '
280         (
281                 cd work/gar/bage &&
282                 >recurse-disable-on-command-line-alt-overriding-config &&
283                 git add recurse-disable-on-command-line-alt-overriding-config &&
284                 git commit -m "Recurse disable on command-line alternative overriding config junk"
285         ) &&
286         (
287                 cd work &&
288                 git add gar/bage &&
289                 git commit -m "Recurse disable on command-line alternative overriding config for gar/bage" &&
290                 git -c push.recurseSubmodules=check push --no-recurse-submodules ../pub.git master &&
291                 # Check that the supermodule commit got there
292                 git fetch ../pub.git &&
293                 git diff --quiet FETCH_HEAD master &&
294                 # But that the submodule commit did not
295                 ( cd gar/bage && git diff --quiet origin/master master^ ) &&
296                 # Now push it to avoid confusing future tests
297                 git push --recurse-submodules=on-demand ../pub.git master
298         )
299 '
300
301 test_expect_success 'submodule entry pointing at a tag is error' '
302         git -C work/gar/bage tag -a test1 -m "tag" &&
303         tag=$(git -C work/gar/bage rev-parse test1^{tag}) &&
304         git -C work update-index --cacheinfo 160000 "$tag" gar/bage &&
305         git -C work commit -m "bad commit" &&
306         test_when_finished "git -C work reset --hard HEAD^" &&
307         test_must_fail git -C work push --recurse-submodules=on-demand ../pub.git master 2>err &&
308         test_i18ngrep "is a tag, not a commit" err
309 '
310
311 test_expect_success 'push fails if recurse submodules option passed as yes' '
312         (
313                 cd work/gar/bage &&
314                 >recurse-push-fails-if-recurse-submodules-passed-as-yes &&
315                 git add recurse-push-fails-if-recurse-submodules-passed-as-yes &&
316                 git commit -m "Recurse push fails if recurse submodules option passed as yes"
317         ) &&
318         (
319                 cd work &&
320                 git add gar/bage &&
321                 git commit -m "Recurse push fails if recurse submodules option passed as yes for gar/bage" &&
322                 test_must_fail git push --recurse-submodules=yes ../pub.git master &&
323                 test_must_fail git -c push.recurseSubmodules=yes push ../pub.git master &&
324                 git push --recurse-submodules=on-demand ../pub.git master
325         )
326 '
327
328 test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
329         (
330                 cd work/gar/bage &&
331                 >junk4 &&
332                 git add junk4 &&
333                 git commit -m "Fourth junk"
334         ) &&
335         (
336                 cd work &&
337                 git branch branch2 &&
338                 git add gar/bage &&
339                 git commit -m "Fourth commit for gar/bage" &&
340                 git checkout branch2 &&
341                 (
342                         cd gar/bage &&
343                         git checkout HEAD~1
344                 ) &&
345                 >junk1 &&
346                 git add junk1 &&
347                 git commit -m "First junk" &&
348                 test_must_fail git push --recurse-submodules=check ../pub.git
349         )
350 '
351
352 test_expect_success 'push succeeds if submodule has no remote and is on the first superproject commit' '
353         git init --bare a &&
354         git clone a a1 &&
355         (
356                 cd a1 &&
357                 git init b
358                 (
359                         cd b &&
360                         >junk &&
361                         git add junk &&
362                         git commit -m "initial"
363                 ) &&
364                 git add b &&
365                 git commit -m "added submodule" &&
366                 git push --recurse-submodule=check origin master
367         )
368 '
369
370 test_expect_success 'push unpushed submodules when not needed' '
371         (
372                 cd work &&
373                 (
374                         cd gar/bage &&
375                         git checkout master &&
376                         >junk5 &&
377                         git add junk5 &&
378                         git commit -m "Fifth junk" &&
379                         git push &&
380                         git rev-parse origin/master >../../../expected
381                 ) &&
382                 git checkout master &&
383                 git add gar/bage &&
384                 git commit -m "Fifth commit for gar/bage" &&
385                 git push --recurse-submodules=on-demand ../pub.git master
386         ) &&
387         (
388                 cd submodule.git &&
389                 git rev-parse master >../actual
390         ) &&
391         test_cmp expected actual
392 '
393
394 test_expect_success 'push unpushed submodules when not needed 2' '
395         (
396                 cd submodule.git &&
397                 git rev-parse master >../expected
398         ) &&
399         (
400                 cd work &&
401                 (
402                         cd gar/bage &&
403                         >junk6 &&
404                         git add junk6 &&
405                         git commit -m "Sixth junk"
406                 ) &&
407                 >junk2 &&
408                 git add junk2 &&
409                 git commit -m "Second junk for work" &&
410                 git push --recurse-submodules=on-demand ../pub.git master
411         ) &&
412         (
413                 cd submodule.git &&
414                 git rev-parse master >../actual
415         ) &&
416         test_cmp expected actual
417 '
418
419 test_expect_success 'push unpushed submodules recursively' '
420         (
421                 cd work &&
422                 (
423                         cd gar/bage &&
424                         git checkout master &&
425                         > junk7 &&
426                         git add junk7 &&
427                         git commit -m "Seventh junk" &&
428                         git rev-parse master >../../../expected
429                 ) &&
430                 git checkout master &&
431                 git add gar/bage &&
432                 git commit -m "Seventh commit for gar/bage" &&
433                 git push --recurse-submodules=on-demand ../pub.git master
434         ) &&
435         (
436                 cd submodule.git &&
437                 git rev-parse master >../actual
438         ) &&
439         test_cmp expected actual
440 '
441
442 test_expect_success 'push unpushable submodule recursively fails' '
443         (
444                 cd work &&
445                 (
446                         cd gar/bage &&
447                         git rev-parse origin/master >../../../expected &&
448                         git checkout master~0 &&
449                         > junk8 &&
450                         git add junk8 &&
451                         git commit -m "Eighth junk"
452                 ) &&
453                 git add gar/bage &&
454                 git commit -m "Eighth commit for gar/bage" &&
455                 test_must_fail git push --recurse-submodules=on-demand ../pub.git master
456         ) &&
457         (
458                 cd submodule.git &&
459                 git rev-parse master >../actual
460         ) &&
461         test_when_finished git -C work reset --hard master^ &&
462         test_cmp expected actual
463 '
464
465 test_expect_success 'push --dry-run does not recursively update submodules' '
466         (
467                 cd work/gar/bage &&
468                 git checkout master &&
469                 git rev-parse master >../../../expected_submodule &&
470                 > junk9 &&
471                 git add junk9 &&
472                 git commit -m "Ninth junk" &&
473
474                 # Go up to 'work' directory
475                 cd ../.. &&
476                 git checkout master &&
477                 git rev-parse master >../expected_pub &&
478                 git add gar/bage &&
479                 git commit -m "Ninth commit for gar/bage" &&
480                 git push --dry-run --recurse-submodules=on-demand ../pub.git master
481         ) &&
482         git -C submodule.git rev-parse master >actual_submodule &&
483         git -C pub.git rev-parse master >actual_pub &&
484         test_cmp expected_pub actual_pub &&
485         test_cmp expected_submodule actual_submodule
486 '
487
488 test_expect_success 'push --dry-run does not recursively update submodules' '
489         git -C work push --dry-run --recurse-submodules=only ../pub.git master &&
490
491         git -C submodule.git rev-parse master >actual_submodule &&
492         git -C pub.git rev-parse master >actual_pub &&
493         test_cmp expected_pub actual_pub &&
494         test_cmp expected_submodule actual_submodule
495 '
496
497 test_expect_success 'push only unpushed submodules recursively' '
498         git -C work/gar/bage rev-parse master >expected_submodule &&
499         git -C pub.git rev-parse master >expected_pub &&
500
501         git -C work push --recurse-submodules=only ../pub.git master &&
502
503         git -C submodule.git rev-parse master >actual_submodule &&
504         git -C pub.git rev-parse master >actual_pub &&
505         test_cmp expected_submodule actual_submodule &&
506         test_cmp expected_pub actual_pub
507 '
508
509 test_expect_success 'push propagating the remotes name to a submodule' '
510         git -C work remote add origin ../pub.git &&
511         git -C work remote add pub ../pub.git &&
512
513         > work/gar/bage/junk10 &&
514         git -C work/gar/bage add junk10 &&
515         git -C work/gar/bage commit -m "Tenth junk" &&
516         git -C work add gar/bage &&
517         git -C work commit -m "Tenth junk added to gar/bage" &&
518
519         # Fails when submodule does not have a matching remote
520         test_must_fail git -C work push --recurse-submodules=on-demand pub master &&
521         # Succeeds when submodules has matching remote and refspec
522         git -C work push --recurse-submodules=on-demand origin master &&
523
524         git -C submodule.git rev-parse master >actual_submodule &&
525         git -C pub.git rev-parse master >actual_pub &&
526         git -C work/gar/bage rev-parse master >expected_submodule &&
527         git -C work rev-parse master >expected_pub &&
528         test_cmp expected_submodule actual_submodule &&
529         test_cmp expected_pub actual_pub
530 '
531
532 test_expect_success 'push propagating refspec to a submodule' '
533         > work/gar/bage/junk11 &&
534         git -C work/gar/bage add junk11 &&
535         git -C work/gar/bage commit -m "Eleventh junk" &&
536
537         git -C work checkout branch2 &&
538         git -C work add gar/bage &&
539         git -C work commit -m "updating gar/bage in branch2" &&
540
541         # Fails when submodule does not have a matching branch
542         test_must_fail git -C work push --recurse-submodules=on-demand origin branch2 &&
543         # Fails when refspec includes an object id
544         test_must_fail git -C work push --recurse-submodules=on-demand origin \
545                 "$(git -C work rev-parse branch2):refs/heads/branch2" &&
546         # Fails when refspec includes HEAD and parent and submodule do not
547         # have the same named branch checked out
548         test_must_fail git -C work push --recurse-submodules=on-demand origin \
549                 HEAD:refs/heads/branch2 &&
550
551         git -C work/gar/bage branch branch2 master &&
552         git -C work push --recurse-submodules=on-demand origin branch2 &&
553
554         git -C submodule.git rev-parse branch2 >actual_submodule &&
555         git -C pub.git rev-parse branch2 >actual_pub &&
556         git -C work/gar/bage rev-parse branch2 >expected_submodule &&
557         git -C work rev-parse branch2 >expected_pub &&
558         test_cmp expected_submodule actual_submodule &&
559         test_cmp expected_pub actual_pub
560 '
561
562 test_expect_success 'push propagating HEAD refspec to a submodule' '
563         git -C work/gar/bage checkout branch2 &&
564         > work/gar/bage/junk12 &&
565         git -C work/gar/bage add junk12 &&
566         git -C work/gar/bage commit -m "Twelfth junk" &&
567
568         git -C work checkout branch2 &&
569         git -C work add gar/bage &&
570         git -C work commit -m "updating gar/bage in branch2" &&
571
572         # Passes since the superproject and submodules HEAD are both on branch2
573         git -C work push --recurse-submodules=on-demand origin \
574                 HEAD:refs/heads/branch2 &&
575
576         git -C submodule.git rev-parse branch2 >actual_submodule &&
577         git -C pub.git rev-parse branch2 >actual_pub &&
578         git -C work/gar/bage rev-parse branch2 >expected_submodule &&
579         git -C work rev-parse branch2 >expected_pub &&
580         test_cmp expected_submodule actual_submodule &&
581         test_cmp expected_pub actual_pub
582 '
583
584 test_done