Skip to content

Commit 96dc883

Browse files
bmwillgitster
authored andcommitted
repository: enable initialization of submodules
Introduce 'repo_submodule_init()' which performs initialization of a 'struct repository' as a submodule of another 'struct repository'. The resulting submodule 'struct repository' can be in one of three states: 1. The submodule is initialized and has a worktree. 2. The submodule is initialized but does not have a worktree. This would occur when the submodule's gitdir is present in the superproject's 'gitdir/modules/' directory yet the submodule has not been checked out in superproject's worktree. 3. The submodule remains uninitialized due to an error in the initialization process or there is no matching submodule at the provided path in the superproject. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 627d934 commit 96dc883

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

repository.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,58 @@ int repo_init(struct repository *repo, const char *gitdir, const char *worktree)
144144
return -1;
145145
}
146146

147+
/*
148+
* Initialize 'submodule' as the submodule given by 'path' in parent repository
149+
* 'superproject'.
150+
* Return 0 upon success and a non-zero value upon failure.
151+
*/
152+
int repo_submodule_init(struct repository *submodule,
153+
struct repository *superproject,
154+
const char *path)
155+
{
156+
const struct submodule *sub;
157+
struct strbuf gitdir = STRBUF_INIT;
158+
struct strbuf worktree = STRBUF_INIT;
159+
int ret = 0;
160+
161+
sub = submodule_from_cache(superproject, null_sha1, path);
162+
if (!sub) {
163+
ret = -1;
164+
goto out;
165+
}
166+
167+
strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", path);
168+
strbuf_repo_worktree_path(&worktree, superproject, "%s", path);
169+
170+
if (repo_init(submodule, gitdir.buf, worktree.buf)) {
171+
/*
172+
* If initilization fails then it may be due to the submodule
173+
* not being populated in the superproject's worktree. Instead
174+
* we can try to initilize the submodule by finding it's gitdir
175+
* in the superproject's 'modules' directory. In this case the
176+
* submodule would not have a worktree.
177+
*/
178+
strbuf_reset(&gitdir);
179+
strbuf_repo_git_path(&gitdir, superproject,
180+
"modules/%s", sub->name);
181+
182+
if (repo_init(submodule, gitdir.buf, NULL)) {
183+
ret = -1;
184+
goto out;
185+
}
186+
}
187+
188+
submodule->submodule_prefix = xstrfmt("%s%s/",
189+
superproject->submodule_prefix ?
190+
superproject->submodule_prefix :
191+
"", path);
192+
193+
out:
194+
strbuf_release(&gitdir);
195+
strbuf_release(&worktree);
196+
return ret;
197+
}
198+
147199
void repo_clear(struct repository *repo)
148200
{
149201
free(repo->gitdir);
@@ -158,6 +210,8 @@ void repo_clear(struct repository *repo)
158210
repo->index_file = NULL;
159211
free(repo->worktree);
160212
repo->worktree = NULL;
213+
free(repo->submodule_prefix);
214+
repo->submodule_prefix = NULL;
161215

162216
if (repo->config) {
163217
git_configset_clear(repo->config);

repository.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ struct repository {
4343
*/
4444
char *worktree;
4545

46+
/*
47+
* Path from the root of the top-level superproject down to this
48+
* repository. This is only non-NULL if the repository is initialized
49+
* as a submodule of another repository.
50+
*/
51+
char *submodule_prefix;
52+
4653
/* Subsystems */
4754
/*
4855
* Repository's config which contains key-value pairs from the usual
@@ -80,6 +87,9 @@ extern struct repository *the_repository;
8087
extern void repo_set_gitdir(struct repository *repo, const char *path);
8188
extern void repo_set_worktree(struct repository *repo, const char *path);
8289
extern int repo_init(struct repository *repo, const char *gitdir, const char *worktree);
90+
extern int repo_submodule_init(struct repository *submodule,
91+
struct repository *superproject,
92+
const char *path);
8393
extern void repo_clear(struct repository *repo);
8494

8595
extern int repo_read_index(struct repository *repo);

0 commit comments

Comments
 (0)