static struct oid_array ref_tips_after_fetch;
/*
- * The following flag is set if the .gitmodules file is unmerged. We then
- * disable recursion for all submodules where .git/config doesn't have a
- * matching config entry because we can't guess what might be configured in
- * .gitmodules unless the user resolves the conflict. When a command line
- * option is given (which always overrides configuration) this flag will be
- * ignored.
+ * Check if the .gitmodules file is unmerged. Parsing of the .gitmodules file
+ * will be disabled because we can't guess what might be configured in
+ * .gitmodules unless the user resolves the conflict.
*/
-static int gitmodules_is_unmerged;
+int is_gitmodules_unmerged(const struct index_state *istate)
+{
+ int pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));
+ if (pos < 0) { /* .gitmodules not found or isn't merged */
+ pos = -1 - pos;
+ if (istate->cache_nr > pos) { /* there is a .gitmodules */
+ const struct cache_entry *ce = istate->cache[pos];
+ if (ce_namelen(ce) == strlen(GITMODULES_FILE) &&
+ !strcmp(ce->name, GITMODULES_FILE))
+ return 1;
+ }
+ }
+
+ return 0;
+}
/*
* Check if the .gitmodules file has unstaged modifications. This must be
if (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */
return -1;
- if (gitmodules_is_unmerged)
+ if (is_gitmodules_unmerged(&the_index))
die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
- submodule = submodule_from_path(null_sha1, oldpath);
+ submodule = submodule_from_path(&null_oid, oldpath);
if (!submodule || !submodule->name) {
warning(_("Could not find section in .gitmodules where path=%s"), oldpath);
return -1;
if (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */
return -1;
- if (gitmodules_is_unmerged)
+ if (is_gitmodules_unmerged(&the_index))
die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
- submodule = submodule_from_path(null_sha1, path);
+ submodule = submodule_from_path(&null_oid, path);
if (!submodule || !submodule->name) {
warning(_("Could not find section in .gitmodules where path=%s"), path);
return -1;
void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
const char *path)
{
- const struct submodule *submodule = submodule_from_path(null_sha1, path);
+ const struct submodule *submodule = submodule_from_path(&null_oid, path);
if (submodule) {
- if (submodule->ignore)
- handle_ignore_submodules_arg(diffopt, submodule->ignore);
- else if (gitmodules_is_unmerged)
- DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
- }
-}
+ const char *ignore;
+ char *key;
-/* For loading from the .gitmodules file. */
-static int git_modules_config(const char *var, const char *value, void *cb)
-{
- if (starts_with(var, "submodule."))
- return parse_submodule_config_option(var, value);
- return 0;
-}
+ key = xstrfmt("submodule.%s.ignore", submodule->name);
+ if (repo_config_get_string_const(the_repository, key, &ignore))
+ ignore = submodule->ignore;
+ free(key);
-/* Loads all submodule settings from the config. */
-int submodule_config(const char *var, const char *value, void *cb)
-{
- if (!strcmp(var, "submodule.recurse")) {
- int v = git_config_bool(var, value) ?
- RECURSE_SUBMODULES_ON : RECURSE_SUBMODULES_OFF;
- config_update_recurse_submodules = v;
- return 0;
- } else {
- return git_modules_config(var, value, cb);
+ if (ignore)
+ handle_ignore_submodules_arg(diffopt, ignore);
+ else if (is_gitmodules_unmerged(&the_index))
+ DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
}
}
return 0;
}
-void load_submodule_cache(void)
-{
- if (config_update_recurse_submodules == RECURSE_SUBMODULES_OFF)
- return;
-
- gitmodules_config();
- git_config(submodule_config, NULL);
-}
-
-void gitmodules_config(void)
-{
- const char *work_tree = get_git_work_tree();
- if (work_tree) {
- struct strbuf gitmodules_path = STRBUF_INIT;
- int pos;
- strbuf_addstr(&gitmodules_path, work_tree);
- strbuf_addstr(&gitmodules_path, "/" GITMODULES_FILE);
- if (read_cache() < 0)
- die("index file corrupt");
- pos = cache_name_pos(GITMODULES_FILE, 11);
- if (pos < 0) { /* .gitmodules not found or isn't merged */
- pos = -1 - pos;
- if (active_nr > pos) { /* there is a .gitmodules */
- const struct cache_entry *ce = active_cache[pos];
- if (ce_namelen(ce) == 11 &&
- !memcmp(ce->name, GITMODULES_FILE, 11))
- gitmodules_is_unmerged = 1;
- }
- }
-
- if (!gitmodules_is_unmerged)
- git_config_from_file(git_modules_config,
- gitmodules_path.buf, NULL);
- strbuf_release(&gitmodules_path);
- }
-}
-
-static int gitmodules_cb(const char *var, const char *value, void *data)
-{
- struct repository *repo = data;
- return submodule_config_option(repo, var, value);
-}
-
-void repo_read_gitmodules(struct repository *repo)
-{
- char *gitmodules_path = repo_worktree_path(repo, GITMODULES_FILE);
-
- git_config_from_file(gitmodules_cb, gitmodules_path, repo);
- free(gitmodules_path);
-}
-
-void gitmodules_config_sha1(const unsigned char *commit_sha1)
-{
- struct strbuf rev = STRBUF_INIT;
- unsigned char sha1[20];
-
- if (gitmodule_sha1_from_commit(commit_sha1, sha1, &rev)) {
- git_config_from_blob_sha1(git_modules_config, rev.buf,
- sha1, NULL);
- }
- strbuf_release(&rev);
-}
-
/*
* Determine if a submodule has been initialized at a given 'path'
*/
const struct string_list *sl;
const struct submodule *module;
- module = submodule_from_cache(repo, null_sha1, path);
+ module = submodule_from_cache(repo, &null_oid, path);
/* early return if there isn't a path->module mapping */
if (!module)
}
}
-int parse_submodule_update_strategy(const char *value,
- struct submodule_update_strategy *dst)
+enum submodule_update_type parse_submodule_update_type(const char *value)
{
- free((void*)dst->command);
- dst->command = NULL;
if (!strcmp(value, "none"))
- dst->type = SM_UPDATE_NONE;
+ return SM_UPDATE_NONE;
else if (!strcmp(value, "checkout"))
- dst->type = SM_UPDATE_CHECKOUT;
+ return SM_UPDATE_CHECKOUT;
else if (!strcmp(value, "rebase"))
- dst->type = SM_UPDATE_REBASE;
+ return SM_UPDATE_REBASE;
else if (!strcmp(value, "merge"))
- dst->type = SM_UPDATE_MERGE;
- else if (skip_prefix(value, "!", &value)) {
- dst->type = SM_UPDATE_COMMAND;
- dst->command = xstrdup(value);
- } else
+ return SM_UPDATE_MERGE;
+ else if (*value == '!')
+ return SM_UPDATE_COMMAND;
+ else
+ return SM_UPDATE_UNSPECIFIED;
+}
+
+int parse_submodule_update_strategy(const char *value,
+ struct submodule_update_strategy *dst)
+{
+ enum submodule_update_type type;
+
+ free((void*)dst->command);
+ dst->command = NULL;
+
+ type = parse_submodule_update_type(value);
+ if (type == SM_UPDATE_UNSPECIFIED)
return -1;
+
+ dst->type = type;
+ if (type == SM_UPDATE_COMMAND)
+ dst->command = xstrdup(value + 1);
+
return 0;
}
if (!should_update_submodules())
return NULL;
- return submodule_from_path(null_sha1, ce->name);
+ return submodule_from_path(&null_oid, ce->name);
}
static struct oid_array *submodule_commits(struct string_list *submodules,
struct argv_array args = ARGV_ARRAY_INIT;
int ret;
- gitmodules_config();
/* No need to check if there are no submodules configured */
if (!submodule_from_path(NULL, NULL))
return 0;
if (!S_ISGITLINK(ce->ce_mode))
continue;
- submodule = submodule_from_path(null_sha1, ce->name);
- if (!submodule)
- submodule = submodule_from_name(null_sha1, ce->name);
+ submodule = submodule_from_path(&null_oid, ce->name);
default_argv = "yes";
if (spf->command_line_option == RECURSE_SUBMODULES_DEFAULT) {
- if (submodule &&
- submodule->fetch_recurse !=
- RECURSE_SUBMODULES_NONE) {
- if (submodule->fetch_recurse ==
- RECURSE_SUBMODULES_OFF)
+ int fetch_recurse = RECURSE_SUBMODULES_NONE;
+
+ if (submodule) {
+ char *key;
+ const char *value;
+
+ fetch_recurse = submodule->fetch_recurse;
+ key = xstrfmt("submodule.%s.fetchRecurseSubmodules", submodule->name);
+ if (!repo_config_get_string_const(the_repository, key, &value)) {
+ fetch_recurse = parse_fetch_recurse_submodules_arg(key, value);
+ }
+ free(key);
+ }
+
+ if (fetch_recurse != RECURSE_SUBMODULES_NONE) {
+ if (fetch_recurse == RECURSE_SUBMODULES_OFF)
continue;
- if (submodule->fetch_recurse ==
- RECURSE_SUBMODULES_ON_DEMAND) {
+ if (fetch_recurse == RECURSE_SUBMODULES_ON_DEMAND) {
if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name))
continue;
default_argv = "on-demand";
}
} else {
- if ((spf->default_option == RECURSE_SUBMODULES_OFF) ||
- gitmodules_is_unmerged)
+ if (spf->default_option == RECURSE_SUBMODULES_OFF)
continue;
if (spf->default_option == RECURSE_SUBMODULES_ON_DEMAND) {
if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name))
if (old && !is_submodule_populated_gently(path, error_code_ptr))
return 0;
- sub = submodule_from_path(null_sha1, path);
+ sub = submodule_from_path(&null_oid, path);
if (!sub)
die("BUG: could not get submodule information for '%s'", path);
real_old_git_dir = real_pathdup(old_git_dir, 1);
- sub = submodule_from_path(null_sha1, path);
+ sub = submodule_from_path(&null_oid, path);
if (!sub)
die(_("could not lookup name for submodule '%s'"), path);
* superproject did not rewrite the git file links yet,
* fix it now.
*/
- sub = submodule_from_path(null_sha1, path);
+ sub = submodule_from_path(&null_oid, path);
if (!sub)
die(_("could not lookup name for submodule '%s'"), path);
connect_work_tree_and_git_dir(path,
strbuf_addstr(buf, git_dir);
}
if (!is_git_directory(buf->buf)) {
- gitmodules_config();
- sub = submodule_from_path(null_sha1, submodule);
+ sub = submodule_from_path(&null_oid, submodule);
if (!sub) {
ret = -1;
goto cleanup;