submodule: unset core.worktree if no working tree is present

When a submodules work tree is removed, we should unset its core.worktree setting as the worktree is no longer present. This is not just in line with the conceptual view of submodules, but it fixes an inconvenience for looking at submodules that are not checked out: git clone --recurse-submodules git://github.com/git/git && cd git && git checkout --recurse-submodules v2.13.0 git -C .git/modules/sha1collisiondetection log fatal: cannot chdir to '../../../sha1collisiondetection': \ No such file or directory With this patch applied, the final call to git log works instead of dying in its setup, as the checkout will unset the core.worktree setting such that following log will be run in a bare repository. This patch covers all commands that are in the unpack machinery, i.e. checkout, read-tree, reset. A follow up patch will address "git submodule deinit", which will also make use of the new function submodule_unset_core_worktree(), which is why we expose it in this patch. This patch was authored as 4fa4f90ccd (submodule: unset core.worktree if no working tree is present, 2018-06-12), which was reverted as part of f178c13fda (Revert "Merge branch 'sb/submodule-core-worktree'", 2018-09-07). The revert was needed as the nearby commit e98317508c (submodule: ensure core.worktree is set after update, 2018-06-18) is faulty and at the time of 7e25437d35 (Merge branch 'sb/submodule-core-worktree', 2018-07-18) we could not revert the faulty commit only, as they were depending on each other: If core.worktree is unset, we have to have ways to ensure that it is set again once the working tree reappears again. Now that 4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c', 2018-09-17), specifically 74d4731da1 (submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13) is present, we already check and ensure core.worktree is set when populating a new work tree, such that we can re-introduce the commits that unset core.worktree when removing the worktree. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stefan Beller committed Dec 14, 2018 at 15:59 UTC 898c2e65b7743f7d56bf50b4ba8bf4f59a0caf93
3 files changed +18 -1
submodule.c
+14
@@ -1561,6 +1561,18 @@ out:
1561 return ret;
1562 }
1563
1564 +void submodule_unset_core_worktree(const struct submodule *sub)
1565 +{
1566 + char *config_path = xstrfmt("%s/modules/%s/config",
1567 + get_git_common_dir(), sub->name);
1568 +
1569 + if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
1570 + warning(_("Could not unset core.worktree setting in submodule '%s'"),
1571 + sub->path);
1572 +
1573 + free(config_path);
1574 +}
1575 +
1576 static const char *get_super_prefix_or_empty(void)
1577 {
1578 const char *s = get_super_prefix();
@@ -1726,6 +1738,8 @@ int submodule_move_head(const char *path,
1738
1739 if (is_empty_dir(path))
1740 rmdir_or_warn(path);
1741 +
1742 + submodule_unset_core_worktree(sub);
1743 }
1744 }
1745 out:
submodule.h
+2
@@ -131,6 +131,8 @@ int submodule_move_head(const char *path,
131 const char *new_head,
132 unsigned flags);
133
134 +void submodule_unset_core_worktree(const struct submodule *sub);
135 +
136 /*
137 * Prepare the "env_array" parameter of a "struct child_process" for executing
138 * a submodule by clearing any repo-specific environment variables, but
t/lib-submodule-update.sh
+2 -1
@@ -709,7 +709,8 @@ test_submodule_recursing_with_args_common() {
709 git branch -t remove_sub1 origin/remove_sub1 &&
710 $command remove_sub1 &&
711 test_superproject_content origin/remove_sub1 &&
712 - ! test -e sub1
712 + ! test -e sub1 &&
713 + test_must_fail git config -f .git/modules/sub1/config core.worktree
714 )
715 '
716 # ... absorbing a .git directory along the way.