summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--submodule.c31
-rwxr-xr-xt/t7506-status-submodule.sh6
2 files changed, 32 insertions, 5 deletions
diff --git a/submodule.c b/submodule.c
index 5294cef641..b6dec70bd1 100644
--- a/submodule.c
+++ b/submodule.c
@@ -14,6 +14,15 @@ static struct string_list config_fetch_recurse_submodules_for_name;
static struct string_list config_ignore_for_name;
static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
static struct string_list changed_submodule_paths;
+/*
+ * 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.
+ */
+static int gitmodules_is_unmerged;
static int add_submodule_odb(const char *path)
{
@@ -63,6 +72,8 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
ignore_option = unsorted_string_list_lookup(&config_ignore_for_name, path_option->util);
if (ignore_option)
handle_ignore_submodules_arg(diffopt, ignore_option->util);
+ else if (gitmodules_is_unmerged)
+ DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
}
}
@@ -82,9 +93,24 @@ 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");
- git_config_from_file(submodule_config, gitmodules_path.buf, NULL);
+ if (read_cache() < 0)
+ die("index file corrupt");
+ pos = cache_name_pos(".gitmodules", 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", 11))
+ gitmodules_is_unmerged = 1;
+ }
+ }
+
+ if (!gitmodules_is_unmerged)
+ git_config_from_file(submodule_config, gitmodules_path.buf, NULL);
strbuf_release(&gitmodules_path);
}
}
@@ -434,7 +460,8 @@ int fetch_populated_submodules(int num_options, const char **options,
default_argv = "on-demand";
}
} else {
- if (config_fetch_recurse_submodules == RECURSE_SUBMODULES_OFF)
+ if ((config_fetch_recurse_submodules == RECURSE_SUBMODULES_OFF) ||
+ gitmodules_is_unmerged)
continue;
if (config_fetch_recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) {
if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name))
diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh
index c2c53441ed..e80e6bb59c 100755
--- a/t/t7506-status-submodule.sh
+++ b/t/t7506-status-submodule.sh
@@ -196,7 +196,7 @@ AA .gitmodules
A sub1
EOF
-test_expect_failure 'status with merge conflict in .gitmodules' '
+test_expect_success 'status with merge conflict in .gitmodules' '
git clone . super &&
test_create_repo_with_commit sub1 &&
test_tick &&
@@ -255,7 +255,7 @@ index badaa4c,44f999a..0000000
++>>>>>>> add_sub1
EOF
-test_expect_failure 'diff with merge conflict in .gitmodules' '
+test_expect_success 'diff with merge conflict in .gitmodules' '
(
cd super &&
git diff >../diff_actual 2>&1
@@ -263,7 +263,7 @@ test_expect_failure 'diff with merge conflict in .gitmodules' '
test_cmp diff_actual diff_expect
'
-test_expect_failure 'diff --submodule with merge conflict in .gitmodules' '
+test_expect_success 'diff --submodule with merge conflict in .gitmodules' '
(
cd super &&
git diff --submodule >../diff_submodule_actual 2>&1