}
/*
+ * NEEDSWORK: With the addition of different configuration options to determine
+ * if a submodule is of interests, the validity of this function's name comes
+ * into question. Once the dust has settled and more concrete terminology is
+ * decided upon, come up with a more proper name for this function. One
+ * potential candidate could be 'is_submodule_active()'.
+ *
* Determine if a submodule has been initialized at a given 'path'
*/
int is_submodule_initialized(const char *path)
{
int ret = 0;
- const struct submodule *module = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ const struct string_list *sl;
+ const struct submodule *module = submodule_from_path(null_sha1, path);
- module = submodule_from_path(null_sha1, path);
+ /* early return if there isn't a path->module mapping */
+ if (!module)
+ return 0;
- if (module) {
- char *key = xstrfmt("submodule.%s.url", module->name);
- char *value = NULL;
+ /* submodule.<name>.active is set */
+ key = xstrfmt("submodule.%s.active", module->name);
+ if (!git_config_get_bool(key, &ret)) {
+ free(key);
+ return ret;
+ }
+ free(key);
- ret = !git_config_get_string(key, &value);
+ /* submodule.active is set */
+ sl = git_config_get_value_multi("submodule.active");
+ if (sl) {
+ struct pathspec ps;
+ struct argv_array args = ARGV_ARRAY_INIT;
+ const struct string_list_item *item;
- free(value);
- free(key);
+ for_each_string_list_item(item, sl) {
+ argv_array_push(&args, item->string);
+ }
+
+ parse_pathspec(&ps, 0, 0, NULL, args.argv);
+ ret = match_pathspec(&ps, path, strlen(path), 0, NULL, 1);
+
+ argv_array_clear(&args);
+ clear_pathspec(&ps);
+ return ret;
}
+ /* fallback to checking if the URL is set */
+ key = xstrfmt("submodule.%s.url", module->name);
+ ret = !git_config_get_string(key, &value);
+
+ free(value);
+ free(key);
return ret;
}
/* If it is an actual gitfile, it doesn't need migration. */
return;
- real_old_git_dir = real_pathdup(old_git_dir);
+ real_old_git_dir = real_pathdup(old_git_dir, 1);
sub = submodule_from_path(null_sha1, path);
if (!sub)
new_git_dir = git_path("modules/%s", sub->name);
if (safe_create_leading_directories_const(new_git_dir) < 0)
die(_("could not create directory '%s'"), new_git_dir);
- real_new_git_dir = real_pathdup(new_git_dir);
+ real_new_git_dir = real_pathdup(new_git_dir, 1);
if (!prefix)
prefix = get_super_prefix();
const char *path,
unsigned flags)
{
- const char *sub_git_dir, *v;
- char *real_sub_git_dir = NULL, *real_common_git_dir = NULL;
+ int err_code;
+ const char *sub_git_dir;
struct strbuf gitdir = STRBUF_INIT;
-
strbuf_addf(&gitdir, "%s/.git", path);
- sub_git_dir = resolve_gitdir(gitdir.buf);
+ sub_git_dir = resolve_gitdir_gently(gitdir.buf, &err_code);
/* Not populated? */
- if (!sub_git_dir)
- goto out;
+ if (!sub_git_dir) {
+ char *real_new_git_dir;
+ const char *new_git_dir;
+ const struct submodule *sub;
+
+ if (err_code == READ_GITFILE_ERR_STAT_FAILED) {
+ /* unpopulated as expected */
+ strbuf_release(&gitdir);
+ return;
+ }
+
+ if (err_code != READ_GITFILE_ERR_NOT_A_REPO)
+ /* We don't know what broke here. */
+ read_gitfile_error_die(err_code, path, NULL);
+
+ /*
+ * Maybe populated, but no git directory was found?
+ * This can happen if the superproject is a submodule
+ * itself and was just absorbed. The absorption of the
+ * superproject did not rewrite the git file links yet,
+ * fix it now.
+ */
+ sub = submodule_from_path(null_sha1, path);
+ if (!sub)
+ die(_("could not lookup name for submodule '%s'"), path);
+ new_git_dir = git_path("modules/%s", sub->name);
+ if (safe_create_leading_directories_const(new_git_dir) < 0)
+ die(_("could not create directory '%s'"), new_git_dir);
+ real_new_git_dir = real_pathdup(new_git_dir, 1);
+ connect_work_tree_and_git_dir(path, real_new_git_dir);
+
+ free(real_new_git_dir);
+ } else {
+ /* Is it already absorbed into the superprojects git dir? */
+ char *real_sub_git_dir = real_pathdup(sub_git_dir, 1);
+ char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1);
- /* Is it already absorbed into the superprojects git dir? */
- real_sub_git_dir = real_pathdup(sub_git_dir);
- real_common_git_dir = real_pathdup(get_git_common_dir());
- if (!skip_prefix(real_sub_git_dir, real_common_git_dir, &v))
- relocate_single_git_dir_into_superproject(prefix, path);
+ if (!starts_with(real_sub_git_dir, real_common_git_dir))
+ relocate_single_git_dir_into_superproject(prefix, path);
+
+ free(real_sub_git_dir);
+ free(real_common_git_dir);
+ }
+ strbuf_release(&gitdir);
if (flags & ABSORB_GITDIR_RECURSE_SUBMODULES) {
struct child_process cp = CHILD_PROCESS_INIT;
strbuf_release(&sb);
}
-
-out:
- strbuf_release(&gitdir);
- free(real_sub_git_dir);
- free(real_common_git_dir);
}