Browse Source

Merge branch 'lh/submodule'

* lh/submodule:
  git-submodule: clone during update, not during init
  git-submodule: move cloning into a separate function
maint
Junio C Hamano 18 years ago
parent
commit
30ba3809a4
  1. 16
      Documentation/git-submodule.txt
  2. 67
      git-submodule.sh
  3. 38
      t/t7400-submodule-basic.sh

16
Documentation/git-submodule.txt

@ -23,15 +23,15 @@ status::
repository. This command is the default command for git-submodule. repository. This command is the default command for git-submodule.


init:: init::
Initialize the submodules, i.e. clone the git repositories specified Initialize the submodules, i.e. register in .git/config each submodule
in the .gitmodules file and checkout the submodule commits specified path and url found in .gitmodules. The key used in git/config is
in the index of the containing repository. This will make the `submodule.$path.url`. This command does not alter existing information
submodules HEAD be detached. in .git/config.


update:: update::
Update the initialized submodules, i.e. checkout the submodule commits Update the registered submodules, i.e. clone missing submodules and
specified in the index of the containing repository. This will make checkout the commit specified in the index of the containing repository.
the submodules HEAD be detached. This will make the submodules HEAD be detached.




OPTIONS OPTIONS
@ -50,7 +50,7 @@ OPTIONS


FILES 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. 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 This file should be formatted in the same way as $GIR_DIR/config. The key
to each submodule url is "module.$path.url". to each submodule url is "module.$path.url".

67
git-submodule.sh

@ -25,20 +25,14 @@ say()
fi 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 ' | path=$1
while read mode sha1 stage path url=$2
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


# If there already is a directory at the submodule path, # If there already is a directory at the submodule path,
# expect it to be empty (since that is the default checkout # expect it to be empty (since that is the default checkout
@ -54,33 +48,37 @@ modules_init()
test -e "$path" && test -e "$path" &&
die "A file already exist at path '$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) url=$(GIT_CONFIG=.gitmodules git-config module."$path".url)
test -z "$url" && test -z "$url" &&
die "No url found for submodule '$path' in .gitmodules" die "No url found for submodule '$path' in .gitmodules"


# MAYBE FIXME: this would be the place to check GIT_CONFIG git-config submodule."$path".url "$url" ||
# for a preferred url for this submodule, possibly like this: die "Failed to register url for submodule '$path'"
#
# 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-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 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) # $@ = requested paths (default to all)
# #
@ -89,14 +87,21 @@ modules_update()
git ls-files --stage -- "$@" | grep -e '^160000 ' | git ls-files --stage -- "$@" | grep -e '^160000 ' |
while read mode sha1 stage path while read mode sha1 stage path
do do
if ! test -d "$path"/.git url=$(git-config submodule."$path".url)
if test -z "$url"
then then
# Only mention uninitialized submodules when its # Only mention uninitialized submodules when its
# path have been specified # path have been specified
test "$#" != "0" && test "$#" != "0" &&
say "Submodule '$path' not initialized" say "Submodule '$path' not initialized"
continue; continue
fi

if ! test -d "$path"/.git
then
module_clone "$path" "$url" || exit
fi fi

subsha1=$(unset GIT_DIR && cd "$path" && subsha1=$(unset GIT_DIR && cd "$path" &&
git-rev-parse --verify HEAD) || git-rev-parse --verify HEAD) ||
die "Unable to find current revision of submodule '$path'" die "Unable to find current revision of submodule '$path'"

38
t/t7400-submodule-basic.sh

@ -40,7 +40,7 @@ test_expect_success 'Prepare submodule testing' '
git-add a lib z && git-add a lib z &&
git-commit -m "super commit 1" && git-commit -m "super commit 1" &&
mv lib .subrepo && 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' ' 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" git-submodule status | grep "^-$rev1"
' '


test_expect_success 'init should fail when path is used by a file' ' 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 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 && echo "hello" >lib &&
if git-submodule init if git-submodule update
then then
echo "[OOPS] init should have failed" echo "[OOPS] update should have failed"
false false
elif test -f lib && test "$(cat lib)" != "hello" elif test -f lib && test "$(cat lib)" != "hello"
then then
echo "[OOPS] init failed but lib file was molested" echo "[OOPS] update failed but lib file was molested"
false false
else else
rm lib rm lib
fi 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 && mkdir lib &&
echo "hello" >lib/a && echo "hello" >lib/a &&
if git-submodule init if git-submodule update
then then
echo "[OOPS] init should have failed" echo "[OOPS] update should have failed"
false false
elif test "$(cat lib/a)" != "hello" elif test "$(cat lib/a)" != "hello"
then then
echo "[OOPS] init failed but lib/a was molested" echo "[OOPS] update failed but lib/a was molested"
false false
else else
rm lib/a rm lib/a
fi 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 && rm -rf lib &&
mkdir lib && mkdir lib &&
git-submodule init && git-submodule update &&
head=$(cd lib && git-rev-parse HEAD) && head=$(cd lib && git-rev-parse HEAD) &&
if test -z "$head" if test -z "$head"
then then
@ -99,7 +113,7 @@ test_expect_success 'init should work when path is an empty dir' '
fi 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" git-submodule status | grep "^ $rev1"
' '



Loading…
Cancel
Save