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>
This commit is contained in:
Jonathan Tan 2021-09-09 11:47:28 -07:00 committed by Junio C Hamano
parent 5df5106e1e
commit 8eb8dcf946
7 changed files with 28 additions and 37 deletions

View File

@ -433,17 +433,14 @@ static int grep_submodule(struct grep_opt *opt,
{ {
struct repository *subrepo; struct repository *subrepo;
struct repository *superproject = opt->repo; struct repository *superproject = opt->repo;
const struct submodule *sub;
struct grep_opt subopt; struct grep_opt subopt;
int hit = 0; int hit = 0;
sub = submodule_from_path(superproject, null_oid(), path);
if (!is_submodule_active(superproject, path)) if (!is_submodule_active(superproject, path))
return 0; return 0;
subrepo = xmalloc(sizeof(*subrepo)); subrepo = xmalloc(sizeof(*subrepo));
if (repo_submodule_init(subrepo, superproject, sub)) { if (repo_submodule_init(subrepo, superproject, path, null_oid())) {
free(subrepo); free(subrepo);
return 0; return 0;
} }

View File

@ -209,10 +209,8 @@ static void show_submodule(struct repository *superproject,
struct dir_struct *dir, const char *path) struct dir_struct *dir, const char *path)
{ {
struct repository subrepo; struct repository subrepo;
const struct submodule *sub = submodule_from_path(superproject,
null_oid(), path);
if (repo_submodule_init(&subrepo, superproject, sub)) if (repo_submodule_init(&subrepo, superproject, path, null_oid()))
return; return;
if (repo_read_index(&subrepo) < 0) if (repo_read_index(&subrepo) < 0)

View File

@ -2540,7 +2540,6 @@ static int push_check(int argc, const char **argv, const char *prefix)
static int ensure_core_worktree(int argc, const char **argv, const char *prefix) static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
{ {
const struct submodule *sub;
const char *path; const char *path;
const char *cw; const char *cw;
struct repository subrepo; struct repository subrepo;
@ -2550,11 +2549,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
path = argv[1]; path = argv[1];
sub = submodule_from_path(the_repository, null_oid(), path); if (repo_submodule_init(&subrepo, the_repository, path, null_oid()))
if (!sub)
BUG("We could get the submodule handle before?");
if (repo_submodule_init(&subrepo, the_repository, sub))
die(_("could not get a repository handle for submodule '%s'"), path); die(_("could not get a repository handle for submodule '%s'"), path);
if (!repo_config_get_string_tmp(&subrepo, "core.worktree", &cw)) { if (!repo_config_get_string_tmp(&subrepo, "core.worktree", &cw)) {

View File

@ -190,19 +190,15 @@ error:
int repo_submodule_init(struct repository *subrepo, int repo_submodule_init(struct repository *subrepo,
struct repository *superproject, struct repository *superproject,
const struct submodule *sub) const char *path,
const struct object_id *treeish_name)
{ {
struct strbuf gitdir = STRBUF_INIT; struct strbuf gitdir = STRBUF_INIT;
struct strbuf worktree = STRBUF_INIT; struct strbuf worktree = STRBUF_INIT;
int ret = 0; int ret = 0;
if (!sub) { strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", path);
ret = -1; strbuf_repo_worktree_path(&worktree, superproject, "%s", path);
goto out;
}
strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", sub->path);
strbuf_repo_worktree_path(&worktree, superproject, "%s", sub->path);
if (repo_init(subrepo, gitdir.buf, worktree.buf)) { if (repo_init(subrepo, gitdir.buf, worktree.buf)) {
/* /*
@ -212,6 +208,13 @@ int repo_submodule_init(struct repository *subrepo,
* in the superproject's 'modules' directory. In this case the * in the superproject's 'modules' directory. In this case the
* submodule would not have a worktree. * submodule would not have a worktree.
*/ */
const struct submodule *sub =
submodule_from_path(superproject, treeish_name, path);
if (!sub) {
ret = -1;
goto out;
}
strbuf_reset(&gitdir); strbuf_reset(&gitdir);
strbuf_repo_git_path(&gitdir, superproject, strbuf_repo_git_path(&gitdir, superproject,
"modules/%s", sub->name); "modules/%s", sub->name);
@ -225,7 +228,7 @@ int repo_submodule_init(struct repository *subrepo,
subrepo->submodule_prefix = xstrfmt("%s%s/", subrepo->submodule_prefix = xstrfmt("%s%s/",
superproject->submodule_prefix ? superproject->submodule_prefix ?
superproject->submodule_prefix : superproject->submodule_prefix :
"", sub->path); "", path);
out: out:
strbuf_release(&gitdir); strbuf_release(&gitdir);

View File

@ -172,15 +172,18 @@ void initialize_the_repository(void);
int repo_init(struct repository *r, const char *gitdir, const char *worktree); int repo_init(struct repository *r, const char *gitdir, const char *worktree);
/* /*
* Initialize the repository 'subrepo' as the submodule given by the * Initialize the repository 'subrepo' as the submodule at the given path. If
* struct submodule 'sub' in parent repository 'superproject'. * the submodule's gitdir cannot be found at <path>/.git, this function calls
* Return 0 upon success and a non-zero value upon failure, which may happen * submodule_from_path() to try to find it. treeish_name is only used if
* if the submodule is not found, or 'sub' is NULL. * submodule_from_path() needs to be called; see its documentation for more
* information.
* Return 0 upon success and a non-zero value upon failure.
*/ */
struct submodule; struct object_id;
int repo_submodule_init(struct repository *subrepo, int repo_submodule_init(struct repository *subrepo,
struct repository *superproject, struct repository *superproject,
const struct submodule *sub); const char *path,
const struct object_id *treeish_name);
void repo_clear(struct repository *repo); void repo_clear(struct repository *repo);
/* /*

View File

@ -520,9 +520,6 @@ static void prepare_submodule_repo_env_in_gitdir(struct strvec *out)
/* /*
* Initialize a repository struct for a submodule based on the provided 'path'. * Initialize a repository struct for a submodule based on the provided 'path'.
* *
* Unlike repo_submodule_init, this tolerates submodules not present
* in .gitmodules. This function exists only to preserve historical behavior,
*
* Returns the repository struct on success, * Returns the repository struct on success,
* NULL when the submodule is not present. * NULL when the submodule is not present.
*/ */
@ -1404,11 +1401,11 @@ static void fetch_task_release(struct fetch_task *p)
} }
static struct repository *get_submodule_repo_for(struct repository *r, static struct repository *get_submodule_repo_for(struct repository *r,
const struct submodule *sub) const char *path)
{ {
struct repository *ret = xmalloc(sizeof(*ret)); struct repository *ret = xmalloc(sizeof(*ret));
if (repo_submodule_init(ret, r, sub)) { if (repo_submodule_init(ret, r, path, null_oid())) {
free(ret); free(ret);
return NULL; return NULL;
} }
@ -1452,7 +1449,7 @@ static int get_next_submodule(struct child_process *cp,
continue; continue;
} }
task->repo = get_submodule_repo_for(spf->r, task->sub); task->repo = get_submodule_repo_for(spf->r, task->sub->path);
if (task->repo) { if (task->repo) {
struct strbuf submodule_prefix = STRBUF_INIT; struct strbuf submodule_prefix = STRBUF_INIT;
child_process_init(cp); child_process_init(cp);

View File

@ -11,15 +11,13 @@ static void die_usage(const char **argv, const char *msg)
int cmd__submodule_nested_repo_config(int argc, const char **argv) int cmd__submodule_nested_repo_config(int argc, const char **argv)
{ {
struct repository subrepo; struct repository subrepo;
const struct submodule *sub;
if (argc < 3) if (argc < 3)
die_usage(argv, "Wrong number of arguments."); die_usage(argv, "Wrong number of arguments.");
setup_git_directory(); setup_git_directory();
sub = submodule_from_path(the_repository, null_oid(), argv[1]); if (repo_submodule_init(&subrepo, the_repository, argv[1], null_oid())) {
if (repo_submodule_init(&subrepo, the_repository, sub)) {
die_usage(argv, "Submodule not found."); die_usage(argv, "Submodule not found.");
} }