Skip to content

Commit

Permalink
submodule: absorb git dir instead of dying on deinit
Browse files Browse the repository at this point in the history
Currently, running 'git submodule deinit' on repos where the
submodule's '.git' is a folder aborts with a message that is not
exactly user friendly. Let's change this to instead warn the user
to rerun the command with '--force'.

This internally calls 'absorb_git_dir_into_superproject()', which
moves the '.git' folder into the superproject and replaces it with
a '.git' file. The rest of the deinit function can operate as it
already does with new-style submodules.

We also edit a test case such that it matches the new behaviour of
deinit.

Suggested-by: Atharva Raykar <raykar.ath@gmail.com>
Signed-off-by: Mugdha Pattnaik <mugdhapattnaik@gmail.com>
  • Loading branch information
mugdhapattnaik committed Aug 27, 2021
1 parent c420321 commit 37c9b59
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 15 deletions.
28 changes: 18 additions & 10 deletions builtin/submodule--helper.c
Expand Up @@ -1539,16 +1539,24 @@ 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_FORCE))
die(_("Submodule work tree '%s' contains a "
".git directory.\nUse --force if you want "
"to move its contents to superproject's "
"module folder and convert .git to a file "
"and then proceed with deinit."),
displaypath);

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(displaypath, flags);

}

if (!(flags & OPT_FORCE)) {
struct child_process cp_rm = CHILD_PROCESS_INIT;
Expand Down
10 changes: 5 additions & 5 deletions t/t7400-submodule-basic.sh
Expand Up @@ -1182,18 +1182,18 @@ 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 fails when submodule has a .git directory unless forced' '
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 -f init &&
! test -d init/.git &&
test -z "$(git config --get-regexp "submodule\.example\.")"
'

test_expect_success 'submodule with UTF-8 name' '
Expand Down

0 comments on commit 37c9b59

Please sign in to comment.