{"thread":{"id":"13052","subject":"[PATCH/RFC 1/7] git-submodule: Extract functions module_info and module_url","startedAt":"2008-04-10T15:50:15Z","lastAt":"2008-04-12T04:50:54Z","messageCount":20,"participants":["Ping Yin","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":7},"messages":[{"id":"74071","messageId":"1207842625-9210-1-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":null,"subject":"[PATCH/RFC] submodule: fallback to .gitmodules and multiple level module definition","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:15Z","receivedAt":"2008-04-10T15:50:15Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"This patch series has two functional improvements for submodule\n\n  - Fall back on .gitmodules if info not found in $GIT_DIR/config\n  - multi-level module definition\n\nPatches 1,2,4 is mainly code refactor but the second one also\nhas some semantic change.\n\nThe other patches do the real functional changes.\n\nPing Yin (7):\n      git-submodule: Extract functions module_info and module_url\n      git-submodule: Extract absolute_url & move absolute url logic to module_clone\n      git-submodule: Fall back on .gitmodules if info not found in $GIT_DIR/config\n      git-submodule: Extract module_add from cmd_add\n      git-submodule: multi-level module definition\n      git-submodule: Don't die when command fails for one submodule\n      git-submodule: \"update --force\" to enforce cloning non-submodule\n\n git-submodule.sh           |  326 ++++++++++++++++++++++++++++++++------------\n t/t7400-submodule-basic.sh |   31 ++++-\n 2 files changed, 267 insertions(+), 90 deletions(-)\n"},{"id":"74070","messageId":"1207842625-9210-2-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-1-git-send-email-pkufranky@gmail.com","subject":"[PATCH/RFC 1/7] git-submodule: Extract functions module_info and module_url","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:16Z","receivedAt":"2008-04-10T15:50:16Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"module_info is extracted to remove the logic redundance which acquires\nmodule names and urls by path filter in several places.\n\nmodule_url is also extracted to prepare for an alternative logic to get url by\nmodule name.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n git-submodule.sh |   40 ++++++++++++++++++++++++++++------------\n 1 files changed, 28 insertions(+), 12 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 56ec353..a5002e1 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -82,6 +82,25 @@ module_name()\n        echo \"$name\"\n }\n \n+module_url() {\n+\tgit config submodule.$1.url\n+}\n+\n+module_info() {\n+\tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\tname=$(module_name \"$path\")\n+\t\tif test -n \"$name\"\n+\t\tthen\n+\t\t\turl=$(module_url \"$name\")\n+\t\t\techo \"$sha1\t$path\t$name\t$url\"\n+\t\telse\n+\t\t\techo \"$sha1\t$path\t\t\"\n+\t\tfi\n+\tdone\n+}\n+\n #\n # Clone a submodule\n #\n@@ -232,12 +251,11 @@ cmd_init()\n \t\tshift\n \tdone\n \n-\tgit ls-files --stage -- \"$@\" | grep '^160000 ' |\n-\twhile read mode sha1 stage path\n+\tmodule_info \"$@\" |\n+\twhile read sha1 path name url\n \tdo\n+\t\ttest -n \"$name\" || exit\n \t\t# Skip already registered paths\n-\t\tname=$(module_name \"$path\") || exit\n-\t\turl=$(git config submodule.\"$name\".url)\n \t\ttest -z \"$url\" || continue\n \n \t\turl=$(GIT_CONFIG=.gitmodules git config submodule.\"$name\".url)\n@@ -286,11 +304,10 @@ cmd_update()\n \t\tshift\n \tdone\n \n-\tgit ls-files --stage -- \"$@\" | grep '^160000 ' |\n-\twhile read mode sha1 stage path\n+\tmodule_info \"$@\" |\n+\twhile read sha1 path name url\n \tdo\n-\t\tname=$(module_name \"$path\") || exit\n-\t\turl=$(git config submodule.\"$name\".url)\n+\t\ttest -n \"$name\" || exit\n \t\tif test -z \"$url\"\n \t\tthen\n \t\t\t# Only mention uninitialized submodules when its\n@@ -537,11 +554,10 @@ cmd_status()\n \t\tshift\n \tdone\n \n-\tgit ls-files --stage -- \"$@\" | grep '^160000 ' |\n-\twhile read mode sha1 stage path\n+\tmodule_info \"$@\" |\n+\twhile read sha1 path name url\n \tdo\n-\t\tname=$(module_name \"$path\") || exit\n-\t\turl=$(git config submodule.\"$name\".url)\n+\t\ttest -n \"$name\" || exit\n \t\tif test -z \"$url\" || ! test -d \"$path\"/.git\n \t\tthen\n \t\t\tsay \"-$sha1 $path\"\n-- \n1.5.5.23.g2a5f\n"},{"id":"74075","messageId":"1207842625-9210-3-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-2-git-send-email-pkufranky@gmail.com","subject":"[PATCH v2 1/3] git-submodule summary: --for-status option","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:17Z","receivedAt":"2008-04-10T15:50:17Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"The --for-status option is mainly used by builtin-status/commit.\nIt adds 'Modified submodules:' line at top and  '# ' prefix to all\nfollowing lines.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n git-submodule.sh             |   17 ++++++++++++++++-\n t/t7401-submodule-summary.sh |   13 +++++++++++++\n 2 files changed, 29 insertions(+), 1 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 56ec353..d7937a5 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -342,6 +342,7 @@ set_name_rev () {\n #\n cmd_summary() {\n \tsummary_limit=-1\n+\tfor_status=\n \n \t# parse $args after \"submodule ... summary\".\n \twhile test $# -ne 0\n@@ -350,6 +351,9 @@ cmd_summary() {\n \t\t--cached)\n \t\t\tcached=\"$1\"\n \t\t\t;;\n+\t\t--for-status)\n+\t\t\tfor_status=\"$1\"\n+\t\t\t;;\n \t\t-n|--summary-limit)\n \t\t\tif summary_limit=$(($2 + 0)) 2>/dev/null && test \"$summary_limit\" = \"$2\"\n \t\t\tthen\n@@ -398,6 +402,12 @@ cmd_summary() {\n \t)\n \n \ttest -n \"$modules\" &&\n+\tif test -n \"$for_status\"; then\n+\t\techo \"# Modified submodules:\"\n+\t\techo \"#\"\n+\telse\n+\t\ttrue\n+\tfi &&\n \tgit diff-index $cached --raw $head -- $modules |\n \tgrep -e '^:160000' -e '^:[0-7]* 160000' |\n \tcut -c2- |\n@@ -499,7 +509,12 @@ cmd_summary() {\n \t\t\techo\n \t\tfi\n \t\techo\n-\tdone\n+\tdone |\n+\tif test -n \"$for_status\"; then\n+\t\tsed -e \"s|^|# |\" -e 's|^# $|#|'\n+\telse\n+\t\tcat\n+\tfi\n }\n #\n # List all submodules, prefixed with:\ndiff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh\nindex 0f3c42a..1dbb39d 100755\n--- a/t/t7401-submodule-summary.sh\n+++ b/t/t7401-submodule-summary.sh\n@@ -192,4 +192,17 @@ test_expect_success 'given commit' \"\n EOF\n \"\n \n+test_expect_success '--for-status' \"\n+    git submodule summary --for-status HEAD^ >actual &&\n+    diff actual - <<-EOF\n+# Modified submodules:\n+#\n+# * sm1 $head6...0000000:\n+#\n+# * sm2 0000000...$head7 (2):\n+#   > Add foo9\n+#\n+EOF\n+\"\n+\n test_done\n-- \n1.5.5.23.g2a5f\n"},{"id":"74072","messageId":"1207842625-9210-4-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-3-git-send-email-pkufranky@gmail.com","subject":"[PATCH v2 2/3] builtin-status: submodule summary support","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:18Z","receivedAt":"2008-04-10T15:50:18Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"This commit teaches 'git commit/status' show 'Modified submodules'\nsection given by\n\ngit submodule summary --cached --for-status --summary-limit <limit>\n\njust before 'Untracked files' section.\n\nThe <limit> is given by the config variable status.submodulesummary\nto limit the submodule summary size. status.submodulesummary is 0 by\ndefault which disables the summary.\n\nAlso mention status.submodulesummary in the documentation.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n Documentation/git-status.txt |    4 ++++\n wt-status.c                  |   39 +++++++++++++++++++++++++++++++++++++++\n 2 files changed, 43 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-status.txt b/Documentation/git-status.txt\nindex 3ea269a..32b6660 100644\n--- a/Documentation/git-status.txt\n+++ b/Documentation/git-status.txt\n@@ -52,6 +52,10 @@ If the config variable `status.relativePaths` is set to false, then all\n paths shown are relative to the repository root, not to the current\n directory.\n \n+If 'status.submodulesummary' is set to a non zero number, the submodule\n+summary will be enabled and a summary of commits for modified submodules\n+will be shown (see --summary-limit option of linkgit:git-submodule[1]).\n+\n See Also\n --------\n linkgit:gitignore[5]\ndiff --git a/wt-status.c b/wt-status.c\nindex b3fd57b..369c519 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -8,9 +8,11 @@\n #include \"revision.h\"\n #include \"diffcore.h\"\n #include \"quote.h\"\n+#include \"run-command.h\"\n \n int wt_status_relative_paths = 1;\n int wt_status_use_color = -1;\n+int wt_status_submodule_summary = 0;\n static char wt_status_colors[][COLOR_MAXLEN] = {\n \t\"\",         /* WT_STATUS_HEADER: normal */\n \t\"\\033[32m\", /* WT_STATUS_UPDATED: green */\n@@ -219,6 +221,38 @@ static void wt_status_print_changed(struct wt_status *s)\n \trev.diffopt.format_callback_data = s;\n \trun_diff_files(&rev, 0);\n }\n+static void wt_status_print_submodule_summary(struct wt_status *s)\n+{\n+\tstruct child_process sm_summary;\n+\tchar summary_limit[64];\n+\tchar index[PATH_MAX];\n+\tconst char *env[] = { index, NULL };\n+\tconst char *argv[] = {\n+\t\t\"submodule\",\n+\t\t\"summary\",\n+\t\t\"--cached\",\n+\t\t\"--for-status\",\n+\t\t\"--summary-limit\",\n+\t\tsummary_limit,\n+\t\ts->amend ? \"HEAD^\" : \"HEAD\",\n+\t\tNULL\n+\t};\n+\n+\tif (!wt_status_submodule_summary)\n+\t\treturn;\n+\n+\tsprintf(summary_limit, \"%d\", wt_status_submodule_summary);\n+\tsnprintf(index, sizeof(index), \"GIT_INDEX_FILE=%s\", s->index_file);\n+\n+\tmemset(&sm_summary, 0, sizeof(sm_summary));\n+\tsm_summary.argv = argv;\n+\tsm_summary.env = env;\n+\tsm_summary.git_cmd = 1;\n+\tsm_summary.no_stdin = 1;\n+\tfflush(s->fp);\n+\tsm_summary.out = dup(fileno(s->fp));    /* run_command closes it */\n+\trun_command(&sm_summary);\n+}\n \n static void wt_status_print_untracked(struct wt_status *s)\n {\n@@ -308,6 +342,7 @@ void wt_status_print(struct wt_status *s)\n \t}\n \n \twt_status_print_changed(s);\n+\twt_status_print_submodule_summary(s);\n \twt_status_print_untracked(s);\n \n \tif (s->verbose && !s->is_initial)\n@@ -330,6 +365,10 @@ void wt_status_print(struct wt_status *s)\n \n int git_status_config(const char *k, const char *v)\n {\n+\tif (!strcmp(k, \"status.submodulesummary\")) {\n+\t\twt_status_submodule_summary = atoi(v);\n+\t\treturn 0;\n+\t}\n \tif (!strcmp(k, \"status.color\") || !strcmp(k, \"color.status\")) {\n \t\twt_status_use_color = git_config_colorbool(k, v, -1);\n \t\treturn 0;\n-- \n1.5.5.23.g2a5f\n"},{"id":"74073","messageId":"1207842625-9210-5-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-4-git-send-email-pkufranky@gmail.com","subject":"[PATCH/RFC 2/7] git-submodule: Extract absolute_url & move absolute url logic to module_clone","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:19Z","receivedAt":"2008-04-10T15:50:19Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"Extract function absolute_url to remove code redundance and inconsistence in\ncmd_init and cmd_add when resolving relative url/path to absolute one.\n\nAlso move resolving absolute url logic from cmd_add to module_clone which\nresults in a litte behaviour change: cmd_update originally doesn't\nresolve absolute url but now it will.\n\nThis behaviour change breaks t7400 which uses relative url './.subrepo'.\nHowever, this test originally doesn't mean to test relative url, so fix\nthe url as '.subrepo'.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n git-submodule.sh           |   41 ++++++++++++++++++-----------------------\n t/t7400-submodule-basic.sh |    2 +-\n 2 files changed, 19 insertions(+), 24 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex a5002e1..4d56135 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -65,6 +65,21 @@ resolve_relative_url ()\n \techo \"$remoteurl/$url\"\n }\n \n+# Resolve relative url/path to absolute one\n+absolute_url () {\n+\tcase \"$1\" in\n+\t./*|../*)\n+\t\t# dereference source url relative to parent's url\n+\t\turl=\"$(resolve_relative_url $1)\" ;;\n+\t*)\n+\t\t# Turn the source into an absolute path if it is local\n+\t\turl=$(get_repo_base \"$1\") ||\n+\t\turl=$1\n+\t\t;;\n+\tesac\n+\techo \"$url\"\n+}\n+\n #\n # Map submodule path to submodule name\n #\n@@ -112,7 +127,7 @@ module_info() {\n module_clone()\n {\n \tpath=$1\n-\turl=$2\n+\turl=$(absolute_url \"$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@@ -195,21 +210,7 @@ cmd_add()\n \t\t\tdie \"'$path' already exists and is not a valid git repo\"\n \t\tfi\n \telse\n-\t\tcase \"$repo\" in\n-\t\t./*|../*)\n-\t\t\t# dereference source url relative to parent's url\n-\t\t\trealrepo=\"$(resolve_relative_url $repo)\" ;;\n-\t\t*)\n-\t\t\t# Turn the source into an absolute path if\n-\t\t\t# it is local\n-\t\t\tif base=$(get_repo_base \"$repo\"); then\n-\t\t\t\trepo=\"$base\"\n-\t\t\tfi\n-\t\t\trealrepo=$repo\n-\t\t\t;;\n-\t\tesac\n-\n-\t\tmodule_clone \"$path\" \"$realrepo\" || exit\n+\t\tmodule_clone \"$path\" \"$repo\" || exit\n \t\t(unset GIT_DIR; cd \"$path\" && git checkout -q ${branch:+-b \"$branch\" \"origin/$branch\"}) ||\n \t\tdie \"Unable to checkout submodule '$path'\"\n \tfi\n@@ -262,13 +263,7 @@ cmd_init()\n \t\ttest -z \"$url\" &&\n \t\tdie \"No url found for submodule path '$path' in .gitmodules\"\n \n-\t\t# Possibly a url relative to parent\n-\t\tcase \"$url\" in\n-\t\t./*|../*)\n-\t\t\turl=\"$(resolve_relative_url \"$url\")\"\n-\t\t\t;;\n-\t\tesac\n-\n+\t\turl=$(absolute_url \"$url\")\n \t\tgit config submodule.\"$name\".url \"$url\" ||\n \t\tdie \"Failed to register url for submodule path '$path'\"\n \ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 2ef85a8..e5d59b8 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -75,7 +75,7 @@ test_expect_success 'init should register submodule url in .git/config' '\n \tthen\n \t\techo \"[OOPS] init succeeded but submodule url is wrong\"\n \t\tfalse\n-\telif ! git config submodule.example.url ./.subrepo\n+\telif ! git config submodule.example.url .subrepo\n \tthen\n \t\techo \"[OOPS] init succeeded but update of url failed\"\n \t\tfalse\n-- \n1.5.5.23.g2a5f\n"},{"id":"74080","messageId":"1207842625-9210-6-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-5-git-send-email-pkufranky@gmail.com","subject":"[PATCH v2 3/3] buitin-status: Add tests for submodule summary","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:20Z","receivedAt":"2008-04-10T15:50:20Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"Signed-off-by: Ping Yin <pkufranky@gmail.com>\n---\n t/t7502-status.sh |  134 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 134 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t7502-status.sh b/t/t7502-status.sh\nindex cd08516..33882c9 100755\n--- a/t/t7502-status.sh\n+++ b/t/t7502-status.sh\n@@ -149,4 +149,138 @@ test_expect_success 'status of partial commit excluding new file in index' '\n \ttest_cmp expect output\n '\n \n+test_expect_success \"setup status submodule summary\" '\n+\ttest_create_repo sm &&\n+\tcd sm &&\n+\t: >foo &&\n+\tgit add foo &&\n+\tgit commit -m \"Add foo\" &&\n+\tcd .. &&\n+\tgit add sm\n+'\n+\n+cat > expect <<EOF\n+# On branch master\n+# Changes to be committed:\n+#   (use \"git reset HEAD <file>...\" to unstage)\n+#\n+#\tnew file:   dir2/added\n+#\tnew file:   sm\n+#\n+# Changed but not updated:\n+#   (use \"git add <file>...\" to update what will be committed)\n+#\n+#\tmodified:   dir1/modified\n+#\n+# Untracked files:\n+#   (use \"git add <file>...\" to include in what will be committed)\n+#\n+#\tdir1/untracked\n+#\tdir2/modified\n+#\tdir2/untracked\n+#\texpect\n+#\toutput\n+#\tuntracked\n+EOF\n+test_expect_success \"status submodule summary is disabled by default\" '\n+\tgit status > output &&\n+\tgit diff expect output\n+'\n+\n+head=$(cd sm && git rev-parse --short=7 --verify HEAD)\n+\n+cat > expect <<EOF\n+# On branch master\n+# Changes to be committed:\n+#   (use \"git reset HEAD <file>...\" to unstage)\n+#\n+#\tnew file:   dir2/added\n+#\tnew file:   sm\n+#\n+# Changed but not updated:\n+#   (use \"git add <file>...\" to update what will be committed)\n+#\n+#\tmodified:   dir1/modified\n+#\n+# Modified submodules:\n+#\n+# * sm 0000000...$head (1):\n+#   > Add foo\n+#\n+# Untracked files:\n+#   (use \"git add <file>...\" to include in what will be committed)\n+#\n+#\tdir1/untracked\n+#\tdir2/modified\n+#\tdir2/untracked\n+#\texpect\n+#\toutput\n+#\tuntracked\n+EOF\n+test_expect_success \"status submodule summary\" '\n+\tgit config status.submodulesummary 10 &&\n+\tgit status > output &&\n+\tgit diff expect output\n+'\n+\n+\n+cat > expect <<EOF\n+# On branch master\n+# Changed but not updated:\n+#   (use \"git add <file>...\" to update what will be committed)\n+#\n+#\tmodified:   dir1/modified\n+#\n+# Untracked files:\n+#   (use \"git add <file>...\" to include in what will be committed)\n+#\n+#\tdir1/untracked\n+#\tdir2/modified\n+#\tdir2/untracked\n+#\texpect\n+#\toutput\n+#\tuntracked\n+no changes added to commit (use \"git add\" and/or \"git commit -a\")\n+EOF\n+test_expect_success \"status submodule summary (clean submodule)\" '\n+\tgit commit -m \"commit submodule\" &&\n+\tgit config status.submodulesummary 10 &&\n+\t! git status > output &&\n+\tgit diff expect output\n+'\n+\n+cat > expect <<EOF\n+# On branch master\n+# Changes to be committed:\n+#   (use \"git reset HEAD^1 <file>...\" to unstage)\n+#\n+#\tnew file:   dir2/added\n+#\tnew file:   sm\n+#\n+# Changed but not updated:\n+#   (use \"git add <file>...\" to update what will be committed)\n+#\n+#\tmodified:   dir1/modified\n+#\n+# Modified submodules:\n+#\n+# * sm 0000000...$head (1):\n+#   > Add foo\n+#\n+# Untracked files:\n+#   (use \"git add <file>...\" to include in what will be committed)\n+#\n+#\tdir1/untracked\n+#\tdir2/modified\n+#\tdir2/untracked\n+#\texpect\n+#\toutput\n+#\tuntracked\n+EOF\n+test_expect_success \"status submodule summary (--amend)\" '\n+\tgit config status.submodulesummary 10 &&\n+\tgit status --amend > output &&\n+\tgit diff expect output\n+'\n+\n test_done\n-- \n1.5.5.23.g2a5f\n"},{"id":"74079","messageId":"1207842625-9210-7-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-6-git-send-email-pkufranky@gmail.com","subject":"[PATCH/RFC 3/7] git-submodule: Fall back on .gitmodules if info not found in $GIT_DIR/config","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:21Z","receivedAt":"2008-04-10T15:50:21Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"Originally, the submodule workflow enforces 'git init' in the beginning\nwhich copies submodule config info from .gitmodules to $GIT_DIR/config.\nThen all subcommands except 'init' and 'add' fetch submodule info from\n$GIT_DIR/config and .gitmodules can be discarded.\n\nHowever, there may be inconsistence between .git/config and .gitmodules\nwhen always using 'git init' at first. If upstream .gitmodules changes,\nit is not easy to sync the changes to $GIT_DIR/config.\n\nRunning 'git init' again may not help much in this case.  Since .git/config\nhas a whole copy of .gitmodules, the user has no easy way to know which\nentries should follow the upstream changes and which entires shouldn't.\n\nActually, .gitmodules which formly only acted as info hints can and should\nplay a more important and essential role.\n\nAs an analogy to .gitignore and .git/info/excludes which are for colleagues'\nand individual wishes separately, .gitmodules is for common requirements and\n$GIT_DIR/config is for special requirements.\n\nThis patch implements a fall back strategy to satisfy both common and\nspecial requirements as follows.\n\n$GIT_DIR/config only keeps submodule info different from .gitmodules.\nAnd the info from $GIT_DIR/config take higher precedence. The code first\nconsults $GIT_DIR/config and then fall back on in-tree .gitmodules file.\n\nWith this patch, init subcommand becomes not forcefull and less meaningful.\nAnd now it is just a tool to help users copy info to $GIT_DIR/config\n(and may modify it later) only when they need.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n git-submodule.sh           |    9 ++++-----\n t/t7400-submodule-basic.sh |   29 +++++++++++++++++++++++++++++\n 2 files changed, 33 insertions(+), 5 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 4d56135..d88e3c3 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -98,7 +98,8 @@ module_name()\n }\n \n module_url() {\n-\tgit config submodule.$1.url\n+\tgit config submodule.$1.url ||\n+\tGIT_CONFIG=.gitmodules git config submodule.$1.url\n }\n \n module_info() {\n@@ -256,12 +257,10 @@ cmd_init()\n \twhile read sha1 path name url\n \tdo\n \t\ttest -n \"$name\" || exit\n-\t\t# Skip already registered paths\n-\t\ttest -z \"$url\" || continue\n-\n-\t\turl=$(GIT_CONFIG=.gitmodules git config submodule.\"$name\".url)\n \t\ttest -z \"$url\" &&\n \t\tdie \"No url found for submodule path '$path' in .gitmodules\"\n+\t\t# Skip already registered paths\n+\t\tgit config submodule.$name.url && continue\n \n \t\turl=$(absolute_url \"$url\")\n \t\tgit config submodule.\"$name\".url \"$url\" ||\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex e5d59b8..d9b48f7 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -174,6 +174,35 @@ test_expect_success 'status should be \"up-to-date\" after update' '\n \tgit-submodule status | grep \"^ $rev1\"\n '\n \n+test_expect_success 'status should be \"modified\" after submodule reset --hard HEAD@{1}' '\n+\tcd init &&\n+\tgit reset --hard HEAD@{1}\n+\trev2=$(git rev-parse HEAD) &&\n+\tcd .. &&\n+\tif test -z \"$rev2\"\n+\tthen\n+\t\techo \"[OOPS] submodule git rev-parse returned nothing\"\n+\t\tfalse\n+\tfi &&\n+\tgit-submodule status | grep \"^+$rev2\"\n+'\n+\n+test_expect_success 'update should checkout rev1 when fall back' '\n+\tgit-config --unset submodule.example.url &&\n+\tGIT_CONFIG=.gitmodules git config submodule.example.url .subrepo &&\n+\tgit-submodule update init &&\n+\thead=$(cd init && git rev-parse HEAD) &&\n+\tif test -z \"$head\"\n+\tthen\n+\t\techo \"[OOPS] submodule git rev-parse returned nothing\"\n+\t\tfalse\n+\telif test \"$head\" != \"$rev1\"\n+\tthen\n+\t\techo \"[OOPS] init did not checkout correct head\"\n+\t\tfalse\n+\tfi\n+'\n+\n test_expect_success 'checkout superproject with subproject already present' '\n \tgit-checkout initial &&\n \tgit-checkout master\n-- \n1.5.5.23.g2a5f\n"},{"id":"74078","messageId":"1207842625-9210-8-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-7-git-send-email-pkufranky@gmail.com","subject":"[PATCH/RFC 4/7] git-submodule: Extract module_add from cmd_add","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:22Z","receivedAt":"2008-04-10T15:50:22Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"cmd_add will later handle the case adding multiple modules, so extract\nmodule_add to add a single module.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n git-submodule.sh |   67 +++++++++++++++++++++++++++++++----------------------\n 1 files changed, 39 insertions(+), 28 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex d88e3c3..996bf2c 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -155,34 +155,7 @@ module_clone()\n #\n # optional branch is stored in global branch variable\n #\n-cmd_add()\n-{\n-\t# parse $args after \"submodule ... add\".\n-\twhile test $# -ne 0\n-\tdo\n-\t\tcase \"$1\" in\n-\t\t-b | --branch)\n-\t\t\tcase \"$2\" in '') usage ;; esac\n-\t\t\tbranch=$2\n-\t\t\tshift\n-\t\t\t;;\n-\t\t-q|--quiet)\n-\t\t\tquiet=1\n-\t\t\t;;\n-\t\t--)\n-\t\t\tshift\n-\t\t\tbreak\n-\t\t\t;;\n-\t\t-*)\n-\t\t\tusage\n-\t\t\t;;\n-\t\t*)\n-\t\t\tbreak\n-\t\t\t;;\n-\t\tesac\n-\t\tshift\n-\tdone\n-\n+module_add() {\n \trepo=$1\n \tpath=$2\n \n@@ -226,6 +199,44 @@ cmd_add()\n }\n \n #\n+# Add a new submodule to the working tree, .gitmodules and the index\n+#\n+# $@ = repo [path]\n+#\n+# optional branch is stored in global branch variable\n+#\n+cmd_add()\n+{\n+\t# parse $args after \"submodule ... add\".\n+\twhile test $# -ne 0\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t-b | --branch)\n+\t\t\tcase \"$2\" in '') usage ;; esac\n+\t\t\tbranch=$2\n+\t\t\tshift\n+\t\t\t;;\n+\t\t-q|--quiet)\n+\t\t\tquiet=1\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t-*)\n+\t\t\tusage\n+\t\t\t;;\n+\t\t*)\n+\t\t\tbreak\n+\t\t\t;;\n+\t\tesac\n+\t\tshift\n+\tdone\n+\n+\tmodule_add \"$1\" \"$2\"\n+}\n+\n+#\n # Register submodules in .git/config\n #\n # $@ = requested paths (default to all)\n-- \n1.5.5.23.g2a5f\n"},{"id":"74076","messageId":"1207842625-9210-9-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-8-git-send-email-pkufranky@gmail.com","subject":"[PATCH/RFC 5/7] git-submodule: multi-level module definition","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:23Z","receivedAt":"2008-04-10T15:50:23Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"This patch introduces multi-level module definition and '--module-name'\noption to designate submodules by logical names instead of path filters.\nThen the init/update/status/add subcommand is enhanced combined with\nthis option.\n\nThe multi-level module definition in .gitmodules was first suggested by\nLinus and etc. in mails \"Let .git/config specify the url for submodules\"\n(http://article.gmane.org/gmane.comp.version-control.git/48939).\n\nFollowing shows an example of such a .gitmodules which finally comes\nfrom the group notation of 'git remote' which is suggested by Johannes\nSchindelin.\n\n.gitmodules with multiple level of indirection\n------------------------------------------------------\n[submodules]\n\tservice = crawler search\n\tcrawler = util imcrawter\n\tsearch = util imsearch\n[submodule \"util\"]\n\turl = git://xyzzy/util.git\n[submodule \"imsearch\"]\n\tpath = search/imsearch\n\turl = git://xyzzy/imsearch.git\n[submodule \"imcrawler\"]\n\tpath = crawler/imcrawter\n\turl = git://xyzzy/imcrawter.git\n------------------------------------------------------\n\nBy adding the 'submodules' section, we can define multi-level modules\nin an infinite levels of indirection.\n\nThe \"-m|--module-name\" option is introduced with which submodules are\ndesignated by logical names instead of real paths as following shows.\n\nIdentical commands forms with/without \"--module-name\"\n---------------------------------------------------\n$ git submodule XXX util imcrawler              (1)\n$ git submodule XXX -n crawler                  (2)\n$ git submodule XXX util imcrawler imsearch     (3)\n$ git submodule XXX -n service                  (4)\n$ git submodule XXX -n crawler search           (5)\n---------------------------------------------------\n* XXX represents status, update or init, but not add\n* (1) and (2) are identical conditionally (explained below)\n* (3), (4) and (5) are identical conditionally\n\nThere are still minor difference between these two forms.\n\nIn the no \"--module-name\" form, the path parameter may be not the real\nsubmodule path, and it just acts as the filter for real submodule paths.\nWhile in the \"--module-name\" form, the name parameter must be the logical\nname, and the real paths corresponding to the logical name may be neither\na submodule path nor even existent.\n\nThis patch handles such a path for different subcommands as follows.\n\n - status: Output 0{40} as the sha1. Doing this can remind the user to\n   add the path as submodule or delete the path from .gitmodules.\n - update: Skip that path and issue a \"Not a submodule\" warning\n - init: Also init for that path\n\nSo in the example above, commands (1) and (2) are identical only when\nutil and imcrawler are already submodules.\n\nThe add subcommand is also enhanced.\n\nThe former workflow to add submodules is adding one by one with\n\"git submodule add url path\" which then modifies .gitmodules. However,\nsometimes it is more convenient to work in the reverse way: edit\n.gitmodules first and then add submodules in batch.\n\nNow \"git submodule add --module-name modulename\" can help us to do that.\nIt will find all submodules corresponding to the logical name and add them\nin batch by using the paths and urls from .gitmodules. Of course, it will\nskip the paths which have already been submodules.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n git-submodule.sh |   86 ++++++++++++++++++++++++++++++++++++++++++++++++++---\n 1 files changed, 81 insertions(+), 5 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 996bf2c..f1c164c 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -4,7 +4,7 @@\n #\n # Copyright (c) 2007 Lars Hjemli\n \n-USAGE=\"[--quiet] [--cached] \\\n+USAGE=\"[--quiet] [--cached] [--module-name] \\\n [add <repo> [-b branch]|status|init|update|summary [-n|--summary-limit <n>] [<commit>]] \\\n [--] [<path>...]\"\n OPTIONS_SPEC=\n@@ -15,6 +15,7 @@ command=\n branch=\n quiet=\n cached=\n+use_module_name=\n \n #\n # print stuff on stdout unless -q was specified\n@@ -97,12 +98,23 @@ module_name()\n        echo \"$name\"\n }\n \n+module_path() {\n+\tgit config submodule.$1.path ||\n+\tGIT_CONFIG=.gitmodules git config submodule.$1.path ||\n+\techo \"$1\"\n+}\n+\n module_url() {\n \tgit config submodule.$1.url ||\n \tGIT_CONFIG=.gitmodules git config submodule.$1.url\n }\n \n module_info() {\n+\tif test -n \"$use_module_name\"\n+\tthen\n+\t\tmodule_info_by_name \"$@\"\n+\t\treturn\n+\tfi\n \tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n \twhile read mode sha1 stage path\n \tdo\n@@ -118,6 +130,50 @@ module_info() {\n }\n \n #\n+# List all submodule info line by line by given names as follows\n+# sha1<tab>path<tab>name<tab>url\n+#\n+# Here we assume that module names and paths don't contain space\n+# characters\n+#\n+# $@ = module names\n+# When names is not given, list all module info\n+#\n+module_info_by_name() {\n+\tif test $# = 0\n+\tthen\n+\t\tnames=$(\n+\t\t{\n+\t\t\tgit config --get-regexp 'submodule.*.url'\n+\t\t\tgit config -f .gitmodules --get-regexp 'submodule.*.url'\n+\t\t} | sed 's/submodule.\\(.*\\).url .*$/\\1/' 2>/dev/null\n+\t\t)\n+\telse\n+\t\tnames=$(module_children_names \"$@\")\n+\tfi\n+\tfor name in $names\n+\tdo\n+\t\turl=$(module_url \"$name\") || continue\n+\t\tpath=$(module_path \"$name\")\n+\t\tsha1=$(git ls-files --stage \"$path\" |\n+\t\t\tgrep \"$path$\" | grep '^160000' | awk '{print $2}')\n+\t\ttest -z \"$sha1\" && sha1=0000000000000000000000000000000000000000\n+\t\techo \"$sha1\t$path\t$name\t$url\"\n+\tdone\n+}\n+\n+module_children_names() {\n+\tfor name\n+\tdo\n+\t\techo \"$name\"\n+\t\tmodule_children_names $(\n+\t\t\tgit config \"submodules.$name\"\n+\t\t\tgit config -f .gitmodules \"submodules.$name\"\n+\t\t)\n+\tdone | sort -u\n+}\n+\n+#\n # Clone a submodule\n #\n # Prior to calling, cmd_update checks that a possibly existing\n@@ -233,7 +289,17 @@ cmd_add()\n \t\tshift\n \tdone\n \n-\tmodule_add \"$1\" \"$2\"\n+\tif test -n \"$use_module_name\"\n+\tthen\n+\t\tmodule_info \"$@\" |\n+\t\twhile read sha1 path name url\n+\t\tdo\n+\t\t\tmodule_add \"$url\" \"$path\"\n+\t\tdone\n+\telse\n+\t\tmodule_add \"$1\" \"$2\"\n+\tfi\n+\n }\n \n #\n@@ -313,7 +379,11 @@ cmd_update()\n \twhile read sha1 path name url\n \tdo\n \t\ttest -n \"$name\" || exit\n-\t\tif test -z \"$url\"\n+\t\tif test $sha1 = 0000000000000000000000000000000000000000\n+\t\tthen\n+\t\t\tsay \"Not a submodule: $name @ $path\"\n+\t\t\tcontinue\n+\t\telif 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@@ -558,12 +628,15 @@ cmd_status()\n \t\tesac\n \t\tshift\n \tdone\n-\n \tmodule_info \"$@\" |\n \twhile read sha1 path name url\n \tdo\n \t\ttest -n \"$name\" || exit\n-\t\tif test -z \"$url\" || ! test -d \"$path\"/.git\n+\t\tif test $sha1 = 0000000000000000000000000000000000000000\n+\t\tthen\n+\t\t\tsay \"*$sha1 $path\"\n+\t\t\tcontinue\n+\t\telif test -z \"$url\" || ! test -d \"$path\"/.git\n \t\tthen\n \t\t\tsay \"-$sha1 $path\"\n \t\t\tcontinue;\n@@ -609,6 +682,9 @@ do\n \t--cached)\n \t\tcached=\"$1\"\n \t\t;;\n+\t-m|--module-name)\n+\t\tuse_module_name=1\n+\t\t;;\n \t--)\n \t\tbreak\n \t\t;;\n-- \n1.5.5.23.g2a5f\n"},{"id":"74077","messageId":"1207842625-9210-10-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-9-git-send-email-pkufranky@gmail.com","subject":"[PATCH/RFC 6/7] git-submodule: Don't die when command fails for one submodule","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:24Z","receivedAt":"2008-04-10T15:50:24Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"When handling multiple modules, init/update/status/add subcommand will\nexit when it fails for one submodule. This patch makes the subcommand\ncontinue bypassing the failure and keep right exit status.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n git-submodule.sh |   87 +++++++++++++++++++++++++++++++++++++++---------------\n 1 files changed, 63 insertions(+), 24 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex f1c164c..b4db676 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -193,15 +193,19 @@ module_clone()\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+\t\t! rmdir \"$path\" 2>/dev/null &&\n+\t\tsay \"Directory '$path' exist, but is neither empty nor a git repository\" &&\n+\t\treturn 1\n \tfi\n \n \ttest -e \"$path\" &&\n-\tdie \"A file already exist at path '$path'\"\n+\tsay \"A file already exist at path '$path'\" &&\n+\treturn 1\n \n-\tgit-clone -n \"$url\" \"$path\" ||\n-\tdie \"Clone of '$url' into submodule path '$path' failed\"\n+\t! git-clone -n \"$url\" \"$path\" &&\n+\tsay \"Clone of '$url' into submodule path '$path' failed\" &&\n+\treturn 1\n+\t:\n }\n \n #\n@@ -227,7 +231,8 @@ module_add() {\n \tfi\n \n \tgit ls-files --error-unmatch \"$path\" > /dev/null 2>&1 &&\n-\tdie \"'$path' already exists in the index\"\n+\tsay \"'$path' already exists in the index\" &&\n+\treturn 1\n \n \t# perhaps the path exists and is already a git repo, else clone it\n \tif test -e \"$path\"\n@@ -237,21 +242,26 @@ module_add() {\n \t\tthen\n \t\t\techo \"Adding existing repo at '$path' to the index\"\n \t\telse\n-\t\t\tdie \"'$path' already exists and is not a valid git repo\"\n+\t\t\tsay \"'$path' already exists and is not a valid git repo\"\n+\t\t\treturn 1\n \t\tfi\n \telse\n-\t\tmodule_clone \"$path\" \"$repo\" || exit\n-\t\t(unset GIT_DIR; cd \"$path\" && git checkout -q ${branch:+-b \"$branch\" \"origin/$branch\"}) ||\n-\t\tdie \"Unable to checkout submodule '$path'\"\n+\t\tmodule_clone \"$path\" \"$repo\" || return 1\n+\t\t! (unset GIT_DIR; cd \"$path\" && git checkout -q ${branch:+-b \"$branch\" \"origin/$branch\"}) &&\n+\t\tsay \"Unable to checkout submodule '$path'\" &&\n+\t\treturn 1\n \tfi\n \n-\tgit add \"$path\" ||\n-\tdie \"Failed to add submodule '$path'\"\n+\t! git add \"$path\" &&\n+\tsay \"Failed to add submodule '$path'\" &&\n+\treturn 1\n \n \tGIT_CONFIG=.gitmodules git config submodule.\"$path\".path \"$path\" &&\n \tGIT_CONFIG=.gitmodules git config submodule.\"$path\".url \"$repo\" &&\n-\tgit add .gitmodules ||\n-\tdie \"Failed to register submodule '$path'\"\n+\t! git add .gitmodules &&\n+\tsay \"Failed to register submodule '$path'\" &&\n+\treturn 1\n+\t:\n }\n \n #\n@@ -292,14 +302,17 @@ cmd_add()\n \tif test -n \"$use_module_name\"\n \tthen\n \t\tmodule_info \"$@\" |\n+\t\t{\n+\t\texit_status=0\n \t\twhile read sha1 path name url\n \t\tdo\n-\t\t\tmodule_add \"$url\" \"$path\"\n+\t\t\tmodule_add \"$url\" \"$path\" || exit_status=1\n \t\tdone\n+\t\ttest $exit_status = 0\n+\t\t}\n \telse\n \t\tmodule_add \"$1\" \"$2\"\n \tfi\n-\n }\n \n #\n@@ -331,20 +344,30 @@ cmd_init()\n \tdone\n \n \tmodule_info \"$@\" |\n+\t{\n+\texit_status=0\n \twhile read sha1 path name url\n \tdo\n-\t\ttest -n \"$name\" || exit\n+\t\ttest -z \"$name\" && exit_status=1 && continue\n \t\ttest -z \"$url\" &&\n-\t\tdie \"No url found for submodule path '$path' in .gitmodules\"\n+\t\tsay \"No url found for submodule path '$path' in .gitmodules\" &&\n+\t\texit_status=1 &&\n+\t\tcontinue\n \t\t# Skip already registered paths\n \t\tgit config submodule.$name.url && continue\n \n \t\turl=$(absolute_url \"$url\")\n \t\tgit config submodule.\"$name\".url \"$url\" ||\n-\t\tdie \"Failed to register url for submodule path '$path'\"\n+\t\t{\n+\t\tsay \"Failed to register url for submodule path '$path'\"\n+\t\texit_status=1\n+\t\tcontinue\n+\t\t}\n \n \t\tsay \"Submodule '$name' ($url) registered for path '$path'\"\n \tdone\n+\texit $exit_status\n+\t}\n }\n \n #\n@@ -376,9 +399,11 @@ cmd_update()\n \tdone\n \n \tmodule_info \"$@\" |\n+\t{\n+\texit_status=0\n \twhile read sha1 path name url\n \tdo\n-\t\ttest -n \"$name\" || exit\n+\t\ttest -z \"$name\" && exit_status=1 && continue\n \t\tif test $sha1 = 0000000000000000000000000000000000000000\n \t\tthen\n \t\t\tsay \"Not a submodule: $name @ $path\"\n@@ -394,23 +419,33 @@ cmd_update()\n \n \t\tif ! test -d \"$path\"/.git\n \t\tthen\n-\t\t\tmodule_clone \"$path\" \"$url\" || exit\n+\t\t\t! module_clone \"$path\" \"$url\" && exit_status=1 && continue\n \t\t\tsubsha1=\n \t\telse\n \t\t\tsubsha1=$(unset GIT_DIR; cd \"$path\" &&\n \t\t\t\tgit rev-parse --verify HEAD) ||\n-\t\t\tdie \"Unable to find current revision in submodule path '$path'\"\n+\t\t\t{\n+\t\t\t\tsay \"Unable to find current revision in submodule path '$path'\"\n+\t\t\t\texit_status=1\n+\t\t\t\tcontinue\n+\t\t\t}\n \t\tfi\n \n \t\tif test \"$subsha1\" != \"$sha1\"\n \t\tthen\n \t\t\t(unset GIT_DIR; cd \"$path\" && git-fetch &&\n \t\t\t\tgit-checkout -q \"$sha1\") ||\n-\t\t\tdie \"Unable to checkout '$sha1' in submodule path '$path'\"\n+\t\t\t{\n+\t\t\t\tsay \"Unable to checkout '$sha1' in submodule path '$path'\"\n+\t\t\t\texit_status=1\n+\t\t\t\tcontinue\n+\t\t\t}\n \n \t\t\tsay \"Submodule path '$path': checked out '$sha1'\"\n \t\tfi\n \tdone\n+\texit $exit_status\n+\t}\n }\n \n set_name_rev () {\n@@ -629,9 +664,11 @@ cmd_status()\n \t\tshift\n \tdone\n \tmodule_info \"$@\" |\n+\t{\n+\texit_status=0\n \twhile read sha1 path name url\n \tdo\n-\t\ttest -n \"$name\" || exit\n+\t\ttest -z \"$name\" && exit_status=1 && continue\n \t\tif test $sha1 = 0000000000000000000000000000000000000000\n \t\tthen\n \t\t\tsay \"*$sha1 $path\"\n@@ -654,6 +691,8 @@ cmd_status()\n \t\t\tsay \"+$sha1 $path$revname\"\n \t\tfi\n \tdone\n+\texit $exit_status\n+\t}\n }\n \n # This loop parses the command line arguments to find the\n-- \n1.5.5.23.g2a5f\n"},{"id":"74074","messageId":"1207842625-9210-11-git-send-email-pkufranky@gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-10-git-send-email-pkufranky@gmail.com","subject":"[PATCH/RFC 7/7] git-submodule: \"update --force\" to enforce cloning non-submodule","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:50:25Z","receivedAt":"2008-04-10T15:50:25Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"If the update subcommand combines with --force, non-submodules\n(i.e. modules existing in .gitmodules or $GIT_DIR/config but not added\nto the super module) will be cloned and the master branch will be\nchecked out.\n\nHowever, if a non-submodule has already been cloned before, the update\nwill be rejected since we don't know what the update means.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n git-submodule.sh |   14 +++++++++++++-\n 1 files changed, 13 insertions(+), 1 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex b4db676..153b61e 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -384,6 +384,9 @@ cmd_update()\n \t\t-q|--quiet)\n \t\t\tquiet=1\n \t\t\t;;\n+\t\t-f | --force)\n+\t\t\tforce=\"$1\"\n+\t\t\t;;\n \t\t--)\n \t\t\tshift\n \t\t\tbreak\n@@ -406,7 +409,8 @@ cmd_update()\n \t\ttest -z \"$name\" && exit_status=1 && continue\n \t\tif test $sha1 = 0000000000000000000000000000000000000000\n \t\tthen\n-\t\t\tsay \"Not a submodule: $name @ $path\"\n+\t\t\ttest -z \"$force\" &&\n+\t\t\tsay \"Not a submodule: $name @ $path\" &&\n \t\t\tcontinue\n \t\telif test -z \"$url\"\n \t\tthen\n@@ -420,8 +424,15 @@ cmd_update()\n \t\tif ! test -d \"$path\"/.git\n \t\tthen\n \t\t\t! module_clone \"$path\" \"$url\" && exit_status=1 && continue\n+\t\t\ttest \"$sha1\" = 0000000000000000000000000000000000000000 &&\n+\t\t\t(unset GIT_DIR; cd \"$path\" && git checkout -q master) &&\n+\t\t\tsay \"non-submodule cloned and master checked out: $name @ $path\" &&\n+\t\t\tcontinue\n \t\t\tsubsha1=\n \t\telse\n+\t\t\ttest \"$sha1\" = 0000000000000000000000000000000000000000 &&\n+\t\t\tsay \"non-submodule already cloned: $name @ $path\" &&\n+\t\t\tcontinue\n \t\t\tsubsha1=$(unset GIT_DIR; cd \"$path\" &&\n \t\t\t\tgit rev-parse --verify HEAD) ||\n \t\t\t{\n@@ -431,6 +442,7 @@ cmd_update()\n \t\t\t}\n \t\tfi\n \n+\n \t\tif test \"$subsha1\" != \"$sha1\"\n \t\tthen\n \t\t\t(unset GIT_DIR; cd \"$path\" && git-fetch &&\n-- \n1.5.5.23.g2a5f\n"},{"id":"74081","messageId":"46dff0320804100857y2037263fodb7795e0ff33cd0c@mail.gmail.com","threadId":"13052","inReplyTo":"1207842625-9210-3-git-send-email-pkufranky@gmail.com","subject":"Re: [PATCH v2 1/3] git-submodule summary: --for-status option","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-10T15:57:36Z","receivedAt":"2008-04-10T15:57:36Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"On Thu, Apr 10, 2008 at 11:50 PM, Ping Yin <pkufranky@gmail.com> wrote:\n>\n> The --for-status option is mainly used by builtin-status/commit.\n>  It adds 'Modified submodules:' line at top and  '# ' prefix to all\n>  following lines.\n>\n\nSorry for the repeated mail. I don't know how it happened. Maybe\nsend-email bug or my misoperation.\n\nSo just Ignore the second one.\n\n\n\n\n-- \nPing Yin\n"},{"id":"74148","messageId":"7vzls0qcmw.fsf@gitster.siamese.dyndns.org","threadId":"13052","inReplyTo":"1207842625-9210-5-git-send-email-pkufranky@gmail.com","subject":"Re: [PATCH/RFC 2/7] git-submodule: Extract absolute_url & move absolute url logic to module_clone","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-04-11T21:56:23Z","receivedAt":"2008-04-11T21:56:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ping Yin <pkufranky@gmail.com> writes:\n\n> This behaviour change breaks t7400 which uses relative url './.subrepo'.\n> However, this test originally doesn't mean to test relative url, so fix\n> the url as '.subrepo'.\n\nHmmm.  Doesn't \"foo\" generally mean the same thing as \"./foo\" in the sense\nboth are relative to the current directory?\n"},{"id":"74149","messageId":"7v4pa8qb2h.fsf@gitster.siamese.dyndns.org","threadId":"13052","inReplyTo":"1207842625-9210-2-git-send-email-pkufranky@gmail.com","subject":"Re: [PATCH/RFC 1/7] git-submodule: Extract functions module_info and module_url","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-04-11T22:30:14Z","receivedAt":"2008-04-11T22:30:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ping Yin <pkufranky@gmail.com> writes:\n\n> @@ -232,12 +251,11 @@ cmd_init()\n>  \t\tshift\n>  \tdone\n>  \n> -\tgit ls-files --stage -- \"$@\" | grep '^160000 ' |\n> -\twhile read mode sha1 stage path\n> +\tmodule_info \"$@\" |\n> +\twhile read sha1 path name url\n>  \tdo\n> +\t\ttest -n \"$name\" || exit\n>  \t\t# Skip already registered paths\n> -\t\tname=$(module_name \"$path\") || exit\n> -\t\turl=$(git config submodule.\"$name\".url)\n>  \t\ttest -z \"$url\" || continue\n\nThis is not a new bug in this round of patch (i.e. the original code\nalready did the same), but I have to wonder if exiting the loop silently\nwhen $name is not set (i.e. .gitmodules does not have an entry to describe\nthe submodule yet) is a good idea.\n\nIf an entry with mode 160000 in the index is an error if it does not have\na corresponding entry in .gitmodules, then this code should say so when\nexiting the loop prematurely.  If it is not, I think it should silently\ncontinue just like missing URL case.\n\nThe user may be right in the process of manually adding a new submodule,\nhas done \"git add\" of the submodule path already but hasn't yet decided\nwhat the name of the submodule or where the final published URL would be.\nIn such a case, you would have 160000 entry in the index that does not\nhave a corresponding entry in .gitmodules and that is perfectly valid.\n\nSo I tend to think that you should treat \"missing name\" and \"missing url\"\nas an non-error case.\n\ncmd_init would obviously need to _notice_ \"missing url\" and refrain from\nadding the missing remote URL to the config, but I do not think it should\nerror out.  Warning might be appropriate in cases, but I dunno.\n\nSame comment applies to cmd_update() and cmd_status().  I would strongly\nsuspect that status may want to ignore missing name/url and show the usual\ndiff, as it does not even have to require the submodule to interact with\nany remote repository at all.  The user may be privately using the\nsubmodule and does not even need to push it out nor pull it from\nelsewhere, and in such a case, .gitmodules may not even be populated with\nan entry for that submodule, ever, not just as a \"right in the middle of\nadding\" status.\n\nWhen the command should be usable without .gitmodules entry, it should not\nrequire one.\n"},{"id":"74160","messageId":"7v3apsotzp.fsf@gitster.siamese.dyndns.org","threadId":"13052","inReplyTo":"1207842625-9210-7-git-send-email-pkufranky@gmail.com","subject":"Re: [PATCH/RFC 3/7] git-submodule: Fall back on .gitmodules if info not found in $GIT_DIR/config","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-04-11T23:24:26Z","receivedAt":"2008-04-11T23:24:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ping Yin <pkufranky@gmail.com> writes:\n\n> Originally, the submodule workflow enforces 'git init' in the beginning\n> which copies submodule config info from .gitmodules to $GIT_DIR/config.\n> Then all subcommands except 'init' and 'add' fetch submodule info from\n> $GIT_DIR/config and .gitmodules can be discarded.\n>\n> However, there may be inconsistence between .git/config and .gitmodules\n> when always using 'git init' at first. If upstream .gitmodules changes,\n> it is not easy to sync the changes to $GIT_DIR/config.\n\nMaybe you missed an earlier thread with Roman Shaposhnik where this issue\nwas discussed and a solution more in line with the original intent of the\ndesign of the submodule system was mentioned (actually I should not take\ncredit for that suggestion as it was not mine but somebody else mentioned\nit back when git-submodule command was initially being designed.  I only\nrecalled there was that one issue in the discussion)?\n"},{"id":"74161","messageId":"7v1w5cotz2.fsf@gitster.siamese.dyndns.org","threadId":"13052","inReplyTo":"1207842625-9210-7-git-send-email-pkufranky@gmail.com","subject":"Re: [PATCH/RFC 3/7] git-submodule: Fall back on .gitmodules if info not found in $GIT_DIR/config","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-04-11T23:24:49Z","receivedAt":"2008-04-11T23:24:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ping Yin <pkufranky@gmail.com> writes:\n\n> Originally, the submodule workflow enforces 'git init' in the beginning\n> which copies submodule config info from .gitmodules to $GIT_DIR/config.\n> Then all subcommands except 'init' and 'add' fetch submodule info from\n> $GIT_DIR/config and .gitmodules can be discarded.\n>\n> However, there may be inconsistence between .git/config and .gitmodules\n> when always using 'git init' at first. If upstream .gitmodules changes,\n> it is not easy to sync the changes to $GIT_DIR/config.\n\nMaybe you missed an earlier thread with Roman Shaposhnik where this issue\nwas discussed and a solution more in line with the original intent of the\ndesign of the submodule system was mentioned (actually I should not take\ncredit for that suggestion as it was not mine but somebody else mentioned\nit back when git-submodule command was initially being designed.  I only\nrecalled there was that one issue in the old discussion but there might\nhave been others)?\n"},{"id":"74170","messageId":"46dff0320804111956p4eb3d9d7o3b404e1d93de5da2@mail.gmail.com","threadId":"13052","inReplyTo":"7vzls0qcmw.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH/RFC 2/7] git-submodule: Extract absolute_url & move absolute url logic to module_clone","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-12T02:56:54Z","receivedAt":"2008-04-12T02:56:54Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"On Sat, Apr 12, 2008 at 5:56 AM, Junio C Hamano <junio@pobox.com> wrote:\n> Ping Yin <pkufranky@gmail.com> writes:\n>\n>  > This behaviour change breaks t7400 which uses relative url './.subrepo'.\n>  > However, this test originally doesn't mean to test relative url, so fix\n>  > the url as '.subrepo'.\n>\n>  Hmmm.  Doesn't \"foo\" generally mean the same thing as \"./foo\" in the sense\n>  both are relative to the current directory?\n\nThere is a little inconsistence in current logic\n\n1. git submodule add ./foo will expand foo with remote.origin.url and\ninit an entry in .gitmodules as\n\"submodule.foo.url=$remoteoriginurl/foo\"\n2. git submodule update will not expand ./foo if  there is an entry\n\"submodule.foo.url=./foo\"  in $GIT_DIR/config\n\nI tend to add the url as is when \"git submodule add\", and then expand\nthe url when running \"git submodule update\". So this will result that\nthe second case expands './foo' as \"$remoteoriginurl/foo\" instead of\n\"foo\"\n\n\n\n\n\n-- \nPing Yin\n"},{"id":"74172","messageId":"46dff0320804112005t9b3cd27gc250dddffb218076@mail.gmail.com","threadId":"13052","inReplyTo":"7v4pa8qb2h.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH/RFC 1/7] git-submodule: Extract functions module_info and module_url","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-12T03:05:23Z","receivedAt":"2008-04-12T03:05:23Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"On Sat, Apr 12, 2008 at 6:30 AM, Junio C Hamano <junio@pobox.com> wrote:\n> Ping Yin <pkufranky@gmail.com> writes:\n>\n>  > @@ -232,12 +251,11 @@ cmd_init()\n>  >               shift\n>  >       done\n>  >\n>  > -     git ls-files --stage -- \"$@\" | grep '^160000 ' |\n>  > -     while read mode sha1 stage path\n>  > +     module_info \"$@\" |\n>  > +     while read sha1 path name url\n>  >       do\n>  > +             test -n \"$name\" || exit\n>  >               # Skip already registered paths\n>  > -             name=$(module_name \"$path\") || exit\n>  > -             url=$(git config submodule.\"$name\".url)\n>  >               test -z \"$url\" || continue\n>\n>  This is not a new bug in this round of patch (i.e. the original code\n>  already did the same), but I have to wonder if exiting the loop silently\n>  when $name is not set (i.e. .gitmodules does not have an entry to describe\n>  the submodule yet) is a good idea.\n>\n>  If an entry with mode 160000 in the index is an error if it does not have\n>  a corresponding entry in .gitmodules, then this code should say so when\n>  exiting the loop prematurely.  If it is not, I think it should silently\n>  continue just like missing URL case.\n>\n>  The user may be right in the process of manually adding a new submodule,\n>  has done \"git add\" of the submodule path already but hasn't yet decided\n>  what the name of the submodule or where the final published URL would be.\n>  In such a case, you would have 160000 entry in the index that does not\n>  have a corresponding entry in .gitmodules and that is perfectly valid.\n>\n>  So I tend to think that you should treat \"missing name\" and \"missing url\"\n>  as an non-error case.\n>\n>  cmd_init would obviously need to _notice_ \"missing url\" and refrain from\n>  adding the missing remote URL to the config, but I do not think it should\n>  error out.  Warning might be appropriate in cases, but I dunno.\n>\n>  Same comment applies to cmd_update() and cmd_status().  I would strongly\n>  suspect that status may want to ignore missing name/url and show the usual\n>  diff, as it does not even have to require the submodule to interact with\n>  any remote repository at all.  The user may be privately using the\n>  submodule and does not even need to push it out nor pull it from\n>  elsewhere, and in such a case, .gitmodules may not even be populated with\n>  an entry for that submodule, ever, not just as a \"right in the middle of\n>  adding\" status.\n\nThis patch just does refactor, i do this in my sixth patch \"Don't die\nwhen command fails for one submodule\"\n\n\n-- \nPing Yin\n"},{"id":"74176","messageId":"46dff0320804112126l6ac3bcf4q8b7cc7b09e596479@mail.gmail.com","threadId":"13052","inReplyTo":"7v1w5cotz2.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH/RFC 3/7] git-submodule: Fall back on .gitmodules if info not found in $GIT_DIR/config","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-12T04:26:07Z","receivedAt":"2008-04-12T04:26:07Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"On Sat, Apr 12, 2008 at 7:24 AM, Junio C Hamano <junio@pobox.com> wrote:\n> Ping Yin <pkufranky@gmail.com> writes:\n>\n>  > Originally, the submodule workflow enforces 'git init' in the beginning\n>  > which copies submodule config info from .gitmodules to $GIT_DIR/config.\n>  > Then all subcommands except 'init' and 'add' fetch submodule info from\n>  > $GIT_DIR/config and .gitmodules can be discarded.\n>  >\n>  > However, there may be inconsistence between .git/config and .gitmodules\n>  > when always using 'git init' at first. If upstream .gitmodules changes,\n>  > it is not easy to sync the changes to $GIT_DIR/config.\n>\n>\n> Maybe you missed an earlier thread with Roman Shaposhnik where this issue\n>  was discussed and a solution more in line with the original intent of the\n>  design of the submodule system was mentioned (actually I should not take\n>  credit for that suggestion as it was not mine but somebody else mentioned\n>  it back when git-submodule command was initially being designed.  I only\n>  recalled there was that one issue in the old discussion but there might\n>  have been others)?\n\nYou mean use \"hooks\" to update $GIT_DIR/config with user interaction\nwhen .gitmodules changes? Or give user hints when \"git submodule\nupdate\" fails?\n\nWhat you said in that thread is that the url in $GIT_DIR/config is\ndifferent from the one in .gitmodules (with protocol change perhaps)\noriginally, and then the url in .gitmodules changes. So when \"git\nsubmodule update\" fails, it notices this change and tell the user.\n\nWhat i mean here is another case. The url in $GIT_DIR/config is the\nsame as the one in .gitmodules, and then the url in .gitmodules\nchange. So this change can be synced automatically to $GIT_DIR/config.\n\nHowever, when both cases happen in the same time, there is no way to\ndifferentiate these two cases. So the command  can't do something\nautomatically and has to leave all choice to the user.\n\nIn an environment with central repositories, all submodule urls will\nbe the same between $GIT_DIR/config and .gitmodules. It is a little\nannoying to give so many users this kind of uneccessary choice if the\nsubmodule url changes in .gitmodules.\n\n\n\n-- \nPing Yin\n"},{"id":"74178","messageId":"7vve2nllqp.fsf@gitster.siamese.dyndns.org","threadId":"13052","inReplyTo":"46dff0320804112005t9b3cd27gc250dddffb218076@mail.gmail.com","subject":"Re: [PATCH/RFC 1/7] git-submodule: Extract functions module_info and module_url","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-04-12T04:50:54Z","receivedAt":"2008-04-12T04:50:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Ping Yin\" <pkufranky@gmail.com> writes:\n\n> On Sat, Apr 12, 2008 at 6:30 AM, Junio C Hamano <junio@pobox.com> wrote:\n>> ...\n>>  Same comment applies to cmd_update() and cmd_status().  I would strongly\n>>  suspect that status may want to ignore missing name/url and show the usual\n>>  diff, as it does not even have to require the submodule to interact with\n>>  any remote repository at all.  The user may be privately using the\n>>  submodule and does not even need to push it out nor pull it from\n>>  elsewhere, and in such a case, .gitmodules may not even be populated with\n>>  an entry for that submodule, ever, not just as a \"right in the middle of\n>>  adding\" status.\n>\n> This patch just does refactor, i do this in my sixth patch \"Don't die\n> when command fails for one submodule\"\n\nFair enough.\n\nAs usual, the preferred order is to first refector, fix without\nenhancement as necessary, then finally build on more solidified base.\n"}]}