repository: support unabsorbed in repo_submodule_init

In preparation for a subsequent commit that migrates code using add_submodule_odb() to repo_submodule_init(), teach repo_submodule_init() to support submodules with unabsorbed gitdirs. (See the documentation for "git submodule absorbgitdirs" for more information about absorbed and unabsorbed gitdirs.) Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Sep 9, 2021 at 11:47 UTC 8eb8dcf94643ca6e7c3f040f3e0bf96e11c7ae47
7 files changed +28 -37
builtin/grep.c
+1 -4
@@ -433,17 +433,14 @@ static int grep_submodule(struct grep_opt *opt,
433 {
434 struct repository *subrepo;
435 struct repository *superproject = opt->repo;
436 - const struct submodule *sub;
436 struct grep_opt subopt;
437 int hit = 0;
438
440 - sub = submodule_from_path(superproject, null_oid(), path);
441 -
439 if (!is_submodule_active(superproject, path))
440 return 0;
441
442 subrepo = xmalloc(sizeof(*subrepo));
446 - if (repo_submodule_init(subrepo, superproject, sub)) {
443 + if (repo_submodule_init(subrepo, superproject, path, null_oid())) {
444 free(subrepo);
445 return 0;
446 }
builtin/ls-files.c
+1 -3
@@ -209,10 +209,8 @@ static void show_submodule(struct repository *superproject,
209 struct dir_struct *dir, const char *path)
210 {
211 struct repository subrepo;
212 - const struct submodule *sub = submodule_from_path(superproject,
213 - null_oid(), path);
212
215 - if (repo_submodule_init(&subrepo, superproject, sub))
213 + if (repo_submodule_init(&subrepo, superproject, path, null_oid()))
214 return;
215
216 if (repo_read_index(&subrepo) < 0)
builtin/submodule--helper.c
+1 -6
@@ -2540,7 +2540,6 @@ static int push_check(int argc, const char **argv, const char *prefix)
2540
2541 static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
2542 {
2543 - const struct submodule *sub;
2543 const char *path;
2544 const char *cw;
2545 struct repository subrepo;
@@ -2550,11 +2549,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
2549
2550 path = argv[1];
2551
2553 - sub = submodule_from_path(the_repository, null_oid(), path);
2554 - if (!sub)
2555 - BUG("We could get the submodule handle before?");
2556 -
2557 - if (repo_submodule_init(&subrepo, the_repository, sub))
2552 + if (repo_submodule_init(&subrepo, the_repository, path, null_oid()))
2553 die(_("could not get a repository handle for submodule '%s'"), path);
2554
2555 if (!repo_config_get_string_tmp(&subrepo, "core.worktree", &cw)) {
repository.c
+12 -9
@@ -190,19 +190,15 @@ error:
190
191 int repo_submodule_init(struct repository *subrepo,
192 struct repository *superproject,
193 - const struct submodule *sub)
193 + const char *path,
194 + const struct object_id *treeish_name)
195 {
196 struct strbuf gitdir = STRBUF_INIT;
197 struct strbuf worktree = STRBUF_INIT;
198 int ret = 0;
199
199 - if (!sub) {
200 - ret = -1;
201 - goto out;
202 - }
203 -
204 - strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", sub->path);
205 - strbuf_repo_worktree_path(&worktree, superproject, "%s", sub->path);
200 + strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", path);
201 + strbuf_repo_worktree_path(&worktree, superproject, "%s", path);
202
203 if (repo_init(subrepo, gitdir.buf, worktree.buf)) {
204 /*
@@ -212,6 +208,13 @@ int repo_submodule_init(struct repository *subrepo,
208 * in the superproject's 'modules' directory. In this case the
209 * submodule would not have a worktree.
210 */
211 + const struct submodule *sub =
212 + submodule_from_path(superproject, treeish_name, path);
213 + if (!sub) {
214 + ret = -1;
215 + goto out;
216 + }
217 +
218 strbuf_reset(&gitdir);
219 strbuf_repo_git_path(&gitdir, superproject,
220 "modules/%s", sub->name);
@@ -225,7 +228,7 @@ int repo_submodule_init(struct repository *subrepo,
228 subrepo->submodule_prefix = xstrfmt("%s%s/",
229 superproject->submodule_prefix ?
230 superproject->submodule_prefix :
228 - "", sub->path);
231 + "", path);
232
233 out:
234 strbuf_release(&gitdir);
repository.h
+9 -6
@@ -172,15 +172,18 @@ void initialize_the_repository(void);
172 int repo_init(struct repository *r, const char *gitdir, const char *worktree);
173
174 /*
175 - * Initialize the repository 'subrepo' as the submodule given by the
176 - * struct submodule 'sub' in parent repository 'superproject'.
177 - * Return 0 upon success and a non-zero value upon failure, which may happen
178 - * if the submodule is not found, or 'sub' is NULL.
175 + * Initialize the repository 'subrepo' as the submodule at the given path. If
176 + * the submodule's gitdir cannot be found at <path>/.git, this function calls
177 + * submodule_from_path() to try to find it. treeish_name is only used if
178 + * submodule_from_path() needs to be called; see its documentation for more
179 + * information.
180 + * Return 0 upon success and a non-zero value upon failure.
181 */
180 -struct submodule;
182 +struct object_id;
183 int repo_submodule_init(struct repository *subrepo,
184 struct repository *superproject,
183 - const struct submodule *sub);
185 + const char *path,
186 + const struct object_id *treeish_name);
187 void repo_clear(struct repository *repo);
188
189 /*
submodule.c
+3 -6
@@ -520,9 +520,6 @@ static void prepare_submodule_repo_env_in_gitdir(struct strvec *out)
520 /*
521 * Initialize a repository struct for a submodule based on the provided 'path'.
522 *
523 - * Unlike repo_submodule_init, this tolerates submodules not present
524 - * in .gitmodules. This function exists only to preserve historical behavior,
525 - *
523 * Returns the repository struct on success,
524 * NULL when the submodule is not present.
525 */
@@ -1404,11 +1401,11 @@ static void fetch_task_release(struct fetch_task *p)
1401 }
1402
1403 static struct repository *get_submodule_repo_for(struct repository *r,
1407 - const struct submodule *sub)
1404 + const char *path)
1405 {
1406 struct repository *ret = xmalloc(sizeof(*ret));
1407
1411 - if (repo_submodule_init(ret, r, sub)) {
1408 + if (repo_submodule_init(ret, r, path, null_oid())) {
1409 free(ret);
1410 return NULL;
1411 }
@@ -1452,7 +1449,7 @@ static int get_next_submodule(struct child_process *cp,
1449 continue;
1450 }
1451
1455 - task->repo = get_submodule_repo_for(spf->r, task->sub);
1452 + task->repo = get_submodule_repo_for(spf->r, task->sub->path);
1453 if (task->repo) {
1454 struct strbuf submodule_prefix = STRBUF_INIT;
1455 child_process_init(cp);
t/helper/test-submodule-nested-repo-config.c
+1 -3
@@ -11,15 +11,13 @@ static void die_usage(const char **argv, const char *msg)
11 int cmd__submodule_nested_repo_config(int argc, const char **argv)
12 {
13 struct repository subrepo;
14 - const struct submodule *sub;
14
15 if (argc < 3)
16 die_usage(argv, "Wrong number of arguments.");
17
18 setup_git_directory();
19
21 - sub = submodule_from_path(the_repository, null_oid(), argv[1]);
22 - if (repo_submodule_init(&subrepo, the_repository, sub)) {
20 + if (repo_submodule_init(&subrepo, the_repository, argv[1], null_oid())) {
21 die_usage(argv, "Submodule not found.");
22 }
23