Merge branch 'jl/submodule-add-by-name'
If you remove a submodule, in order to keep the repository so that "git checkout" to an older commit in the superproject history can resurrect the submodule, the real repository will stay in $GIT_DIR of the superproject. A later "git submodule add $path" to add a different submodule at the same path will fail. Diagnose this case a bit better, and if the user really wants to add an unrelated submodule at the same path, give the "--name" option to give it a place in $GIT_DIR of the superproject that does not conflict with the original submodule. * jl/submodule-add-by-name: submodule add: Fail when .git/modules/<name> already exists unless forced Teach "git submodule add" the --name option
This commit is contained in:
commit
fdb4d27158
@ -9,7 +9,7 @@ git-submodule - Initialize, update or inspect submodules
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git submodule' [--quiet] add [-b branch] [-f|--force]
|
||||
'git submodule' [--quiet] add [-b branch] [-f|--force] [--name <name>]
|
||||
[--reference <repository>] [--] <repository> [<path>]
|
||||
'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
|
||||
'git submodule' [--quiet] init [--] [<path>...]
|
||||
@ -265,6 +265,11 @@ OPTIONS
|
||||
Initialize all submodules for which "git submodule init" has not been
|
||||
called so far before updating.
|
||||
|
||||
--name::
|
||||
This option is only valid for the add command. It sets the submodule's
|
||||
name to the given string instead of defaulting to its path. The name
|
||||
must be valid as a directory name and may not end with a '/'.
|
||||
|
||||
--reference <repository>::
|
||||
This option is only valid for add and update commands. These
|
||||
commands sometimes need to clone a remote repository. In this case,
|
||||
|
@ -18,7 +18,9 @@ working tree, is a text file with a syntax matching the requirements
|
||||
of linkgit:git-config[1].
|
||||
|
||||
The file contains one subsection per submodule, and the subsection value
|
||||
is the name of the submodule. Each submodule section also contains the
|
||||
is the name of the submodule. The name is set to the path where the
|
||||
submodule has been added unless it was customized with the '--name'
|
||||
option of 'git submodule add'. Each submodule section also contains the
|
||||
following required keys:
|
||||
|
||||
submodule.<name>.path::
|
||||
|
@ -5,7 +5,7 @@
|
||||
# Copyright (c) 2007 Lars Hjemli
|
||||
|
||||
dashless=$(basename "$0" | sed -e 's/-/ /')
|
||||
USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>]
|
||||
USAGE="[--quiet] add [-b branch] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
|
||||
or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
|
||||
or: $dashless [--quiet] init [--] [<path>...]
|
||||
or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
|
||||
@ -29,6 +29,7 @@ files=
|
||||
nofetch=
|
||||
update=
|
||||
prefix=
|
||||
custom_name=
|
||||
|
||||
# The function takes at most 2 arguments. The first argument is the
|
||||
# URL that navigates to the submodule origin repo. When relative, this URL
|
||||
@ -179,8 +180,9 @@ module_name()
|
||||
module_clone()
|
||||
{
|
||||
sm_path=$1
|
||||
url=$2
|
||||
reference="$3"
|
||||
name=$2
|
||||
url=$3
|
||||
reference="$4"
|
||||
quiet=
|
||||
if test -n "$GIT_QUIET"
|
||||
then
|
||||
@ -189,8 +191,6 @@ module_clone()
|
||||
|
||||
gitdir=
|
||||
gitdir_base=
|
||||
name=$(module_name "$sm_path" 2>/dev/null)
|
||||
test -n "$name" || name="$sm_path"
|
||||
base_name=$(dirname "$name")
|
||||
|
||||
gitdir=$(git rev-parse --git-dir)
|
||||
@ -272,6 +272,11 @@ cmd_add()
|
||||
reference="$1"
|
||||
shift
|
||||
;;
|
||||
--name)
|
||||
case "$2" in '') usage ;; esac
|
||||
custom_name=$2
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
@ -336,6 +341,13 @@ Use -f if you really want to add it." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -n "$custom_name"
|
||||
then
|
||||
sm_name="$custom_name"
|
||||
else
|
||||
sm_name="$sm_path"
|
||||
fi
|
||||
|
||||
# perhaps the path exists and is already a git repo, else clone it
|
||||
if test -e "$sm_path"
|
||||
then
|
||||
@ -347,8 +359,21 @@ Use -f if you really want to add it." >&2
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
module_clone "$sm_path" "$realrepo" "$reference" || exit
|
||||
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
|
||||
(
|
||||
clear_local_git_env
|
||||
cd "$sm_path" &&
|
||||
@ -359,13 +384,13 @@ Use -f if you really want to add it." >&2
|
||||
esac
|
||||
) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")"
|
||||
fi
|
||||
git config submodule."$sm_path".url "$realrepo"
|
||||
git config submodule."$sm_name".url "$realrepo"
|
||||
|
||||
git add $force "$sm_path" ||
|
||||
die "$(eval_gettext "Failed to add submodule '\$sm_path'")"
|
||||
|
||||
git config -f .gitmodules submodule."$sm_path".path "$sm_path" &&
|
||||
git config -f .gitmodules submodule."$sm_path".url "$repo" &&
|
||||
git config -f .gitmodules submodule."$sm_name".path "$sm_path" &&
|
||||
git config -f .gitmodules submodule."$sm_name".url "$repo" &&
|
||||
git add --force .gitmodules ||
|
||||
die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
|
||||
}
|
||||
@ -594,7 +619,7 @@ Maybe you want to use 'update --init'?")"
|
||||
|
||||
if ! test -d "$sm_path"/.git -o -f "$sm_path"/.git
|
||||
then
|
||||
module_clone "$sm_path" "$url" "$reference"|| exit
|
||||
module_clone "$sm_path" "$name" "$url" "$reference" || exit
|
||||
cloned_modules="$cloned_modules;$name"
|
||||
subsha1=
|
||||
else
|
||||
|
@ -681,4 +681,79 @@ test_expect_success 'moving the superproject does not break submodules' '
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule add --name allows to replace a submodule with another at the same path' '
|
||||
(
|
||||
cd addtest2 &&
|
||||
(
|
||||
cd repo &&
|
||||
echo "$submodurl/repo" >expect &&
|
||||
git config remote.origin.url >actual &&
|
||||
test_cmp expect actual &&
|
||||
echo "gitdir: ../.git/modules/repo" >expect &&
|
||||
test_cmp expect .git
|
||||
) &&
|
||||
rm -rf repo &&
|
||||
git rm repo &&
|
||||
git submodule add -q --name repo_new "$submodurl/bare.git" repo >actual &&
|
||||
test ! -s actual &&
|
||||
echo "gitdir: ../.git/modules/submod" >expect &&
|
||||
test_cmp expect submod/.git &&
|
||||
(
|
||||
cd repo &&
|
||||
echo "$submodurl/bare.git" >expect &&
|
||||
git config remote.origin.url >actual &&
|
||||
test_cmp expect actual &&
|
||||
echo "gitdir: ../.git/modules/repo_new" >expect &&
|
||||
test_cmp expect .git
|
||||
) &&
|
||||
echo "repo" >expect &&
|
||||
git config -f .gitmodules submodule.repo.path >actual &&
|
||||
test_cmp expect actual &&
|
||||
git config -f .gitmodules submodule.repo_new.path >actual &&
|
||||
test_cmp expect actual&&
|
||||
echo "$submodurl/repo" >expect &&
|
||||
git config -f .gitmodules submodule.repo.url >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/repo" >expect &&
|
||||
git config submodule.repo.url >actual &&
|
||||
test_cmp expect actual &&
|
||||
echo "$submodurl/bare.git" >expect &&
|
||||
git config submodule.repo_new.url >actual &&
|
||||
test_cmp expect actual
|
||||
)
|
||||
'
|
||||
|
||||
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
|
||||
|
@ -627,7 +627,7 @@ test_expect_success 'submodule add properly re-creates deeper level submodules'
|
||||
(cd super &&
|
||||
git reset --hard master &&
|
||||
rm -rf deeper/ &&
|
||||
git submodule add ../submodule deeper/submodule
|
||||
git submodule add --force ../submodule deeper/submodule
|
||||
)
|
||||
'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user