# to protect the history!
#
-# Test that submodule contents are currently not updated when switching
-# between commits that change a submodule.
-test_submodule_switch () {
+# Internal function; use test_submodule_switch() or
+# test_submodule_forced_switch() instead.
+test_submodule_switch_common() {
command="$1"
######################### Appearing submodule #########################
# Switching to a commit letting a submodule appear creates empty dir ...
test_submodule_content sub1 origin/add_sub1
)
'
- # ... and doesn't care if it already exists ...
+ # ... and doesn't care if it already exists.
test_expect_$RESULT "$command: added submodule leaves existing empty directory alone" '
prolog &&
reset_work_tree_to no_submodule &&
test_submodule_content sub1 origin/add_sub1
)
'
- # ... unless there is an untracked file in its place.
- test_expect_success "$command: added submodule doesn't remove untracked unignored file with same name" '
- prolog &&
- reset_work_tree_to no_submodule &&
- (
- cd submodule_update &&
- git branch -t add_sub1 origin/add_sub1 &&
- >sub1 &&
- test_must_fail $command add_sub1 &&
- test_superproject_content origin/no_submodule &&
- test_must_be_empty sub1
- )
- '
# Replacing a tracked file with a submodule produces an empty
# directory ...
test_expect_$RESULT "$command: replace tracked file with submodule creates empty directory" '
# submodule files with the newly checked out ones in the
# directory of the same name while it shouldn't.
RESULT="failure"
+ elif test "$KNOWN_FAILURE_FORCED_SWITCH_TESTS" = 1
+ then
+ # All existing tests that use test_submodule_forced_switch()
+ # require this.
+ RESULT="failure"
else
RESULT="success"
fi
test_submodule_content sub1 origin/modify_sub1
)
'
-
# Updating a submodule to an invalid sha1 doesn't update the
# submodule's work tree, subsequent update will fail
test_expect_$RESULT "$command: modified submodule does not update submodule work tree to invalid commit" '
'
}
-# Test that submodule contents are currently not updated when switching
-# between commits that change a submodule, but throwing away local changes in
-# the superproject is allowed.
-test_submodule_forced_switch () {
+# Declares and invokes several tests that, in various situations, checks that
+# the provided transition function:
+# - succeeds in updating the worktree and index of a superproject to a target
+# commit, or fails atomically (depending on the test situation)
+# - if succeeds, the contents of submodule directories are unchanged
+# - if succeeds, once "git submodule update" is invoked, the contents of
+# submodule directories are updated
+#
+# Use as follows:
+#
+# my_func () {
+# target=$1
+# # Do something here that updates the worktree and index to match target,
+# # but not any submodule directories.
+# }
+# test_submodule_switch "my_func"
+test_submodule_switch () {
command="$1"
- ######################### Appearing submodule #########################
- # Switching to a commit letting a submodule appear creates empty dir ...
- test_expect_success "$command: added submodule creates empty directory" '
- prolog &&
- reset_work_tree_to no_submodule &&
- (
- cd submodule_update &&
- git branch -t add_sub1 origin/add_sub1 &&
- $command add_sub1 &&
- test_superproject_content origin/add_sub1 &&
- test_dir_is_empty sub1 &&
- git submodule update --init --recursive &&
- test_submodule_content sub1 origin/add_sub1
- )
- '
- # ... and doesn't care if it already exists ...
- test_expect_success "$command: added submodule leaves existing empty directory alone" '
+ test_submodule_switch_common "$command"
+
+ # An empty directory does not prevent the creation of a submodule of
+ # the same name, but a file does.
+ test_expect_success "$command: added submodule doesn't remove untracked unignored file with same name" '
prolog &&
reset_work_tree_to no_submodule &&
(
cd submodule_update &&
git branch -t add_sub1 origin/add_sub1 &&
- mkdir sub1 &&
- $command add_sub1 &&
- test_superproject_content origin/add_sub1 &&
- test_dir_is_empty sub1 &&
- git submodule update --init --recursive &&
- test_submodule_content sub1 origin/add_sub1
+ >sub1 &&
+ test_must_fail $command add_sub1 &&
+ test_superproject_content origin/no_submodule &&
+ test_must_be_empty sub1
)
'
- # ... unless there is an untracked file in its place.
+}
+
+# Same as test_submodule_switch(), except that throwing away local changes in
+# the superproject is allowed.
+test_submodule_forced_switch () {
+ command="$1"
+ KNOWN_FAILURE_FORCED_SWITCH_TESTS=1
+ test_submodule_switch_common "$command"
+
+ # When forced, a file in the superproject does not prevent creating a
+ # submodule of the same name.
test_expect_success "$command: added submodule does remove untracked unignored file with same name when forced" '
prolog &&
reset_work_tree_to no_submodule &&
test_dir_is_empty sub1
)
'
- # Replacing a tracked file with a submodule produces an empty
- # directory ...
- test_expect_success "$command: replace tracked file with submodule creates empty directory" '
- prolog &&
- reset_work_tree_to replace_sub1_with_file &&
- (
- cd submodule_update &&
- git branch -t replace_file_with_sub1 origin/replace_file_with_sub1 &&
- $command replace_file_with_sub1 &&
- test_superproject_content origin/replace_file_with_sub1 &&
- test_dir_is_empty sub1 &&
- git submodule update --init --recursive &&
- test_submodule_content sub1 origin/replace_file_with_sub1
- )
- '
- # ... as does removing a directory with tracked files with a
- # submodule.
- test_expect_success "$command: replace directory with submodule" '
- prolog &&
- reset_work_tree_to replace_sub1_with_directory &&
- (
- cd submodule_update &&
- git branch -t replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
- $command replace_directory_with_sub1 &&
- test_superproject_content origin/replace_directory_with_sub1 &&
- test_dir_is_empty sub1 &&
- git submodule update --init --recursive &&
- test_submodule_content sub1 origin/replace_directory_with_sub1
- )
- '
-
- ######################## Disappearing submodule #######################
- # Removing a submodule doesn't remove its work tree ...
- test_expect_success "$command: removed submodule leaves submodule directory and its contents in place" '
- prolog &&
- reset_work_tree_to add_sub1 &&
- (
- cd submodule_update &&
- git branch -t remove_sub1 origin/remove_sub1 &&
- $command remove_sub1 &&
- test_superproject_content origin/remove_sub1 &&
- test_submodule_content sub1 origin/add_sub1
- )
- '
- # ... especially when it contains a .git directory.
- test_expect_success "$command: removed submodule leaves submodule containing a .git directory alone" '
- prolog &&
- reset_work_tree_to add_sub1 &&
- (
- cd submodule_update &&
- git branch -t remove_sub1 origin/remove_sub1 &&
- replace_gitfile_with_git_dir sub1 &&
- $command remove_sub1 &&
- test_superproject_content origin/remove_sub1 &&
- test_git_directory_is_unchanged sub1 &&
- test_submodule_content sub1 origin/add_sub1
- )
- '
- # Replacing a submodule with files in a directory must fail as the
- # submodule work tree isn't removed ...
- test_expect_failure "$command: replace submodule with a directory must fail" '
- prolog &&
- reset_work_tree_to add_sub1 &&
- (
- cd submodule_update &&
- git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
- test_must_fail $command replace_sub1_with_directory &&
- test_superproject_content origin/add_sub1 &&
- test_submodule_content sub1 origin/add_sub1
- )
- '
- # ... especially when it contains a .git directory.
- test_expect_failure "$command: replace submodule containing a .git directory with a directory must fail" '
- prolog &&
- reset_work_tree_to add_sub1 &&
- (
- cd submodule_update &&
- git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
- replace_gitfile_with_git_dir sub1 &&
- test_must_fail $command replace_sub1_with_directory &&
- test_superproject_content origin/add_sub1 &&
- test_git_directory_is_unchanged sub1 &&
- test_submodule_content sub1 origin/add_sub1
- )
- '
- # Replacing it with a file must fail as it could throw away any local
- # work tree changes ...
- test_expect_failure "$command: replace submodule with a file must fail" '
- prolog &&
- reset_work_tree_to add_sub1 &&
- (
- cd submodule_update &&
- git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
- test_must_fail $command replace_sub1_with_file &&
- test_superproject_content origin/add_sub1 &&
- test_submodule_content sub1 origin/add_sub1
- )
- '
- # ... or even destroy unpushed parts of submodule history if that
- # still uses a .git directory.
- test_expect_failure "$command: replace submodule containing a .git directory with a file must fail" '
- prolog &&
- reset_work_tree_to add_sub1 &&
- (
- cd submodule_update &&
- git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
- replace_gitfile_with_git_dir sub1 &&
- test_must_fail $command replace_sub1_with_file &&
- test_superproject_content origin/add_sub1 &&
- test_git_directory_is_unchanged sub1 &&
- test_submodule_content sub1 origin/add_sub1
- )
- '
-
- ########################## Modified submodule #########################
- # Updating a submodule sha1 doesn't update the submodule's work tree
- test_expect_success "$command: modified submodule does not update submodule work tree" '
- prolog &&
- reset_work_tree_to add_sub1 &&
- (
- cd submodule_update &&
- git branch -t modify_sub1 origin/modify_sub1 &&
- $command modify_sub1 &&
- test_superproject_content origin/modify_sub1 &&
- test_submodule_content sub1 origin/add_sub1 &&
- git submodule update &&
- test_submodule_content sub1 origin/modify_sub1
- )
- '
- # Updating a submodule to an invalid sha1 doesn't update the
- # submodule's work tree, subsequent update will fail
- test_expect_success "$command: modified submodule does not update submodule work tree to invalid commit" '
- prolog &&
- reset_work_tree_to add_sub1 &&
- (
- cd submodule_update &&
- git branch -t invalid_sub1 origin/invalid_sub1 &&
- $command invalid_sub1 &&
- test_superproject_content origin/invalid_sub1 &&
- test_submodule_content sub1 origin/add_sub1 &&
- test_must_fail git submodule update &&
- test_submodule_content sub1 origin/add_sub1
- )
- '
- # Updating a submodule from an invalid sha1 doesn't update the
- # submodule's work tree, subsequent update will succeed
- test_expect_success "$command: modified submodule does not update submodule work tree from invalid commit" '
- prolog &&
- reset_work_tree_to invalid_sub1 &&
- (
- cd submodule_update &&
- git branch -t valid_sub1 origin/valid_sub1 &&
- $command valid_sub1 &&
- test_superproject_content origin/valid_sub1 &&
- test_dir_is_empty sub1 &&
- git submodule update --init --recursive &&
- test_submodule_content sub1 origin/valid_sub1
- )
- '
}
# Test that submodule contents are correctly updated when switching