diff options
-rw-r--r-- | repository.c | 54 | ||||
-rw-r--r-- | repository.h | 10 |
2 files changed, 64 insertions, 0 deletions
diff --git a/repository.c b/repository.c index 358c175172..edca907404 100644 --- a/repository.c +++ b/repository.c @@ -144,6 +144,58 @@ error: return -1; } +/* + * Initialize 'submodule' as the submodule given by 'path' in parent repository + * 'superproject'. + * Return 0 upon success and a non-zero value upon failure. + */ +int repo_submodule_init(struct repository *submodule, + struct repository *superproject, + const char *path) +{ + const struct submodule *sub; + struct strbuf gitdir = STRBUF_INIT; + struct strbuf worktree = STRBUF_INIT; + int ret = 0; + + sub = submodule_from_cache(superproject, null_sha1, path); + if (!sub) { + ret = -1; + goto out; + } + + strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", path); + strbuf_repo_worktree_path(&worktree, superproject, "%s", path); + + if (repo_init(submodule, gitdir.buf, worktree.buf)) { + /* + * If initilization fails then it may be due to the submodule + * not being populated in the superproject's worktree. Instead + * we can try to initilize the submodule by finding it's gitdir + * in the superproject's 'modules' directory. In this case the + * submodule would not have a worktree. + */ + strbuf_reset(&gitdir); + strbuf_repo_git_path(&gitdir, superproject, + "modules/%s", sub->name); + + if (repo_init(submodule, gitdir.buf, NULL)) { + ret = -1; + goto out; + } + } + + submodule->submodule_prefix = xstrfmt("%s%s/", + superproject->submodule_prefix ? + superproject->submodule_prefix : + "", path); + +out: + strbuf_release(&gitdir); + strbuf_release(&worktree); + return ret; +} + void repo_clear(struct repository *repo) { free(repo->gitdir); @@ -158,6 +210,8 @@ void repo_clear(struct repository *repo) repo->index_file = NULL; free(repo->worktree); repo->worktree = NULL; + free(repo->submodule_prefix); + repo->submodule_prefix = NULL; if (repo->config) { git_configset_clear(repo->config); diff --git a/repository.h b/repository.h index c40738ceb8..417787f3ef 100644 --- a/repository.h +++ b/repository.h @@ -43,6 +43,13 @@ struct repository { */ char *worktree; + /* + * Path from the root of the top-level superproject down to this + * repository. This is only non-NULL if the repository is initialized + * as a submodule of another repository. + */ + char *submodule_prefix; + /* Subsystems */ /* * Repository's config which contains key-value pairs from the usual @@ -80,6 +87,9 @@ extern struct repository *the_repository; extern void repo_set_gitdir(struct repository *repo, const char *path); extern void repo_set_worktree(struct repository *repo, const char *path); extern int repo_init(struct repository *repo, const char *gitdir, const char *worktree); +extern int repo_submodule_init(struct repository *submodule, + struct repository *superproject, + const char *path); extern void repo_clear(struct repository *repo); extern int repo_read_index(struct repository *repo); |