Skip to content

Commit f7511fd

Browse files
committed
Merge branch 'jt/submodule-name-to-gitdir'
Code refactoring. * jt/submodule-name-to-gitdir: submodule: extract path to submodule gitdir func
2 parents 188da7d + ce125d4 commit f7511fd

File tree

5 files changed

+72
-27
lines changed

5 files changed

+72
-27
lines changed

builtin/submodule--helper.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -1668,18 +1668,24 @@ static int add_possible_reference_from_superproject(
16681668
* standard layout with .git/(modules/<name>)+/objects
16691669
*/
16701670
if (strip_suffix(odb->path, "/objects", &len)) {
1671+
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);
16751676

1677+
repo_init(&alternate, sb.buf, NULL);
1678+
16761679
/*
16771680
* We need to end the new path with '/' to mark it as a dir,
16781681
* otherwise a submodule name containing '/' will be broken
16791682
* as the last part of a missing submodule reference would
16801683
* be taken as a file name.
16811684
*/
1682-
strbuf_addf(&sb, "/modules/%s/", sas->submodule_name);
1685+
strbuf_reset(&sb);
1686+
submodule_name_to_gitdir(&sb, &alternate, sas->submodule_name);
1687+
strbuf_addch(&sb, '/');
1688+
repo_clear(&alternate);
16831689

16841690
sm_alternate = compute_alternate_path(sb.buf, &err);
16851691
if (sm_alternate) {
@@ -1749,7 +1755,7 @@ static int clone_submodule(struct module_clone_data *clone_data)
17491755
struct strbuf sb = STRBUF_INIT;
17501756
struct child_process cp = CHILD_PROCESS_INIT;
17511757

1752-
strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), clone_data->name);
1758+
submodule_name_to_gitdir(&sb, the_repository, clone_data->name);
17531759
sm_gitdir = absolute_pathdup(sb.buf);
17541760
strbuf_reset(&sb);
17551761

dir.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3799,7 +3799,7 @@ static void connect_wt_gitdir_in_nested(const char *sub_worktree,
37993799
strbuf_reset(&sub_wt);
38003800
strbuf_reset(&sub_gd);
38013801
strbuf_addf(&sub_wt, "%s/%s", sub_worktree, sub->path);
3802-
strbuf_addf(&sub_gd, "%s/modules/%s", sub_gitdir, sub->name);
3802+
submodule_name_to_gitdir(&sub_gd, &subrepo, sub->name);
38033803

38043804
connect_work_tree_and_git_dir(sub_wt.buf, sub_gd.buf, 1);
38053805
}

repository.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,7 @@ int repo_submodule_init(struct repository *subrepo,
213213
* submodule would not have a worktree.
214214
*/
215215
strbuf_reset(&gitdir);
216-
strbuf_repo_git_path(&gitdir, superproject,
217-
"modules/%s", sub->name);
216+
submodule_name_to_gitdir(&gitdir, superproject, sub->name);
218217

219218
if (repo_init(subrepo, gitdir.buf, NULL)) {
220219
ret = -1;

submodule.c

+55-22
Original file line numberDiff line numberDiff line change
@@ -1859,14 +1859,16 @@ int bad_to_remove_submodule(const char *path, unsigned flags)
18591859

18601860
void submodule_unset_core_worktree(const struct submodule *sub)
18611861
{
1862-
char *config_path = xstrfmt("%s/modules/%s/config",
1863-
get_git_dir(), sub->name);
1862+
struct strbuf config_path = STRBUF_INIT;
18641863

1865-
if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
1864+
submodule_name_to_gitdir(&config_path, the_repository, sub->name);
1865+
strbuf_addstr(&config_path, "/config");
1866+
1867+
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);
18681870

1869-
free(config_path);
1871+
strbuf_release(&config_path);
18701872
}
18711873

18721874
static const char *get_super_prefix_or_empty(void)
@@ -1962,20 +1964,22 @@ int submodule_move_head(const char *path,
19621964
absorb_git_dir_into_superproject(path,
19631965
ABSORB_GITDIR_RECURSE_SUBMODULES);
19641966
} else {
1965-
char *gitdir = xstrfmt("%s/modules/%s",
1966-
get_git_dir(), sub->name);
1967-
connect_work_tree_and_git_dir(path, gitdir, 0);
1968-
free(gitdir);
1967+
struct strbuf gitdir = STRBUF_INIT;
1968+
submodule_name_to_gitdir(&gitdir, the_repository,
1969+
sub->name);
1970+
connect_work_tree_and_git_dir(path, gitdir.buf, 0);
1971+
strbuf_release(&gitdir);
19691972

19701973
/* make sure the index is clean as well */
19711974
submodule_reset_index(path);
19721975
}
19731976

19741977
if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
1975-
char *gitdir = xstrfmt("%s/modules/%s",
1976-
get_git_dir(), sub->name);
1977-
connect_work_tree_and_git_dir(path, gitdir, 1);
1978-
free(gitdir);
1978+
struct strbuf gitdir = STRBUF_INIT;
1979+
submodule_name_to_gitdir(&gitdir, the_repository,
1980+
sub->name);
1981+
connect_work_tree_and_git_dir(path, gitdir.buf, 1);
1982+
strbuf_release(&gitdir);
19791983
}
19801984
}
19811985

