{"thread":{"id":"8438","subject":"[PATCH 2/2] git-submodule: clone during update, not during init","startedAt":"2007-06-05T09:29:10Z","lastAt":"2007-06-17T15:56:15Z","messageCount":11,"participants":["Lars Hjemli","Johannes Sixt","Junio C Hamano","Sven Verdoolaege"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"44050","messageId":"11810357523435-git-send-email-hjemli@gmail.com","threadId":"8438","inReplyTo":null,"subject":"[PATCH 0/2] git-submodule: make it easier to use alternate urls","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-06-05T09:29:10Z","receivedAt":"2007-06-05T09:29:10Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"\nThis patch-series teaches git-submodule to register submodule urls in\n.git/config during 'git-submodule init' and to perform the actual cloning\nduring 'git-submodule update', using the url stored in .git/config. So now\nthe downstream users can specify their preferred urls for each interesting\nsubmodule by editing their .git/config after running 'git-submodule init'.\n\n Documentation/git-submodule.txt |   16 ++++----\n git-submodule.sh                |   83 ++++++++++++++++++++------------------\n t/t7400-submodule-basic.sh      |   38 ++++++++++++------\n 3 files changed, 78 insertions(+), 59 deletions(-)\n"},{"id":"44049","messageId":"11810357522478-git-send-email-hjemli@gmail.com","threadId":"8438","inReplyTo":"11810357523435-git-send-email-hjemli@gmail.com","subject":"[PATCH 1/2] git-submodule: move cloning into a separate function","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-06-05T09:29:11Z","receivedAt":"2007-06-05T09:29:11Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This is just a simple refactoring of modules_init() with no change in\nfunctionality.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n git-submodule.sh |   44 ++++++++++++++++++++++++++++----------------\n 1 files changed, 28 insertions(+), 16 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 6ed5a6c..a89ea88 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -25,6 +25,33 @@ say()\n \tfi\n }\n \n+\n+#\n+# Clone a submodule\n+#\n+module_clone()\n+{\n+\tpath=$1\n+\turl=$2\n+\n+\t# If there already is a directory at the submodule path,\n+\t# expect it to be empty (since that is the default checkout\n+\t# action) and try to remove it.\n+\t# Note: if $path is a symlink to a directory the test will\n+\t# succeed but the rmdir will fail. We might want to fix this.\n+\tif test -d \"$path\"\n+\tthen\n+\t\trmdir \"$path\" 2>/dev/null ||\n+\t\tdie \"Directory '$path' exist, but is neither empty nor a git repository\"\n+\tfi\n+\n+\ttest -e \"$path\" &&\n+\tdie \"A file already exist at path '$path'\"\n+\n+\tgit-clone -n \"$url\" \"$path\" ||\n+\tdie \"Clone of submodule '$path' failed\"\n+}\n+\n #\n # Run clone + checkout on missing submodules\n #\n@@ -40,20 +67,6 @@ modules_init()\n \t\t# repository\n \t\ttest -d \"$path\"/.git && continue\n \n-\t\t# If there already is a directory at the submodule path,\n-\t\t# expect it to be empty (since that is the default checkout\n-\t\t# action) and try to remove it.\n-\t\t# Note: if $path is a symlink to a directory the test will\n-\t\t# succeed but the rmdir will fail. We might want to fix this.\n-\t\tif test -d \"$path\"\n-\t\tthen\n-\t\t\trmdir \"$path\" 2>/dev/null ||\n-\t\t\tdie \"Directory '$path' exist, but is neither empty nor a git repository\"\n-\t\tfi\n-\n-\t\ttest -e \"$path\" &&\n-\t\tdie \"A file already exist at path '$path'\"\n-\n \t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n \t\ttest -z \"$url\" &&\n \t\tdie \"No url found for submodule '$path' in .gitmodules\"\n@@ -69,8 +82,7 @@ modules_init()\n \t\t# logical modulename (if present) as key. But this would need\n \t\t# another fallback mechanism if the module wasn't named.\n \n-\t\tgit-clone -n \"$url\" \"$path\" ||\n-\t\tdie \"Clone of submodule '$path' failed\"\n+\t\tmodule_clone \"$path\" \"$url\" || exit $?\n \n \t\t(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n \t\tdie \"Checkout of submodule '$path' failed\"\n-- \n1.5.2.841.gc9eafb\n"},{"id":"44048","messageId":"11810357523233-git-send-email-hjemli@gmail.com","threadId":"8438","inReplyTo":"11810357523435-git-send-email-hjemli@gmail.com","subject":"[PATCH 2/2] git-submodule: clone during update, not during init","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-06-05T09:29:12Z","receivedAt":"2007-06-05T09:29:12Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This teaches 'git-submodule init' to register submodule paths and urls in\n.git/config instead of actually cloning them. The cloning is now handled\nas part of 'git-submodule update'.\n\nWith this change it is possible to specify preferred/alternate urls for\nthe submodules in .git/config before the submodules are cloned.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n Documentation/git-submodule.txt |   16 +++++++-------\n git-submodule.sh                |   41 ++++++++++++++++----------------------\n t/t7400-submodule-basic.sh      |   38 ++++++++++++++++++++++++-----------\n 3 files changed, 51 insertions(+), 44 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex cb0424f..f8fb80f 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -23,15 +23,15 @@ status::\n \trepository. This command is the default command for git-submodule.\n \n init::\n-\tInitialize the submodules, i.e. clone the git repositories specified\n-\tin the .gitmodules file and checkout the submodule commits specified\n-\tin the index of the containing repository. This will make the\n-\tsubmodules HEAD be detached.\n+\tInitialize the submodules, i.e. register in .git/config each submodule\n+\tpath and url found in .gitmodules. The key used in git/config is\n+\t`submodule.$path.url`. This command does not alter existing information\n+\tin .git/config.\n \n update::\n-\tUpdate the initialized submodules, i.e. checkout the submodule commits\n-\tspecified in the index of the containing repository. This will make\n-\tthe submodules HEAD be detached.\n+\tUpdate the registered submodules, i.e. clone missing submodules and\n+\tcheckout the commit specified in the index of the containing repository.\n+\tThis will make the submodules HEAD be detached.\n \n \n OPTIONS\n@@ -50,7 +50,7 @@ OPTIONS\n \n FILES\n -----\n-When cloning submodules, a .gitmodules file in the top-level directory\n+When initializing submodules, a .gitmodules file in the top-level directory\n of the containing repository is used to find the url of each submodule.\n This file should be formatted in the same way as $GIR_DIR/config. The key\n to each submodule url is \"module.$path.url\".\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex a89ea88..e7b6978 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -53,7 +53,7 @@ module_clone()\n }\n \n #\n-# Run clone + checkout on missing submodules\n+# Register submodules in .git/config\n #\n # $@ = requested paths (default to all)\n #\n@@ -62,37 +62,23 @@ modules_init()\n \tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n \twhile read mode sha1 stage path\n \tdo\n-\t\t# Skip submodule paths that already contain a .git directory.\n-\t\t# This will also trigger if $path is a symlink to a git\n-\t\t# repository\n-\t\ttest -d \"$path\"/.git && continue\n+\t\t# Skip already registered paths\n+\t\turl=$(git-config submodule.\"$path\".url)\n+\t\ttest -z \"$url\" || continue\n \n \t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n \t\ttest -z \"$url\" &&\n \t\tdie \"No url found for submodule '$path' in .gitmodules\"\n \n-\t\t# MAYBE FIXME: this would be the place to check GIT_CONFIG\n-\t\t# for a preferred url for this submodule, possibly like this:\n-\t\t#\n-\t\t# modname=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".name)\n-\t\t# alturl=$(git-config module.\"$modname\".url)\n-\t\t#\n-\t\t# This would let the versioned .gitmodules file use the submodule\n-\t\t# path as key, while the unversioned GIT_CONFIG would use the\n-\t\t# logical modulename (if present) as key. But this would need\n-\t\t# another fallback mechanism if the module wasn't named.\n+\t\tgit-config submodule.\"$path\".url \"$url\" ||\n+\t\tdie \"Failed to register url for submodule '$path'\"\n \n-\t\tmodule_clone \"$path\" \"$url\" || exit $?\n-\n-\t\t(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n-\t\tdie \"Checkout of submodule '$path' failed\"\n-\n-\t\tsay \"Submodule '$path' initialized\"\n+\t\tsay \"Submodule '$path' registered with url '$url'\"\n \tdone\n }\n \n #\n-# Checkout correct revision of each initialized submodule\n+# Update each submodule path to correct revision, using clone and checkout as needed\n #\n # $@ = requested paths (default to all)\n #\n@@ -101,14 +87,21 @@ modules_update()\n \tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n \twhile read mode sha1 stage path\n \tdo\n-\t\tif ! test -d \"$path\"/.git\n+\t\turl=$(git-config submodule.\"$path\".url)\n+\t\tif test -z \"$url\"\n \t\tthen\n \t\t\t# Only mention uninitialized submodules when its\n \t\t\t# path have been specified\n \t\t\ttest \"$#\" != \"0\" &&\n \t\t\tsay \"Submodule '$path' not initialized\"\n-\t\t\tcontinue;\n+\t\t\tcontinue\n \t\tfi\n+\n+\t\tif ! test -d \"$path\"/.git\n+\t\tthen\n+\t\t\tmodule_clone \"$path\" \"$url\" || exit $?\n+\t\tfi\n+\n \t\tsubsha1=$(unset GIT_DIR && cd \"$path\" &&\n \t\t\tgit-rev-parse --verify HEAD) ||\n \t\tdie \"Unable to find current revision of submodule '$path'\"\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 6274729..3940433 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -40,7 +40,7 @@ test_expect_success 'Prepare submodule testing' '\n \tgit-add a lib z &&\n \tgit-commit -m \"super commit 1\" &&\n \tmv lib .subrepo &&\n-\tGIT_CONFIG=.gitmodules git-config module.lib.url ./.subrepo\n+\tGIT_CONFIG=.gitmodules git-config module.lib.url git://example.com/lib.git\n '\n \n test_expect_success 'status should only print one line' '\n@@ -52,41 +52,55 @@ test_expect_success 'status should initially be \"missing\"' '\n \tgit-submodule status | grep \"^-$rev1\"\n '\n \n-test_expect_success 'init should fail when path is used by a file' '\n+test_expect_success 'init should register submodule url in .git/config' '\n+\tgit-submodule init &&\n+\turl=$(git-config submodule.lib.url) &&\n+\tif test \"$url\" != \"git://example.com/lib.git\"\n+\tthen\n+\t\techo \"[OOPS] init succeeded but submodule url is wrong\"\n+\t\tfalse\n+\telif ! git-config submodule.lib.url ./.subrepo\n+\tthen\n+\t\techo \"[OOPS] init succeeded but update of url failed\"\n+\t\tfalse\n+\tfi\n+'\n+\n+test_expect_success 'update should fail when path is used by a file' '\n \techo \"hello\" >lib &&\n-\tif git-submodule init\n+\tif git-submodule update\n \tthen\n-\t\techo \"[OOPS] init should have failed\"\n+\t\techo \"[OOPS] update should have failed\"\n \t\tfalse\n \telif test -f lib && test \"$(cat lib)\" != \"hello\"\n \tthen\n-\t\techo \"[OOPS] init failed but lib file was molested\"\n+\t\techo \"[OOPS] update failed but lib file was molested\"\n \t\tfalse\n \telse\n \t\trm lib\n \tfi\n '\n \n-test_expect_success 'init should fail when path is used by a nonempty directory' '\n+test_expect_success 'update should fail when path is used by a nonempty directory' '\n \tmkdir lib &&\n \techo \"hello\" >lib/a &&\n-\tif git-submodule init\n+\tif git-submodule update\n \tthen\n-\t\techo \"[OOPS] init should have failed\"\n+\t\techo \"[OOPS] update should have failed\"\n \t\tfalse\n \telif test \"$(cat lib/a)\" != \"hello\"\n \tthen\n-\t\techo \"[OOPS] init failed but lib/a was molested\"\n+\t\techo \"[OOPS] update failed but lib/a was molested\"\n \t\tfalse\n \telse\n \t\trm lib/a\n \tfi\n '\n \n-test_expect_success 'init should work when path is an empty dir' '\n+test_expect_success 'update should work when path is an empty dir' '\n \trm -rf lib &&\n \tmkdir lib &&\n-\tgit-submodule init &&\n+\tgit-submodule update &&\n \thead=$(cd lib && git-rev-parse HEAD) &&\n \tif test -z \"$head\"\n \tthen\n@@ -99,7 +113,7 @@ test_expect_success 'init should work when path is an empty dir' '\n \tfi\n '\n \n-test_expect_success 'status should be \"up-to-date\" after init' '\n+test_expect_success 'status should be \"up-to-date\" after update' '\n \tgit-submodule status | grep \"^ $rev1\"\n '\n \n-- \n1.5.2.841.gc9eafb\n"},{"id":"44064","messageId":"46653DB2.997A3ABD@eudaptics.com","threadId":"8438","inReplyTo":"11810357522478-git-send-email-hjemli@gmail.com","subject":"Re: [PATCH 1/2] git-submodule: move cloning into a separate function","fromName":"Johannes Sixt","fromEmail":"j.sixt@eudaptics.com","sentAt":"2007-06-05T10:40:50Z","receivedAt":"2007-06-05T10:40:50Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Lars Hjemli wrote:\n> +               module_clone \"$path\" \"$url\" || exit $?\n\nMinor nit: The idiom that is commonly used in situations like this (see\nother git-* shell scripts):\n\n\t\tmodule_clone \"$path\" \"$url\" || exit\n\nbecause exit without argument uses the code of the last command\nexecuted.\n\n-- Hannes\n"},{"id":"44066","messageId":"op.ttf34qd99pspc6@localhost","threadId":"8438","inReplyTo":"46653DB2.997A3ABD@eudaptics.com","subject":"[PATCH 1/2] git-submodule: move cloning into a separate function","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-06-05T11:13:28Z","receivedAt":"2007-06-05T11:13:28Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This is just a simple refactoring of modules_init() with no change in\nfunctionality.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n\nOn Tue, 05 Jun 2007 12:40:50 +0200, Johannes Sixt <J.Sixt@eudaptics.com> wrote:\n\n> Lars Hjemli wrote:\n>> +               module_clone \"$path\" \"$url\" || exit $?\n>\n> Minor nit: The idiom that is commonly used in situations like this (see\n> other git-* shell scripts):\n>\n> \t\tmodule_clone \"$path\" \"$url\" || exit\n>\n> because exit without argument uses the code of the last command\n> executed.\n>\n\nThanks, I'll follow up with matching changes to [patch 2/2].\n\n\n  git-submodule.sh |   44 ++++++++++++++++++++++++++++----------------\n  1 files changed, 28 insertions(+), 16 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 6ed5a6c..a89ea88 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -25,6 +25,33 @@ say()\n  \tfi\n  }\n\n+\n+#\n+# Clone a submodule\n+#\n+module_clone()\n+{\n+\tpath=$1\n+\turl=$2\n+\n+\t# If there already is a directory at the submodule path,\n+\t# expect it to be empty (since that is the default checkout\n+\t# action) and try to remove it.\n+\t# Note: if $path is a symlink to a directory the test will\n+\t# succeed but the rmdir will fail. We might want to fix this.\n+\tif test -d \"$path\"\n+\tthen\n+\t\trmdir \"$path\" 2>/dev/null ||\n+\t\tdie \"Directory '$path' exist, but is neither empty nor a git repository\"\n+\tfi\n+\n+\ttest -e \"$path\" &&\n+\tdie \"A file already exist at path '$path'\"\n+\n+\tgit-clone -n \"$url\" \"$path\" ||\n+\tdie \"Clone of submodule '$path' failed\"\n+}\n+\n  #\n  # Run clone + checkout on missing submodules\n  #\n@@ -40,20 +67,6 @@ modules_init()\n  \t\t# repository\n  \t\ttest -d \"$path\"/.git && continue\n\n-\t\t# If there already is a directory at the submodule path,\n-\t\t# expect it to be empty (since that is the default checkout\n-\t\t# action) and try to remove it.\n-\t\t# Note: if $path is a symlink to a directory the test will\n-\t\t# succeed but the rmdir will fail. We might want to fix this.\n-\t\tif test -d \"$path\"\n-\t\tthen\n-\t\t\trmdir \"$path\" 2>/dev/null ||\n-\t\t\tdie \"Directory '$path' exist, but is neither empty nor a git repository\"\n-\t\tfi\n-\n-\t\ttest -e \"$path\" &&\n-\t\tdie \"A file already exist at path '$path'\"\n-\n  \t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n  \t\ttest -z \"$url\" &&\n  \t\tdie \"No url found for submodule '$path' in .gitmodules\"\n@@ -69,8 +82,7 @@ modules_init()\n  \t\t# logical modulename (if present) as key. But this would need\n  \t\t# another fallback mechanism if the module wasn't named.\n\n-\t\tgit-clone -n \"$url\" \"$path\" ||\n-\t\tdie \"Clone of submodule '$path' failed\"\n+\t\tmodule_clone \"$path\" \"$url\" || exit\n\n  \t\t(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n  \t\tdie \"Checkout of submodule '$path' failed\"\n-- \n1.5.2.841.gc9eafb\n"},{"id":"44067","messageId":"op.ttf4crpn9pspc6@localhost","threadId":"8438","inReplyTo":"11810357523233-git-send-email-hjemli@gmail.com","subject":"[PATCH 2/2] git-submodule: clone during update, not during init","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-06-05T11:18:17Z","receivedAt":"2007-06-05T11:18:17Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This teaches 'git-submodule init' to register submodule paths and urls in\n.git/config instead of actually cloning them. The cloning is now handled\nas part of 'git-submodule update'.\n\nWith this change it is possible to specify preferred/alternate urls for\nthe submodules in .git/config before the submodules are cloned.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n\nChanged from '|| exit @?' to '|| exit'.\n\n\n  Documentation/git-submodule.txt |   16 +++++++-------\n  git-submodule.sh                |   41 ++++++++++++++++----------------------\n  t/t7400-submodule-basic.sh      |   38 ++++++++++++++++++++++++-----------\n  3 files changed, 51 insertions(+), 44 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex cb0424f..f8fb80f 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -23,15 +23,15 @@ status::\n  \trepository. This command is the default command for git-submodule.\n\n  init::\n-\tInitialize the submodules, i.e. clone the git repositories specified\n-\tin the .gitmodules file and checkout the submodule commits specified\n-\tin the index of the containing repository. This will make the\n-\tsubmodules HEAD be detached.\n+\tInitialize the submodules, i.e. register in .git/config each submodule\n+\tpath and url found in .gitmodules. The key used in git/config is\n+\t`submodule.$path.url`. This command does not alter existing information\n+\tin .git/config.\n\n  update::\n-\tUpdate the initialized submodules, i.e. checkout the submodule commits\n-\tspecified in the index of the containing repository. This will make\n-\tthe submodules HEAD be detached.\n+\tUpdate the registered submodules, i.e. clone missing submodules and\n+\tcheckout the commit specified in the index of the containing repository.\n+\tThis will make the submodules HEAD be detached.\n\n\n  OPTIONS\n@@ -50,7 +50,7 @@ OPTIONS\n\n  FILES\n  -----\n-When cloning submodules, a .gitmodules file in the top-level directory\n+When initializing submodules, a .gitmodules file in the top-level directory\n  of the containing repository is used to find the url of each submodule.\n  This file should be formatted in the same way as $GIR_DIR/config. The key\n  to each submodule url is \"module.$path.url\".\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex a89ea88..e7b6978 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -53,7 +53,7 @@ module_clone()\n  }\n\n  #\n-# Run clone + checkout on missing submodules\n+# Register submodules in .git/config\n  #\n  # $@ = requested paths (default to all)\n  #\n@@ -62,37 +62,23 @@ modules_init()\n  \tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n  \twhile read mode sha1 stage path\n  \tdo\n-\t\t# Skip submodule paths that already contain a .git directory.\n-\t\t# This will also trigger if $path is a symlink to a git\n-\t\t# repository\n-\t\ttest -d \"$path\"/.git && continue\n+\t\t# Skip already registered paths\n+\t\turl=$(git-config submodule.\"$path\".url)\n+\t\ttest -z \"$url\" || continue\n\n  \t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n  \t\ttest -z \"$url\" &&\n  \t\tdie \"No url found for submodule '$path' in .gitmodules\"\n\n-\t\t# MAYBE FIXME: this would be the place to check GIT_CONFIG\n-\t\t# for a preferred url for this submodule, possibly like this:\n-\t\t#\n-\t\t# modname=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".name)\n-\t\t# alturl=$(git-config module.\"$modname\".url)\n-\t\t#\n-\t\t# This would let the versioned .gitmodules file use the submodule\n-\t\t# path as key, while the unversioned GIT_CONFIG would use the\n-\t\t# logical modulename (if present) as key. But this would need\n-\t\t# another fallback mechanism if the module wasn't named.\n+\t\tgit-config submodule.\"$path\".url \"$url\" ||\n+\t\tdie \"Failed to register url for submodule '$path'\"\n\n-\t\tmodule_clone \"$path\" \"$url\" || exit\n-\n-\t\t(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n-\t\tdie \"Checkout of submodule '$path' failed\"\n-\n-\t\tsay \"Submodule '$path' initialized\"\n+\t\tsay \"Submodule '$path' registered with url '$url'\"\n  \tdone\n  }\n\n  #\n-# Checkout correct revision of each initialized submodule\n+# Update each submodule path to correct revision, using clone and checkout as needed\n  #\n  # $@ = requested paths (default to all)\n  #\n@@ -101,14 +87,21 @@ modules_update()\n  \tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n  \twhile read mode sha1 stage path\n  \tdo\n-\t\tif ! test -d \"$path\"/.git\n+\t\turl=$(git-config submodule.\"$path\".url)\n+\t\tif test -z \"$url\"\n  \t\tthen\n  \t\t\t# Only mention uninitialized submodules when its\n  \t\t\t# path have been specified\n  \t\t\ttest \"$#\" != \"0\" &&\n  \t\t\tsay \"Submodule '$path' not initialized\"\n-\t\t\tcontinue;\n+\t\t\tcontinue\n  \t\tfi\n+\n+\t\tif ! test -d \"$path\"/.git\n+\t\tthen\n+\t\t\tmodule_clone \"$path\" \"$url\" || exit\n+\t\tfi\n+\n  \t\tsubsha1=$(unset GIT_DIR && cd \"$path\" &&\n  \t\t\tgit-rev-parse --verify HEAD) ||\n  \t\tdie \"Unable to find current revision of submodule '$path'\"\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 6274729..3940433 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -40,7 +40,7 @@ test_expect_success 'Prepare submodule testing' '\n  \tgit-add a lib z &&\n  \tgit-commit -m \"super commit 1\" &&\n  \tmv lib .subrepo &&\n-\tGIT_CONFIG=.gitmodules git-config module.lib.url ./.subrepo\n+\tGIT_CONFIG=.gitmodules git-config module.lib.url git://example.com/lib.git\n  '\n\n  test_expect_success 'status should only print one line' '\n@@ -52,41 +52,55 @@ test_expect_success 'status should initially be \"missing\"' '\n  \tgit-submodule status | grep \"^-$rev1\"\n  '\n\n-test_expect_success 'init should fail when path is used by a file' '\n+test_expect_success 'init should register submodule url in .git/config' '\n+\tgit-submodule init &&\n+\turl=$(git-config submodule.lib.url) &&\n+\tif test \"$url\" != \"git://example.com/lib.git\"\n+\tthen\n+\t\techo \"[OOPS] init succeeded but submodule url is wrong\"\n+\t\tfalse\n+\telif ! git-config submodule.lib.url ./.subrepo\n+\tthen\n+\t\techo \"[OOPS] init succeeded but update of url failed\"\n+\t\tfalse\n+\tfi\n+'\n+\n+test_expect_success 'update should fail when path is used by a file' '\n  \techo \"hello\" >lib &&\n-\tif git-submodule init\n+\tif git-submodule update\n  \tthen\n-\t\techo \"[OOPS] init should have failed\"\n+\t\techo \"[OOPS] update should have failed\"\n  \t\tfalse\n  \telif test -f lib && test \"$(cat lib)\" != \"hello\"\n  \tthen\n-\t\techo \"[OOPS] init failed but lib file was molested\"\n+\t\techo \"[OOPS] update failed but lib file was molested\"\n  \t\tfalse\n  \telse\n  \t\trm lib\n  \tfi\n  '\n\n-test_expect_success 'init should fail when path is used by a nonempty directory' '\n+test_expect_success 'update should fail when path is used by a nonempty directory' '\n  \tmkdir lib &&\n  \techo \"hello\" >lib/a &&\n-\tif git-submodule init\n+\tif git-submodule update\n  \tthen\n-\t\techo \"[OOPS] init should have failed\"\n+\t\techo \"[OOPS] update should have failed\"\n  \t\tfalse\n  \telif test \"$(cat lib/a)\" != \"hello\"\n  \tthen\n-\t\techo \"[OOPS] init failed but lib/a was molested\"\n+\t\techo \"[OOPS] update failed but lib/a was molested\"\n  \t\tfalse\n  \telse\n  \t\trm lib/a\n  \tfi\n  '\n\n-test_expect_success 'init should work when path is an empty dir' '\n+test_expect_success 'update should work when path is an empty dir' '\n  \trm -rf lib &&\n  \tmkdir lib &&\n-\tgit-submodule init &&\n+\tgit-submodule update &&\n  \thead=$(cd lib && git-rev-parse HEAD) &&\n  \tif test -z \"$head\"\n  \tthen\n@@ -99,7 +113,7 @@ test_expect_success 'init should work when path is an empty dir' '\n  \tfi\n  '\n\n-test_expect_success 'status should be \"up-to-date\" after init' '\n+test_expect_success 'status should be \"up-to-date\" after update' '\n  \tgit-submodule status | grep \"^ $rev1\"\n  '\n\n-- \n1.5.2.841.gc9eafb\n"},{"id":"44146","messageId":"7vira15uon.fsf@assigned-by-dhcp.cox.net","threadId":"8438","inReplyTo":"op.ttf34qd99pspc6@localhost","subject":"Re: [PATCH 1/2] git-submodule: move cloning into a separate function","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-06-06T08:55:04Z","receivedAt":"2007-06-06T08:55:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Lars Hjemli\" <hjemli@gmail.com> writes:\n\n> This is just a simple refactoring of modules_init() with no change in\n> functionality.\n>\n> Signed-off-by: Lars Hjemli <hjemli@gmail.com>\n> ---\n>\n> On Tue, 05 Jun 2007 12:40:50 +0200, Johannes Sixt <J.Sixt@eudaptics.com> wrote:\n>\n>> Lars Hjemli wrote:\n>>> +               module_clone \"$path\" \"$url\" || exit $?\n>>\n>> Minor nit: The idiom that is commonly used in situations like this (see\n>> other git-* shell scripts):\n>>\n>> \t\tmodule_clone \"$path\" \"$url\" || exit\n>>\n>> because exit without argument uses the code of the last command\n>> executed.\n>>\n>\n> Thanks, I'll follow up with matching changes to [patch 2/2].\n>\n\nThis seems to be WS munged by your mailer.\n\n> ...\n> +\tdie \"Clone of submodule '$path' failed\"\n> +}\n> +\n>   #\n>   # Run clone + checkout on missing submodules\n>   #\n> @@ -40,20 +67,6 @@ modules_init()\n>   \t\t# repository\n"},{"id":"44150","messageId":"1181121182725-git-send-email-hjemli@gmail.com","threadId":"8438","inReplyTo":"7vira15uon.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 1/2] git-submodule: move cloning into a separate function","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-06-06T09:13:01Z","receivedAt":"2007-06-06T09:13:01Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This is just a simple refactoring of modules_init() with no change in\nfunctionality.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n\nOn 6/6/07, Junio C Hamano <junkio@cox.net> wrote:\n> This seems to be WS munged by your mailer.\n\nOuch, I didn't notice...\n\n\n git-submodule.sh |   44 ++++++++++++++++++++++++++++----------------\n 1 files changed, 28 insertions(+), 16 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 6ed5a6c..a89ea88 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -25,6 +25,33 @@ say()\n \tfi\n }\n \n+\n+#\n+# Clone a submodule\n+#\n+module_clone()\n+{\n+\tpath=$1\n+\turl=$2\n+\n+\t# If there already is a directory at the submodule path,\n+\t# expect it to be empty (since that is the default checkout\n+\t# action) and try to remove it.\n+\t# Note: if $path is a symlink to a directory the test will\n+\t# succeed but the rmdir will fail. We might want to fix this.\n+\tif test -d \"$path\"\n+\tthen\n+\t\trmdir \"$path\" 2>/dev/null ||\n+\t\tdie \"Directory '$path' exist, but is neither empty nor a git repository\"\n+\tfi\n+\n+\ttest -e \"$path\" &&\n+\tdie \"A file already exist at path '$path'\"\n+\n+\tgit-clone -n \"$url\" \"$path\" ||\n+\tdie \"Clone of submodule '$path' failed\"\n+}\n+\n #\n # Run clone + checkout on missing submodules\n #\n@@ -40,20 +67,6 @@ modules_init()\n \t\t# repository\n \t\ttest -d \"$path\"/.git && continue\n \n-\t\t# If there already is a directory at the submodule path,\n-\t\t# expect it to be empty (since that is the default checkout\n-\t\t# action) and try to remove it.\n-\t\t# Note: if $path is a symlink to a directory the test will\n-\t\t# succeed but the rmdir will fail. We might want to fix this.\n-\t\tif test -d \"$path\"\n-\t\tthen\n-\t\t\trmdir \"$path\" 2>/dev/null ||\n-\t\t\tdie \"Directory '$path' exist, but is neither empty nor a git repository\"\n-\t\tfi\n-\n-\t\ttest -e \"$path\" &&\n-\t\tdie \"A file already exist at path '$path'\"\n-\n \t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n \t\ttest -z \"$url\" &&\n \t\tdie \"No url found for submodule '$path' in .gitmodules\"\n@@ -69,8 +82,7 @@ modules_init()\n \t\t# logical modulename (if present) as key. But this would need\n \t\t# another fallback mechanism if the module wasn't named.\n \n-\t\tgit-clone -n \"$url\" \"$path\" ||\n-\t\tdie \"Clone of submodule '$path' failed\"\n+\t\tmodule_clone \"$path\" \"$url\" || exit\n \n \t\t(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n \t\tdie \"Checkout of submodule '$path' failed\"\n-- \n1.5.2.841.gc9eafb\n"},{"id":"44149","messageId":"11811211823082-git-send-email-hjemli@gmail.com","threadId":"8438","inReplyTo":"1181121182725-git-send-email-hjemli@gmail.com","subject":"[PATCH 2/2] git-submodule: clone during update, not during init","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-06-06T09:13:02Z","receivedAt":"2007-06-06T09:13:02Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This teaches 'git-submodule init' to register submodule paths and urls in\n.git/config instead of actually cloning them. The cloning is now handled\nas part of 'git-submodule update'.\n\nWith this change it is possible to specify preferred/alternate urls for\nthe submodules in .git/config before the submodules are cloned.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n Documentation/git-submodule.txt |   16 +++++++-------\n git-submodule.sh                |   41 ++++++++++++++++----------------------\n t/t7400-submodule-basic.sh      |   38 ++++++++++++++++++++++++-----------\n 3 files changed, 51 insertions(+), 44 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex cb0424f..f8fb80f 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -23,15 +23,15 @@ status::\n \trepository. This command is the default command for git-submodule.\n \n init::\n-\tInitialize the submodules, i.e. clone the git repositories specified\n-\tin the .gitmodules file and checkout the submodule commits specified\n-\tin the index of the containing repository. This will make the\n-\tsubmodules HEAD be detached.\n+\tInitialize the submodules, i.e. register in .git/config each submodule\n+\tpath and url found in .gitmodules. The key used in git/config is\n+\t`submodule.$path.url`. This command does not alter existing information\n+\tin .git/config.\n \n update::\n-\tUpdate the initialized submodules, i.e. checkout the submodule commits\n-\tspecified in the index of the containing repository. This will make\n-\tthe submodules HEAD be detached.\n+\tUpdate the registered submodules, i.e. clone missing submodules and\n+\tcheckout the commit specified in the index of the containing repository.\n+\tThis will make the submodules HEAD be detached.\n \n \n OPTIONS\n@@ -50,7 +50,7 @@ OPTIONS\n \n FILES\n -----\n-When cloning submodules, a .gitmodules file in the top-level directory\n+When initializing submodules, a .gitmodules file in the top-level directory\n of the containing repository is used to find the url of each submodule.\n This file should be formatted in the same way as $GIR_DIR/config. The key\n to each submodule url is \"module.$path.url\".\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex a89ea88..e7b6978 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -53,7 +53,7 @@ module_clone()\n }\n \n #\n-# Run clone + checkout on missing submodules\n+# Register submodules in .git/config\n #\n # $@ = requested paths (default to all)\n #\n@@ -62,37 +62,23 @@ modules_init()\n \tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n \twhile read mode sha1 stage path\n \tdo\n-\t\t# Skip submodule paths that already contain a .git directory.\n-\t\t# This will also trigger if $path is a symlink to a git\n-\t\t# repository\n-\t\ttest -d \"$path\"/.git && continue\n+\t\t# Skip already registered paths\n+\t\turl=$(git-config submodule.\"$path\".url)\n+\t\ttest -z \"$url\" || continue\n \n \t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n \t\ttest -z \"$url\" &&\n \t\tdie \"No url found for submodule '$path' in .gitmodules\"\n \n-\t\t# MAYBE FIXME: this would be the place to check GIT_CONFIG\n-\t\t# for a preferred url for this submodule, possibly like this:\n-\t\t#\n-\t\t# modname=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".name)\n-\t\t# alturl=$(git-config module.\"$modname\".url)\n-\t\t#\n-\t\t# This would let the versioned .gitmodules file use the submodule\n-\t\t# path as key, while the unversioned GIT_CONFIG would use the\n-\t\t# logical modulename (if present) as key. But this would need\n-\t\t# another fallback mechanism if the module wasn't named.\n+\t\tgit-config submodule.\"$path\".url \"$url\" ||\n+\t\tdie \"Failed to register url for submodule '$path'\"\n \n-\t\tmodule_clone \"$path\" \"$url\" || exit\n-\n-\t\t(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n-\t\tdie \"Checkout of submodule '$path' failed\"\n-\n-\t\tsay \"Submodule '$path' initialized\"\n+\t\tsay \"Submodule '$path' registered with url '$url'\"\n \tdone\n }\n \n #\n-# Checkout correct revision of each initialized submodule\n+# Update each submodule path to correct revision, using clone and checkout as needed\n #\n # $@ = requested paths (default to all)\n #\n@@ -101,14 +87,21 @@ modules_update()\n \tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n \twhile read mode sha1 stage path\n \tdo\n-\t\tif ! test -d \"$path\"/.git\n+\t\turl=$(git-config submodule.\"$path\".url)\n+\t\tif test -z \"$url\"\n \t\tthen\n \t\t\t# Only mention uninitialized submodules when its\n \t\t\t# path have been specified\n \t\t\ttest \"$#\" != \"0\" &&\n \t\t\tsay \"Submodule '$path' not initialized\"\n-\t\t\tcontinue;\n+\t\t\tcontinue\n \t\tfi\n+\n+\t\tif ! test -d \"$path\"/.git\n+\t\tthen\n+\t\t\tmodule_clone \"$path\" \"$url\" || exit\n+\t\tfi\n+\n \t\tsubsha1=$(unset GIT_DIR && cd \"$path\" &&\n \t\t\tgit-rev-parse --verify HEAD) ||\n \t\tdie \"Unable to find current revision of submodule '$path'\"\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 6274729..3940433 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -40,7 +40,7 @@ test_expect_success 'Prepare submodule testing' '\n \tgit-add a lib z &&\n \tgit-commit -m \"super commit 1\" &&\n \tmv lib .subrepo &&\n-\tGIT_CONFIG=.gitmodules git-config module.lib.url ./.subrepo\n+\tGIT_CONFIG=.gitmodules git-config module.lib.url git://example.com/lib.git\n '\n \n test_expect_success 'status should only print one line' '\n@@ -52,41 +52,55 @@ test_expect_success 'status should initially be \"missing\"' '\n \tgit-submodule status | grep \"^-$rev1\"\n '\n \n-test_expect_success 'init should fail when path is used by a file' '\n+test_expect_success 'init should register submodule url in .git/config' '\n+\tgit-submodule init &&\n+\turl=$(git-config submodule.lib.url) &&\n+\tif test \"$url\" != \"git://example.com/lib.git\"\n+\tthen\n+\t\techo \"[OOPS] init succeeded but submodule url is wrong\"\n+\t\tfalse\n+\telif ! git-config submodule.lib.url ./.subrepo\n+\tthen\n+\t\techo \"[OOPS] init succeeded but update of url failed\"\n+\t\tfalse\n+\tfi\n+'\n+\n+test_expect_success 'update should fail when path is used by a file' '\n \techo \"hello\" >lib &&\n-\tif git-submodule init\n+\tif git-submodule update\n \tthen\n-\t\techo \"[OOPS] init should have failed\"\n+\t\techo \"[OOPS] update should have failed\"\n \t\tfalse\n \telif test -f lib && test \"$(cat lib)\" != \"hello\"\n \tthen\n-\t\techo \"[OOPS] init failed but lib file was molested\"\n+\t\techo \"[OOPS] update failed but lib file was molested\"\n \t\tfalse\n \telse\n \t\trm lib\n \tfi\n '\n \n-test_expect_success 'init should fail when path is used by a nonempty directory' '\n+test_expect_success 'update should fail when path is used by a nonempty directory' '\n \tmkdir lib &&\n \techo \"hello\" >lib/a &&\n-\tif git-submodule init\n+\tif git-submodule update\n \tthen\n-\t\techo \"[OOPS] init should have failed\"\n+\t\techo \"[OOPS] update should have failed\"\n \t\tfalse\n \telif test \"$(cat lib/a)\" != \"hello\"\n \tthen\n-\t\techo \"[OOPS] init failed but lib/a was molested\"\n+\t\techo \"[OOPS] update failed but lib/a was molested\"\n \t\tfalse\n \telse\n \t\trm lib/a\n \tfi\n '\n \n-test_expect_success 'init should work when path is an empty dir' '\n+test_expect_success 'update should work when path is an empty dir' '\n \trm -rf lib &&\n \tmkdir lib &&\n-\tgit-submodule init &&\n+\tgit-submodule update &&\n \thead=$(cd lib && git-rev-parse HEAD) &&\n \tif test -z \"$head\"\n \tthen\n@@ -99,7 +113,7 @@ test_expect_success 'init should work when path is an empty dir' '\n \tfi\n '\n \n-test_expect_success 'status should be \"up-to-date\" after init' '\n+test_expect_success 'status should be \"up-to-date\" after update' '\n \tgit-submodule status | grep \"^ $rev1\"\n '\n \n-- \n1.5.2.841.gc9eafb\n"},{"id":"45222","messageId":"20070617143802.GV955MdfPADPa@greensroom.kotnet.org","threadId":"8438","inReplyTo":"op.ttf34qd99pspc6@localhost","subject":"Re: [PATCH 1/2] git-submodule: move cloning into a separate function","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-06-17T14:38:02Z","receivedAt":"2007-06-17T14:38:02Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Tue, Jun 05, 2007 at 01:13:28PM +0200, Lars Hjemli wrote:\n> +module_clone()\n> +{\n> +\tpath=$1\n> +\turl=$2\n> +\n> +\t# If there already is a directory at the submodule path,\n> +\t# expect it to be empty (since that is the default checkout\n> +\t# action) and try to remove it.\n> +\t# Note: if $path is a symlink to a directory the test will\n> +\t# succeed but the rmdir will fail. We might want to fix this.\n> +\tif test -d \"$path\"\n> +\tthen\n> +\t\trmdir \"$path\" 2>/dev/null ||\n> +\t\tdie \"Directory '$path' exist, but is neither empty nor a git repository\"\n\nWhat makes you say that '$path' is not a git repository?\n\nskimo\n"},{"id":"45227","messageId":"8c5c35580706170856n64747190xeaf88fc2deafd273@mail.gmail.com","threadId":"8438","inReplyTo":"20070617143802.GV955MdfPADPa@greensroom.kotnet.org","subject":"Re: [PATCH 1/2] git-submodule: move cloning into a separate function","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-06-17T15:56:15Z","receivedAt":"2007-06-17T15:56:15Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On 6/17/07, Sven Verdoolaege <skimo@kotnet.org> wrote:\n> On Tue, Jun 05, 2007 at 01:13:28PM +0200, Lars Hjemli wrote:\n> > +module_clone()\n> > +{\n> > +     path=$1\n> > +     url=$2\n> > +\n> > +     # If there already is a directory at the submodule path,\n> > +     # expect it to be empty (since that is the default checkout\n> > +     # action) and try to remove it.\n> > +     # Note: if $path is a symlink to a directory the test will\n> > +     # succeed but the rmdir will fail. We might want to fix this.\n> > +     if test -d \"$path\"\n> > +     then\n> > +             rmdir \"$path\" 2>/dev/null ||\n> > +             die \"Directory '$path' exist, but is neither empty nor a git repository\"\n>\n> What makes you say that '$path' is not a git repository?\n>\n\nThe function assumes it's only invoked when no repo is present in $path/.git.\n\n-- \nlarsh\n"}]}