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