]> git.ipfire.org Git - thirdparty/git.git/commitdiff
submodule: absorb git dir instead of dying on deinit
authorMugdha Pattnaik <mugdhapattnaik@gmail.com>
Fri, 19 Nov 2021 10:56:27 +0000 (10:56 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 19 Nov 2021 17:19:54 +0000 (09:19 -0800)
Currently, running 'git submodule deinit' on repos where the
submodule's '.git' is a directory, aborts with a message that is not
exactly user friendly.

Let's change this to instead warn the user that the .git/ directory
has been absorbed into the superproject.
The rest of the deinit function can operate as it already does with
new-style submodules.

In one test, we used to require "git submodule deinit" to fail even
with the "--force" option when the submodule's .git/ directory is not
absorbed. Adjust it to expect the operation to pass.

Suggested-by: Atharva Raykar <raykar.ath@gmail.com>
Signed-off-by: Mugdha Pattnaik <mugdhapattnaik@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/submodule--helper.c
t/t7400-submodule-basic.sh

index 88ce6be69cb1ef757012caaf7d935dfa862d79ef..b45fa78c06b7dc072a2e867fffa601e80a14654d 100644 (file)
@@ -1503,16 +1503,17 @@ static void deinit_submodule(const char *path, const char *prefix,
                struct strbuf sb_rm = STRBUF_INIT;
                const char *format;
 
-               /*
-                * protect submodules containing a .git directory
-                * NEEDSWORK: instead of dying, automatically call
-                * absorbgitdirs and (possibly) warn.
-                */
-               if (is_directory(sub_git_dir))
-                       die(_("Submodule work tree '%s' contains a .git "
-                             "directory (use 'rm -rf' if you really want "
-                             "to remove it including all of its history)"),
-                           displaypath);
+               if (is_directory(sub_git_dir)) {
+                       if (!(flags & OPT_QUIET))
+                               warning(_("Submodule work tree '%s' contains a .git "
+                                         "directory. This will be replaced with a "
+                                         ".git file by using absorbgitdirs."),
+                                       displaypath);
+
+                       absorb_git_dir_into_superproject(path,
+                                                        ABSORB_GITDIR_RECURSE_SUBMODULES);
+
+               }
 
                if (!(flags & OPT_FORCE)) {
                        struct child_process cp_rm = CHILD_PROCESS_INIT;
index cb1b8e35dbfa65d92636da5f9737c0ec8a1e26aa..e7cec2e457af7767a1fbda11535ed4c855f09db7 100755 (executable)
@@ -1182,18 +1182,17 @@ test_expect_success 'submodule deinit is silent when used on an uninitialized su
        rmdir init example2
 '
 
-test_expect_success 'submodule deinit fails when submodule has a .git directory even when forced' '
+test_expect_success 'submodule deinit absorbs .git directory if .git is a directory' '
        git submodule update --init &&
        (
                cd init &&
                rm .git &&
-               cp -R ../.git/modules/example .git &&
+               mv ../.git/modules/example .git &&
                GIT_WORK_TREE=. git config --unset core.worktree
        ) &&
-       test_must_fail git submodule deinit init &&
-       test_must_fail git submodule deinit -f init &&
-       test -d init/.git &&
-       test -n "$(git config --get-regexp "submodule\.example\.")"
+       git submodule deinit init &&
+       test_path_is_missing init/.git &&
+       test -z "$(git config --get-regexp "submodule\.example\.")"
 '
 
 test_expect_success 'submodule with UTF-8 name' '