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