aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/submodule--helper.c19
-rwxr-xr-xt/t7425-submodule-gitdir-path-extension.sh59
2 files changed, 78 insertions, 0 deletions
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 746f9fa63c..2fa71c814c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -465,6 +465,10 @@ static int validate_and_set_submodule_gitdir(struct strbuf *gitdir_path,
static void create_default_gitdir_config(const char *submodule_name)
{
struct strbuf gitdir_path = STRBUF_INIT;
+ struct git_hash_ctx ctx;
+ char hex_name_hash[GIT_MAX_HEXSZ + 1], header[128];
+ unsigned char raw_name_hash[GIT_MAX_RAWSZ];
+ int header_len;
/* Case 1: try the plain module name */
repo_git_path_append(the_repository, &gitdir_path, "modules/%s", submodule_name);
@@ -506,6 +510,21 @@ static void create_default_gitdir_config(const char *submodule_name)
return;
}
+ /* Case 2.4: If all the above failed, try a hash of the name as a last resort */
+ header_len = snprintf(header, sizeof(header), "blob %zu", strlen(submodule_name));
+ the_hash_algo->init_fn(&ctx);
+ the_hash_algo->update_fn(&ctx, header, header_len);
+ the_hash_algo->update_fn(&ctx, "\0", 1);
+ the_hash_algo->update_fn(&ctx, submodule_name, strlen(submodule_name));
+ the_hash_algo->final_fn(raw_name_hash, &ctx);
+ hash_to_hex_algop_r(hex_name_hash, raw_name_hash, the_hash_algo);
+ strbuf_reset(&gitdir_path);
+ repo_git_path_append(the_repository, &gitdir_path, "modules/%s", hex_name_hash);
+ if (!validate_and_set_submodule_gitdir(&gitdir_path, submodule_name)) {
+ strbuf_release(&gitdir_path);
+ return;
+ }
+
/* Case 3: nothing worked, error out */
die(_("failed to set a valid default config for 'submodule.%s.gitdir'. "
"Please ensure it is set, for example by running something like: "
diff --git a/t/t7425-submodule-gitdir-path-extension.sh b/t/t7425-submodule-gitdir-path-extension.sh
index 3cca93c897..a76e64a9f7 100755
--- a/t/t7425-submodule-gitdir-path-extension.sh
+++ b/t/t7425-submodule-gitdir-path-extension.sh
@@ -438,4 +438,63 @@ test_expect_success CASE_INSENSITIVE_FS 'verify case-folding conflicts are corre
verify_submodule_gitdir_path cloned-folding "fooBar" "modules/fooBar0"
'
+test_expect_success CASE_INSENSITIVE_FS 'verify hashing conflict resolution as a last resort' '
+ git clone -c extensions.submodulePathConfig=true main cloned-hash &&
+ (
+ cd cloned-hash &&
+
+ # conflict: add all submodule conflicting variants until we reach the
+ # final hashing conflict resolution for submodule "foo"
+ git submodule add ../new-sub "foo" &&
+ git submodule add ../new-sub "foo0" &&
+ git submodule add ../new-sub "foo1" &&
+ git submodule add ../new-sub "foo2" &&
+ git submodule add ../new-sub "foo3" &&
+ git submodule add ../new-sub "foo4" &&
+ git submodule add ../new-sub "foo5" &&
+ git submodule add ../new-sub "foo6" &&
+ git submodule add ../new-sub "foo7" &&
+ git submodule add ../new-sub "foo8" &&
+ git submodule add ../new-sub "foo9" &&
+ git submodule add ../new-sub "%46oo" &&
+ git submodule add ../new-sub "%46oo0" &&
+ git submodule add ../new-sub "%46oo1" &&
+ git submodule add ../new-sub "%46oo2" &&
+ git submodule add ../new-sub "%46oo3" &&
+ git submodule add ../new-sub "%46oo4" &&
+ git submodule add ../new-sub "%46oo5" &&
+ git submodule add ../new-sub "%46oo6" &&
+ git submodule add ../new-sub "%46oo7" &&
+ git submodule add ../new-sub "%46oo8" &&
+ git submodule add ../new-sub "%46oo9" &&
+ test_commit add-foo-variants &&
+ git submodule add ../new-sub "Foo" &&
+ test_commit add-uppercase-foo
+ ) &&
+ verify_submodule_gitdir_path cloned-hash "foo" "modules/foo" &&
+ verify_submodule_gitdir_path cloned-hash "foo0" "modules/foo0" &&
+ verify_submodule_gitdir_path cloned-hash "foo1" "modules/foo1" &&
+ verify_submodule_gitdir_path cloned-hash "foo2" "modules/foo2" &&
+ verify_submodule_gitdir_path cloned-hash "foo3" "modules/foo3" &&
+ verify_submodule_gitdir_path cloned-hash "foo4" "modules/foo4" &&
+ verify_submodule_gitdir_path cloned-hash "foo5" "modules/foo5" &&
+ verify_submodule_gitdir_path cloned-hash "foo6" "modules/foo6" &&
+ verify_submodule_gitdir_path cloned-hash "foo7" "modules/foo7" &&
+ verify_submodule_gitdir_path cloned-hash "foo8" "modules/foo8" &&
+ verify_submodule_gitdir_path cloned-hash "foo9" "modules/foo9" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo" "modules/%46oo" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo0" "modules/%46oo0" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo1" "modules/%46oo1" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo2" "modules/%46oo2" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo3" "modules/%46oo3" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo4" "modules/%46oo4" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo5" "modules/%46oo5" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo6" "modules/%46oo6" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo7" "modules/%46oo7" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo8" "modules/%46oo8" &&
+ verify_submodule_gitdir_path cloned-hash "%46oo9" "modules/%46oo9" &&
+ hash=$(printf "Foo" | git hash-object --stdin) &&
+ verify_submodule_gitdir_path cloned-hash "Foo" "modules/${hash}"
+'
+
test_done