* lh/submodule:
  git-submodule: clone during update, not during init
  git-submodule: move cloning into a separate function
This commit is contained in:
Junio C Hamano 2007-06-12 00:17:26 -07:00
Родитель f26cacf495 211b7f19c7
Коммит 30ba3809a4
3 изменённых файлов: 79 добавлений и 60 удалений

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

@ -23,15 +23,15 @@ status::
repository. This command is the default command for git-submodule.
init::
Initialize the submodules, i.e. clone the git repositories specified
in the .gitmodules file and checkout the submodule commits specified
in the index of the containing repository. This will make the
submodules HEAD be detached.
Initialize the submodules, i.e. register in .git/config each submodule
path and url found in .gitmodules. The key used in git/config is
`submodule.$path.url`. This command does not alter existing information
in .git/config.
update::
Update the initialized submodules, i.e. checkout the submodule commits
specified in the index of the containing repository. This will make
the submodules HEAD be detached.
Update the registered submodules, i.e. clone missing submodules and
checkout the commit specified in the index of the containing repository.
This will make the submodules HEAD be detached.
OPTIONS
@ -50,7 +50,7 @@ OPTIONS
FILES
-----
When cloning submodules, a .gitmodules file in the top-level directory
When initializing submodules, a .gitmodules file in the top-level directory
of the containing repository is used to find the url of each submodule.
This file should be formatted in the same way as $GIR_DIR/config. The key
to each submodule url is "module.$path.url".

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

@ -25,20 +25,14 @@ say()
fi
}
#
# Run clone + checkout on missing submodules
# Clone a submodule
#
# $@ = requested paths (default to all)
#
modules_init()
module_clone()
{
git ls-files --stage -- "$@" | grep -e '^160000 ' |
while read mode sha1 stage path
do
# Skip submodule paths that already contain a .git directory.
# This will also trigger if $path is a symlink to a git
# repository
test -d "$path"/.git && continue
path=$1
url=$2
# If there already is a directory at the submodule path,
# expect it to be empty (since that is the default checkout
@ -54,33 +48,37 @@ modules_init()
test -e "$path" &&
die "A file already exist at path '$path'"
git-clone -n "$url" "$path" ||
die "Clone of submodule '$path' failed"
}
#
# Register submodules in .git/config
#
# $@ = requested paths (default to all)
#
modules_init()
{
git ls-files --stage -- "$@" | grep -e '^160000 ' |
while read mode sha1 stage path
do
# Skip already registered paths
url=$(git-config submodule."$path".url)
test -z "$url" || continue
url=$(GIT_CONFIG=.gitmodules git-config module."$path".url)
test -z "$url" &&
die "No url found for submodule '$path' in .gitmodules"
# MAYBE FIXME: this would be the place to check GIT_CONFIG
# for a preferred url for this submodule, possibly like this:
#
# modname=$(GIT_CONFIG=.gitmodules git-config module."$path".name)
# alturl=$(git-config module."$modname".url)
#
# This would let the versioned .gitmodules file use the submodule
# path as key, while the unversioned GIT_CONFIG would use the
# logical modulename (if present) as key. But this would need
# another fallback mechanism if the module wasn't named.
git-config submodule."$path".url "$url" ||
die "Failed to register url for submodule '$path'"
git-clone -n "$url" "$path" ||
die "Clone of submodule '$path' failed"
(unset GIT_DIR && cd "$path" && git-checkout -q "$sha1") ||
die "Checkout of submodule '$path' failed"
say "Submodule '$path' initialized"
say "Submodule '$path' registered with url '$url'"
done
}
#
# Checkout correct revision of each initialized submodule
# Update each submodule path to correct revision, using clone and checkout as needed
#
# $@ = requested paths (default to all)
#
@ -89,14 +87,21 @@ modules_update()
git ls-files --stage -- "$@" | grep -e '^160000 ' |
while read mode sha1 stage path
do
if ! test -d "$path"/.git
url=$(git-config submodule."$path".url)
if test -z "$url"
then
# Only mention uninitialized submodules when its
# path have been specified
test "$#" != "0" &&
say "Submodule '$path' not initialized"
continue;
continue
fi
if ! test -d "$path"/.git
then
module_clone "$path" "$url" || exit
fi
subsha1=$(unset GIT_DIR && cd "$path" &&
git-rev-parse --verify HEAD) ||
die "Unable to find current revision of submodule '$path'"

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

@ -40,7 +40,7 @@ test_expect_success 'Prepare submodule testing' '
git-add a lib z &&
git-commit -m "super commit 1" &&
mv lib .subrepo &&
GIT_CONFIG=.gitmodules git-config module.lib.url ./.subrepo
GIT_CONFIG=.gitmodules git-config module.lib.url git://example.com/lib.git
'
test_expect_success 'status should only print one line' '
@ -52,41 +52,55 @@ test_expect_success 'status should initially be "missing"' '
git-submodule status | grep "^-$rev1"
'
test_expect_success 'init should fail when path is used by a file' '
echo "hello" >lib &&
if git-submodule init
test_expect_success 'init should register submodule url in .git/config' '
git-submodule init &&
url=$(git-config submodule.lib.url) &&
if test "$url" != "git://example.com/lib.git"
then
echo "[OOPS] init should have failed"
echo "[OOPS] init succeeded but submodule url is wrong"
false
elif ! git-config submodule.lib.url ./.subrepo
then
echo "[OOPS] init succeeded but update of url failed"
false
fi
'
test_expect_success 'update should fail when path is used by a file' '
echo "hello" >lib &&
if git-submodule update
then
echo "[OOPS] update should have failed"
false
elif test -f lib && test "$(cat lib)" != "hello"
then
echo "[OOPS] init failed but lib file was molested"
echo "[OOPS] update failed but lib file was molested"
false
else
rm lib
fi
'
test_expect_success 'init should fail when path is used by a nonempty directory' '
test_expect_success 'update should fail when path is used by a nonempty directory' '
mkdir lib &&
echo "hello" >lib/a &&
if git-submodule init
if git-submodule update
then
echo "[OOPS] init should have failed"
echo "[OOPS] update should have failed"
false
elif test "$(cat lib/a)" != "hello"
then
echo "[OOPS] init failed but lib/a was molested"
echo "[OOPS] update failed but lib/a was molested"
false
else
rm lib/a
fi
'
test_expect_success 'init should work when path is an empty dir' '
test_expect_success 'update should work when path is an empty dir' '
rm -rf lib &&
mkdir lib &&
git-submodule init &&
git-submodule update &&
head=$(cd lib && git-rev-parse HEAD) &&
if test -z "$head"
then
@ -99,7 +113,7 @@ test_expect_success 'init should work when path is an empty dir' '
fi
'
test_expect_success 'status should be "up-to-date" after init' '
test_expect_success 'status should be "up-to-date" after update' '
git-submodule status | grep "^ $rev1"
'