Merge branch 'jk/gc-pre-detach-under-hook' into maint
[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 recurse-submodules on command line overrides config' '
130         (
131                 cd work/gar/bage &&
132                 >recurse-check-on-command-line-overriding-config &&
133                 git add recurse-check-on-command-line-overriding-config &&
134                 git commit -m "Recurse on command-line overriding config junk"
135         ) &&
136         (
137                 cd work &&
138                 git add gar/bage &&
139                 git commit -m "Recurse on command-line overriding config for gar/bage" &&
140
141                 # Ensure that we can override on-demand in the config
142                 # to just check submodules
143                 test_must_fail git -c push.recurseSubmodules=on-demand push --recurse-submodules=check ../pub.git master &&
144                 # Check that the supermodule commit did not get there
145                 git fetch ../pub.git &&
146                 git diff --quiet FETCH_HEAD master^ &&
147                 # Check that the submodule commit did not get there
148                 (cd gar/bage && git diff --quiet origin/master master^) &&
149
150                 # Ensure that we can override check in the config to
151                 # disable submodule recursion entirely
152                 (cd gar/bage && git diff --quiet origin/master master^) &&
153                 git -c push.recurseSubmodules=on-demand push --recurse-submodules=no ../pub.git master &&
154                 git fetch ../pub.git &&
155                 git diff --quiet FETCH_HEAD master &&
156                 (cd gar/bage && git diff --quiet origin/master master^) &&
157
158                 # Ensure that we can override check in the config to
159                 # disable submodule recursion entirely (alternative form)
160                 git -c push.recurseSubmodules=on-demand push --no-recurse-submodules ../pub.git master &&
161                 git fetch ../pub.git &&
162                 git diff --quiet FETCH_HEAD master &&
163                 (cd gar/bage && git diff --quiet origin/master master^) &&
164
165                 # Ensure that we can override check in the config to
166                 # push the submodule too
167                 git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git master &&
168                 git fetch ../pub.git &&
169                 git diff --quiet FETCH_HEAD master &&
170                 (cd gar/bage && git diff --quiet origin/master master)
171         )
172 '
173
174 test_expect_success 'push recurse-submodules last one wins on command line' '
175         (
176                 cd work/gar/bage &&
177                 >recurse-check-on-command-line-overriding-earlier-command-line &&
178                 git add recurse-check-on-command-line-overriding-earlier-command-line &&
179                 git commit -m "Recurse on command-line overridiing earlier command-line junk"
180         ) &&
181         (
182                 cd work &&
183                 git add gar/bage &&
184                 git commit -m "Recurse on command-line overriding earlier command-line for gar/bage" &&
185
186                 # should result in "check"
187                 test_must_fail git push --recurse-submodules=on-demand --recurse-submodules=check ../pub.git master &&
188                 # Check that the supermodule commit did not get there
189                 git fetch ../pub.git &&
190                 git diff --quiet FETCH_HEAD master^ &&
191                 # Check that the submodule commit did not get there
192                 (cd gar/bage && git diff --quiet origin/master master^) &&
193
194                 # should result in "no"
195                 git push --recurse-submodules=on-demand --recurse-submodules=no ../pub.git master &&
196                 # Check that the supermodule commit did get there
197                 git fetch ../pub.git &&
198                 git diff --quiet FETCH_HEAD master &&
199                 # Check that the submodule commit did not get there
200                 (cd gar/bage && git diff --quiet origin/master master^) &&
201
202                 # should result in "no"
203                 git push --recurse-submodules=on-demand --no-recurse-submodules ../pub.git master &&
204                 # Check that the submodule commit did not get there
205                 (cd gar/bage && git diff --quiet origin/master master^) &&
206
207                 # But the options in the other order should push the submodule
208                 git push --recurse-submodules=check --recurse-submodules=on-demand ../pub.git master &&
209                 # Check that the submodule commit did get there
210                 git fetch ../pub.git &&
211                 (cd gar/bage && git diff --quiet origin/master master)
212         )
213 '
214
215 test_expect_success 'push succeeds if submodule commit not on remote using on-demand from cmdline overriding config' '
216         (
217                 cd work/gar/bage &&
218                 >recurse-on-demand-on-command-line-overriding-config &&
219                 git add recurse-on-demand-on-command-line-overriding-config &&
220                 git commit -m "Recurse on-demand on command-line overriding config junk"
221         ) &&
222         (
223                 cd work &&
224                 git add gar/bage &&
225                 git commit -m "Recurse on-demand on command-line overriding config for gar/bage" &&
226                 git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git master &&
227                 # Check that the supermodule commit got there
228                 git fetch ../pub.git &&
229                 git diff --quiet FETCH_HEAD master &&
230                 # Check that the submodule commit got there
231                 cd gar/bage &&
232                 git diff --quiet origin/master master
233         )
234 '
235
236 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline overriding config' '
237         (
238                 cd work/gar/bage &&
239                 >recurse-disable-on-command-line-overriding-config &&
240                 git add recurse-disable-on-command-line-overriding-config &&
241                 git commit -m "Recurse disable on command-line overriding config junk"
242         ) &&
243         (
244                 cd work &&
245                 git add gar/bage &&
246                 git commit -m "Recurse disable on command-line overriding config for gar/bage" &&
247                 git -c push.recurseSubmodules=check push --recurse-submodules=no ../pub.git master &&
248                 # Check that the supermodule commit got there
249                 git fetch ../pub.git &&
250                 git diff --quiet FETCH_HEAD master &&
251                 # But that the submodule commit did not
252                 ( cd gar/bage && git diff --quiet origin/master master^ ) &&
253                 # Now push it to avoid confusing future tests
254                 git push --recurse-submodules=on-demand ../pub.git master
255         )
256 '
257
258 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline (alternative form) overriding config' '
259         (
260                 cd work/gar/bage &&
261                 >recurse-disable-on-command-line-alt-overriding-config &&
262                 git add recurse-disable-on-command-line-alt-overriding-config &&
263                 git commit -m "Recurse disable on command-line alternative overriding config junk"
264         ) &&
265         (
266                 cd work &&
267                 git add gar/bage &&
268                 git commit -m "Recurse disable on command-line alternative overriding config for gar/bage" &&
269                 git -c push.recurseSubmodules=check push --no-recurse-submodules ../pub.git master &&
270                 # Check that the supermodule commit got there
271                 git fetch ../pub.git &&
272                 git diff --quiet FETCH_HEAD master &&
273                 # But that the submodule commit did not
274                 ( cd gar/bage && git diff --quiet origin/master master^ ) &&
275                 # Now push it to avoid confusing future tests
276                 git push --recurse-submodules=on-demand ../pub.git master
277         )
278 '
279
280 test_expect_success 'push fails if recurse submodules option passed as yes' '
281         (
282                 cd work/gar/bage &&
283                 >recurse-push-fails-if-recurse-submodules-passed-as-yes &&
284                 git add recurse-push-fails-if-recurse-submodules-passed-as-yes &&
285                 git commit -m "Recurse push fails if recurse submodules option passed as yes"
286         ) &&
287         (
288                 cd work &&
289                 git add gar/bage &&
290                 git commit -m "Recurse push fails if recurse submodules option passed as yes for gar/bage" &&
291                 test_must_fail git push --recurse-submodules=yes ../pub.git master &&
292                 test_must_fail git -c push.recurseSubmodules=yes push ../pub.git master &&
293                 git push --recurse-submodules=on-demand ../pub.git master
294         )
295 '
296
297 test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
298         (
299                 cd work/gar/bage &&
300                 >junk4 &&
301                 git add junk4 &&
302                 git commit -m "Fourth junk"
303         ) &&
304         (
305                 cd work &&
306                 git branch branch2 &&
307                 git add gar/bage &&
308                 git commit -m "Fourth commit for gar/bage" &&
309                 git checkout branch2 &&
310                 (
311                         cd gar/bage &&
312                         git checkout HEAD~1
313                 ) &&
314                 >junk1 &&
315                 git add junk1 &&
316                 git commit -m "First junk" &&
317                 test_must_fail git push --recurse-submodules=check ../pub.git
318         )
319 '
320
321 test_expect_success 'push succeeds if submodule has no remote and is on the first superproject commit' '
322         git init --bare a &&
323         git clone a a1 &&
324         (
325                 cd a1 &&
326                 git init b
327                 (
328                         cd b &&
329                         >junk &&
330                         git add junk &&
331                         git commit -m "initial"
332                 ) &&
333                 git add b &&
334                 git commit -m "added submodule" &&
335                 git push --recurse-submodule=check origin master
336         )
337 '
338
339 test_expect_success 'push unpushed submodules when not needed' '
340         (
341                 cd work &&
342                 (
343                         cd gar/bage &&
344                         git checkout master &&
345                         >junk5 &&
346                         git add junk5 &&
347                         git commit -m "Fifth junk" &&
348                         git push &&
349                         git rev-parse origin/master >../../../expected
350                 ) &&
351                 git checkout master &&
352                 git add gar/bage &&
353                 git commit -m "Fifth commit for gar/bage" &&
354                 git push --recurse-submodules=on-demand ../pub.git master
355         ) &&
356         (
357                 cd submodule.git &&
358                 git rev-parse master >../actual
359         ) &&
360         test_cmp expected actual
361 '
362
363 test_expect_success 'push unpushed submodules when not needed 2' '
364         (
365                 cd submodule.git &&
366                 git rev-parse master >../expected
367         ) &&
368         (
369                 cd work &&
370                 (
371                         cd gar/bage &&
372                         >junk6 &&
373                         git add junk6 &&
374                         git commit -m "Sixth junk"
375                 ) &&
376                 >junk2 &&
377                 git add junk2 &&
378                 git commit -m "Second junk for work" &&
379                 git push --recurse-submodules=on-demand ../pub.git master
380         ) &&
381         (
382                 cd submodule.git &&
383                 git rev-parse master >../actual
384         ) &&
385         test_cmp expected actual
386 '
387
388 test_expect_success 'push unpushed submodules recursively' '
389         (
390                 cd work &&
391                 (
392                         cd gar/bage &&
393                         git checkout master &&
394                         > junk7 &&
395                         git add junk7 &&
396                         git commit -m "Seventh junk" &&
397                         git rev-parse master >../../../expected
398                 ) &&
399                 git checkout master &&
400                 git add gar/bage &&
401                 git commit -m "Seventh commit for gar/bage" &&
402                 git push --recurse-submodules=on-demand ../pub.git master
403         ) &&
404         (
405                 cd submodule.git &&
406                 git rev-parse master >../actual
407         ) &&
408         test_cmp expected actual
409 '
410
411 test_expect_success 'push unpushable submodule recursively fails' '
412         (
413                 cd work &&
414                 (
415                         cd gar/bage &&
416                         git rev-parse origin/master >../../../expected &&
417                         git checkout master~0 &&
418                         > junk8 &&
419                         git add junk8 &&
420                         git commit -m "Eighth junk"
421                 ) &&
422                 git add gar/bage &&
423                 git commit -m "Eighth commit for gar/bage" &&
424                 test_must_fail git push --recurse-submodules=on-demand ../pub.git master
425         ) &&
426         (
427                 cd submodule.git &&
428                 git rev-parse master >../actual
429         ) &&
430         test_when_finished git -C work reset --hard master^ &&
431         test_cmp expected actual
432 '
433
434 test_expect_success 'push --dry-run does not recursively update submodules' '
435         (
436                 cd work/gar/bage &&
437                 git checkout master &&
438                 git rev-parse master >../../../expected_submodule &&
439                 > junk9 &&
440                 git add junk9 &&
441                 git commit -m "Ninth junk" &&
442
443                 # Go up to 'work' directory
444                 cd ../.. &&
445                 git checkout master &&
446                 git rev-parse master >../expected_pub &&
447                 git add gar/bage &&
448                 git commit -m "Ninth commit for gar/bage" &&
449                 git push --dry-run --recurse-submodules=on-demand ../pub.git master
450         ) &&
451         git -C submodule.git rev-parse master >actual_submodule &&
452         git -C pub.git rev-parse master >actual_pub &&
453         test_cmp expected_pub actual_pub &&
454         test_cmp expected_submodule actual_submodule
455 '
456
457 test_expect_success 'push --dry-run does not recursively update submodules' '
458         git -C work push --dry-run --recurse-submodules=only ../pub.git master &&
459
460         git -C submodule.git rev-parse master >actual_submodule &&
461         git -C pub.git rev-parse master >actual_pub &&
462         test_cmp expected_pub actual_pub &&
463         test_cmp expected_submodule actual_submodule
464 '
465
466 test_expect_success 'push only unpushed submodules recursively' '
467         git -C work/gar/bage rev-parse master >expected_submodule &&
468         git -C pub.git rev-parse master >expected_pub &&
469
470         git -C work push --recurse-submodules=only ../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_submodule actual_submodule &&
475         test_cmp expected_pub actual_pub
476 '
477
478 test_expect_success 'push propagating the remotes name to a submodule' '
479         git -C work remote add origin ../pub.git &&
480         git -C work remote add pub ../pub.git &&
481
482         > work/gar/bage/junk10 &&
483         git -C work/gar/bage add junk10 &&
484         git -C work/gar/bage commit -m "Tenth junk" &&
485         git -C work add gar/bage &&
486         git -C work commit -m "Tenth junk added to gar/bage" &&
487
488         # Fails when submodule does not have a matching remote
489         test_must_fail git -C work push --recurse-submodules=on-demand pub master &&
490         # Succeeds when submodules has matching remote and refspec
491         git -C work push --recurse-submodules=on-demand origin master &&
492
493         git -C submodule.git rev-parse master >actual_submodule &&
494         git -C pub.git rev-parse master >actual_pub &&
495         git -C work/gar/bage rev-parse master >expected_submodule &&
496         git -C work rev-parse master >expected_pub &&
497         test_cmp expected_submodule actual_submodule &&
498         test_cmp expected_pub actual_pub
499 '
500
501 test_expect_success 'push propagating refspec to a submodule' '
502         > work/gar/bage/junk11 &&
503         git -C work/gar/bage add junk11 &&
504         git -C work/gar/bage commit -m "Eleventh junk" &&
505
506         git -C work checkout branch2 &&
507         git -C work add gar/bage &&
508         git -C work commit -m "updating gar/bage in branch2" &&
509
510         # Fails when submodule does not have a matching branch
511         test_must_fail git -C work push --recurse-submodules=on-demand origin branch2 &&
512         # Fails when refspec includes an object id
513         test_must_fail git -C work push --recurse-submodules=on-demand origin \
514                 "$(git -C work rev-parse branch2):refs/heads/branch2" &&
515         # Fails when refspec includes 'HEAD' as it is unsupported at this time
516         test_must_fail git -C work push --recurse-submodules=on-demand origin \
517                 HEAD:refs/heads/branch2 &&
518
519         git -C work/gar/bage branch branch2 master &&
520         git -C work push --recurse-submodules=on-demand origin branch2 &&
521
522         git -C submodule.git rev-parse branch2 >actual_submodule &&
523         git -C pub.git rev-parse branch2 >actual_pub &&
524         git -C work/gar/bage rev-parse branch2 >expected_submodule &&
525         git -C work rev-parse branch2 >expected_pub &&
526         test_cmp expected_submodule actual_submodule &&
527         test_cmp expected_pub actual_pub
528 '
529
530 test_done