Merge branch 'rs/wt-status-cleanup'
[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 'push fails if recurse submodules option passed as yes' '
302         (
303                 cd work/gar/bage &&
304                 >recurse-push-fails-if-recurse-submodules-passed-as-yes &&
305                 git add recurse-push-fails-if-recurse-submodules-passed-as-yes &&
306                 git commit -m "Recurse push fails if recurse submodules option passed as yes"
307         ) &&
308         (
309                 cd work &&
310                 git add gar/bage &&
311                 git commit -m "Recurse push fails if recurse submodules option passed as yes for gar/bage" &&
312                 test_must_fail git push --recurse-submodules=yes ../pub.git master &&
313                 test_must_fail git -c push.recurseSubmodules=yes push ../pub.git master &&
314                 git push --recurse-submodules=on-demand ../pub.git master
315         )
316 '
317
318 test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
319         (
320                 cd work/gar/bage &&
321                 >junk4 &&
322                 git add junk4 &&
323                 git commit -m "Fourth junk"
324         ) &&
325         (
326                 cd work &&
327                 git branch branch2 &&
328                 git add gar/bage &&
329                 git commit -m "Fourth commit for gar/bage" &&
330                 git checkout branch2 &&
331                 (
332                         cd gar/bage &&
333                         git checkout HEAD~1
334                 ) &&
335                 >junk1 &&
336                 git add junk1 &&
337                 git commit -m "First junk" &&
338                 test_must_fail git push --recurse-submodules=check ../pub.git
339         )
340 '
341
342 test_expect_success 'push succeeds if submodule has no remote and is on the first superproject commit' '
343         git init --bare a &&
344         git clone a a1 &&
345         (
346                 cd a1 &&
347                 git init b
348                 (
349                         cd b &&
350                         >junk &&
351                         git add junk &&
352                         git commit -m "initial"
353                 ) &&
354                 git add b &&
355                 git commit -m "added submodule" &&
356                 git push --recurse-submodule=check origin master
357         )
358 '
359
360 test_expect_success 'push unpushed submodules when not needed' '
361         (
362                 cd work &&
363                 (
364                         cd gar/bage &&
365                         git checkout master &&
366                         >junk5 &&
367                         git add junk5 &&
368                         git commit -m "Fifth junk" &&
369                         git push &&
370                         git rev-parse origin/master >../../../expected
371                 ) &&
372                 git checkout master &&
373                 git add gar/bage &&
374                 git commit -m "Fifth commit for gar/bage" &&
375                 git push --recurse-submodules=on-demand ../pub.git master
376         ) &&
377         (
378                 cd submodule.git &&
379                 git rev-parse master >../actual
380         ) &&
381         test_cmp expected actual
382 '
383
384 test_expect_success 'push unpushed submodules when not needed 2' '
385         (
386                 cd submodule.git &&
387                 git rev-parse master >../expected
388         ) &&
389         (
390                 cd work &&
391                 (
392                         cd gar/bage &&
393                         >junk6 &&
394                         git add junk6 &&
395                         git commit -m "Sixth junk"
396                 ) &&
397                 >junk2 &&
398                 git add junk2 &&
399                 git commit -m "Second junk for work" &&
400                 git push --recurse-submodules=on-demand ../pub.git master
401         ) &&
402         (
403                 cd submodule.git &&
404                 git rev-parse master >../actual
405         ) &&
406         test_cmp expected actual
407 '
408
409 test_expect_success 'push unpushed submodules recursively' '
410         (
411                 cd work &&
412                 (
413                         cd gar/bage &&
414                         git checkout master &&
415                         > junk7 &&
416                         git add junk7 &&
417                         git commit -m "Seventh junk" &&
418                         git rev-parse master >../../../expected
419                 ) &&
420                 git checkout master &&
421                 git add gar/bage &&
422                 git commit -m "Seventh commit for gar/bage" &&
423                 git push --recurse-submodules=on-demand ../pub.git master
424         ) &&
425         (
426                 cd submodule.git &&
427                 git rev-parse master >../actual
428         ) &&
429         test_cmp expected actual
430 '
431
432 test_expect_success 'push unpushable submodule recursively fails' '
433         (
434                 cd work &&
435                 (
436                         cd gar/bage &&
437                         git rev-parse origin/master >../../../expected &&
438                         git checkout master~0 &&
439                         > junk8 &&
440                         git add junk8 &&
441                         git commit -m "Eighth junk"
442                 ) &&
443                 git add gar/bage &&
444                 git commit -m "Eighth commit for gar/bage" &&
445                 test_must_fail git push --recurse-submodules=on-demand ../pub.git master
446         ) &&
447         (
448                 cd submodule.git &&
449                 git rev-parse master >../actual
450         ) &&
451         test_when_finished git -C work reset --hard master^ &&
452         test_cmp expected actual
453 '
454
455 test_expect_success 'push --dry-run does not recursively update submodules' '
456         (
457                 cd work/gar/bage &&
458                 git checkout master &&
459                 git rev-parse master >../../../expected_submodule &&
460                 > junk9 &&
461                 git add junk9 &&
462                 git commit -m "Ninth junk" &&
463
464                 # Go up to 'work' directory
465                 cd ../.. &&
466                 git checkout master &&
467                 git rev-parse master >../expected_pub &&
468                 git add gar/bage &&
469                 git commit -m "Ninth commit for gar/bage" &&
470                 git push --dry-run --recurse-submodules=on-demand ../pub.git master
471         ) &&
472         git -C submodule.git rev-parse master >actual_submodule &&
473         git -C pub.git rev-parse master >actual_pub &&
474         test_cmp expected_pub actual_pub &&
475         test_cmp expected_submodule actual_submodule
476 '
477
478 test_expect_success 'push --dry-run does not recursively update submodules' '
479         git -C work push --dry-run --recurse-submodules=only ../pub.git master &&
480
481         git -C submodule.git rev-parse master >actual_submodule &&
482         git -C pub.git rev-parse master >actual_pub &&
483         test_cmp expected_pub actual_pub &&
484         test_cmp expected_submodule actual_submodule
485 '
486
487 test_expect_success 'push only unpushed submodules recursively' '
488         git -C work/gar/bage rev-parse master >expected_submodule &&
489         git -C pub.git rev-parse master >expected_pub &&
490
491         git -C work push --recurse-submodules=only ../pub.git master &&
492
493         git -C submodule.git rev-parse master >actual_submodule &&
494         git -C pub.git rev-parse master >actual_pub &&
495         test_cmp expected_submodule actual_submodule &&
496         test_cmp expected_pub actual_pub
497 '
498
499 test_expect_success 'push propagating the remotes name to a submodule' '
500         git -C work remote add origin ../pub.git &&
501         git -C work remote add pub ../pub.git &&
502
503         > work/gar/bage/junk10 &&
504         git -C work/gar/bage add junk10 &&
505         git -C work/gar/bage commit -m "Tenth junk" &&
506         git -C work add gar/bage &&
507         git -C work commit -m "Tenth junk added to gar/bage" &&
508
509         # Fails when submodule does not have a matching remote
510         test_must_fail git -C work push --recurse-submodules=on-demand pub master &&
511         # Succeeds when submodules has matching remote and refspec
512         git -C work push --recurse-submodules=on-demand origin master &&
513
514         git -C submodule.git rev-parse master >actual_submodule &&
515         git -C pub.git rev-parse master >actual_pub &&
516         git -C work/gar/bage rev-parse master >expected_submodule &&
517         git -C work rev-parse master >expected_pub &&
518         test_cmp expected_submodule actual_submodule &&
519         test_cmp expected_pub actual_pub
520 '
521
522 test_expect_success 'push propagating refspec to a submodule' '
523         > work/gar/bage/junk11 &&
524         git -C work/gar/bage add junk11 &&
525         git -C work/gar/bage commit -m "Eleventh junk" &&
526
527         git -C work checkout branch2 &&
528         git -C work add gar/bage &&
529         git -C work commit -m "updating gar/bage in branch2" &&
530
531         # Fails when submodule does not have a matching branch
532         test_must_fail git -C work push --recurse-submodules=on-demand origin branch2 &&
533         # Fails when refspec includes an object id
534         test_must_fail git -C work push --recurse-submodules=on-demand origin \
535                 "$(git -C work rev-parse branch2):refs/heads/branch2" &&
536         # Fails when refspec includes 'HEAD' as it is unsupported at this time
537         test_must_fail git -C work push --recurse-submodules=on-demand origin \
538                 HEAD:refs/heads/branch2 &&
539
540         git -C work/gar/bage branch branch2 master &&
541         git -C work push --recurse-submodules=on-demand origin branch2 &&
542
543         git -C submodule.git rev-parse branch2 >actual_submodule &&
544         git -C pub.git rev-parse branch2 >actual_pub &&
545         git -C work/gar/bage rev-parse branch2 >expected_submodule &&
546         git -C work rev-parse branch2 >expected_pub &&
547         test_cmp expected_submodule actual_submodule &&
548         test_cmp expected_pub actual_pub
549 '
550
551 test_done