{"thread":{"id":"41247","subject":"[PATCH 1/5] submodule init: Write submodule registration to stderr","startedAt":"2016-01-23T00:31:38Z","lastAt":"2016-02-01T20:21:21Z","messageCount":14,"participants":["Stefan Beller","Sebastian Schuberth","Jens Lehmann"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"276595","messageId":"1453509103-16470-1-git-send-email-sbeller@google.com","threadId":"41247","inReplyTo":null,"subject":"[RFC/PATCH 0/5] [WAS: Submodule Groups] Labels and submodule.autoInitialize","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-01-23T00:31:38Z","receivedAt":"2016-01-23T00:31:38Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"This series introduces labels which you can attach to submodules like so:\n\n    $ cat .gitmodules\n    [submodule \"gcc\"]\n        path = gcc\n        url = git://...\n        label = default\n        label = devel\n    [submodule \"linux\"]\n        path = linux\n        url = git://...\n        label = default\n\n    $ git submodule add --name emacs --label \"editor\" --label default git://...\n    \n    # If upstream has submodules properly labeled, you can make use of them:\n    \n    $ git config --add submodule.autoInitialize \"*default\"\n    $ git config --add submodule.autoInitialize \":name\"\n    $ git config --add submodule.autoInitialize \"./by/path\"\n    \n    # The prefix * denotes a label as found in .gitmodules\n    # : goes before names \n    # path are prefixed ./ currently\n    # both path and names need work\n    \n    # no --init necessary, partially initializes submodules (only those which\n    # were specified by label, name or path)\n    $ git submodule update\n    \n    # time passes, upstream may have added new submodules and we get them without\n    # extra commands!\n    $ git submodule update\n    \n    # The above configuration can be given to git clone directly via:\n    $ git clone --init-submodule=*labelA ...\n    \nWhy?\n====\nIf you have lots of submodules, you probably don't need all of them at once,\nbut you have functional units. Some submodules are absolutely required,\nsome are optional and only for very specific purposes.\n\nChanges to the previous version with groups:\n====\n* it's called labels now (it's easier to imagine to attach more than one\n  label to a submodule than having it in more groups)\n* In .git/config we have another name, too (\"submodule.autoInitialize\")\n* Support for more than just groups, but also names and paths are supported\n  (in a very rudimentary way though)\n  \nThis series applies on top of sb/submodule-init, or can be found at\nhttps://github.com/stefanbeller/git/tree/submodule-groups-v3\n  \n  Thanks,\n  Stefan\n\nStefan Beller (5):\n  submodule init: Write submodule registration to stderr\n  git submodule: Teach add to label submodules\n  submodule-config: keep labels around\n  submodule update: respect submodule.autoInitialize\n  builtin/clone: Configure submodule.autoInitialize via --init-submodule\n\n Documentation/git-clone.txt     |   6 ++\n Documentation/git-submodule.txt |   5 +-\n builtin/clone.c                 |  40 +++++++++-\n builtin/submodule--helper.c     |  58 +++++++++++++-\n git-submodule.sh                |  14 +++-\n submodule-config.c              |  15 ++++\n submodule-config.h              |   2 +\n t/t7400-submodule-basic.sh      | 165 ++++++++++++++++++++++++++++++++++++++++\n 8 files changed, 298 insertions(+), 7 deletions(-)\n\n-- \n2.7.0.rc0.42.g77a36b9.dirty\n"},{"id":"276594","messageId":"1453509103-16470-2-git-send-email-sbeller@google.com","threadId":"41247","inReplyTo":"1453509103-16470-1-git-send-email-sbeller@google.com","subject":"[PATCH 1/5] submodule init: Write submodule registration to stderr","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-01-23T00:31:39Z","receivedAt":"2016-01-23T00:31:39Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"The registration of the submodule will be reported to stderr, as that is\nconsistent with the rest of progress reporting within Git.\n\nThis helps us in a later patch when we want to reuse the\ninit_submodule function in update_clone whose stdout will be piped\nto shell which reads parameters off stdout in a very specific way.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n builtin/submodule--helper.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex c9b0c05..05c18a3 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -267,7 +267,7 @@ static void init_submodule(const char *path, const char *prefix, int quiet)\n \t\t\tdie(_(\"Failed to register url for submodule path '%s'\"),\n \t\t\t    displaypath);\n \t\tif (!quiet)\n-\t\t\tprintf(_(\"Submodule '%s' (%s) registered for path '%s'\\n\"),\n+\t\t\tfprintf(stderr, _(\"Submodule '%s' (%s) registered for path '%s'\\n\"),\n \t\t\t\tsub->name, url, displaypath);\n \t\tfree(url);\n \t}\n-- \n2.7.0.rc0.42.g77a36b9.dirty\n"},{"id":"276598","messageId":"1453509103-16470-3-git-send-email-sbeller@google.com","threadId":"41247","inReplyTo":"1453509103-16470-1-git-send-email-sbeller@google.com","subject":"[PATCH 2/5] git submodule: Teach add to label submodules","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-01-23T00:31:40Z","receivedAt":"2016-01-23T00:31:40Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"When adding new submodules, you can specify the\nlabel(s) the submodule belongs to by giving one or more\n--label arguments. This will record each label in the\n.gitmodules file as a value of the key\n\"submodule.$NAME.label\".\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n Documentation/git-submodule.txt |  5 ++++-\n git-submodule.sh                | 14 +++++++++++++-\n t/t7400-submodule-basic.sh      | 32 ++++++++++++++++++++++++++++++++\n 3 files changed, 49 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex 13adebf..c0744eb 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -9,7 +9,7 @@ git-submodule - Initialize, update or inspect submodules\n SYNOPSIS\n --------\n [verse]\n-'git submodule' [--quiet] add [-b <branch>] [-f|--force] [--name <name>]\n+'git submodule' [--quiet] add [-b <branch>] [-f|--force] [-l|--label <label>]\n \t      [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]\n 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]\n 'git submodule' [--quiet] init [--] [<path>...]\n@@ -101,6 +101,9 @@ is the superproject and submodule repositories will be kept\n together in the same relative location, and only the\n superproject's URL needs to be provided: git-submodule will correctly\n locate the submodule using the relative URL in .gitmodules.\n++\n+If at least one label argument was given, all labels are recorded in the\n+.gitmodules file in the label fields.\n \n status::\n \tShow the status of the submodules. This will print the SHA-1 of the\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 6fce0dc..65b740c 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -5,7 +5,7 @@\n # Copyright (c) 2007 Lars Hjemli\n \n dashless=$(basename \"$0\" | sed -e 's/-/ /')\n-USAGE=\"[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]\n+USAGE=\"[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [-l|--label <label>][--] <repository> [<path>]\n    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]\n    or: $dashless [--quiet] init [--] [<path>...]\n    or: $dashless [--quiet] deinit [-f|--force] [--] <path>...\n@@ -130,6 +130,7 @@ cmd_add()\n {\n \t# parse $args after \"submodule ... add\".\n \treference_path=\n+\tlabels=\n \twhile test $# -ne 0\n \tdo\n \t\tcase \"$1\" in\n@@ -165,6 +166,13 @@ cmd_add()\n \t\t--depth=*)\n \t\t\tdepth=$1\n \t\t\t;;\n+\t\t-l|--label)\n+\t\t\tlabels=\"${labels} $2\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\t--label=*)\n+\t\t\tlabels=\"${labels} ${1#--label=}\"\n+\t\t\t;;\n \t\t--)\n \t\t\tshift\n \t\t\tbreak\n@@ -292,6 +300,10 @@ Use -f if you really want to add it.\" >&2\n \n \tgit config -f .gitmodules submodule.\"$sm_name\".path \"$sm_path\" &&\n \tgit config -f .gitmodules submodule.\"$sm_name\".url \"$repo\" &&\n+\tfor label in $labels\n+\tdo\n+\t\tgit config --add -f .gitmodules submodule.\"$sm_name\".label \"${label}\"\n+\tdone &&\n \tif test -n \"$branch\"\n \tthen\n \t\tgit config -f .gitmodules submodule.\"$sm_name\".branch \"$branch\"\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 5991e3c..01d54e3 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -986,6 +986,7 @@ test_expect_success 'submodule with UTF-8 name' '\n '\n \n test_expect_success 'submodule add clone shallow submodule' '\n+\ttest_when_finished \"rm -rf super\" &&\n \tmkdir super &&\n \tpwd=$(pwd) &&\n \t(\n@@ -999,5 +1000,36 @@ test_expect_success 'submodule add clone shallow submodule' '\n \t)\n '\n \n+test_expect_success 'submodule add records a label' '\n+\ttest_when_finished \"rm -rf super\" &&\n+\tmkdir super &&\n+\tpwd=$(pwd) &&\n+\t(\n+\t\tcd super &&\n+\t\tgit init &&\n+\t\tgit submodule add --label labelA file://\"$pwd\"/example2 submodule &&\n+\t\tgit config -f .gitmodules submodule.\"submodule\".label >actual &&\n+\t\techo labelA >expected &&\n+\t\ttest_cmp expected actual\n+\t)\n+'\n+\n+cat >expected <<-EOF\n+labelA\n+labelB\n+EOF\n+\n+test_expect_success 'submodule add records multiple lables' '\n+\ttest_when_finished \"rm -rf super\" &&\n+\tmkdir super &&\n+\tpwd=$(pwd) &&\n+\t(\n+\t\tcd super &&\n+\t\tgit init &&\n+\t\tgit submodule add --label=labelA -l labelB file://\"$pwd\"/example2 submodule &&\n+\t\tgit config --get-all -f .gitmodules submodule.\"submodule\".label >../actual\n+\t) &&\n+\ttest_cmp expected actual\n+'\n \n test_done\n-- \n2.7.0.rc0.42.g77a36b9.dirty\n"},{"id":"276596","messageId":"1453509103-16470-4-git-send-email-sbeller@google.com","threadId":"41247","inReplyTo":"1453509103-16470-1-git-send-email-sbeller@google.com","subject":"[PATCH 3/5] submodule-config: keep labels around","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-01-23T00:31:41Z","receivedAt":"2016-01-23T00:31:41Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"We need the submodule groups in a later patch.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n submodule-config.c | 15 +++++++++++++++\n submodule-config.h |  2 ++\n 2 files changed, 17 insertions(+)\n\ndiff --git a/submodule-config.c b/submodule-config.c\nindex a32259e..245a0f6 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -60,6 +60,10 @@ static void free_one_config(struct submodule_entry *entry)\n {\n \tfree((void *) entry->config->path);\n \tfree((void *) entry->config->name);\n+\tif (entry->config->labels) {\n+\t\tstring_list_clear(entry->config->labels, 0);\n+\t\tfree(entry->config->labels);\n+\t}\n \tfree(entry->config);\n }\n \n@@ -184,6 +188,7 @@ static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache,\n \tsubmodule->update = NULL;\n \tsubmodule->fetch_recurse = RECURSE_SUBMODULES_NONE;\n \tsubmodule->ignore = NULL;\n+\tsubmodule->labels = NULL;\n \n \thashcpy(submodule->gitmodules_sha1, gitmodules_sha1);\n \n@@ -324,6 +329,16 @@ static int parse_specific_submodule_config(const char *subsection, int subsectio\n \t\t\tfree((void *) submodule->update);\n \t\t\tsubmodule->update = xstrdup(value);\n \t\t}\n+\t} else if (!strcmp(key, \"label\")) {\n+\t\tif (!value)\n+\t\t\tret = config_error_nonbool(var);\n+\t\telse {\n+\t\t\tif (!submodule->labels) {\n+\t\t\t\tsubmodule->labels = xmalloc(sizeof(*submodule->labels));\n+\t\t\t\tstring_list_init(submodule->labels, 1);\n+\t\t\t}\n+\t\t\tstring_list_insert(submodule->labels, value);\n+\t\t}\n \t}\n \n \treturn ret;\ndiff --git a/submodule-config.h b/submodule-config.h\nindex d9bbf9a..df73fd7 100644\n--- a/submodule-config.h\n+++ b/submodule-config.h\n@@ -17,6 +17,8 @@ struct submodule {\n \tconst char *update;\n \t/* the sha1 blob id of the responsible .gitmodules file */\n \tunsigned char gitmodules_sha1[20];\n+\t/* sorted, not as on disk */\n+\tstruct string_list *labels;\n };\n \n int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg);\n-- \n2.7.0.rc0.42.g77a36b9.dirty\n"},{"id":"276597","messageId":"1453509103-16470-5-git-send-email-sbeller@google.com","threadId":"41247","inReplyTo":"1453509103-16470-1-git-send-email-sbeller@google.com","subject":"[PATCH 4/5] submodule update: respect submodule.autoInitialize","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-01-23T00:31:42Z","receivedAt":"2016-01-23T00:31:42Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"All submodules which are selected via submodule.autoInitialize\nare initialized if they were not initialized before updating\nthe submodules.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n builtin/submodule--helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++-\n t/t7400-submodule-basic.sh  | 32 ++++++++++++++++++++++++++\n 2 files changed, 87 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 05c18a3..61e2488 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -579,9 +579,10 @@ struct submodule_update_clone {\n \tconst char *prefix;\n \tstruct module_list list;\n \tstruct string_list projectlines;\n+\tstruct string_list *initialize;\n \tstruct pathspec pathspec;\n };\n-#define SUBMODULE_UPDATE_CLONE_INIT {0, 0, 0, NULL, NULL, NULL, NULL, NULL, MODULE_LIST_INIT, STRING_LIST_INIT_DUP}\n+#define SUBMODULE_UPDATE_CLONE_INIT {0, 0, 0, NULL, NULL, NULL, NULL, NULL, MODULE_LIST_INIT, STRING_LIST_INIT_DUP, NULL}\n \n static void fill_clone_command(struct child_process *cp, int quiet,\n \t\t\t       const char *prefix, const char *path,\n@@ -624,6 +625,7 @@ static int update_clone_get_next_task(struct child_process *cp,\n \t\tconst char *update_module = NULL;\n \t\tchar *url = NULL;\n \t\tint needs_cloning = 0;\n+\t\tint auto_init = 0;\n \n \t\tif (ce_stage(ce)) {\n \t\t\tif (pp->recursive_prefix)\n@@ -667,6 +669,49 @@ static int update_clone_get_next_task(struct child_process *cp,\n \t\tstrbuf_reset(&sb);\n \t\tstrbuf_addf(&sb, \"submodule.%s.url\", sub->name);\n \t\tgit_config_get_string(sb.buf, &url);\n+\t\tif (pp->initialize) {\n+\t\t\tif (sub->labels) {\n+\t\t\t\tstruct string_list_item *item;\n+\t\t\t\tfor_each_string_list_item(item, sub->labels) {\n+\t\t\t\t\tstrbuf_reset(&sb);\n+\t\t\t\t\tstrbuf_addf(&sb, \"*%s\", item->string);\n+\t\t\t\t\tif (string_list_has_string(\n+\t\t\t\t\t    pp->initialize, sb.buf)) {\n+\t\t\t\t\t\tauto_init = 1;\n+\t\t\t\t\t\tbreak;\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (sub->path) {\n+\t\t\t\t/*\n+\t\t\t\t * NEEDSWORK: This currently works only for\n+\t\t\t\t * exact paths, but we want to enable\n+\t\t\t\t * inexact matches such wildcards.\n+\t\t\t\t */\n+\t\t\t\tstrbuf_reset(&sb);\n+\t\t\t\tstrbuf_addf(&sb, \"./%s\", sub->path);\n+\t\t\t\tif (string_list_has_string(pp->initialize, sb.buf)) {\n+\t\t\t\t\tauto_init = 1;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (sub->name) {\n+\t\t\t\t/*\n+\t\t\t\t * NEEDSWORK: Same as with path. Do we want to\n+\t\t\t\t * support wildcards or such?\n+\t\t\t\t */\n+\t\t\t\tstrbuf_reset(&sb);\n+\t\t\t\tstrbuf_addf(&sb, \":%s\", sub->name);\n+\t\t\t\tif (string_list_has_string(pp->initialize, sb.buf)) {\n+\t\t\t\t\tauto_init = 1;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (auto_init) {\n+\t\t\t\tif (!url) {\n+\t\t\t\t\tinit_submodule(sub->path, pp->prefix, pp->quiet);\n+\t\t\t\t\turl = xstrdup(sub->url);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n \t\tif (!url) {\n \t\t\t/*\n \t\t\t * Only mention uninitialized submodules when its\n@@ -733,6 +778,7 @@ static int update_clone_task_finished(int result,\n static int update_clone(int argc, const char **argv, const char *prefix)\n {\n \tint max_jobs = -1;\n+\tconst struct string_list *list;\n \tstruct string_list_item *item;\n \tstruct submodule_update_clone pp = SUBMODULE_UPDATE_CLONE_INIT;\n \n@@ -777,6 +823,14 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \t/* Overlay the parsed .gitmodules file with .git/config */\n \tgit_config(git_submodule_config, NULL);\n \n+\tlist = git_config_get_value_multi(\"submodule.autoInitialize\");\n+\tif (list) {\n+\t\tpp.initialize = xmalloc(sizeof(*pp.initialize));\n+\t\tstring_list_init(pp.initialize, 1);\n+\t\tfor_each_string_list_item(item, list)\n+\t\t\tstring_list_insert(pp.initialize, item->string);\n+\t}\n+\n \tif (max_jobs < 0)\n \t\tmax_jobs = config_parallel_submodules();\n \tif (max_jobs < 0)\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 01d54e3..e1ade1e 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -1032,4 +1032,36 @@ test_expect_success 'submodule add records multiple lables' '\n \ttest_cmp expected actual\n '\n \n+cat <<EOF > expected\n+submodule\n+submodule1\n+submodule2\n+-submodule3\n+EOF\n+\n+test_expect_success 'submodule update auto-initializes submodules' '\n+\ttest_when_finished \"rm -rf super super_clone\" &&\n+\tmkdir super &&\n+\tpwd=$(pwd) &&\n+\t(\n+\t\tcd super &&\n+\t\tgit init &&\n+\t\tgit submodule add --label labelA file://\"$pwd\"/example2 submodule &&\n+\t\tgit submodule add --name specialSnowflake file://\"$pwd\"/example2 submodule1 &&\n+\t\tgit submodule add file://\"$pwd\"/example2 submodule2 &&\n+\t\tgit submodule add file://\"$pwd\"/example2 submodule3 &&\n+\t\tgit commit -a -m \"create repository with 4 submodules, one is labeled\"\n+\t) &&\n+\tgit clone super super_clone &&\n+\t(\n+\t\tcd super_clone &&\n+\t\tgit config submodule.autoInitialize \\*labelA &&\n+\t\tgit config --add submodule.autoInitialize :specialSnowflake &&\n+\t\tgit config --add submodule.autoInitialize ./submodule2 &&\n+\t\tgit submodule update &&\n+\t\tgit submodule status |cut -c1,42-52 | tr -d \" \" >../actual\n+\t) &&\n+\ttest_cmp actual expected\n+'\n+\n test_done\n-- \n2.7.0.rc0.42.g77a36b9.dirty\n"},{"id":"276599","messageId":"1453509103-16470-6-git-send-email-sbeller@google.com","threadId":"41247","inReplyTo":"1453509103-16470-1-git-send-email-sbeller@google.com","subject":"[PATCH 5/5] builtin/clone: Configure submodule.autoInitialize via --init-submodule","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-01-23T00:31:43Z","receivedAt":"2016-01-23T00:31:43Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"When invoking clone with the --init-submodule option, the choice will be\nrecorded in the submodule.autoInitialize config option.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n Documentation/git-clone.txt |   6 +++\n builtin/clone.c             |  40 ++++++++++++++++--\n t/t7400-submodule-basic.sh  | 101 ++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 144 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt\nindex 6db7b6d..4baf444 100644\n--- a/Documentation/git-clone.txt\n+++ b/Documentation/git-clone.txt\n@@ -214,6 +214,12 @@ objects from the source repository into a pack in the cloned repository.\n \trepository does not have a worktree/checkout (i.e. if any of\n \t`--no-checkout`/`-n`, `--bare`, or `--mirror` is given)\n \n+--init-submodule::\n+\tAfter the repository is cloned, specified submodules are cloned.\n+\tIt is possible to give multiple specifications by repeating the\n+\targument. This option will be recorded in the repository config\n+\tas `submodule.autoInitialize`.\n+\n --separate-git-dir=<git dir>::\n \tInstead of placing the cloned repository where it is supposed\n \tto be, place the cloned repository at the specified directory,\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex b004fb4..3c37c3d 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -51,6 +51,22 @@ static struct string_list option_config;\n static struct string_list option_reference;\n static int option_dissociate;\n static int max_jobs = -1;\n+static struct string_list init_submodules;\n+\n+static int init_submodules_cb(const struct option *opt, const char *arg, int unset)\n+{\n+\tstruct string_list_item *item;\n+\tstruct string_list sl = STRING_LIST_INIT_DUP;\n+\n+\tif (unset)\n+\t\treturn -1;\n+\n+\tstring_list_split(&sl, arg, ',', -1);\n+\tfor_each_string_list_item(item, &sl)\n+\t\tstring_list_append((struct string_list *)opt->value, item->string);\n+\n+\treturn 0;\n+}\n \n static struct option builtin_clone_options[] = {\n \tOPT__VERBOSITY(&option_verbosity),\n@@ -95,6 +111,8 @@ static struct option builtin_clone_options[] = {\n \t\t   N_(\"separate git dir from working tree\")),\n \tOPT_STRING_LIST('c', \"config\", &option_config, N_(\"key=value\"),\n \t\t\tN_(\"set config inside the new repository\")),\n+\tOPT_CALLBACK(0, \"init-submodule\", &init_submodules, N_(\"string\"),\n+\t\t\tN_(\"clone specific submodules\"), init_submodules_cb),\n \tOPT_END()\n };\n \n@@ -723,9 +741,17 @@ static int checkout(void)\n \terr |= run_hook_le(NULL, \"post-checkout\", sha1_to_hex(null_sha1),\n \t\t\t   sha1_to_hex(sha1), \"1\", NULL);\n \n-\tif (!err && option_recursive) {\n+\tif (err)\n+\t\tgoto out;\n+\n+\tif (option_recursive || init_submodules.nr > 0) {\n \t\tstruct argv_array args = ARGV_ARRAY_INIT;\n-\t\targv_array_pushl(&args, \"submodule\", \"update\", \"--init\", \"--recursive\", NULL);\n+\t\targv_array_pushl(&args, \"submodule\", \"update\", NULL);\n+\n+\t\tif (option_recursive) {\n+\t\t\targv_array_pushf(&args, \"--init\");\n+\t\t\targv_array_pushf(&args, \"--recursive\");\n+\t\t}\n \n \t\tif (max_jobs != -1)\n \t\t\targv_array_pushf(&args, \"--jobs=%d\", max_jobs);\n@@ -733,7 +759,7 @@ static int checkout(void)\n \t\terr = run_command_v_opt(args.argv, RUN_GIT_CMD);\n \t\targv_array_clear(&args);\n \t}\n-\n+out:\n \treturn err;\n }\n \n@@ -867,6 +893,14 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \t\t\tdie(_(\"--bare and --separate-git-dir are incompatible.\"));\n \t\toption_no_checkout = 1;\n \t}\n+\tif (init_submodules.nr > 0) {\n+\t\tstruct string_list_item *item;\n+\t\tstruct strbuf sb = STRBUF_INIT;\n+\t\tfor_each_string_list_item(item, &init_submodules) {\n+\t\t\tstrbuf_addf(&sb, \"submodule.autoInitialize=%s\", item->string);\n+\t\t\tstring_list_append(&option_config, strbuf_detach(&sb, 0));\n+\t\t}\n+\t}\n \n \tif (!option_origin)\n \t\toption_origin = \"origin\";\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex e1ade1e..e83f403 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -1064,4 +1064,105 @@ test_expect_success 'submodule update auto-initializes submodules' '\n \ttest_cmp actual expected\n '\n \n+cat <<EOF > expected\n+submodule\n+-submodule1\n+EOF\n+\n+test_expect_success 'clone --init-submodule works' '\n+\ttest_when_finished \"rm -rf super super_clone\" &&\n+\tmkdir super &&\n+\tpwd=$(pwd) &&\n+\t(\n+\t\tcd super &&\n+\t\tgit init &&\n+\t\tgit submodule add --label labelA file://\"$pwd\"/example2 submodule &&\n+\t\tgit submodule add file://\"$pwd\"/example2 submodule1 &&\n+\t\tgit commit -a -m \"create repository with 2 submodules, one is in a group\"\n+\t) &&\n+\tgit clone --init-submodule \\*labelA super super_clone &&\n+\t(\n+\t\tcd super_clone &&\n+\t\tgit submodule status |cut -c1,42-52 | tr -d \" \" >../actual\n+\t) &&\n+\ttest_cmp actual expected\n+'\n+\n+cat <<EOF > expected\n+-submodule1\n+submoduleA\n+-submoduleB\n+submoduleC\n+-submoduleD\n+submoduleE\n+EOF\n+\n+test_expect_success 'clone initializes submodules correctly with more than one --init-submodule option' '\n+\ttest_when_finished \"rm -rf super super_clone\" &&\n+\tmkdir super &&\n+\tpwd=$(pwd) &&\n+\t(\n+\t\tcd super &&\n+\t\tgit init &&\n+\t\tgit submodule add --label groupA file://\"$pwd\"/example2 submoduleA &&\n+\t\tgit submodule add --label groupB file://\"$pwd\"/example2 submoduleB &&\n+\t\tgit submodule add --label groupC file://\"$pwd\"/example2 submoduleC &&\n+\t\tgit submodule add --label groupD --name submoduleE file://\"$pwd\"/example2 submoduleD &&\n+\t\tgit submodule add --label groupE --name submoduleD file://\"$pwd\"/example2 submoduleE &&\n+\t\tgit submodule add file://\"$pwd\"/example2 submodule1 &&\n+\t\tgit commit -a -m \"create repository with submodules groups\"\n+\t) &&\n+\tgit clone --init-submodule=\\*groupA --init-submodule ./submoduleC --init-submodule :submoduleD super super_clone &&\n+\t(\n+\t\tcd super_clone &&\n+\t\tgit submodule status |cut -c1,42-52 | tr -d \" \" >../actual\n+\t) &&\n+\ttest_cmp actual expected\n+'\n+\n+cat <<EOF > expected1\n+submoduleA\n+-submoduleB\n+EOF\n+\n+cat <<EOF > expected2\n+submoduleA\n+-submoduleB\n+submoduleC\n+EOF\n+\n+test_expect_success 'clone and subsequent updates correctly auto-initialize submodules' '\n+\ttest_when_finished \"rm -rf super super_clone\" &&\n+\tmkdir super &&\n+\tpwd=$(pwd) &&\n+\t(\n+\t\tcd super &&\n+\t\tgit init &&\n+\t\tgit submodule add --label LA file://\"$pwd\"/example2 submoduleA &&\n+\t\tgit submodule add file://\"$pwd\"/example2 submoduleB &&\n+\t\tgit commit -a -m \"create repository with submodules groups\"\n+\t) &&\n+\tgit clone --init-submodule=\\*LA super super_clone &&\n+\t(\n+\t\tcd super_clone &&\n+\t\tgit submodule status |cut -c1,42-52 | tr -d \" \" >../actual\n+\t) &&\n+\ttest_cmp actual expected1 &&\n+\t(\n+\t\tcd super &&\n+\t\tgit init &&\n+\t\tgit submodule add --label LA file://\"$pwd\"/example2 submoduleC &&\n+\t\tgit commit -a -m \"add another labled submodule\"\n+\t) &&\n+\t(\n+\t\tcd super_clone &&\n+\t\t# obtain the new superproject\n+\t\tgit pull &&\n+\t\t# submoduleC should just appear as it has the label LA\n+\t\t# which was configured to autoInitialize in git clone\n+\t\tgit submodule update &&\n+\t\tgit submodule status |cut -c1,42-52 | tr -d \" \" >../actual\n+\t) &&\n+\ttest_cmp actual expected2\n+'\n test_done\n-- \n2.7.0.rc0.42.g77a36b9.dirty\n"},{"id":"276668","messageId":"CAHGBnuMM5KWMUZd_ZNkEvP_homqy4kg3z356V3fhsLveZhjtBA@mail.gmail.com","threadId":"41247","inReplyTo":"1453509103-16470-4-git-send-email-sbeller@google.com","subject":"Re: [PATCH 3/5] submodule-config: keep labels around","fromName":"Sebastian Schuberth","fromEmail":"sschuberth@gmail.com","sentAt":"2016-01-24T18:06:10Z","receivedAt":"2016-01-24T18:06:10Z","isPatch":true,"sender":{"key":"sschuberth@gmail.com","avatar":"https://avatars.githubusercontent.com/u/349154?v=4"},"body":"On Sat, Jan 23, 2016 at 1:31 AM, Stefan Beller <sbeller@google.com> wrote:\n\n> We need the submodule groups in a later patch.\n\nThe commit message should now say \"labels\", too, I guess.\n\n-- \nSebastian Schuberth\n"},{"id":"276670","messageId":"56A52818.8080808@web.de","threadId":"41247","inReplyTo":"1453509103-16470-1-git-send-email-sbeller@google.com","subject":"Re: [RFC/PATCH 0/5] [WAS: Submodule Groups] Labels and submodule.autoInitialize","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2016-01-24T19:38:00Z","receivedAt":"2016-01-24T19:38:00Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Disclaimer: Due to my currently very limited Git time budget I only\nglanced over the recent discussion and patches. If you think I missed\nsomething already discussed, I'd be happy being pointed to the relevant\ndiscussion so I can catch up and avoid wasting everybody's time.\n\nAm 23.01.2016 um 01:31 schrieb Stefan Beller:\n> This series introduces labels which you can attach to submodules like so:\n>\n>      $ cat .gitmodules\n>      [submodule \"gcc\"]\n>          path = gcc\n>          url = git://...\n>          label = default\n>          label = devel\n>      [submodule \"linux\"]\n>          path = linux\n>          url = git://...\n>          label = default\n>\n>      $ git submodule add --name emacs --label \"editor\" --label default git://...\n>\n>      # If upstream has submodules properly labeled, you can make use of them:\n\nCool. Without having looked at the code I assume you also can label\nsubmodules yourself in .git/config (or your global config) to override\nupstream's settings (or use your own labels if .gitmodules does not\ncontain any)?\n\n>      $ git config --add submodule.autoInitialize \"*default\"\n>      $ git config --add submodule.autoInitialize \":name\"\n>      $ git config --add submodule.autoInitialize \"./by/path\"\n\nOk. Though we might wanna call it submodule.autoUpdate, as initializing\nit is only the prerequisite for automatically updating submodules. And\nI believe automatically updating is the thing we're after here, right?\n\nI'll try to explain why I believe we should be generous in initializing\nsubmodules: If a submodule in one branch has a label configured to be\nautomatically updated and hasn't got the same label in another branch,\nwe still need to initialize the submodule even when we are on the latter\nbranch in case the user switches to the first branch, right? And the\nfetch command needs to fetch submodule changes too when they happen in\na branch where this submodule is part of a label group configured to be\nupdated automatically, no matter what is currently found in the work\ntree.\n\nSo I'd propose to:\n\n*) Initialize every submodule present on clone or newly fetched when\n    the autoUpdate config is set.\n\n*) Automatically fetch only those submodules that are changed in\n    a commit where they have a label configured (in the commit's\n    .gitmodules or locally) that is to be checked out.\n\n*) Let \"git submodule update\" update only those submodules that\n    have an autoupdate label configured.\n\nThat will make switching between branches with different label\nconfigurations work fine. Or am I missing something here?\n\nAnd we need to teach diff and status to complain about empty work\ntrees and missing initialization of submodules that are to be\nautomatically updated too.\n\n>      # The prefix * denotes a label as found in .gitmodules\n>      # : goes before names\n>      # path are prefixed ./ currently\n>      # both path and names need work\n\nQuestion: how do I configure all submodules to be automatically\ninitialized without having to give them a label? \"./*\"? Or just\nsetting the option without a specific value?\n\n>      # no --init necessary, partially initializes submodules (only those which\n>      # were specified by label, name or path)\n>      $ git submodule update\n\nYup. Just like they will be fetched if they haven't been yet they\nshould be initialized if they haven't been yet but are configured\nto be automatically updated.\n\n>      # time passes, upstream may have added new submodules and we get them without\n>      # extra commands!\n>      $ git submodule update\n>\n>      # The above configuration can be given to git clone directly via:\n>      $ git clone --init-submodule=*labelA ...\n\nOk. Expecially nice is the ability to also give names and paths to\n\"--init-submodule\". (but maybe that option should be called\n\"--autoupdate-submodule\" for the reasons stated above?)\n\n> Why?\n> ====\n> If you have lots of submodules, you probably don't need all of them at once,\n> but you have functional units. Some submodules are absolutely required,\n> some are optional and only for very specific purposes.\n\nI'd rather like to see this as a special case of sparse checkout, as\nthis will be a submodule-specific solution to a more generic problem.\nBut as I understand configuring sparse checkout won't materialize for\nquite some time, so I suspect we'll have to add labels first to make\ncurrent submodule users happy in the near future. Sparse configuration\ncan then re-use the infrastructure added here.\n\n> Changes to the previous version with groups:\n> ====\n> * it's called labels now (it's easier to imagine to attach more than one\n>    label to a submodule than having it in more groups)\n> * In .git/config we have another name, too (\"submodule.autoInitialize\")\n> * Support for more than just groups, but also names and paths are supported\n>    (in a very rudimentary way though)\n>\n> This series applies on top of sb/submodule-init, or can be found at\n> https://github.com/stefanbeller/git/tree/submodule-groups-v3\n>\n>    Thanks,\n>    Stefan\n>\n> Stefan Beller (5):\n>    submodule init: Write submodule registration to stderr\n>    git submodule: Teach add to label submodules\n>    submodule-config: keep labels around\n>    submodule update: respect submodule.autoInitialize\n>    builtin/clone: Configure submodule.autoInitialize via --init-submodule\n>\n>   Documentation/git-clone.txt     |   6 ++\n>   Documentation/git-submodule.txt |   5 +-\n>   builtin/clone.c                 |  40 +++++++++-\n>   builtin/submodule--helper.c     |  58 +++++++++++++-\n>   git-submodule.sh                |  14 +++-\n>   submodule-config.c              |  15 ++++\n>   submodule-config.h              |   2 +\n>   t/t7400-submodule-basic.sh      | 165 ++++++++++++++++++++++++++++++++++++++++\n>   8 files changed, 298 insertions(+), 7 deletions(-)\n>\n"},{"id":"276722","messageId":"CAGZ79kZAt1wfqrf1Hk2p5tx=m9OXednsyRFYP6VeVcG69Do91g@mail.gmail.com","threadId":"41247","inReplyTo":"CAHGBnuMM5KWMUZd_ZNkEvP_homqy4kg3z356V3fhsLveZhjtBA@mail.gmail.com","subject":"Re: [PATCH 3/5] submodule-config: keep labels around","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-01-25T18:06:31Z","receivedAt":"2016-01-25T18:06:31Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Sun, Jan 24, 2016 at 10:06 AM, Sebastian Schuberth\n<sschuberth@gmail.com> wrote:\n> On Sat, Jan 23, 2016 at 1:31 AM, Stefan Beller <sbeller@google.com> wrote:\n>\n>> We need the submodule groups in a later patch.\n>\n> The commit message should now say \"labels\", too, I guess.\n\nSure, thanks for catching!\n\n>\n> --\n> Sebastian Schuberth\n"},{"id":"276726","messageId":"CAGZ79kY1Wa7kHh7GaCTAAmyaRgrT4_91XLaHZFrko9umEbNYkw@mail.gmail.com","threadId":"41247","inReplyTo":"56A52818.8080808@web.de","subject":"Re: [RFC/PATCH 0/5] [WAS: Submodule Groups] Labels and submodule.autoInitialize","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-01-25T18:59:12Z","receivedAt":"2016-01-25T18:59:12Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Sun, Jan 24, 2016 at 11:38 AM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n> Disclaimer: Due to my currently very limited Git time budget I only\n> glanced over the recent discussion and patches. If you think I missed\n> something already discussed, I'd be happy being pointed to the relevant\n> discussion so I can catch up and avoid wasting everybody's time.\n>\n> Am 23.01.2016 um 01:31 schrieb Stefan Beller:\n>>\n>> This series introduces labels which you can attach to submodules like so:\n>>\n>>      $ cat .gitmodules\n>>      [submodule \"gcc\"]\n>>          path = gcc\n>>          url = git://...\n>>          label = default\n>>          label = devel\n>>      [submodule \"linux\"]\n>>          path = linux\n>>          url = git://...\n>>          label = default\n>>\n>>      $ git submodule add --name emacs --label \"editor\" --label default\n>> git://...\n>>\n>>      # If upstream has submodules properly labeled, you can make use of\n>> them:\n>\n>\n> Cool. Without having looked at the code I assume you also can label\n> submodules yourself in .git/config (or your global config) to override\n> upstream's settings (or use your own labels if .gitmodules does not\n> contain any)?\n\nI am not sure. I'll add a test for that in a reroll and make sure it passes.\n\n>\n>>      $ git config --add submodule.autoInitialize \"*default\"\n>>      $ git config --add submodule.autoInitialize \":name\"\n>>      $ git config --add submodule.autoInitialize \"./by/path\"\n>\n>\n> Ok. Though we might wanna call it submodule.autoUpdate, as initializing\n> it is only the prerequisite for automatically updating submodules. And\n> I believe automatically updating is the thing we're after here, right?\n\nI am not sure here, too. I would not mind an occasional \"git submodule update\"\nfor whenever I want upstream to come down on my disk. However that's what I\ndo with \"git pull\" in the non-submodule case, so you'd expect git pull to\nalso run the update strategies for all submodules which are configured to\nautoUpdate?\n\nThat makes sense to me. Though I never use \"git pull\" to begin with.\nI always use fetch and see how to go from there (merge or rebase\nafter inspecting the code I fetched). That would mean we want to\nadd the autoUpdate strategy to merge/rebase and the fetching of\nsubmodules to the fetch command?\n\n>\n> I'll try to explain why I believe we should be generous in initializing\n> submodules: If a submodule in one branch has a label configured to be\n> automatically updated and hasn't got the same label in another branch,\n> we still need to initialize the submodule even when we are on the latter\n> branch in case the user switches to the first branch, right?\n\nNo. \"git checkout\" ought to autoInitalize the submodule in question when\nswitching branches. I don't want to see initialized, but unused submodules\naround (neither empty dirs nor in the .git/config ideally)?\n\n\n> And the\n> fetch command needs to fetch submodule changes too when they happen in\n> a branch where this submodule is part of a label group configured to be\n> updated automatically, no matter what is currently found in the work\n> tree.\n\nRight, as said above fetch needs to fetch all the submodules as well. I wonder\nif it needs to fetch all submodule sha1s only or just try to get as\nmuch from the\nsubmodule as possible.\n\n>\n> So I'd propose to:\n>\n> *) Initialize every submodule present on clone or newly fetched when\n>    the autoUpdate config is set.\n\nWhat if you clone branch A and then switch to B ? B has a submodule which\nwas not initialized in A. I do not think initializing on clone/fetch\nis the right thing\nto do, but rather the branch switching command (checkout) shall make sure\nall its autoUpdate/autoInitialze submodules are setup properly, no?\n\n>\n> *) Automatically fetch only those submodules that are changed in\n>    a commit where they have a label configured (in the commit's\n>    .gitmodules or locally) that is to be checked out.\n\nNot sure I follow here.\n\n>\n> *) Let \"git submodule update\" update only those submodules that\n>    have an autoupdate label configured.\n\nWhy not update all initialized submodules? (In my imagination\n\"all initialized submodules\" are equal to \"all submodules the user is\ninterested in\", i.e. when going from branch A to B, the checkout will\n(de-)init submodules as necessary.\n\n>\n> That will make switching between branches with different label\n> configurations work fine. Or am I missing something here?\n>\n> And we need to teach diff and status to complain about empty work\n> trees and missing initialization of submodules that are to be\n> automatically updated too.\n\nWhat about empty work trees?\n\nI'll add \"git status\" complaining about missing initialized submodules.\n\n>\n>>      # The prefix * denotes a label as found in .gitmodules\n>>      # : goes before names\n>>      # path are prefixed ./ currently\n>>      # both path and names need work\n>\n>\n> Question: how do I configure all submodules to be automatically\n> initialized without having to give them a label? \"./*\"? Or just\n> setting the option without a specific value?\n\nI'd guess ./* should do. Path wildcard patterns are not supported in this\nseries, but I think it would be a viable way.\n\n>\n>>      # no --init necessary, partially initializes submodules (only those\n>> which\n>>      # were specified by label, name or path)\n>>      $ git submodule update\n>\n>\n> Yup. Just like they will be fetched if they haven't been yet they\n> should be initialized if they haven't been yet but are configured\n> to be automatically updated.\n>\n>>      # time passes, upstream may have added new submodules and we get them\n>> without\n>>      # extra commands!\n>>      $ git submodule update\n>>\n>>      # The above configuration can be given to git clone directly via:\n>>      $ git clone --init-submodule=*labelA ...\n>\n>\n> Ok. Expecially nice is the ability to also give names and paths to\n> \"--init-submodule\". (but maybe that option should be called\n> \"--autoupdate-submodule\" for the reasons stated above?)\n\nIf I can understand the discussion above a bit further, I'd be happy\nto rename the option.\n\nI think we have some different opinions on when\nsubmodules are initialized (the invariant of what an initalized submodules\nmeans), and resulting from that we also have different opinions on when\nto do the (de-)init.\n\n>\n>> Why?\n>> ====\n>> If you have lots of submodules, you probably don't need all of them at\n>> once,\n>> but you have functional units. Some submodules are absolutely required,\n>> some are optional and only for very specific purposes.\n>\n>\n> I'd rather like to see this as a special case of sparse checkout, as\n> this will be a submodule-specific solution to a more generic problem.\n\nThat makes sense.\n\n> But as I understand configuring sparse checkout won't materialize for\n> quite some time, so I suspect we'll have to add labels first to make\n> current submodule users happy in the near future. Sparse configuration\n> can then re-use the infrastructure added here.\n>\n>\n\n\nThanks,\nStefan\n"},{"id":"276832","messageId":"56A7DE2C.3020308@web.de","threadId":"41247","inReplyTo":"CAGZ79kY1Wa7kHh7GaCTAAmyaRgrT4_91XLaHZFrko9umEbNYkw@mail.gmail.com","subject":"Re: [RFC/PATCH 0/5] [WAS: Submodule Groups] Labels and submodule.autoInitialize","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2016-01-26T20:59:24Z","receivedAt":"2016-01-26T20:59:24Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 25.01.2016 um 19:59 schrieb Stefan Beller:\n> On Sun, Jan 24, 2016 at 11:38 AM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>> Am 23.01.2016 um 01:31 schrieb Stefan Beller:\n>>>\n>>> This series introduces labels which you can attach to submodules like so:\n>>>\n>>>       $ cat .gitmodules\n>>>       [submodule \"gcc\"]\n>>>           path = gcc\n>>>           url = git://...\n>>>           label = default\n>>>           label = devel\n>>>       [submodule \"linux\"]\n>>>           path = linux\n>>>           url = git://...\n>>>           label = default\n>>>\n>>>       $ git submodule add --name emacs --label \"editor\" --label default\n>>> git://...\n>>>\n>>>       # If upstream has submodules properly labeled, you can make use of\n>>> them:\n>>\n>>\n>> Cool. Without having looked at the code I assume you also can label\n>> submodules yourself in .git/config (or your global config) to override\n>> upstream's settings (or use your own labels if .gitmodules does not\n>> contain any)?\n>\n> I am not sure. I'll add a test for that in a reroll and make sure it passes.\n\nThanks.\n\n>>\n>>>       $ git config --add submodule.autoInitialize \"*default\"\n>>>       $ git config --add submodule.autoInitialize \":name\"\n>>>       $ git config --add submodule.autoInitialize \"./by/path\"\n>>\n>>\n>> Ok. Though we might wanna call it submodule.autoUpdate, as initializing\n>> it is only the prerequisite for automatically updating submodules. And\n>> I believe automatically updating is the thing we're after here, right?\n>\n> I am not sure here, too. I would not mind an occasional \"git submodule update\"\n> for whenever I want upstream to come down on my disk.\n >\n> However that's what I\n> do with \"git pull\" in the non-submodule case, so you'd expect git pull to\n> also run the update strategies for all submodules which are configured to\n> autoUpdate?\n>\n> That makes sense to me. Though I never use \"git pull\" to begin with.\n> I always use fetch and see how to go from there (merge or rebase\n> after inspecting the code I fetched). That would mean we want to\n> add the autoUpdate strategy to merge/rebase and the fetching of\n> submodules to the fetch command?\n\nHmm, maybe autoUpdate promises too much. After all this config is\njust about which submodules are chosen to be updated on clone and\nsubmodule update, not on all the other work tree manipulating\ncommands.\n\nAnd it's similar to what sparse does. So what about calling that\n\"submodule.updateSparse\"? Or maybe \"submodule.sparseCheckout\"?\nSuggestions welcome.\n\n>> I'll try to explain why I believe we should be generous in initializing\n>> submodules: If a submodule in one branch has a label configured to be\n>> automatically updated and hasn't got the same label in another branch,\n>> we still need to initialize the submodule even when we are on the latter\n>> branch in case the user switches to the first branch, right?\n>\n> No. \"git checkout\" ought to autoInitalize the submodule in question when\n> switching branches. I don't want to see initialized, but unused submodules\n> around (neither empty dirs nor in the .git/config ideally)?\n\nWhy not? Empty dirs is what unpopulated submodules look like from day\none (and they make the user aware she cannot add a file of the same\nname). And you'll see initialized, but unused submodules around every\ntime you switch to a branch that doesn't contain this submodule at all.\n\nAnd keeping them initialized even if they aren't currently checked out\nis the only way they can keep their settings when the user is switching\nbetween branches.\n\n>> And the\n>> fetch command needs to fetch submodule changes too when they happen in\n>> a branch where this submodule is part of a label group configured to be\n>> updated automatically, no matter what is currently found in the work\n>> tree.\n>\n> Right, as said above fetch needs to fetch all the submodules as well. I wonder\n> if it needs to fetch all submodule sha1s only or just try to get as\n> much from the\n> submodule as possible.\n\nRight now we just do a simple fetch, but only fetching the SHA-1s could\nbe an optimization useful for busy submodules later on.\n\n>> So I'd propose to:\n>>\n>> *) Initialize every submodule present on clone or newly fetched when\n>>     the autoUpdate config is set.\n>\n> What if you clone branch A and then switch to B ? B has a submodule which\n> was not initialized in A. I do not think initializing on clone/fetch\n> is the right thing\n> to do, but rather the branch switching command (checkout) shall make sure\n> all its autoUpdate/autoInitialze submodules are setup properly, no?\n\nI disagree. If you init all submodules on clone/fetch you might need\nto change the upstream URL right after that. You can't do that on a\nsubsequent branch switch which needs to initialize the submodule again,\nas the former deinit did nuke that configuration.\n\n>> *) Automatically fetch only those submodules that are changed in\n>>     a commit where they have a label configured (in the commit's\n>>     .gitmodules or locally) that is to be checked out.\n>\n> Not sure I follow here.\n\nWe could restrict fetch to not fetch everything but just those changes\nneeded for sparse submodule update. To be able to do that it would\nhave to examine the fetched superproject commits if a submodule changed\nand if it is configured to be automatically updated in that commit.\n\n>> *) Let \"git submodule update\" update only those submodules that\n>>     have an autoupdate label configured.\n>\n> Why not update all initialized submodules? (In my imagination\n> \"all initialized submodules\" are equal to \"all submodules the user is\n> interested in\", i.e. when going from branch A to B, the checkout will\n> (de-)init submodules as necessary.\n\nAnd throw away any customization the user did (to the URL or other\nconfigurations)?\n\nWithout this sparse/label/group functionality, init is the way the\nuser tells us he is interested in a submodule. But when configuring\na label/name/path to update, the old meaning of init is obsolete\nand superseded by the new mechanism.\n\n>> That will make switching between branches with different label\n>> configurations work fine. Or am I missing something here?\n>>\n>> And we need to teach diff and status to complain about empty work\n>> trees and missing initialization of submodules that are to be\n>> automatically updated too.\n>\n> What about empty work trees?\n>\n> I'll add \"git status\" complaining about missing initialized submodules.\n\nIf they are to be updated on the next \"git submodule update\" ;-)\n\n>>\n>>>       # The prefix * denotes a label as found in .gitmodules\n>>>       # : goes before names\n>>>       # path are prefixed ./ currently\n>>>       # both path and names need work\n>>\n>>\n>> Question: how do I configure all submodules to be automatically\n>> initialized without having to give them a label? \"./*\"? Or just\n>> setting the option without a specific value?\n>\n> I'd guess ./* should do. Path wildcard patterns are not supported in this\n> series, but I think it would be a viable way.\n\nOk.\n\n>>>       # no --init necessary, partially initializes submodules (only those\n>>> which\n>>>       # were specified by label, name or path)\n>>>       $ git submodule update\n>>\n>>\n>> Yup. Just like they will be fetched if they haven't been yet they\n>> should be initialized if they haven't been yet but are configured\n>> to be automatically updated.\n>>\n>>>       # time passes, upstream may have added new submodules and we get them\n>>> without\n>>>       # extra commands!\n>>>       $ git submodule update\n>>>\n>>>       # The above configuration can be given to git clone directly via:\n>>>       $ git clone --init-submodule=*labelA ...\n>>\n>>\n>> Ok. Expecially nice is the ability to also give names and paths to\n>> \"--init-submodule\". (but maybe that option should be called\n>> \"--autoupdate-submodule\" for the reasons stated above?)\n>\n> If I can understand the discussion above a bit further, I'd be happy\n> to rename the option.\n>\n> I think we have some different opinions on when\n> submodules are initialized (the invariant of what an initalized submodules\n> means), and resulting from that we also have different opinions on when\n> to do the (de-)init.\n\nYes. But I hope my arguments will convince you ;-)\n"},{"id":"276836","messageId":"CAGZ79kapcGDFx+=VNCPvRMUGBJiTzJqGWv6UzPNgMOVBKgwXdw@mail.gmail.com","threadId":"41247","inReplyTo":"56A7DE2C.3020308@web.de","subject":"Re: [RFC/PATCH 0/5] [WAS: Submodule Groups] Labels and submodule.autoInitialize","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-01-26T21:50:23Z","receivedAt":"2016-01-26T21:50:23Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Jan 26, 2016 at 12:59 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n\n>>> Ok. Though we might wanna call it submodule.autoUpdate, as initializing\n>>> it is only the prerequisite for automatically updating submodules. And\n>>> I believe automatically updating is the thing we're after here, right?\n>>\n>>\n>> I am not sure here, too. I would not mind an occasional \"git submodule\n>> update\"\n>> for whenever I want upstream to come down on my disk.\n>\n>>\n>>\n>> However that's what I\n>> do with \"git pull\" in the non-submodule case, so you'd expect git pull to\n>> also run the update strategies for all submodules which are configured to\n>> autoUpdate?\n>>\n>> That makes sense to me. Though I never use \"git pull\" to begin with.\n>> I always use fetch and see how to go from there (merge or rebase\n>> after inspecting the code I fetched). That would mean we want to\n>> add the autoUpdate strategy to merge/rebase and the fetching of\n>> submodules to the fetch command?\n>\n>\n> Hmm, maybe autoUpdate promises too much.\n\nYes, this very much. I feel like I get burned whenever I send a large\npatch series.\nSo I want to have this first feature be the smallest \"operational\nunit\" that makes sense.\n\n> After all this config is\n> just about which submodules are chosen to be updated on clone and\n> submodule update, not on all the other work tree manipulating\n> commands.\n\nSo you'd imagine that \"git submodule update\" would remove the\nsubmodule and setup an empty directory in case that submodule is\nnot configured ? (after switching branches or when just having cloned\nthat thing.)\n\n>\n> And it's similar to what sparse does. So what about calling that\n> \"submodule.updateSparse\"? Or maybe \"submodule.sparseCheckout\"?\n> Suggestions welcome.\n\nI'd only suggest when it's clear to me what that option actually does. :)\n\n>\n>>> I'll try to explain why I believe we should be generous in initializing\n>>> submodules: If a submodule in one branch has a label configured to be\n>>> automatically updated and hasn't got the same label in another branch,\n>>> we still need to initialize the submodule even when we are on the latter\n>>> branch in case the user switches to the first branch, right?\n>>\n>>\n>> No. \"git checkout\" ought to autoInitalize the submodule in question when\n>> switching branches. I don't want to see initialized, but unused submodules\n>> around (neither empty dirs nor in the .git/config ideally)?\n>\n>\n> Why not? Empty dirs is what unpopulated submodules look like from day\n> one (and they make the user aware she cannot add a file of the same\n> name). And you'll see initialized, but unused submodules around every\n> time you switch to a branch that doesn't contain this submodule at all.\n\nI see. We need to keep the dir around to block that file name from being\nadded. That makes sense.\n\nMentally I am still stuck in the \"very large superproject tracking all the\nmodules of an operating system\" thing, where I'd find it annoying if you'd have\n100 top level directories, but you have one populated for your work.\n\nBut the reason for name blocking makes sense, so I'll follow with that.\n\n>\n> And keeping them initialized even if they aren't currently checked out\n> is the only way they can keep their settings when the user is switching\n> between branches.\n\nRight, but we could invent some non-initialized, but we keep the\nsettings somewhere\nmode. But as I agree on having them initialized, I'll take this an an\nextra point to\nfollow your reasoning.\n\n>\n>>> And the\n>>> fetch command needs to fetch submodule changes too when they happen in\n>>> a branch where this submodule is part of a label group configured to be\n>>> updated automatically, no matter what is currently found in the work\n>>> tree.\n>>\n>>\n>> Right, as said above fetch needs to fetch all the submodules as well. I\n>> wonder\n>> if it needs to fetch all submodule sha1s only or just try to get as\n>> much from the\n>> submodule as possible.\n>\n>\n> Right now we just do a simple fetch, but only fetching the SHA-1s could\n> be an optimization useful for busy submodules later on.\n\nI'd rather not call it optimisation, but a correctness thing. What if you\nforce-pushed other content to the submodule (the sha1 is gone and\nmaybe should not be reachable) or the other case where you want to\nclone the submodule with depth 1 (that is a serious case, which currently\nbreaks). In the shallow submodule case you need to have the exact sha1\nfor cloning, otherwise it doesn't work correctly.\n\n>\n>>> So I'd propose to:\n>>>\n>>> *) Initialize every submodule present on clone or newly fetched when\n>>>     the autoUpdate config is set.\n>>\n>>\n>> What if you clone branch A and then switch to B ? B has a submodule which\n>> was not initialized in A. I do not think initializing on clone/fetch\n>> is the right thing\n>> to do, but rather the branch switching command (checkout) shall make sure\n>> all its autoUpdate/autoInitialze submodules are setup properly, no?\n>\n>\n> I disagree. If you init all submodules on clone/fetch you might need\n> to change the upstream URL right after that. You can't do that on a\n> subsequent branch switch which needs to initialize the submodule again,\n> as the former deinit did nuke that configuration.\n\nSo we need to keep the information around, which we do by keeping\nall the modules initialized all the time.\n\n>\n>>> *) Automatically fetch only those submodules that are changed in\n>>>     a commit where they have a label configured (in the commit's\n>>>     .gitmodules or locally) that is to be checked out.\n>>\n>>\n>> Not sure I follow here.\n>\n>\n> We could restrict fetch to not fetch everything but just those changes\n> needed for sparse submodule update. To be able to do that it would\n> have to examine the fetched superproject commits if a submodule changed\n> and if it is configured to be automatically updated in that commit.\n\nok, that's an optimisation for later? (not strictly needed for the first series)\n\n>\n>>> *) Let \"git submodule update\" update only those submodules that\n>>>     have an autoupdate label configured.\n>>\n>>\n>> Why not update all initialized submodules? (In my imagination\n>> \"all initialized submodules\" are equal to \"all submodules the user is\n>> interested in\", i.e. when going from branch A to B, the checkout will\n>> (de-)init submodules as necessary.\n>\n>\n> And throw away any customization the user did (to the URL or other\n> configurations)?\n>\n> Without this sparse/label/group functionality, init is the way the\n> user tells us he is interested in a submodule. But when configuring\n> a label/name/path to update, the old meaning of init is obsolete\n> and superseded by the new mechanism.\n\nOr if we keep it at \"--initSubmodule\" only, which only initializes\na subset of new submodules, the meaning is not superseded.\n\nBy having the initSubmodule thing set, the user tells us \"I am interested\nin all currently initialized submodules plus some more in the future, but\nthese have not arrived yet. To know which submodules I mean in the future\napply this pattern.\"\n\nLet's take the simplest case:\n\nA user is interested in all the submodules. So currently they clone\nand initialize all of them. When upstream adds a new submodule, their\nexpectation is broken that all submodules are there and checked out.\nby having the autoInit option, we'd just initialize any new submodule\nand the user assumption \"I have all the submodules\" is true after\nany \"submodule update\".\n\nBy that point of view, we would not need to keep all submodules initialized,\nbut only those the user is interested in. No need to have complicated\nbranch switching rules, but just as now \"plus some futureproof rules\nto declare my interest of submodules\".\n\n>\n>>> That will make switching between branches with different label\n>>> configurations work fine. Or am I missing something here?\n>>>\n>>> And we need to teach diff and status to complain about empty work\n>>> trees and missing initialization of submodules that are to be\n>>> automatically updated too.\n>>\n>>\n>> What about empty work trees?\n>>\n>> I'll add \"git status\" complaining about missing initialized submodules.\n>\n>\n> If they are to be updated on the next \"git submodule update\" ;-)\n\nright.\n\n>\n>>>\n>>>>       # The prefix * denotes a label as found in .gitmodules\n>>>>       # : goes before names\n>>>>       # path are prefixed ./ currently\n>>>>       # both path and names need work\n>>>\n>>>\n>>>\n>>> Question: how do I configure all submodules to be automatically\n>>> initialized without having to give them a label? \"./*\"? Or just\n>>> setting the option without a specific value?\n>>\n>>\n>> I'd guess ./* should do. Path wildcard patterns are not supported in this\n>> series, but I think it would be a viable way.\n>\n>\n> Ok.\n>\n>>>>       # no --init necessary, partially initializes submodules (only\n>>>> those\n>>>> which\n>>>>       # were specified by label, name or path)\n>>>>       $ git submodule update\n>>>\n>>>\n>>>\n>>> Yup. Just like they will be fetched if they haven't been yet they\n>>> should be initialized if they haven't been yet but are configured\n>>> to be automatically updated.\n>>>\n>>>>       # time passes, upstream may have added new submodules and we get\n>>>> them\n>>>> without\n>>>>       # extra commands!\n>>>>       $ git submodule update\n>>>>\n>>>>       # The above configuration can be given to git clone directly via:\n>>>>       $ git clone --init-submodule=*labelA ...\n>>>\n>>>\n>>>\n>>> Ok. Expecially nice is the ability to also give names and paths to\n>>> \"--init-submodule\". (but maybe that option should be called\n>>> \"--autoupdate-submodule\" for the reasons stated above?)\n>>\n>>\n>> If I can understand the discussion above a bit further, I'd be happy\n>> to rename the option.\n>>\n>> I think we have some different opinions on when\n>> submodules are initialized (the invariant of what an initalized submodules\n>> means), and resulting from that we also have different opinions on when\n>> to do the (de-)init.\n>\n>\n> Yes. But I hope my arguments will convince you ;-)\n\n--autoupdate-submodule seems to be one step ahead of my current understanding?\n\nThanks,\nStefan\n"},{"id":"277143","messageId":"56AE7804.1060609@web.de","threadId":"41247","inReplyTo":"CAGZ79kapcGDFx+=VNCPvRMUGBJiTzJqGWv6UzPNgMOVBKgwXdw@mail.gmail.com","subject":"Re: [RFC/PATCH 0/5] [WAS: Submodule Groups] Labels and submodule.autoInitialize","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2016-01-31T21:09:24Z","receivedAt":"2016-01-31T21:09:24Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 26.01.2016 um 22:50 schrieb Stefan Beller:\n> On Tue, Jan 26, 2016 at 12:59 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>\n>>>> Ok. Though we might wanna call it submodule.autoUpdate, as initializing\n>>>> it is only the prerequisite for automatically updating submodules. And\n>>>> I believe automatically updating is the thing we're after here, right?\n>>>\n>>>\n>>> I am not sure here, too. I would not mind an occasional \"git submodule\n>>> update\"\n>>> for whenever I want upstream to come down on my disk.\n>>\n>>>\n>>>\n>>> However that's what I\n>>> do with \"git pull\" in the non-submodule case, so you'd expect git pull to\n>>> also run the update strategies for all submodules which are configured to\n>>> autoUpdate?\n>>>\n>>> That makes sense to me. Though I never use \"git pull\" to begin with.\n>>> I always use fetch and see how to go from there (merge or rebase\n>>> after inspecting the code I fetched). That would mean we want to\n>>> add the autoUpdate strategy to merge/rebase and the fetching of\n>>> submodules to the fetch command?\n>>\n>>\n>> Hmm, maybe autoUpdate promises too much.\n>\n> Yes, this very much. I feel like I get burned whenever I send a large\n> patch series.\n> So I want to have this first feature be the smallest \"operational\n> unit\" that makes sense.\n\nAgreed.\n\n>> After all this config is\n>> just about which submodules are chosen to be updated on clone and\n>> submodule update, not on all the other work tree manipulating\n>> commands.\n>\n> So you'd imagine that \"git submodule update\" would remove the\n> submodule and setup an empty directory in case that submodule is\n> not configured ? (after switching branches or when just having cloned\n> that thing.)\n\nNot as a result of the label feature we are talking about here,\nI think that should just do what currently happens to removed\nsubmodules: they are left populated but are ignored by status,\ndiff and submodule update. Removing the content is part of the\nrecursive submodule update topic.\n\n>> And it's similar to what sparse does. So what about calling that\n>> \"submodule.updateSparse\"? Or maybe \"submodule.sparseCheckout\"?\n>> Suggestions welcome.\n>\n> I'd only suggest when it's clear to me what that option actually does. :)\n\nFair enough! ;-)\n\n>>>> And the\n>>>> fetch command needs to fetch submodule changes too when they happen in\n>>>> a branch where this submodule is part of a label group configured to be\n>>>> updated automatically, no matter what is currently found in the work\n>>>> tree.\n>>>\n>>>\n>>> Right, as said above fetch needs to fetch all the submodules as well. I\n>>> wonder\n>>> if it needs to fetch all submodule sha1s only or just try to get as\n>>> much from the\n>>> submodule as possible.\n>>\n>>\n>> Right now we just do a simple fetch, but only fetching the SHA-1s could\n>> be an optimization useful for busy submodules later on.\n>\n> I'd rather not call it optimisation, but a correctness thing. What if you\n> force-pushed other content to the submodule (the sha1 is gone and\n> maybe should not be reachable)or the other case where you want to\n> clone the submodule with depth 1 (that is a serious case, which currently\n> breaks). In the shallow submodule case you need to have the exact sha1\n> for cloning, otherwise it doesn't work correctly.\n\nI'm convinced. Correctness it is! :-)\n\n>>>> So I'd propose to:\n>>>>\n>>>> *) Initialize every submodule present on clone or newly fetched when\n>>>>      the autoUpdate config is set.\n>>>\n>>>\n>>> What if you clone branch A and then switch to B ? B has a submodule which\n>>> was not initialized in A. I do not think initializing on clone/fetch\n>>> is the right thing\n>>> to do, but rather the branch switching command (checkout) shall make sure\n>>> all its autoUpdate/autoInitialze submodules are setup properly, no?\n>>\n>>\n>> I disagree. If you init all submodules on clone/fetch you might need\n>> to change the upstream URL right after that. You can't do that on a\n>> subsequent branch switch which needs to initialize the submodule again,\n>> as the former deinit did nuke that configuration.\n>\n> So we need to keep the information around, which we do by keeping\n> all the modules initialized all the time.\n\nYup.\n\n>>>> *) Automatically fetch only those submodules that are changed in\n>>>>      a commit where they have a label configured (in the commit's\n>>>>      .gitmodules or locally) that is to be checked out.\n>>>\n>>>\n>>> Not sure I follow here.\n>>\n>>\n>> We could restrict fetch to not fetch everything but just those changes\n>> needed for sparse submodule update. To be able to do that it would\n>> have to examine the fetched superproject commits if a submodule changed\n>> and if it is configured to be automatically updated in that commit.\n>\n> ok, that's an optimisation for later? (not strictly needed for the first series)\n\nDefinitely.\n\n>>>> *) Let \"git submodule update\" update only those submodules that\n>>>>      have an autoupdate label configured.\n>>>\n>>>\n>>> Why not update all initialized submodules? (In my imagination\n>>> \"all initialized submodules\" are equal to \"all submodules the user is\n>>> interested in\", i.e. when going from branch A to B, the checkout will\n>>> (de-)init submodules as necessary.\n>>\n>>\n>> And throw away any customization the user did (to the URL or other\n>> configurations)?\n>>\n>> Without this sparse/label/group functionality, init is the way the\n>> user tells us he is interested in a submodule. But when configuring\n>> a label/name/path to update, the old meaning of init is obsolete\n>> and superseded by the new mechanism.\n>\n> Or if we keep it at \"--initSubmodule\" only, which only initializes\n> a subset of new submodules, the meaning is not superseded.\n>\n> By having the initSubmodule thing set, the user tells us \"I am interested\n> in all currently initialized submodules plus some more in the future, but\n> these have not arrived yet. To know which submodules I mean in the future\n> apply this pattern.\"\n>\n> Let's take the simplest case:\n>\n> A user is interested in all the submodules. So currently they clone\n> and initialize all of them. When upstream adds a new submodule, their\n> expectation is broken that all submodules are there and checked out.\n> by having the autoInit option, we'd just initialize any new submodule\n> and the user assumption \"I have all the submodules\" is true after\n> any \"submodule update\".\n>\n> By that point of view, we would not need to keep all submodules initialized,\n> but only those the user is interested in. No need to have complicated\n> branch switching rules, but just as now \"plus some futureproof rules\n> to declare my interest of submodules\".\n\nI'm not sure what \"complicated branch switching rules\" you are\nreferring to here, as far as I can see these only happen when we do\nnot automatically initialize all submodules. What am I missing?\n\nYou'd have to deal with initialized but not to be updated submodules\nanyway (due to the user choosing a different label or upstream\nchanging label assigments). So it looks to me like the approach to\ninitialize them all as soon as they appear is easier to grok. And\nupdate, diff and status will just skip all submodules that don't\nmatch the configured label(s).\n\nAdditionally this will make it easier to e.g. change the upstream\nURL of the submodules in one go, as this has to be done after they\nhave been initialized. If you clone the android repo from a local\nmirror it'd be great to just update all URL settings once right\nafter clone instead of having to do that again each time you choose\na different group.\n\nSo I'm not per se against a lazy submodule init like you seem to\npropose it, but I believe it'd be better to just init them all as\nsoon as they appear.\n\n>>>>>        # The prefix * denotes a label as found in .gitmodules\n>>>>>        # : goes before names\n>>>>>        # path are prefixed ./ currently\n>>>>>        # both path and names need work\n>>>>\n>>>>\n>>>>\n>>>> Question: how do I configure all submodules to be automatically\n>>>> initialized without having to give them a label? \"./*\"? Or just\n>>>> setting the option without a specific value?\n>>>\n>>>\n>>> I'd guess ./* should do. Path wildcard patterns are not supported in this\n>>> series, but I think it would be a viable way.\n>>\n>>\n>> Ok.\n>>\n>>>>>        # no --init necessary, partially initializes submodules (only\n>>>>> those\n>>>>> which\n>>>>>        # were specified by label, name or path)\n>>>>>        $ git submodule update\n>>>>\n>>>>\n>>>>\n>>>> Yup. Just like they will be fetched if they haven't been yet they\n>>>> should be initialized if they haven't been yet but are configured\n>>>> to be automatically updated.\n>>>>\n>>>>>        # time passes, upstream may have added new submodules and we get\n>>>>> them\n>>>>> without\n>>>>>        # extra commands!\n>>>>>        $ git submodule update\n>>>>>\n>>>>>        # The above configuration can be given to git clone directly via:\n>>>>>        $ git clone --init-submodule=*labelA ...\n>>>>\n>>>>\n>>>>\n>>>> Ok. Expecially nice is the ability to also give names and paths to\n>>>> \"--init-submodule\". (but maybe that option should be called\n>>>> \"--autoupdate-submodule\" for the reasons stated above?)\n>>>\n>>>\n>>> If I can understand the discussion above a bit further, I'd be happy\n>>> to rename the option.\n>>>\n>>> I think we have some different opinions on when\n>>> submodules are initialized (the invariant of what an initalized submodules\n>>> means), and resulting from that we also have different opinions on when\n>>> to do the (de-)init.\n>>\n>>\n>> Yes. But I hope my arguments will convince you ;-)\n>\n> --autoupdate-submodule seems to be one step ahead of my current understanding?\n\nYes, sorry for the confusion.\n"},{"id":"277182","messageId":"CAGZ79kb=Cj_bOc6rQ83jWc+m-DDcFQav3XM741DyaebwehJiHg@mail.gmail.com","threadId":"41247","inReplyTo":"56AE7804.1060609@web.de","subject":"Re: [RFC/PATCH 0/5] [WAS: Submodule Groups] Labels and submodule.autoInitialize","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-02-01T20:21:21Z","receivedAt":"2016-02-01T20:21:21Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Sun, Jan 31, 2016 at 1:09 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>>> After all this config is\n>>> just about which submodules are chosen to be updated on clone and\n>>> submodule update, not on all the other work tree manipulating\n>>> commands.\n>>\n>>\n>> So you'd imagine that \"git submodule update\" would remove the\n>> submodule and setup an empty directory in case that submodule is\n>> not configured ? (after switching branches or when just having cloned\n>> that thing.)\n>\n>\n> Not as a result of the label feature we are talking about here,\n> I think that should just do what currently happens to removed\n> submodules: they are left populated but are ignored by status,\n> diff and submodule update. Removing the content is part of the\n> recursive submodule update topic.\n\nThat is our second next big difference in understanding.\nWhen having an autoInitialize option, we would not go further into\nmaking rules for when to update submodules. \"git submodule update\"\nwould just update all initialzed submodules. (This thought ties well\ntogether with only initializing those submodules that you want instead\nof all of them.)\n\nNow that we want to init all the submodules, it makes sense to only\nupdate those we are interested in.\n\nSo from what I understand now:\n\n(If labels are configured, then)\n\n * init a submodule at the earliest time possible, (i.e. while\n   cloning or when upstream added a new submodule and\n   we fetch it? Though then the init would be performed not in\n   clone/fetch, but the \"submodule update\" step)\n\n * never deinit submodules automatically\n\n * submodule update is picky what to update by default.\n   It will only update by label selection or directly specified submodules\n   (git submodule update foo will update foo no matter if foo is in the\n   selected group, a plain \"git submodule update\" however will only\n   update group/label selected modules.)\n\n>>>\n>>>\n>>> And throw away any customization the user did (to the URL or other\n>>> configurations)?\n>>>\n>>> Without this sparse/label/group functionality, init is the way the\n>>> user tells us he is interested in a submodule. But when configuring\n>>> a label/name/path to update, the old meaning of init is obsolete\n>>> and superseded by the new mechanism.\n>>\n>>\n>> Or if we keep it at \"--initSubmodule\" only, which only initializes\n>> a subset of new submodules, the meaning is not superseded.\n>>\n>> By having the initSubmodule thing set, the user tells us \"I am interested\n>> in all currently initialized submodules plus some more in the future, but\n>> these have not arrived yet. To know which submodules I mean in the future\n>> apply this pattern.\"\n>>\n>> Let's take the simplest case:\n>>\n>> A user is interested in all the submodules. So currently they clone\n>> and initialize all of them. When upstream adds a new submodule, their\n>> expectation is broken that all submodules are there and checked out.\n>> by having the autoInit option, we'd just initialize any new submodule\n>> and the user assumption \"I have all the submodules\" is true after\n>> any \"submodule update\".\n>>\n>> By that point of view, we would not need to keep all submodules\n>> initialized,\n>> but only those the user is interested in. No need to have complicated\n>> branch switching rules, but just as now \"plus some futureproof rules\n>> to declare my interest of submodules\".\n>\n>\n> I'm not sure what \"complicated branch switching rules\" you are\n> referring to here, as far as I can see these only happen when we do\n> not automatically initialize all submodules. What am I missing?\n\nI was assuming we need to delete the submodules and preserve\ntheir state somewhere.\n\nSo what I understand now:\n\n$ git checkout <anotherbranch> # will not touch submodules, however\n$ git submodule update # may update a different selection as the\n$ # selection changed by a different .gitmodules file\n\n>\n> You'd have to deal with initialized but not to be updated submodules\n> anyway (due to the user choosing a different label or upstream\n> changing label assigments). So it looks to me like the approach to\n> initialize them all as soon as they appear is easier to grok. And\n> update, diff and status will just skip all submodules that don't\n> match the configured label(s).\n\nWe can teach update, diff and status to ignore those non selected\nsubmodules just fine, but I still think it is somewhat ugly.\n(Consider the build system, which now needs to somehow know\nwhich submodules to build. The non selected modules may\nerror out when building as their dependencies are wrong/not met;\nalso humans don't like wading through a ton of empty directories\nto find their pet project)\n\n>\n> Additionally this will make it easier to e.g. change the upstream\n> URL of the submodules in one go, as this has to be done after they\n> have been initialized. If you clone the android repo from a local\n> mirror it'd be great to just update all URL settings once right\n> after clone instead of having to do that again each time you choose\n> a different group.\n>\n> So I'm not per se against a lazy submodule init like you seem to\n> propose it, but I believe it'd be better to just init them all as\n> soon as they appear.\n\nok, I'll prepare a patch series for that.\n\n>>> Yes. But I hope my arguments will convince you ;-)\n>>\n>>\n>> --autoupdate-submodule seems to be one step ahead of my current\n>> understanding?\n>\n>\n> Yes, sorry for the confusion.\n\nSo now is time to start bikeshedding (aka naming things) again ;)\n\nThe main feature I'd understand is to only apply submodule update, diff, status\n(and maybe more) to the selected submodules. So maybe\n\n    $ git clone --apply-actions-to-label <label/path/name pattern>\n[may be repeated]\n\n    $ git submodule update # no additional arguments\n\n    $ git submodule add --label <label name>\n\nIn the .gitmodules file we can still have \"submodule.$foo.label\" but in the\n.git/config we may want to have \"submodule.action-on-label\" instead ?\n\nThanks,\nStefan\n"}]}