in src/submodule.c [252:365]
int git_submodule_lookup(
git_submodule **out, /* NULL if user only wants to test existence */
git_repository *repo,
const char *name) /* trailing slash is allowed */
{
int error;
unsigned int location;
git_submodule *sm;
assert(repo && name);
if (repo->is_bare) {
git_error_set(GIT_ERROR_SUBMODULE, "cannot get submodules without a working tree");
return -1;
}
if (repo->submodule_cache != NULL) {
if ((sm = git_strmap_get(repo->submodule_cache, name)) != NULL) {
if (out) {
*out = sm;
GIT_REFCOUNT_INC(*out);
}
return 0;
}
}
if ((error = submodule_alloc(&sm, repo, name)) < 0)
return error;
if ((error = git_submodule_reload(sm, false)) < 0) {
git_submodule_free(sm);
return error;
}
if ((error = git_submodule_location(&location, sm)) < 0) {
git_submodule_free(sm);
return error;
}
/* If it's not configured or we're looking by path */
if (location == 0 || location == GIT_SUBMODULE_STATUS_IN_WD) {
git_config_backend *mods;
const char *pattern = "submodule\\..*\\.path";
git_buf path = GIT_BUF_INIT;
fbp_data data = { NULL, NULL };
git_buf_puts(&path, name);
while (path.ptr[path.size-1] == '/') {
path.ptr[--path.size] = '\0';
}
data.path = path.ptr;
mods = open_gitmodules(repo, GITMODULES_EXISTING);
if (mods)
error = git_config_backend_foreach_match(mods, pattern, find_by_path, &data);
git_config_backend_free(mods);
if (error < 0) {
git_submodule_free(sm);
git_buf_dispose(&path);
return error;
}
if (data.name) {
git__free(sm->name);
sm->name = data.name;
sm->path = git_buf_detach(&path);
/* Try to load again with the right name */
if ((error = git_submodule_reload(sm, false)) < 0) {
git_submodule_free(sm);
return error;
}
}
git_buf_dispose(&path);
}
if ((error = git_submodule_location(&location, sm)) < 0) {
git_submodule_free(sm);
return error;
}
/* If we still haven't found it, do the WD check */
if (location == 0 || location == GIT_SUBMODULE_STATUS_IN_WD) {
git_submodule_free(sm);
error = GIT_ENOTFOUND;
/* If it's not configured, we still check if there's a repo at the path */
if (git_repository_workdir(repo)) {
git_buf path = GIT_BUF_INIT;
if (git_buf_join3(&path,
'/', git_repository_workdir(repo), name, DOT_GIT) < 0)
return -1;
if (git_path_exists(path.ptr))
error = GIT_EEXISTS;
git_buf_dispose(&path);
}
submodule_set_lookup_error(error, name);
return error;
}
if (out)
*out = sm;
else
git_submodule_free(sm);
return 0;
}