{"thread":{"id":"44527","subject":"[PATCHv3 0/3] submodule-config: clarify/cleanup docs and header","startedAt":"2016-11-22T01:36:04Z","lastAt":"2016-11-22T18:36:46Z","messageCount":6,"participants":["Stefan Beller","Junio C Hamano","Brandon Williams"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"306277","messageId":"20161122013550.1800-1-sbeller@google.com","threadId":"44527","inReplyTo":null,"subject":"[PATCHv3 0/3] submodule-config: clarify/cleanup docs and header","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-11-22T01:35:47Z","receivedAt":"2016-11-22T01:36:04Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"replacing sb/submodule-config-cleanup\n\nv3:\ndiff to current origin/sb/submodule-config-cleanup:\ndiff --git a/Documentation/technical/api-submodule-config.txt b/Documentation/technical/api-submodule-config.txt\nindex 1df7a827ff..e06a3fd2de 100644\n--- a/Documentation/technical/api-submodule-config.txt\n+++ b/Documentation/technical/api-submodule-config.txt\n@@ -49,17 +49,17 @@ Functions\n \n `const struct submodule *submodule_from_path(const unsigned char *commit_or_tree, const char *path)`::\n \n-\tLookup values for one submodule by its commit_sha1 and path.\n+\tLookup values for one submodule by its commit_or_tree and path.\n \n `const struct submodule *submodule_from_name(const unsigned char *commit_or_tree, const char *name)`::\n \n \tThe same as above but lookup by name.\n \n Whenever a submodule configuration is parsed in `parse_submodule_config_option`\n-via e.g. `gitmodules_config()`, it will be overwrite the entry with the sha1\n-zeroed out.  So in the normal case, when HEAD:.gitmodules is parsed first and\n-then overlayed with the repository configuration, the null_sha1 entry contains\n-the local configuration of a submodule (e.g. consolidated values from local git\n+via e.g. `gitmodules_config()`, it will be overwrite the null_sha1 entry.\n+So in the normal case, when HEAD:.gitmodules is parsed first and then overlayed\n+with the repository configuration, the null_sha1 entry contains the local\n+configuration of a submodule (e.g. consolidated values from local git\n configuration and the .gitmodules file in the worktree).\n \n For an example usage see test-submodule-config.c.\ndiff --git a/submodule-config.c b/submodule-config.c\nindex 4c5f5d074b..d88a746c56 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -448,7 +448,6 @@ static const struct submodule *config_from(struct submodule_cache *cache,\n \n \t/* fill the submodule config into the cache */\n \tparameter.cache = cache;\n-\t// todo: get the actual tree here:\n \tparameter.commit_or_tree = commit_or_tree;\n \tparameter.gitmodules_sha1 = sha1;\n \tparameter.overwrite = 0;\n        \nv2:\naddressed Jacobs concerns in patch2, fixing all occurrences of commit_sha1.\n\nThanks,\nStefan\n\ninterdiff to v1:\ndiff --git a/Documentation/technical/api-submodule-config.txt b/Documentation/technical/api-submodule-config.txt\nindex 1df7a827ff..a91c1f085e 100644\n--- a/Documentation/technical/api-submodule-config.txt\n+++ b/Documentation/technical/api-submodule-config.txt\n@@ -49,7 +49,7 @@ Functions\n\n `const struct submodule *submodule_from_path(const unsigned char *commit_or_tree, const char *path)`::\n\n-       Lookup values for one submodule by its commit_sha1 and path.\n+       Lookup values for one submodule by its commit_or_tree and path.\n\n `const struct submodule *submodule_from_name(const unsigned char *commit_or_tree, const char *name)`::\n\n\nv1:\nA small series that would have helped me understand the submodule config\nonce again.\n\nThanks,\nStefan\n\nStefan Beller (3):\n  submodule config: inline config_from_{name, path}\n  submodule-config: rename commit_sha1 to commit_or_tree\n  submodule-config: clarify parsing of null_sha1 element\n\n Documentation/technical/api-submodule-config.txt | 13 ++++--\n submodule-config.c                               | 58 ++++++++++--------------\n submodule-config.h                               |  4 +-\n t/t7411-submodule-config.sh                      | 11 +++++\n 4 files changed, 44 insertions(+), 42 deletions(-)\n\n-- \n2.11.0.rc2.18.g0126045.dirty\n\n"},{"id":"306278","messageId":"20161122013550.1800-3-sbeller@google.com","threadId":"44527","inReplyTo":"20161122013550.1800-1-sbeller@google.com","subject":"[PATCHv3 2/3] submodule-config: rename commit_sha1 to commit_or_tree","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-11-22T01:35:49Z","receivedAt":"2016-11-22T01:36:08Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"It is also possible to pass in a tree hash to lookup a submodule config.\nMake it clear by naming the variables accrodingly. Looking up a submodule\nconfig by tree hash will come in handy in a later patch.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n Documentation/technical/api-submodule-config.txt |  8 ++---\n submodule-config.c                               | 46 ++++++++++++------------\n submodule-config.h                               |  4 +--\n t/t7411-submodule-config.sh                      | 11 ++++++\n 4 files changed, 40 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/technical/api-submodule-config.txt b/Documentation/technical/api-submodule-config.txt\nindex 941fa178dd..768458580f 100644\n--- a/Documentation/technical/api-submodule-config.txt\n+++ b/Documentation/technical/api-submodule-config.txt\n@@ -47,15 +47,15 @@ Functions\n \tCan be passed to the config parsing infrastructure to parse\n \tlocal (worktree) submodule configurations.\n \n-`const struct submodule *submodule_from_path(const unsigned char *commit_sha1, const char *path)`::\n+`const struct submodule *submodule_from_path(const unsigned char *commit_or_tree, const char *path)`::\n \n-\tLookup values for one submodule by its commit_sha1 and path.\n+\tLookup values for one submodule by its commit_or_tree and path.\n \n-`const struct submodule *submodule_from_name(const unsigned char *commit_sha1, const char *name)`::\n+`const struct submodule *submodule_from_name(const unsigned char *commit_or_tree, const char *name)`::\n \n \tThe same as above but lookup by name.\n \n-If given the null_sha1 as commit_sha1 the local configuration of a\n+If given the null_sha1 as commit_or_tree the local configuration of a\n submodule will be returned (e.g. consolidated values from local git\n configuration and the .gitmodules file in the worktree).\n \ndiff --git a/submodule-config.c b/submodule-config.c\nindex 15ffab6af4..d88a746c56 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -263,12 +263,12 @@ int parse_push_recurse_submodules_arg(const char *opt, const char *arg)\n \treturn parse_push_recurse(opt, arg, 1);\n }\n \n-static void warn_multiple_config(const unsigned char *commit_sha1,\n+static void warn_multiple_config(const unsigned char *commit_or_tree,\n \t\t\t\t const char *name, const char *option)\n {\n \tconst char *commit_string = \"WORKTREE\";\n-\tif (commit_sha1)\n-\t\tcommit_string = sha1_to_hex(commit_sha1);\n+\tif (commit_or_tree)\n+\t\tcommit_string = sha1_to_hex(commit_or_tree);\n \twarning(\"%s:.gitmodules, multiple configurations found for \"\n \t\t\t\"'submodule.%s.%s'. Skipping second one!\",\n \t\t\tcommit_string, name, option);\n@@ -276,7 +276,7 @@ static void warn_multiple_config(const unsigned char *commit_sha1,\n \n struct parse_config_parameter {\n \tstruct submodule_cache *cache;\n-\tconst unsigned char *commit_sha1;\n+\tconst unsigned char *commit_or_tree;\n \tconst unsigned char *gitmodules_sha1;\n \tint overwrite;\n };\n@@ -300,7 +300,7 @@ static int parse_config(const char *var, const char *value, void *data)\n \t\tif (!value)\n \t\t\tret = config_error_nonbool(var);\n \t\telse if (!me->overwrite && submodule->path)\n-\t\t\twarn_multiple_config(me->commit_sha1, submodule->name,\n+\t\t\twarn_multiple_config(me->commit_or_tree, submodule->name,\n \t\t\t\t\t\"path\");\n \t\telse {\n \t\t\tif (submodule->path)\n@@ -314,7 +314,7 @@ static int parse_config(const char *var, const char *value, void *data)\n \t\tint die_on_error = is_null_sha1(me->gitmodules_sha1);\n \t\tif (!me->overwrite &&\n \t\t    submodule->fetch_recurse != RECURSE_SUBMODULES_NONE)\n-\t\t\twarn_multiple_config(me->commit_sha1, submodule->name,\n+\t\t\twarn_multiple_config(me->commit_or_tree, submodule->name,\n \t\t\t\t\t\"fetchrecursesubmodules\");\n \t\telse\n \t\t\tsubmodule->fetch_recurse = parse_fetch_recurse(\n@@ -324,7 +324,7 @@ static int parse_config(const char *var, const char *value, void *data)\n \t\tif (!value)\n \t\t\tret = config_error_nonbool(var);\n \t\telse if (!me->overwrite && submodule->ignore)\n-\t\t\twarn_multiple_config(me->commit_sha1, submodule->name,\n+\t\t\twarn_multiple_config(me->commit_or_tree, submodule->name,\n \t\t\t\t\t\"ignore\");\n \t\telse if (strcmp(value, \"untracked\") &&\n \t\t\t strcmp(value, \"dirty\") &&\n@@ -340,7 +340,7 @@ static int parse_config(const char *var, const char *value, void *data)\n \t\tif (!value) {\n \t\t\tret = config_error_nonbool(var);\n \t\t} else if (!me->overwrite && submodule->url) {\n-\t\t\twarn_multiple_config(me->commit_sha1, submodule->name,\n+\t\t\twarn_multiple_config(me->commit_or_tree, submodule->name,\n \t\t\t\t\t\"url\");\n \t\t} else {\n \t\t\tfree((void *) submodule->url);\n@@ -351,21 +351,21 @@ static int parse_config(const char *var, const char *value, void *data)\n \t\t\tret = config_error_nonbool(var);\n \t\telse if (!me->overwrite &&\n \t\t\t submodule->update_strategy.type != SM_UPDATE_UNSPECIFIED)\n-\t\t\twarn_multiple_config(me->commit_sha1, submodule->name,\n+\t\t\twarn_multiple_config(me->commit_or_tree, submodule->name,\n \t\t\t\t\t     \"update\");\n \t\telse if (parse_submodule_update_strategy(value,\n \t\t\t &submodule->update_strategy) < 0)\n \t\t\t\tdie(_(\"invalid value for %s\"), var);\n \t} else if (!strcmp(item.buf, \"shallow\")) {\n \t\tif (!me->overwrite && submodule->recommend_shallow != -1)\n-\t\t\twarn_multiple_config(me->commit_sha1, submodule->name,\n+\t\t\twarn_multiple_config(me->commit_or_tree, submodule->name,\n \t\t\t\t\t     \"shallow\");\n \t\telse\n \t\t\tsubmodule->recommend_shallow =\n \t\t\t\tgit_config_bool(var, value);\n \t} else if (!strcmp(item.buf, \"branch\")) {\n \t\tif (!me->overwrite && submodule->branch)\n-\t\t\twarn_multiple_config(me->commit_sha1, submodule->name,\n+\t\t\twarn_multiple_config(me->commit_or_tree, submodule->name,\n \t\t\t\t\t     \"branch\");\n \t\telse {\n \t\t\tfree((void *)submodule->branch);\n@@ -379,18 +379,18 @@ static int parse_config(const char *var, const char *value, void *data)\n \treturn ret;\n }\n \n-static int gitmodule_sha1_from_commit(const unsigned char *commit_sha1,\n+static int gitmodule_sha1_from_commit(const unsigned char *commit_or_tree,\n \t\t\t\t      unsigned char *gitmodules_sha1,\n \t\t\t\t      struct strbuf *rev)\n {\n \tint ret = 0;\n \n-\tif (is_null_sha1(commit_sha1)) {\n+\tif (is_null_sha1(commit_or_tree)) {\n \t\thashclr(gitmodules_sha1);\n \t\treturn 1;\n \t}\n \n-\tstrbuf_addf(rev, \"%s:.gitmodules\", sha1_to_hex(commit_sha1));\n+\tstrbuf_addf(rev, \"%s:.gitmodules\", sha1_to_hex(commit_or_tree));\n \tif (get_sha1(rev->buf, gitmodules_sha1) >= 0)\n \t\tret = 1;\n \n@@ -402,7 +402,7 @@ static int gitmodule_sha1_from_commit(const unsigned char *commit_sha1,\n  * revisions.\n  */\n static const struct submodule *config_from(struct submodule_cache *cache,\n-\t\tconst unsigned char *commit_sha1, const char *key,\n+\t\tconst unsigned char *commit_or_tree, const char *key,\n \t\tenum lookup_type lookup_type)\n {\n \tstruct strbuf rev = STRBUF_INIT;\n@@ -418,7 +418,7 @@ static const struct submodule *config_from(struct submodule_cache *cache,\n \t * return the first submodule. Can be used to check whether\n \t * there are any submodules parsed.\n \t */\n-\tif (!commit_sha1 || !key) {\n+\tif (!commit_or_tree || !key) {\n \t\tstruct hashmap_iter iter;\n \t\tstruct submodule_entry *entry;\n \n@@ -428,7 +428,7 @@ static const struct submodule *config_from(struct submodule_cache *cache,\n \t\treturn entry->config;\n \t}\n \n-\tif (!gitmodule_sha1_from_commit(commit_sha1, sha1, &rev))\n+\tif (!gitmodule_sha1_from_commit(commit_or_tree, sha1, &rev))\n \t\tgoto out;\n \n \tswitch (lookup_type) {\n@@ -448,7 +448,7 @@ static const struct submodule *config_from(struct submodule_cache *cache,\n \n \t/* fill the submodule config into the cache */\n \tparameter.cache = cache;\n-\tparameter.commit_sha1 = commit_sha1;\n+\tparameter.commit_or_tree = commit_or_tree;\n \tparameter.gitmodules_sha1 = sha1;\n \tparameter.overwrite = 0;\n \tgit_config_from_mem(parse_config, CONFIG_ORIGIN_SUBMODULE_BLOB, rev.buf,\n@@ -484,7 +484,7 @@ int parse_submodule_config_option(const char *var, const char *value)\n {\n \tstruct parse_config_parameter parameter;\n \tparameter.cache = &the_submodule_cache;\n-\tparameter.commit_sha1 = NULL;\n+\tparameter.commit_or_tree = NULL;\n \tparameter.gitmodules_sha1 = null_sha1;\n \tparameter.overwrite = 1;\n \n@@ -492,18 +492,18 @@ int parse_submodule_config_option(const char *var, const char *value)\n \treturn parse_config(var, value, &parameter);\n }\n \n-const struct submodule *submodule_from_name(const unsigned char *commit_sha1,\n+const struct submodule *submodule_from_name(const unsigned char *commit_or_tree,\n \t\tconst char *name)\n {\n \tensure_cache_init();\n-\treturn config_from(&the_submodule_cache, commit_sha1, name, lookup_name);\n+\treturn config_from(&the_submodule_cache, commit_or_tree, name, lookup_name);\n }\n \n-const struct submodule *submodule_from_path(const unsigned char *commit_sha1,\n+const struct submodule *submodule_from_path(const unsigned char *commit_or_tree,\n \t\tconst char *path)\n {\n \tensure_cache_init();\n-\treturn config_from(&the_submodule_cache, commit_sha1, path, lookup_path);\n+\treturn config_from(&the_submodule_cache, commit_or_tree, path, lookup_path);\n }\n \n void submodule_free(void)\ndiff --git a/submodule-config.h b/submodule-config.h\nindex d05c542d2c..99df8e593c 100644\n--- a/submodule-config.h\n+++ b/submodule-config.h\n@@ -25,9 +25,9 @@ struct submodule {\n int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg);\n int parse_push_recurse_submodules_arg(const char *opt, const char *arg);\n int parse_submodule_config_option(const char *var, const char *value);\n-const struct submodule *submodule_from_name(const unsigned char *commit_sha1,\n+const struct submodule *submodule_from_name(const unsigned char *commit_or_tree,\n \t\tconst char *name);\n-const struct submodule *submodule_from_path(const unsigned char *commit_sha1,\n+const struct submodule *submodule_from_path(const unsigned char *commit_or_tree,\n \t\tconst char *path);\n void submodule_free(void);\n \ndiff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh\nindex 47562ce465..301ed5e48f 100755\n--- a/t/t7411-submodule-config.sh\n+++ b/t/t7411-submodule-config.sh\n@@ -93,6 +93,17 @@ test_expect_success 'error message contains blob reference' '\n \t)\n '\n \n+test_expect_success 'using tree sha1 works' '\n+\t(\n+\t\tcd super &&\n+\t\ttree=$(git rev-parse HEAD^{tree}) &&\n+\t\tcommit=$(git rev-parse HEAD^{commit}) &&\n+\t\ttest-submodule-config $commit b >expect &&\n+\t\ttest-submodule-config $tree b >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n cat >super/expect_url <<EOF\n Submodule url: 'git@somewhere.else.net:a.git' for path 'b'\n Submodule url: 'git@somewhere.else.net:submodule.git' for path 'submodule'\n-- \n2.11.0.rc2.18.g0126045.dirty\n\n"},{"id":"306279","messageId":"20161122013550.1800-2-sbeller@google.com","threadId":"44527","inReplyTo":"20161122013550.1800-1-sbeller@google.com","subject":"[PATCHv3 1/3] submodule config: inline config_from_{name, path}","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-11-22T01:35:48Z","receivedAt":"2016-11-22T01:36:15Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"There is no other user of config_from_{name, path}, such that there is no\nreason for the existence of these one liner functions. Just inline these\nto increase readability.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n submodule-config.c | 16 ++--------------\n 1 file changed, 2 insertions(+), 14 deletions(-)\n\ndiff --git a/submodule-config.c b/submodule-config.c\nindex 098085be69..15ffab6af4 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -471,18 +471,6 @@ static const struct submodule *config_from(struct submodule_cache *cache,\n \treturn submodule;\n }\n \n-static const struct submodule *config_from_path(struct submodule_cache *cache,\n-\t\tconst unsigned char *commit_sha1, const char *path)\n-{\n-\treturn config_from(cache, commit_sha1, path, lookup_path);\n-}\n-\n-static const struct submodule *config_from_name(struct submodule_cache *cache,\n-\t\tconst unsigned char *commit_sha1, const char *name)\n-{\n-\treturn config_from(cache, commit_sha1, name, lookup_name);\n-}\n-\n static void ensure_cache_init(void)\n {\n \tif (is_cache_init)\n@@ -508,14 +496,14 @@ const struct submodule *submodule_from_name(const unsigned char *commit_sha1,\n \t\tconst char *name)\n {\n \tensure_cache_init();\n-\treturn config_from_name(&the_submodule_cache, commit_sha1, name);\n+\treturn config_from(&the_submodule_cache, commit_sha1, name, lookup_name);\n }\n \n const struct submodule *submodule_from_path(const unsigned char *commit_sha1,\n \t\tconst char *path)\n {\n \tensure_cache_init();\n-\treturn config_from_path(&the_submodule_cache, commit_sha1, path);\n+\treturn config_from(&the_submodule_cache, commit_sha1, path, lookup_path);\n }\n \n void submodule_free(void)\n-- \n2.11.0.rc2.18.g0126045.dirty\n\n"},{"id":"306280","messageId":"20161122013550.1800-4-sbeller@google.com","threadId":"44527","inReplyTo":"20161122013550.1800-1-sbeller@google.com","subject":"[PATCHv3 3/3] submodule-config: clarify parsing of null_sha1 element","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-11-22T01:35:50Z","receivedAt":"2016-11-22T01:36:18Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/technical/api-submodule-config.txt | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/technical/api-submodule-config.txt b/Documentation/technical/api-submodule-config.txt\nindex 768458580f..e06a3fd2de 100644\n--- a/Documentation/technical/api-submodule-config.txt\n+++ b/Documentation/technical/api-submodule-config.txt\n@@ -55,8 +55,11 @@ Functions\n \n \tThe same as above but lookup by name.\n \n-If given the null_sha1 as commit_or_tree the local configuration of a\n-submodule will be returned (e.g. consolidated values from local git\n+Whenever a submodule configuration is parsed in `parse_submodule_config_option`\n+via e.g. `gitmodules_config()`, it will be overwrite the null_sha1 entry.\n+So in the normal case, when HEAD:.gitmodules is parsed first and then overlayed\n+with the repository configuration, the null_sha1 entry contains the local\n+configuration of a submodule (e.g. consolidated values from local git\n configuration and the .gitmodules file in the worktree).\n \n For an example usage see test-submodule-config.c.\n-- \n2.11.0.rc2.18.g0126045.dirty\n\n"},{"id":"306286","messageId":"xmqqziksfae3.fsf@gitster.mtv.corp.google.com","threadId":"44527","inReplyTo":"20161122013550.1800-4-sbeller@google.com","subject":"Re: [PATCHv3 3/3] submodule-config: clarify parsing of null_sha1 element","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-11-22T03:42:28Z","receivedAt":"2016-11-22T03:42:45Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> +Whenever a submodule configuration is parsed in `parse_submodule_config_option`\n> +via e.g. `gitmodules_config()`, it will be overwrite the null_sha1 entry.\n\nIt will overwrite?  It will be overwritten?  I guess it is the latter?\n\n> +So in the normal case, when HEAD:.gitmodules is parsed first and then overlayed\n> +with the repository configuration, the null_sha1 entry contains the local\n> +configuration of a submodule (e.g. consolidated values from local git\n>  configuration and the .gitmodules file in the worktree).\n>  \n>  For an example usage see test-submodule-config.c.\n"},{"id":"306329","messageId":"20161122183639.GA65825@google.com","threadId":"44527","inReplyTo":"xmqqziksfae3.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCHv3 3/3] submodule-config: clarify parsing of null_sha1 element","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2016-11-22T18:36:39Z","receivedAt":"2016-11-22T18:36:46Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 11/21, Junio C Hamano wrote:\n> Stefan Beller <sbeller@google.com> writes:\n> \n> > +Whenever a submodule configuration is parsed in `parse_submodule_config_option`\n> > +via e.g. `gitmodules_config()`, it will be overwrite the null_sha1 entry.\n> \n> It will overwrite?  It will be overwritten?  I guess it is the latter?\n> \n> > +So in the normal case, when HEAD:.gitmodules is parsed first and then overlayed\n> > +with the repository configuration, the null_sha1 entry contains the local\n> > +configuration of a submodule (e.g. consolidated values from local git\n> >  configuration and the .gitmodules file in the worktree).\n> >  \n> >  For an example usage see test-submodule-config.c.\n\nI brought this up in v2, he must have just missed it for v3.\n\n-- \nBrandon Williams\n"}]}