Test case for various cases of deleted submodules: 1. Clone a repo where an `old` submodule has been removed in HEAD. Try to checkout a revision from before `old` was deleted. This can fail in a rather ugly way depending on how the `git checkout` and `git submodule` commands are used. 2. Clone a repo where a `new` submodule has been added. Try to checkout a revision from before `new` was added. This can leave `new` lying around in some circumstances, and not in others, in a way which is confusing (at least to me). Signed-off-by: Luke Diamand <luke@xxxxxxxxxxx> --- t/t5619-submodules-missing.sh | 104 ++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 t/t5619-submodules-missing.sh diff --git a/t/t5619-submodules-missing.sh b/t/t5619-submodules-missing.sh new file mode 100755 index 0000000000..d7878c52fc --- /dev/null +++ b/t/t5619-submodules-missing.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +test_description='Clone a repo containing submodules. Sync to a revision where the submodule is missing or added' + +. ./test-lib.sh + +pwd=$(pwd) + +# Setup a super project with a submodule called `old`, which gets deleted, and +# a submodule `new` which is added later on. + +test_expect_success 'setup' ' + mkdir super old new && + git -C old init && + test_commit -C old commit_old && + (cd super && + git init . && + git submodule add ../old old && + git commit -m "adding submodule old" && + test_commit commit2 && + git tag OLD && + test_path_is_file old/commit_old.t && + git rm old && + git commit -m "Remove old submodule" && + test_commit commit3 + ) && + git -C new init && + test_commit -C new commit_new && + (cd super && + git tag BEFORE_NEW && + git submodule add ../new new && + git commit -m "adding submodule new" && + test_commit commit4 + ) +' + +# Checkout the OLD tag inside the original repo. This works fine since all of +# the submodules are present in .git/modules. +test_expect_success 'checkout old inside original repo' ' + (cd super && + git config advice.detachedHead false && + git tag LATEST && + git checkout --recurse-submodules OLD && + git submodule update --checkout --remote --force && + test_path_is_file old/commit_old.t && + test_path_is_missing new/commit_new.t && + git checkout --recurse-submodules LATEST && + test_path_is_file new/commit_new.t + ) +' + +# Clone the repo, and then checkout the OLD tag inside the clone. +# The `old` submodule does not get updated. Instead we get: +# +# fatal: not a git repository: ../.git/modules/old +# fatal: could not reset submodule index +# +# That's because `old` is missing from .git/modules since it +# was not cloned originally and `checkout` does not know how to +# fetch the remote submodules, whereas `submodule update --remote` does. + +test_expect_failure 'checkout old with --recurse-submodules' ' + test_when_finished "rm -fr super-clone" && + git clone --recurse-submodules super super-clone && + (cd super-clone && + git config advice.detachedHead false && + test_path_is_file commit3.t && + test_path_is_file commit2.t && + test_path_is_missing old && + test_path_is_file new/commit_new.t && + git checkout --recurse-submodules OLD && + git submodule update --checkout --remote --force && + test_path_is_file commit2.t && + test_path_is_missing commit3.t && + test_path_is_dir old && + test_path_is_file old/commit_old.t + ) +' + +# As above, but this time, instead of using "checkout --recurse-submodules" we just +# use "checkout" to avoid the missing submodule error. +# +# The checkout of `old` now works fine, but instead `new` is left lying +# around with seemingly no way to clean it up. Even a later invocation of +# `git checkout --recurse-submodules` does not get rid of it. + +test_expect_failure 'checkout old without --recurse-submodules' ' + test_when_finished "rm -fr super-clone" && + git clone --recurse-submodules super super-clone && + (cd super-clone && + git config advice.detachedHead false && + test_path_is_file new/commit_new.t && + git checkout OLD && + git submodule update --checkout --remote --force && + git checkout --recurse-submodules OLD && + test_path_is_file commit2.t && + test_path_is_missing commit3.t && + test_path_is_dir old && + test_path_is_file old/commit_old.t && + test_path_is_missing new/commit_new.t + ) +' + +test_done -- 2.28.0.762.g324f61785e