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