From 823bab09c68b4048e433ab48b9185302c2f4b63a Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Tue, 18 Apr 2017 14:37:23 -0700 Subject: submodule.c: uninitialized submodules are ignored in recursive commands This was an oversight when working on the working tree modifying commands recursing into submodules. To test for uninitialized submodules, introduce another submodule "uninitialized_sub". Adding it via `submodule add` will activate the submodule in the preparation area (in create_lib_submodule_repo we setup all the things in submodule_update_repo), but the later tests will use a new testing repo that clones the preparation repo in which the new submodule is not initialized. By adding it to the branch "add_sub1", which is the starting point of all other branches, we have wide coverage. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- submodule.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'submodule.c') diff --git a/submodule.c b/submodule.c index 7c3c4b17fb..ccf8932731 100644 --- a/submodule.c +++ b/submodule.c @@ -1333,6 +1333,9 @@ int submodule_move_head(const char *path, struct child_process cp = CHILD_PROCESS_INIT; const struct submodule *sub; + if (!is_submodule_initialized(path)) + return 0; + sub = submodule_from_path(null_sha1, path); if (!sub) -- cgit v1.2.1 From f2d48994dc11ba367e92c38c8025c3354418145a Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Tue, 18 Apr 2017 14:37:24 -0700 Subject: submodule.c: submodule_move_head works with broken submodules Early on in submodule_move_head just after the check if the submodule is initialized, we need to check if the submodule is populated correctly. If the submodule is initialized but doesn't look like it is populated, this is a red flag and can indicate multiple sorts of failures: (1) The submodule may be recorded at an object name, that is missing. (2) The submodule '.git' file link may be broken and it is not pointing at a repository. In both cases we want to complain to the user in the non-forced mode, and in the forced mode ignoring the old state and just moving the submodule into its new state with a fixed '.git' file link. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- submodule.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'submodule.c') diff --git a/submodule.c b/submodule.c index ccf8932731..20ed5b5681 100644 --- a/submodule.c +++ b/submodule.c @@ -1332,10 +1332,24 @@ int submodule_move_head(const char *path, int ret = 0; struct child_process cp = CHILD_PROCESS_INIT; const struct submodule *sub; + int *error_code_ptr, error_code; if (!is_submodule_initialized(path)) return 0; + if (flags & SUBMODULE_MOVE_HEAD_FORCE) + /* + * Pass non NULL pointer to is_submodule_populated_gently + * to prevent die()-ing. We'll use connect_work_tree_and_git_dir + * to fixup the submodule in the force case later. + */ + error_code_ptr = &error_code; + else + error_code_ptr = NULL; + + if (old && !is_submodule_populated_gently(path, error_code_ptr)) + return 0; + sub = submodule_from_path(null_sha1, path); if (!sub) @@ -1353,15 +1367,21 @@ int submodule_move_head(const char *path, absorb_git_dir_into_superproject("", path, ABSORB_GITDIR_RECURSE_SUBMODULES); } else { - struct strbuf sb = STRBUF_INIT; - strbuf_addf(&sb, "%s/modules/%s", + char *gitdir = xstrfmt("%s/modules/%s", get_git_common_dir(), sub->name); - connect_work_tree_and_git_dir(path, sb.buf); - strbuf_release(&sb); + connect_work_tree_and_git_dir(path, gitdir); + free(gitdir); /* make sure the index is clean as well */ submodule_reset_index(path); } + + if (old && (flags & SUBMODULE_MOVE_HEAD_FORCE)) { + char *gitdir = xstrfmt("%s/modules/%s", + get_git_common_dir(), sub->name); + connect_work_tree_and_git_dir(path, gitdir); + free(gitdir); + } } prepare_submodule_repo_env_no_git_dir(&cp.env_array); -- cgit v1.2.1