Merge branch 'sb/submodule-core-worktree'
authorJunio C Hamano <gitster@pobox.com>
Wed, 18 Jul 2018 19:20:28 +0000 (12:20 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 18 Jul 2018 19:20:28 +0000 (12:20 -0700)
"git submodule" did not correctly adjust core.worktree setting that
indicates whether/where a submodule repository has its associated
working tree across various state transitions, which has been
corrected.

* sb/submodule-core-worktree:
submodule deinit: unset core.worktree
submodule: ensure core.worktree is set after update
submodule: unset core.worktree if no working tree is present

builtin/submodule--helper.c
git-submodule.sh
submodule.c
submodule.h
t/lib-submodule-update.sh
t/t7400-submodule-basic.sh
index 20ae9191ca376841ca2540502d85a3dc150d3417..216e3daf5c9ea95d174efc89be2f42942d85472e 100644 (file)
@@ -1124,6 +1124,8 @@ static void deinit_submodule(const char *path, const char *prefix,
                if (!(flags & OPT_QUIET))
                        printf(format, displaypath);
 
+               submodule_unset_core_worktree(sub);
+
                strbuf_release(&sb_rm);
        }
 
@@ -2004,6 +2006,29 @@ static int check_name(int argc, const char **argv, const char *prefix)
        return 0;
 }
 
+static int connect_gitdir_workingtree(int argc, const char **argv, const char *prefix)
+{
+       struct strbuf sb = STRBUF_INIT;
+       const char *name, *path;
+       char *sm_gitdir;
+
+       if (argc != 3)
+               BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
+
+       name = argv[1];
+       path = argv[2];
+
+       strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
+       sm_gitdir = absolute_pathdup(sb.buf);
+
+       connect_work_tree_and_git_dir(path, sm_gitdir, 0);
+
+       strbuf_release(&sb);
+       free(sm_gitdir);
+
+       return 0;
+}
+
 #define SUPPORT_SUPER_PREFIX (1<<0)
 
 struct cmd_struct {
@@ -2017,6 +2042,7 @@ static struct cmd_struct commands[] = {
        {"name", module_name, 0},
        {"clone", module_clone, 0},
        {"update-clone", update_clone, 0},
+       {"connect-gitdir-workingtree", connect_gitdir_workingtree, 0},
        {"relative-path", resolve_relative_path, 0},
        {"resolve-relative-url", resolve_relative_url, 0},
        {"resolve-relative-url-test", resolve_relative_url_test, 0},
index 5f9d9f6ea3713be458c006501c503d8d660e9ddf..8b5ad59bdee39eba4fc56b28d6771a291dac55f0 100755 (executable)
@@ -577,6 +577,11 @@ cmd_update()
                        die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
                fi
 
+               if ! $(git config -f "$(git rev-parse --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
+               then
+                       git submodule--helper connect-gitdir-workingtree "$name" "$sm_path"
+               fi
+
                if test "$subsha1" != "$sha1" || test -n "$force"
                then
                        subforce=$force
index 0998ea2345800449c08bca12fbedd236f6b55eb6..d3a9aab83dc90b0c7797cc4b83d0a83bf6c196b7 100644 (file)
@@ -1534,6 +1534,18 @@ int bad_to_remove_submodule(const char *path, unsigned flags)
        return ret;
 }
 
+void submodule_unset_core_worktree(const struct submodule *sub)
+{
+       char *config_path = xstrfmt("%s/modules/%s/config",
+                                   get_git_common_dir(), sub->name);
+
+       if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
+               warning(_("Could not unset core.worktree setting in submodule '%s'"),
+                         sub->path);
+
+       free(config_path);
+}
+
 static const char *get_super_prefix_or_empty(void)
 {
        const char *s = get_super_prefix();
@@ -1699,6 +1711,8 @@ int submodule_move_head(const char *path,
 
                        if (is_empty_dir(path))
                                rmdir_or_warn(path);
+
+                       submodule_unset_core_worktree(sub);
                }
        }
 out:
index 7856b8a0b3d676cde20095f69a4d000d8cf38615..4644683e6cb39916a942e501eacb8663d89c3f6b 100644 (file)
@@ -121,6 +121,8 @@ extern int submodule_move_head(const char *path,
                               const char *new_head,
                               unsigned flags);
 
+void submodule_unset_core_worktree(const struct submodule *sub);
+
 /*
  * Prepare the "env_array" parameter of a "struct child_process" for executing
  * a submodule by clearing any repo-specific environment variables, but
index 1f38a85371ab49790d14d3d4b82a0ee6e52789dd..aa5ac03325a8c5038e9b568fceb1e953f4a0dcf4 100755 (executable)
@@ -235,7 +235,7 @@ reset_work_tree_to_interested () {
        then
                mkdir -p submodule_update/.git/modules/sub1/modules &&
                cp -r submodule_update_repo/.git/modules/sub1/modules/sub2 submodule_update/.git/modules/sub1/modules/sub2
-               GIT_WORK_TREE=. git -C submodule_update/.git/modules/sub1/modules/sub2 config --unset core.worktree
+               # core.worktree is unset for sub2 as it is not checked out
        fi &&
        # indicate we are interested in the submodule:
        git -C submodule_update config submodule.sub1.url "bogus" &&
@@ -709,7 +709,8 @@ test_submodule_recursing_with_args_common() {
                        git branch -t remove_sub1 origin/remove_sub1 &&
                        $command remove_sub1 &&
                        test_superproject_content origin/remove_sub1 &&
-                       ! test -e sub1
+                       ! test -e sub1 &&
+                       test_must_fail git config -f .git/modules/sub1/config core.worktree
                )
        '
        # ... absorbing a .git directory along the way.
index 812db137b8db2f6f8457ccb5d6ab27e0215dbe1a..48fd14fae6e9ac04f2edac3592bfb3ee4504cab1 100755 (executable)
@@ -993,6 +993,11 @@ test_expect_success 'submodule deinit should remove the whole submodule section
        rmdir init
 '
 
+test_expect_success 'submodule deinit should unset core.worktree' '
+       test_path_is_file .git/modules/example/config &&
+       test_must_fail git config -f .git/modules/example/config core.worktree
+'
+
 test_expect_success 'submodule deinit from subdirectory' '
        git submodule update --init &&
        git config submodule.example.foo bar &&