···16681668 * standard layout with .git/(modules/<name>)+/objects
16691669 */
16701670 if (strip_suffix(odb->path, "/objects", &len)) {
16711671+ struct repository alternate;
16711672 char *sm_alternate;
16721673 struct strbuf sb = STRBUF_INIT;
16731674 struct strbuf err = STRBUF_INIT;
16741675 strbuf_add(&sb, odb->path, len);
16761676+16771677+ repo_init(&alternate, sb.buf, NULL);
1675167816761679 /*
16771680 * We need to end the new path with '/' to mark it as a dir,
···16791682 * as the last part of a missing submodule reference would
16801683 * be taken as a file name.
16811684 */
16821682- strbuf_addf(&sb, "/modules/%s/", sas->submodule_name);
16851685+ strbuf_reset(&sb);
16861686+ submodule_name_to_gitdir(&sb, &alternate, sas->submodule_name);
16871687+ strbuf_addch(&sb, '/');
16881688+ repo_clear(&alternate);
1683168916841690 sm_alternate = compute_alternate_path(sb.buf, &err);
16851691 if (sm_alternate) {
···17491755 struct strbuf sb = STRBUF_INIT;
17501756 struct child_process cp = CHILD_PROCESS_INIT;
1751175717521752- strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), clone_data->name);
17581758+ submodule_name_to_gitdir(&sb, the_repository, clone_data->name);
17531759 sm_gitdir = absolute_pathdup(sb.buf);
17541760 strbuf_reset(&sb);
17551761
···213213 * submodule would not have a worktree.
214214 */
215215 strbuf_reset(&gitdir);
216216- strbuf_repo_git_path(&gitdir, superproject,
217217- "modules/%s", sub->name);
216216+ submodule_name_to_gitdir(&gitdir, superproject, sub->name);
218217219218 if (repo_init(subrepo, gitdir.buf, NULL)) {
220219 ret = -1;
+55-22
submodule.c
···1859185918601860void submodule_unset_core_worktree(const struct submodule *sub)
18611861{
18621862- char *config_path = xstrfmt("%s/modules/%s/config",
18631863- get_git_dir(), sub->name);
18621862+ struct strbuf config_path = STRBUF_INIT;
1864186318651865- if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
18641864+ submodule_name_to_gitdir(&config_path, the_repository, sub->name);
18651865+ strbuf_addstr(&config_path, "/config");
18661866+18671867+ if (git_config_set_in_file_gently(config_path.buf, "core.worktree", NULL))
18661868 warning(_("Could not unset core.worktree setting in submodule '%s'"),
18671869 sub->path);
1868187018691869- free(config_path);
18711871+ strbuf_release(&config_path);
18701872}
1871187318721874static const char *get_super_prefix_or_empty(void)
···19621964 absorb_git_dir_into_superproject(path,
19631965 ABSORB_GITDIR_RECURSE_SUBMODULES);
19641966 } else {
19651965- char *gitdir = xstrfmt("%s/modules/%s",
19661966- get_git_dir(), sub->name);
19671967- connect_work_tree_and_git_dir(path, gitdir, 0);
19681968- free(gitdir);
19671967+ struct strbuf gitdir = STRBUF_INIT;
19681968+ submodule_name_to_gitdir(&gitdir, the_repository,
19691969+ sub->name);
19701970+ connect_work_tree_and_git_dir(path, gitdir.buf, 0);
19711971+ strbuf_release(&gitdir);
1969197219701973 /* make sure the index is clean as well */
19711974 submodule_reset_index(path);
19721975 }
1973197619741977 if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
19751975- char *gitdir = xstrfmt("%s/modules/%s",
19761976- get_git_dir(), sub->name);
19771977- connect_work_tree_and_git_dir(path, gitdir, 1);
19781978- free(gitdir);
19781978+ struct strbuf gitdir = STRBUF_INIT;
19791979+ submodule_name_to_gitdir(&gitdir, the_repository,
19801980+ sub->name);
19811981+ connect_work_tree_and_git_dir(path, gitdir.buf, 1);
19821982+ strbuf_release(&gitdir);
19791983 }
19801984 }
19811985···20902094static void relocate_single_git_dir_into_superproject(const char *path)
20912095{
20922096 char *old_git_dir = NULL, *real_old_git_dir = NULL, *real_new_git_dir = NULL;
20932093- char *new_git_dir;
20972097+ struct strbuf new_gitdir = STRBUF_INIT;
20942098 const struct submodule *sub;
2095209920962100 if (submodule_uses_worktrees(path))
···21082112 if (!sub)
21092113 die(_("could not lookup name for submodule '%s'"), path);
2110211421112111- new_git_dir = git_pathdup("modules/%s", sub->name);
21122112- if (validate_submodule_git_dir(new_git_dir, sub->name) < 0)
21152115+ submodule_name_to_gitdir(&new_gitdir, the_repository, sub->name);
21162116+ if (validate_submodule_git_dir(new_gitdir.buf, sub->name) < 0)
21132117 die(_("refusing to move '%s' into an existing git dir"),
21142118 real_old_git_dir);
21152115- if (safe_create_leading_directories_const(new_git_dir) < 0)
21162116- die(_("could not create directory '%s'"), new_git_dir);
21172117- real_new_git_dir = real_pathdup(new_git_dir, 1);
21182118- free(new_git_dir);
21192119+ if (safe_create_leading_directories_const(new_gitdir.buf) < 0)
21202120+ die(_("could not create directory '%s'"), new_gitdir.buf);
21212121+ real_new_git_dir = real_pathdup(new_gitdir.buf, 1);
2119212221202123 fprintf(stderr, _("Migrating git directory of '%s%s' from\n'%s' to\n'%s'\n"),
21212124 get_super_prefix_or_empty(), path,
···21262129 free(old_git_dir);
21272130 free(real_old_git_dir);
21282131 free(real_new_git_dir);
21322132+ strbuf_release(&new_gitdir);
21292133}
2130213421312135/*
···21452149 /* Not populated? */
21462150 if (!sub_git_dir) {
21472151 const struct submodule *sub;
21522152+ struct strbuf sub_gitdir = STRBUF_INIT;
2148215321492154 if (err_code == READ_GITFILE_ERR_STAT_FAILED) {
21502155 /* unpopulated as expected */
···21662171 sub = submodule_from_path(the_repository, null_oid(), path);
21672172 if (!sub)
21682173 die(_("could not lookup name for submodule '%s'"), path);
21692169- connect_work_tree_and_git_dir(path,
21702170- git_path("modules/%s", sub->name), 0);
21742174+ submodule_name_to_gitdir(&sub_gitdir, the_repository, sub->name);
21752175+ connect_work_tree_and_git_dir(path, sub_gitdir.buf, 0);
21762176+ strbuf_release(&sub_gitdir);
21712177 } else {
21722178 /* Is it already absorbed into the superprojects git dir? */
21732179 char *real_sub_git_dir = real_pathdup(sub_git_dir, 1);
···23182324 goto cleanup;
23192325 }
23202326 strbuf_reset(buf);
23212321- strbuf_git_path(buf, "%s/%s", "modules", sub->name);
23272327+ submodule_name_to_gitdir(buf, the_repository, sub->name);
23222328 }
2323232923242330cleanup:
23252331 return ret;
23262332}
23332333+23342334+void submodule_name_to_gitdir(struct strbuf *buf, struct repository *r,
23352335+ const char *submodule_name)
23362336+{
23372337+ /*
23382338+ * NEEDSWORK: The current way of mapping a submodule's name to
23392339+ * its location in .git/modules/ has problems with some naming
23402340+ * schemes. For example, if a submodule is named "foo" and
23412341+ * another is named "foo/bar" (whether present in the same
23422342+ * superproject commit or not - the problem will arise if both
23432343+ * superproject commits have been checked out at any point in
23442344+ * time), or if two submodule names only have different cases in
23452345+ * a case-insensitive filesystem.
23462346+ *
23472347+ * There are several solutions, including encoding the path in
23482348+ * some way, introducing a submodule.<name>.gitdir config in
23492349+ * .git/config (not .gitmodules) that allows overriding what the
23502350+ * gitdir of a submodule would be (and teach Git, upon noticing
23512351+ * a clash, to automatically determine a non-clashing name and
23522352+ * to write such a config), or introducing a
23532353+ * submodule.<name>.gitdir config in .gitmodules that repo
23542354+ * administrators can explicitly set. Nothing has been decided,
23552355+ * so for now, just append the name at the end of the path.
23562356+ */
23572357+ strbuf_repo_git_path(buf, r, "modules/");
23582358+ strbuf_addstr(buf, submodule_name);
23592359+}
+7
submodule.h
···133133int submodule_to_gitdir(struct strbuf *buf, const char *submodule);
134134135135/*
136136+ * Given a submodule name, create a path to where the submodule's gitdir lives
137137+ * inside of the provided repository's 'modules' directory.
138138+ */
139139+void submodule_name_to_gitdir(struct strbuf *buf, struct repository *r,
140140+ const char *submodule_name);
141141+142142+/*
136143 * Make sure that no submodule's git dir is nested in a sibling submodule's.
137144 */
138145int validate_submodule_git_dir(char *git_dir, const char *submodule_name);