@@ -2090,7 +2094,7 @@ int validate_submodule_git_dir(char *git_dir, const char *submodule_name)
20902094
static 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;
2093-
char *new_git_dir;
2097+
struct strbuf new_gitdir = STRBUF_INIT;
20942098
const struct submodule *sub;
20952099

20962100
if (submodule_uses_worktrees(path))
@@ -2108,14 +2112,13 @@ static void relocate_single_git_dir_into_superproject(const char *path)
21082112
if (!sub)
21092113
die(_("could not lookup name for submodule '%s'"), path);
21102114

2111-
new_git_dir = git_pathdup("modules/%s", sub->name);
2112-
if (validate_submodule_git_dir(new_git_dir, sub->name) < 0)
2115+
submodule_name_to_gitdir(&new_gitdir, the_repository, sub->name);
2116+
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);
2115-
if (safe_create_leading_directories_const(new_git_dir) < 0)
2116-
die(_("could not create directory '%s'"), new_git_dir);
2117-
real_new_git_dir = real_pathdup(new_git_dir, 1);
2118-
free(new_git_dir);
2119+
if (safe_create_leading_directories_const(new_gitdir.buf) < 0)
2120+
die(_("could not create directory '%s'"), new_gitdir.buf);
2121+
real_new_git_dir = real_pathdup(new_gitdir.buf, 1);
21192122

21202123
fprintf(stderr, _("Migrating git directory of '%s%s' from\n'%s' to\n'%s'\n"),
21212124
get_super_prefix_or_empty(), path,
@@ -2126,6 +2129,7 @@ static void relocate_single_git_dir_into_superproject(const char *path)
21262129
free(old_git_dir);
21272130
free(real_old_git_dir);
21282131
free(real_new_git_dir);
2132+
strbuf_release(&new_gitdir);
21292133
}
21302134

21312135
/*
@@ -2145,6 +2149,7 @@ void absorb_git_dir_into_superproject(const char *path,
21452149
/* Not populated? */
21462150
if (!sub_git_dir) {
21472151
const struct submodule *sub;
2152+
struct strbuf sub_gitdir = STRBUF_INIT;
21482153

21492154
if (err_code == READ_GITFILE_ERR_STAT_FAILED) {
21502155
/* unpopulated as expected */
@@ -2166,8 +2171,9 @@ void absorb_git_dir_into_superproject(const char *path,
21662171
sub = submodule_from_path(the_repository, null_oid(), path);
21672172
if (!sub)
21682173
die(_("could not lookup name for submodule '%s'"), path);
2169-
connect_work_tree_and_git_dir(path,
2170-
git_path("modules/%s", sub->name), 0);
2174+
submodule_name_to_gitdir(&sub_gitdir, the_repository, sub->name);
2175+
connect_work_tree_and_git_dir(path, sub_gitdir.buf, 0);
2176+
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);
@@ -2318,9 +2324,36 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule)
23182324
goto cleanup;
23192325
}
23202326
strbuf_reset(buf);
2321-
strbuf_git_path(buf, "%s/%s", "modules", sub->name);
2327+
submodule_name_to_gitdir(buf, the_repository, sub->name);
23222328
}
23232329

23242330
cleanup:
23252331
return ret;
23262332
}
2333+
2334+
void submodule_name_to_gitdir(struct strbuf *buf, struct repository *r,
2335+
const char *submodule_name)
2336+
{
2337+
/*
2338+
* NEEDSWORK: The current way of mapping a submodule's name to
2339+
* its location in .git/modules/ has problems with some naming
2340+
* schemes. For example, if a submodule is named "foo" and
2341+
* another is named "foo/bar" (whether present in the same
2342+
* superproject commit or not - the problem will arise if both
2343+
* superproject commits have been checked out at any point in
2344+
* time), or if two submodule names only have different cases in
2345+
* a case-insensitive filesystem.
2346+
*
2347+
* There are several solutions, including encoding the path in
2348+
* some way, introducing a submodule.<name>.gitdir config in
2349+
* .git/config (not .gitmodules) that allows overriding what the
2350+
* gitdir of a submodule would be (and teach Git, upon noticing
2351+
* a clash, to automatically determine a non-clashing name and
2352+
* to write such a config), or introducing a
2353+
* submodule.<name>.gitdir config in .gitmodules that repo
2354+
* administrators can explicitly set. Nothing has been decided,
2355+
* so for now, just append the name at the end of the path.
2356+
*/
2357+
strbuf_repo_git_path(buf, r, "modules/");
2358+
strbuf_addstr(buf, submodule_name);
2359+
}

submodule.h

+7
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ int push_unpushed_submodules(struct repository *r,
132132
*/
133133
int submodule_to_gitdir(struct strbuf *buf, const char *submodule);
134134

135+
/*
136+
* Given a submodule name, create a path to where the submodule's gitdir lives
137+
* inside of the provided repository's 'modules' directory.
138+
*/
139+
void submodule_name_to_gitdir(struct strbuf *buf, struct repository *r,
140+
const char *submodule_name);
141+
135142
/*
136143
* Make sure that no submodule's git dir is nested in a sibling submodule's.
137144
*/

0 commit comments

Comments
 (0)