submodule add: Fail when .git/modules/<name> already exists unless forced

When adding a new submodule it can happen that .git/modules/<name> already
contains a submodule repo, e.g. when a submodule is removed from the work
tree and another submodule is added at the same path. But then the work
tree of the submodule will be populated using the existing repository and
not the one the user provided, which results in an incorrect work tree. On
the other hand the user might reactivate a submodule removed earlier, then
reusing that .git directory is the Right Thing to do.

As git can't decide what is the case, error out and tell the user she
should use either use a different name for the submodule with the "--name"
option or can reuse the .git directory for the newly added submodule by
providing the --force option (which only makes sense when the upstream
matches, so the error message lists all remotes of .git/modules/<name>).

In one test in t7406 the --force option had to be added to "git submodule
add", as that test re-adds a formerly removed submodule.

Reported-by: Jonathan Johnson <me@jondavidjohn.com>
Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jens Lehmann 2012-09-30 23:01:29 +02:00 коммит произвёл Junio C Hamano
Родитель 73b0898d0d
Коммит 4b7c286ec7
3 изменённых файлов: 45 добавлений и 2 удалений

Просмотреть файл

@ -359,7 +359,20 @@ Use -f if you really want to add it." >&2
fi fi
else else
if test -d ".git/modules/$sm_name"
then
if test -z "$force"
then
echo >&2 "$(eval_gettext "A git directory for '\$sm_name' is found locally with remote(s):")"
GIT_DIR=".git/modules/$sm_name" GIT_WORK_TREE=. git remote -v | grep '(fetch)' | sed -e s,^," ", -e s,' (fetch)',, >&2
echo >&2 "$(eval_gettext "If you want to reuse this local git directory instead of cloning again from")"
echo >&2 " $realrepo"
echo >&2 "$(eval_gettext "use the '--force' option. If the local git directory is not the correct repo")"
die "$(eval_gettext "or you are unsure what this means choose another name with the '--name' option.")"
else
echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")"
fi
fi
module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" || exit module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" || exit
( (
clear_local_git_env clear_local_git_env

Просмотреть файл

@ -726,4 +726,34 @@ test_expect_success 'submodule add --name allows to replace a submodule with ano
) )
' '
test_expect_success 'submodule add with an existing name fails unless forced' '
(
cd addtest2 &&
rm -rf repo &&
git rm repo &&
test_must_fail git submodule add -q --name repo_new "$submodurl/repo.git" repo &&
test ! -d repo &&
echo "repo" >expect &&
git config -f .gitmodules submodule.repo_new.path >actual &&
test_cmp expect actual&&
echo "$submodurl/bare.git" >expect &&
git config -f .gitmodules submodule.repo_new.url >actual &&
test_cmp expect actual &&
echo "$submodurl/bare.git" >expect &&
git config submodule.repo_new.url >actual &&
test_cmp expect actual &&
git submodule add -f -q --name repo_new "$submodurl/repo.git" repo &&
test -d repo &&
echo "repo" >expect &&
git config -f .gitmodules submodule.repo_new.path >actual &&
test_cmp expect actual&&
echo "$submodurl/repo.git" >expect &&
git config -f .gitmodules submodule.repo_new.url >actual &&
test_cmp expect actual &&
echo "$submodurl/repo.git" >expect &&
git config submodule.repo_new.url >actual &&
test_cmp expect actual
)
'
test_done test_done

Просмотреть файл

@ -627,7 +627,7 @@ test_expect_success 'submodule add properly re-creates deeper level submodules'
(cd super && (cd super &&
git reset --hard master && git reset --hard master &&
rm -rf deeper/ && rm -rf deeper/ &&
git submodule add ../submodule deeper/submodule git submodule add --force ../submodule deeper/submodule
) )
' '