summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--repository.c54
-rw-r--r--repository.h10
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);