1
+# Create a submodule layout used for all tests below.
2
+#
3
+# The following use cases are covered:
4
+# - New submodule (no_submodule => add_sub1)
5
+# - Removed submodule (add_sub1 => remove_sub1)
6
+# - Updated submodule (add_sub1 => modify_sub1)
7
+# - Submodule updated to invalid commit (add_sub1 => invalid_sub1)
8
+# - Submodule updated from invalid commit (invalid_sub1 => valid_sub1)
9
+# - Submodule replaced by tracked files in directory (add_sub1 =>
10
+# replace_sub1_with_directory)
11
+# - Directory containing tracked files replaced by submodule
12
+# (replace_sub1_with_directory => replace_directory_with_sub1)
13
+# - Submodule replaced by tracked file with the same name (add_sub1 =>
14
+# replace_sub1_with_file)
15
+# - Tracked file replaced by submodule (replace_sub1_with_file =>
16
+# replace_file_with_sub1)
17
+#
18
+# --O-----O
19
+# / ^ replace_directory_with_sub1
20
+# / replace_sub1_with_directory
21
+# /----O
22
+# / ^
23
+# / modify_sub1
24
+# O------O-------O
25
+# ^ ^\ ^
26
+# | | \ remove_sub1
27
+# | | -----O-----O
28
+# | | \ ^ replace_file_with_sub1
29
+# | | \ replace_sub1_with_file
30
+# | add_sub1 --O-----O
31
+# no_submodule ^ valid_sub1
32
+# invalid_sub1
33
+#
34
+create_lib_submodule_repo () {
35
+ git init submodule_update_repo &&
36
+ (
37
+ cd submodule_update_repo &&
38
+ echo "expect" >>.gitignore &&
39
+ echo "actual" >>.gitignore &&
40
+ echo "x" >file1 &&
41
+ echo "y" >file2 &&
42
+ git add .gitignore file1 file2 &&
43
+ git commit -m "Base" &&
44
+ git branch "no_submodule" &&
45
+
46
+ git checkout -b "add_sub1" &&
47
+ git submodule add ./. sub1 &&
48
+ git config -f .gitmodules submodule.sub1.ignore all &&
49
+ git config submodule.sub1.ignore all &&
50
+ git add .gitmodules &&
51
+ git commit -m "Add sub1" &&
52
+ git checkout -b remove_sub1 &&
53
+ git revert HEAD &&
54
+
55
+ git checkout -b "modify_sub1" "add_sub1" &&
56
+ git submodule update &&
57
+ (
58
+ cd sub1 &&
59
+ git fetch &&
60
+ git checkout -b "modifications" &&
61
+ echo "z" >file2 &&
62
+ echo "x" >file3 &&
63
+ git add file2 file3 &&
64
+ git commit -m "modified file2 and added file3" &&
65
+ git push origin modifications
66
+ ) &&
67
+ git add sub1 &&
68
+ git commit -m "Modify sub1" &&
69
+
70
+ git checkout -b "replace_sub1_with_directory" "add_sub1" &&
71
+ git submodule update &&
72
+ (
73
+ cd sub1 &&
74
+ git checkout modifications
75
+ ) &&
76
+ git rm --cached sub1 &&
77
+ rm sub1/.git* &&
78
+ git config -f .gitmodules --remove-section "submodule.sub1" &&
79
+ git add .gitmodules sub1/* &&
80
+ git commit -m "Replace sub1 with directory" &&
81
+ git checkout -b replace_directory_with_sub1 &&
82
+ git revert HEAD &&
83
+
84
+ git checkout -b "replace_sub1_with_file" "add_sub1" &&
85
+ git rm sub1 &&
86
+ echo "content" >sub1 &&
87
+ git add sub1 &&
88
+ git commit -m "Replace sub1 with file" &&
89
+ git checkout -b replace_file_with_sub1 &&
90
+ git revert HEAD &&
91
+
92
+ git checkout -b "invalid_sub1" "add_sub1" &&
93
+ git update-index --cacheinfo 160000 0123456789012345678901234567890123456789 sub1 &&
94
+ git commit -m "Invalid sub1 commit" &&
95
+ git checkout -b valid_sub1 &&
96
+ git revert HEAD &&
97
+ git checkout master
98
+ )
99
+}
100
+
101
+# Helper function to replace gitfile with .git directory
102
+replace_gitfile_with_git_dir () {
103
+ (
104
+ cd "$1" &&
105
+ git_dir="$(git rev-parse --git-dir)" &&
106
+ rm -f .git &&
107
+ cp -R "$git_dir" .git &&
108
+ GIT_WORK_TREE=. git config --unset core.worktree
109
+ )
110
+}
111
+
112
+# Test that the .git directory in the submodule is unchanged (except for the
113
+# core.worktree setting, which appears only in $GIT_DIR/modules/$1/config).
114
+# Call this function before test_submodule_content as the latter might
115
+# write the index file leading to false positive index differences.
116
+#
117
+# Note that this only supports submodules at the root level of the
118
+# superproject, with the default name, i.e. same as its path.
119
+test_git_directory_is_unchanged () {
120
+ (
121
+ cd ".git/modules/$1" &&
122
+ # does core.worktree point at the right place?
123
+ test "$(git config core.worktree)" = "../../../$1" &&
124
+ # remove it temporarily before comparing, as
125
+ # "$1/.git/config" lacks it...
126
+ git config --unset core.worktree
127
+ ) &&
128
+ diff -r ".git/modules/$1" "$1/.git" &&
129
+ (
130
+ # ... and then restore.
131
+ cd ".git/modules/$1" &&
132
+ git config core.worktree "../../../$1"
133
+ )
134
+}
135
+
136
+# Helper function to be executed at the start of every test below, it sets up
137
+# the submodule repo if it doesn't exist and configures the most problematic
138
+# settings for diff.ignoreSubmodules.
139
+prolog () {
140
+ (test -d submodule_update_repo || create_lib_submodule_repo) &&
141
+ test_config_global diff.ignoreSubmodules all &&
142
+ test_config diff.ignoreSubmodules all
143
+}
144
+
145
+# Helper function to bring work tree back into the state given by the
146
+# commit. This includes trying to populate sub1 accordingly if it exists and
147
+# should be updated to an existing commit.
148
+reset_work_tree_to () {
149
+ rm -rf submodule_update &&
150
+ git clone submodule_update_repo submodule_update &&
151
+ (
152
+ cd submodule_update &&
153
+ rm -rf sub1 &&
154
+ git checkout -f "$1" &&
155
+ git status -u -s >actual &&
156
+ test_must_be_empty actual &&
157
+ sha1=$(git rev-parse --revs-only HEAD:sub1) &&
158
+ if test -n "$sha1" &&
159
+ test $(cd "sub1" && git rev-parse --verify "$sha1^{commit}")
160
+ then
161
+ git submodule update --init --recursive "sub1"
162
+ fi
163
+ )
164
+}
165
+
166
+# Test that the superproject contains the content according to commit "$1"
167
+# (the work tree must match the index for everything but submodules but the
168
+# index must exactly match the given commit including any submodule SHA-1s).
169
+test_superproject_content () {
170
+ git diff-index --cached "$1" >actual &&
171
+ test_must_be_empty actual &&
172
+ git diff-files --ignore-submodules >actual &&
173
+ test_must_be_empty actual
174
+}
175
+
176
+# Test that the given submodule at path "$1" contains the content according
177
+# to the submodule commit recorded in the superproject's commit "$2"
178
+test_submodule_content () {
179
+ if test $# != 2
180
+ then
181
+ echo "test_submodule_content needs two arguments"
182
+ return 1
183
+ fi &&
184
+ submodule="$1" &&
185
+ commit="$2" &&
186
+ test -d "$submodule"/ &&
187
+ if ! test -f "$submodule"/.git && ! test -d "$submodule"/.git
188
+ then
189
+ echo "Submodule $submodule is not populated"
190
+ return 1
191
+ fi &&
192
+ sha1=$(git rev-parse --verify "$commit:$submodule") &&
193
+ if test -z "$sha1"
194
+ then
195
+ echo "Couldn't retrieve SHA-1 of $submodule for $commit"
196
+ return 1
197
+ fi &&
198
+ (
199
+ cd "$submodule" &&
200
+ git status -u -s >actual &&
201
+ test_must_be_empty actual &&
202
+ git diff "$sha1" >actual &&
203
+ test_must_be_empty actual
204
+ )
205
+}
206
+
207
+# Test that the following transitions are correctly handled:
208
+# - Updated submodule
209
+# - New submodule
210
+# - Removed submodule
211
+# - Directory containing tracked files replaced by submodule
212
+# - Submodule replaced by tracked files in directory
213
+# - Submodule replaced by tracked file with the same name
214
+# - tracked file replaced by submodule
215
+#
216
+# The default is that submodule contents aren't changed until "git submodule
217
+# update" is run. And even then that command doesn't delete the work tree of
218
+# a removed submodule.
219
+#
220
+# Removing a submodule containing a .git directory must fail even when forced
221
+# to protect the history!
222
+#
223
+
224
+# Test that submodule contents are currently not updated when switching
225
+# between commits that change a submodule.
226
+test_submodule_switch () {
227
+ command="$1"
228
+ ######################### Appearing submodule #########################
229
+ # Switching to a commit letting a submodule appear creates empty dir ...
230
+ test_expect_success "$command: added submodule creates empty directory" '
231
+ prolog &&
232
+ reset_work_tree_to no_submodule &&
233
+ (
234
+ cd submodule_update &&
235
+ git branch -t add_sub1 origin/add_sub1 &&
236
+ $command add_sub1 &&
237
+ test_superproject_content origin/add_sub1 &&
238
+ test_dir_is_empty sub1 &&
239
+ git submodule update --init --recursive &&
240
+ test_submodule_content sub1 origin/add_sub1
241
+ )
242
+ '
243
+ # ... and doesn't care if it already exists ...
244
+ test_expect_success "$command: added submodule leaves existing empty directory alone" '
245
+ prolog &&
246
+ reset_work_tree_to no_submodule &&
247
+ (
248
+ cd submodule_update &&
249
+ mkdir sub1 &&
250
+ git branch -t add_sub1 origin/add_sub1 &&
251
+ $command add_sub1 &&
252
+ test_superproject_content origin/add_sub1 &&
253
+ test_dir_is_empty sub1 &&
254
+ git submodule update --init --recursive &&
255
+ test_submodule_content sub1 origin/add_sub1
256
+ )
257
+ '
258
+ # ... unless there is an untracked file in its place.
259
+ test_expect_success "$command: added submodule doesn't remove untracked unignored file with same name" '
260
+ prolog &&
261
+ reset_work_tree_to no_submodule &&
262
+ (
263
+ cd submodule_update &&
264
+ git branch -t add_sub1 origin/add_sub1 &&
265
+ >sub1 &&
266
+ test_must_fail $command add_sub1 &&
267
+ test_superproject_content origin/no_submodule &&
268
+ test_must_be_empty sub1
269
+ )
270
+ '
271
+ # Replacing a tracked file with a submodule produces an empty
272
+ # directory ...
273
+ test_expect_success "$command: replace tracked file with submodule creates empty directory" '
274
+ prolog &&
275
+ reset_work_tree_to replace_sub1_with_file &&
276
+ (
277
+ cd submodule_update &&
278
+ git branch -t replace_file_with_sub1 origin/replace_file_with_sub1 &&
279
+ $command replace_file_with_sub1 &&
280
+ test_superproject_content origin/replace_file_with_sub1 &&
281
+ test_dir_is_empty sub1 &&
282
+ git submodule update --init --recursive &&
283
+ test_submodule_content sub1 origin/replace_file_with_sub1
284
+ )
285
+ '
286
+ # ... as does removing a directory with tracked files with a
287
+ # submodule.
288
+ test_expect_success "$command: replace directory with submodule" '
289
+ prolog &&
290
+ reset_work_tree_to replace_sub1_with_directory &&
291
+ (
292
+ cd submodule_update &&
293
+ git branch -t replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
294
+ $command replace_directory_with_sub1 &&
295
+ test_superproject_content origin/replace_directory_with_sub1 &&
296
+ test_dir_is_empty sub1 &&
297
+ git submodule update --init --recursive &&
298
+ test_submodule_content sub1 origin/replace_directory_with_sub1
299
+ )
300
+ '
301
+
302
+ ######################## Disappearing submodule #######################
303
+ # Removing a submodule doesn't remove its work tree ...
304
+ test_expect_success "$command: removed submodule leaves submodule directory and its contents in place" '
305
+ prolog &&
306
+ reset_work_tree_to add_sub1 &&
307
+ (
308
+ cd submodule_update &&
309
+ git branch -t remove_sub1 origin/remove_sub1 &&
310
+ $command remove_sub1 &&
311
+ test_superproject_content origin/remove_sub1 &&
312
+ test_submodule_content sub1 origin/add_sub1
313
+ )
314
+ '
315
+ # ... especially when it contains a .git directory.
316
+ test_expect_success "$command: removed submodule leaves submodule containing a .git directory alone" '
317
+ prolog &&
318
+ reset_work_tree_to add_sub1 &&
319
+ (
320
+ cd submodule_update &&
321
+ git branch -t remove_sub1 origin/remove_sub1 &&
322
+ replace_gitfile_with_git_dir sub1 &&
323
+ $command remove_sub1 &&
324
+ test_superproject_content origin/remove_sub1 &&
325
+ test_git_directory_is_unchanged sub1 &&
326
+ test_submodule_content sub1 origin/add_sub1
327
+ )
328
+ '
329
+ # Replacing a submodule with files in a directory must fail as the
330
+ # submodule work tree isn't removed ...
331
+ test_expect_success "$command: replace submodule with a directory must fail" '
332
+ prolog &&
333
+ reset_work_tree_to add_sub1 &&
334
+ (
335
+ cd submodule_update &&
336
+ git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
337
+ test_must_fail $command replace_sub1_with_directory &&
338
+ test_superproject_content origin/add_sub1 &&
339
+ test_submodule_content sub1 origin/add_sub1
340
+ )
341
+ '
342
+ # ... especially when it contains a .git directory.
343
+ test_expect_success "$command: replace submodule containing a .git directory with a directory must fail" '
344
+ prolog &&
345
+ reset_work_tree_to add_sub1 &&
346
+ (
347
+ cd submodule_update &&
348
+ git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
349
+ replace_gitfile_with_git_dir sub1 &&
350
+ test_must_fail $command replace_sub1_with_directory &&
351
+ test_superproject_content origin/add_sub1 &&
352
+ test_git_directory_is_unchanged sub1 &&
353
+ test_submodule_content sub1 origin/add_sub1
354
+ )
355
+ '
356
+ # Replacing it with a file must fail as it could throw away any local
357
+ # work tree changes ...
358
+ test_expect_failure "$command: replace submodule with a file must fail" '
359
+ prolog &&
360
+ reset_work_tree_to add_sub1 &&
361
+ (
362
+ cd submodule_update &&
363
+ git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
364
+ test_must_fail $command replace_sub1_with_file &&
365
+ test_superproject_content origin/add_sub1 &&
366
+ test_submodule_content sub1 origin/add_sub1
367
+ )
368
+ '
369
+ # ... or even destroy unpushed parts of submodule history if that
370
+ # still uses a .git directory.
371
+ test_expect_failure "$command: replace submodule containing a .git directory with a file must fail" '
372
+ prolog &&
373
+ reset_work_tree_to add_sub1 &&
374
+ (
375
+ cd submodule_update &&
376
+ git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
377
+ replace_gitfile_with_git_dir sub1 &&
378
+ test_must_fail $command replace_sub1_with_file &&
379
+ test_superproject_content origin/add_sub1 &&
380
+ test_git_directory_is_unchanged sub1 &&
381
+ test_submodule_content sub1 origin/add_sub1
382
+ )
383
+ '
384
+
385
+ ########################## Modified submodule #########################
386
+ # Updating a submodule sha1 doesn't update the submodule's work tree
387
+ test_expect_success "$command: modified submodule does not update submodule work tree" '
388
+ prolog &&
389
+ reset_work_tree_to add_sub1 &&
390
+ (
391
+ cd submodule_update &&
392
+ git branch -t modify_sub1 origin/modify_sub1 &&
393
+ $command modify_sub1 &&
394
+ test_superproject_content origin/modify_sub1 &&
395
+ test_submodule_content sub1 origin/add_sub1 &&
396
+ git submodule update &&
397
+ test_submodule_content sub1 origin/modify_sub1
398
+ )
399
+ '
400
+
401
+ # Updating a submodule to an invalid sha1 doesn't update the
402
+ # submodule's work tree, subsequent update will fail
403
+ test_expect_success "$command: modified submodule does not update submodule work tree to invalid commit" '
404
+ prolog &&
405
+ reset_work_tree_to add_sub1 &&
406
+ (
407
+ cd submodule_update &&
408
+ git branch -t invalid_sub1 origin/invalid_sub1 &&
409
+ $command invalid_sub1 &&
410
+ test_superproject_content origin/invalid_sub1 &&
411
+ test_submodule_content sub1 origin/add_sub1 &&
412
+ test_must_fail git submodule update &&
413
+ test_submodule_content sub1 origin/add_sub1
414
+ )
415
+ '
416
+ # Updating a submodule from an invalid sha1 doesn't update the
417
+ # submodule's work tree, subsequent update will succeed
418
+ test_expect_success "$command: modified submodule does not update submodule work tree from invalid commit" '
419
+ prolog &&
420
+ reset_work_tree_to invalid_sub1 &&
421
+ (
422
+ cd submodule_update &&
423
+ git branch -t valid_sub1 origin/valid_sub1 &&
424
+ $command valid_sub1 &&
425
+ test_superproject_content origin/valid_sub1 &&
426
+ test_dir_is_empty sub1 &&
427
+ git submodule update --init --recursive &&
428
+ test_submodule_content sub1 origin/valid_sub1
429
+ )
430
+ '
431
+}
432
+
433
+# Test that submodule contents are currently not updated when switching
434
+# between commits that change a submodule, but throwing away local changes in
435
+# the superproject is allowed.
436
+test_submodule_forced_switch () {
437
+ command="$1"
438
+ ######################### Appearing submodule #########################
439
+ # Switching to a commit letting a submodule appear creates empty dir ...
440
+ test_expect_success "$command: added submodule creates empty directory" '
441
+ prolog &&
442
+ reset_work_tree_to no_submodule &&
443
+ (
444
+ cd submodule_update &&
445
+ git branch -t add_sub1 origin/add_sub1 &&
446
+ $command add_sub1 &&
447
+ test_superproject_content origin/add_sub1 &&
448
+ test_dir_is_empty sub1 &&
449
+ git submodule update --init --recursive &&
450
+ test_submodule_content sub1 origin/add_sub1
451
+ )
452
+ '
453
+ # ... and doesn't care if it already exists ...
454
+ test_expect_success "$command: added submodule leaves existing empty directory alone" '
455
+ prolog &&
456
+ reset_work_tree_to no_submodule &&
457
+ (
458
+ cd submodule_update &&
459
+ git branch -t add_sub1 origin/add_sub1 &&
460
+ mkdir sub1 &&
461
+ $command add_sub1 &&
462
+ test_superproject_content origin/add_sub1 &&
463
+ test_dir_is_empty sub1 &&
464
+ git submodule update --init --recursive &&
465
+ test_submodule_content sub1 origin/add_sub1
466
+ )
467
+ '
468
+ # ... unless there is an untracked file in its place.
469
+ test_expect_success "$command: added submodule does remove untracked unignored file with same name when forced" '
470
+ prolog &&
471
+ reset_work_tree_to no_submodule &&
472
+ (
473
+ cd submodule_update &&
474
+ git branch -t add_sub1 origin/add_sub1 &&
475
+ >sub1 &&
476
+ $command add_sub1 &&
477
+ test_superproject_content origin/add_sub1 &&
478
+ test_dir_is_empty sub1
479
+ )
480
+ '
481
+ # Replacing a tracked file with a submodule produces an empty
482
+ # directory ...
483
+ test_expect_success "$command: replace tracked file with submodule creates empty directory" '
484
+ prolog &&
485
+ reset_work_tree_to replace_sub1_with_file &&
486
+ (
487
+ cd submodule_update &&
488
+ git branch -t replace_file_with_sub1 origin/replace_file_with_sub1 &&
489
+ $command replace_file_with_sub1 &&
490
+ test_superproject_content origin/replace_file_with_sub1 &&
491
+ test_dir_is_empty sub1 &&
492
+ git submodule update --init --recursive &&
493
+ test_submodule_content sub1 origin/replace_file_with_sub1
494
+ )
495
+ '
496
+ # ... as does removing a directory with tracked files with a
497
+ # submodule.
498
+ test_expect_success "$command: replace directory with submodule" '
499
+ prolog &&
500
+ reset_work_tree_to replace_sub1_with_directory &&
501
+ (
502
+ cd submodule_update &&
503
+ git branch -t replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
504
+ $command replace_directory_with_sub1 &&
505
+ test_superproject_content origin/replace_directory_with_sub1 &&
506
+ test_dir_is_empty sub1 &&
507
+ git submodule update --init --recursive &&
508
+ test_submodule_content sub1 origin/replace_directory_with_sub1
509
+ )
510
+ '
511
+
512
+ ######################## Disappearing submodule #######################
513
+ # Removing a submodule doesn't remove its work tree ...
514
+ test_expect_success "$command: removed submodule leaves submodule directory and its contents in place" '
515
+ prolog &&
516
+ reset_work_tree_to add_sub1 &&
517
+ (
518
+ cd submodule_update &&
519
+ git branch -t remove_sub1 origin/remove_sub1 &&
520
+ $command remove_sub1 &&
521
+ test_superproject_content origin/remove_sub1 &&
522
+ test_submodule_content sub1 origin/add_sub1
523
+ )
524
+ '
525
+ # ... especially when it contains a .git directory.
526
+ test_expect_success "$command: removed submodule leaves submodule containing a .git directory alone" '
527
+ prolog &&
528
+ reset_work_tree_to add_sub1 &&
529
+ (
530
+ cd submodule_update &&
531
+ git branch -t remove_sub1 origin/remove_sub1 &&
532
+ replace_gitfile_with_git_dir sub1 &&
533
+ $command remove_sub1 &&
534
+ test_superproject_content origin/remove_sub1 &&
535
+ test_git_directory_is_unchanged sub1 &&
536
+ test_submodule_content sub1 origin/add_sub1
537
+ )
538
+ '
539
+ # Replacing a submodule with files in a directory must fail as the
540
+ # submodule work tree isn't removed ...
541
+ test_expect_failure "$command: replace submodule with a directory must fail" '
542
+ prolog &&
543
+ reset_work_tree_to add_sub1 &&
544
+ (
545
+ cd submodule_update &&
546
+ git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
547
+ test_must_fail $command replace_sub1_with_directory &&
548
+ test_superproject_content origin/add_sub1 &&
549
+ test_submodule_content sub1 origin/add_sub1
550
+ )
551
+ '
552
+ # ... especially when it contains a .git directory.
553
+ test_expect_failure "$command: replace submodule containing a .git directory with a directory must fail" '
554
+ prolog &&
555
+ reset_work_tree_to add_sub1 &&
556
+ (
557
+ cd submodule_update &&
558
+ git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
559
+ replace_gitfile_with_git_dir sub1 &&
560
+ test_must_fail $command replace_sub1_with_directory &&
561
+ test_superproject_content origin/add_sub1 &&
562
+ test_git_directory_is_unchanged sub1 &&
563
+ test_submodule_content sub1 origin/add_sub1
564
+ )
565
+ '
566
+ # Replacing it with a file must fail as it could throw away any local
567
+ # work tree changes ...
568
+ test_expect_failure "$command: replace submodule with a file must fail" '
569
+ prolog &&
570
+ reset_work_tree_to add_sub1 &&
571
+ (
572
+ cd submodule_update &&
573
+ git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
574
+ test_must_fail $command replace_sub1_with_file &&
575
+ test_superproject_content origin/add_sub1 &&
576
+ test_submodule_content sub1 origin/add_sub1
577
+ )
578
+ '
579
+ # ... or even destroy unpushed parts of submodule history if that
580
+ # still uses a .git directory.
581
+ test_expect_failure "$command: replace submodule containing a .git directory with a file must fail" '
582
+ prolog &&
583
+ reset_work_tree_to add_sub1 &&
584
+ (
585
+ cd submodule_update &&
586
+ git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
587
+ replace_gitfile_with_git_dir sub1 &&
588
+ test_must_fail $command replace_sub1_with_file &&
589
+ test_superproject_content origin/add_sub1 &&
590
+ test_git_directory_is_unchanged sub1 &&
591
+ test_submodule_content sub1 origin/add_sub1
592
+ )
593
+ '
594
+
595
+ ########################## Modified submodule #########################
596
+ # Updating a submodule sha1 doesn't update the submodule's work tree
597
+ test_expect_success "$command: modified submodule does not update submodule work tree" '
598
+ prolog &&
599
+ reset_work_tree_to add_sub1 &&
600
+ (
601
+ cd submodule_update &&
602
+ git branch -t modify_sub1 origin/modify_sub1 &&
603
+ $command modify_sub1 &&
604
+ test_superproject_content origin/modify_sub1 &&
605
+ test_submodule_content sub1 origin/add_sub1 &&
606
+ git submodule update &&
607
+ test_submodule_content sub1 origin/modify_sub1
608
+ )
609
+ '
610
+ # Updating a submodule to an invalid sha1 doesn't update the
611
+ # submodule's work tree, subsequent update will fail
612
+ test_expect_success "$command: modified submodule does not update submodule work tree to invalid commit" '
613
+ prolog &&
614
+ reset_work_tree_to add_sub1 &&
615
+ (
616
+ cd submodule_update &&
617
+ git branch -t invalid_sub1 origin/invalid_sub1 &&
618
+ $command invalid_sub1 &&
619
+ test_superproject_content origin/invalid_sub1 &&
620
+ test_submodule_content sub1 origin/add_sub1 &&
621
+ test_must_fail git submodule update &&
622
+ test_submodule_content sub1 origin/add_sub1
623
+ )
624
+ '
625
+ # Updating a submodule from an invalid sha1 doesn't update the
626
+ # submodule's work tree, subsequent update will succeed
627
+ test_expect_success "$command: modified submodule does not update submodule work tree from invalid commit" '
628
+ prolog &&
629
+ reset_work_tree_to invalid_sub1 &&
630
+ (
631
+ cd submodule_update &&
632
+ git branch -t valid_sub1 origin/valid_sub1 &&
633
+ $command valid_sub1 &&
634
+ test_superproject_content origin/valid_sub1 &&
635
+ test_dir_is_empty sub1 &&
636
+ git submodule update --init --recursive &&
637
+ test_submodule_content sub1 origin/valid_sub1
638
+ )
639
+ '
640
+}