{"thread":{"id":"48911","subject":"[PATCH 0/6] Resend of origin/sb/submodule-update-in-c","startedAt":"2018-07-18T19:49:04Z","lastAt":"2018-07-18T23:12:01Z","messageCount":9,"participants":["Stefan Beller","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"352964","messageId":"20180718194853.57994-1-sbeller@google.com","threadId":"48911","inReplyTo":null,"subject":"[PATCH 0/6] Resend of origin/sb/submodule-update-in-c","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-07-18T19:48:47Z","receivedAt":"2018-07-18T19:49:04Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"This fixes the compilation issue raised by SZEDER and Stolee,\n\n\n6:  3c156c79ae7 ! 6:  f82f24e73b6 submodule--helper: introduce new update-module-mode helper\n    @@ -10,7 +10,6 @@\n         for arbitrary repositories.\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n     diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\n     --- a/builtin/submodule--helper.c\n    @@ -74,7 +73,7 @@\n     +\tdetermine_submodule_update_strategy(the_repository,\n     +\t\t\t\t\t    just_cloned, path, update,\n     +\t\t\t\t\t    &update_strategy);\n    -+\tfprintf(stdout, submodule_strategy_to_string(&update_strategy));\n    ++\tfputs(submodule_strategy_to_string(&update_strategy), stdout);\n     +\n     +\treturn 0;\n     +}\n\nThanks,\nStefan\n"},{"id":"352965","messageId":"20180718194853.57994-2-sbeller@google.com","threadId":"48911","inReplyTo":"20180718194853.57994-1-sbeller@google.com","subject":"[PATCH 1/6] git-submodule.sh: align error reporting for update mode to use path","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-07-18T19:48:48Z","receivedAt":"2018-07-18T19:49:06Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"All other error messages in cmd_update are reporting the submodule based\non its path, so let's do that for invalid update modes, too.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n git-submodule.sh | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 5f9d9f6ea37..8a611865397 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -627,7 +627,7 @@ cmd_update()\n \t\t\t\tmust_die_on_failure=yes\n \t\t\t\t;;\n \t\t\t*)\n-\t\t\t\tdie \"$(eval_gettext \"Invalid update mode '$update_module' for submodule '$name'\")\"\n+\t\t\t\tdie \"$(eval_gettext \"Invalid update mode '$update_module' for submodule path '$path'\")\"\n \t\t\tesac\n \n \t\t\tif (sanitize_submodule_env; cd \"$sm_path\" && $command \"$sha1\")\n-- \n2.18.0.233.g985f88cf7e-goog\n\n"},{"id":"352966","messageId":"20180718194853.57994-3-sbeller@google.com","threadId":"48911","inReplyTo":"20180718194853.57994-1-sbeller@google.com","subject":"[PATCH 2/6] git-submodule.sh: rename unused variables","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-07-18T19:48:49Z","receivedAt":"2018-07-18T19:49:09Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"The 'mode' variable is not used in cmd_update for its original purpose,\nrename it to 'dummy' as it only serves the purpose to abort quickly\ndocumenting this knowledge.\n\nThe variable 'stage' is also not used any more in cmd_update, so remove it.\n\nThis went unnoticed as first each function used the commonly used\nsubmodule listing, which was converted in 74703a1e4df (submodule: rewrite\n`module_list` shell function in C, 2015-09-02). When cmd_update was\nusing its own function starting in 48308681b07 (git submodule update:\nhave a dedicated helper for cloning, 2016-02-29), its removal was missed.\n\nA later patch in this series also touches the communication between\nthe submodule helper and git-submodule.sh, but let's have this as\na preparatory patch, as it eases the next patch, which stores the\nraw data instead of the line printed for this communication.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n builtin/submodule--helper.c | 5 ++---\n git-submodule.sh            | 4 ++--\n 2 files changed, 4 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 20ae9191ca3..ebcfe85bfa9 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1571,9 +1571,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,\n \tneeds_cloning = !file_exists(sb.buf);\n \n \tstrbuf_reset(&sb);\n-\tstrbuf_addf(&sb, \"%06o %s %d %d\\t%s\\n\", ce->ce_mode,\n-\t\t\toid_to_hex(&ce->oid), ce_stage(ce),\n-\t\t\tneeds_cloning, ce->name);\n+\tstrbuf_addf(&sb, \"dummy %s %d\\t%s\\n\",\n+\t\t    oid_to_hex(&ce->oid), needs_cloning, ce->name);\n \tstring_list_append(&suc->projectlines, sb.buf);\n \n \tif (!needs_cloning)\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 8a611865397..56588aa304d 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -531,9 +531,9 @@ cmd_update()\n \t\t\"$@\" || echo \"#unmatched\" $?\n \t} | {\n \terr=\n-\twhile read -r mode sha1 stage just_cloned sm_path\n+\twhile read -r quickabort sha1 just_cloned sm_path\n \tdo\n-\t\tdie_if_unmatched \"$mode\" \"$sha1\"\n+\t\tdie_if_unmatched \"$quickabort\" \"$sha1\"\n \n \t\tname=$(git submodule--helper name \"$sm_path\") || exit\n \t\tif ! test -z \"$update\"\n-- \n2.18.0.233.g985f88cf7e-goog\n\n"},{"id":"352967","messageId":"20180718194853.57994-4-sbeller@google.com","threadId":"48911","inReplyTo":"20180718194853.57994-1-sbeller@google.com","subject":"[PATCH 3/6] builtin/submodule--helper: factor out submodule updating","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-07-18T19:48:50Z","receivedAt":"2018-07-18T19:49:11Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Separate the command line parsing from the actual execution of the command\nwithin the repository. For now there is not a lot of execution as\nmost of it is still in git-submodule.sh.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n builtin/submodule--helper.c | 59 +++++++++++++++++++++----------------\n 1 file changed, 33 insertions(+), 26 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex ebcfe85bfa9..96929ba1096 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1472,6 +1472,8 @@ struct submodule_update_clone {\n \t/* failed clones to be retried again */\n \tconst struct cache_entry **failed_clones;\n \tint failed_clones_nr, failed_clones_alloc;\n+\n+\tint max_jobs;\n };\n #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \\\n \tSUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \\\n@@ -1714,11 +1716,36 @@ static int gitmodules_update_clone_config(const char *var, const char *value,\n \treturn 0;\n }\n \n+static int update_submodules(struct submodule_update_clone *suc)\n+{\n+\tstruct string_list_item *item;\n+\n+\trun_processes_parallel(suc->max_jobs,\n+\t\t\t       update_clone_get_next_task,\n+\t\t\t       update_clone_start_failure,\n+\t\t\t       update_clone_task_finished,\n+\t\t\t       suc);\n+\n+\t/*\n+\t * We saved the output and put it out all at once now.\n+\t * That means:\n+\t * - the listener does not have to interleave their (checkout)\n+\t *   work with our fetching.  The writes involved in a\n+\t *   checkout involve more straightforward sequential I/O.\n+\t * - the listener can avoid doing any work if fetching failed.\n+\t */\n+\tif (suc->quickstop)\n+\t\treturn 1;\n+\n+\tfor_each_string_list_item(item, &suc->projectlines)\n+\t\tfprintf(stdout, \"%s\", item->string);\n+\n+\treturn 0;\n+}\n+\n static int update_clone(int argc, const char **argv, const char *prefix)\n {\n \tconst char *update = NULL;\n-\tint max_jobs = 1;\n-\tstruct string_list_item *item;\n \tstruct pathspec pathspec;\n \tstruct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;\n \n@@ -1740,7 +1767,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \t\tOPT_STRING(0, \"depth\", &suc.depth, \"<depth>\",\n \t\t\t   N_(\"Create a shallow clone truncated to the \"\n \t\t\t      \"specified number of revisions\")),\n-\t\tOPT_INTEGER('j', \"jobs\", &max_jobs,\n+\t\tOPT_INTEGER('j', \"jobs\", &suc.max_jobs,\n \t\t\t    N_(\"parallel jobs\")),\n \t\tOPT_BOOL(0, \"recommend-shallow\", &suc.recommend_shallow,\n \t\t\t    N_(\"whether the initial clone should follow the shallow recommendation\")),\n@@ -1756,8 +1783,8 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \t};\n \tsuc.prefix = prefix;\n \n-\tconfig_from_gitmodules(gitmodules_update_clone_config, &max_jobs);\n-\tgit_config(gitmodules_update_clone_config, &max_jobs);\n+\tconfig_from_gitmodules(gitmodules_update_clone_config, &suc.max_jobs);\n+\tgit_config(gitmodules_update_clone_config, &suc.max_jobs);\n \n \targc = parse_options(argc, argv, prefix, module_update_clone_options,\n \t\t\t     git_submodule_helper_usage, 0);\n@@ -1772,27 +1799,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \tif (pathspec.nr)\n \t\tsuc.warn_if_uninitialized = 1;\n \n-\trun_processes_parallel(max_jobs,\n-\t\t\t       update_clone_get_next_task,\n-\t\t\t       update_clone_start_failure,\n-\t\t\t       update_clone_task_finished,\n-\t\t\t       &suc);\n-\n-\t/*\n-\t * We saved the output and put it out all at once now.\n-\t * That means:\n-\t * - the listener does not have to interleave their (checkout)\n-\t *   work with our fetching.  The writes involved in a\n-\t *   checkout involve more straightforward sequential I/O.\n-\t * - the listener can avoid doing any work if fetching failed.\n-\t */\n-\tif (suc.quickstop)\n-\t\treturn 1;\n-\n-\tfor_each_string_list_item(item, &suc.projectlines)\n-\t\tfprintf(stdout, \"%s\", item->string);\n-\n-\treturn 0;\n+\treturn update_submodules(&suc);\n }\n \n static int resolve_relative_path(int argc, const char **argv, const char *prefix)\n-- \n2.18.0.233.g985f88cf7e-goog\n\n"},{"id":"352968","messageId":"20180718194853.57994-5-sbeller@google.com","threadId":"48911","inReplyTo":"20180718194853.57994-1-sbeller@google.com","subject":"[PATCH 4/6] builtin/submodule--helper: store update_clone information in a struct","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-07-18T19:48:51Z","receivedAt":"2018-07-18T19:49:12Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"The information that is printed for update_submodules in\n'submodule--helper update-clone' and consumed by 'git submodule update'\nis stored as a string per submodule. This made sense at the time of\n48308681b07 (git submodule update: have a dedicated helper for cloning,\n2016-02-29), but as we want to migrate the rest of the submodule update\ninto C, we're better off having access to the raw information in a helper\nstruct.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n builtin/submodule--helper.c | 37 +++++++++++++++++++++++++++----------\n 1 file changed, 27 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 96929ba1096..fb54936efc7 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1444,6 +1444,12 @@ static int module_clone(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n+struct update_clone_data {\n+\tconst struct submodule *sub;\n+\tstruct object_id oid;\n+\tunsigned just_cloned;\n+};\n+\n struct submodule_update_clone {\n \t/* index into 'list', the list of submodules to look into for cloning */\n \tint current;\n@@ -1463,8 +1469,9 @@ struct submodule_update_clone {\n \tconst char *recursive_prefix;\n \tconst char *prefix;\n \n-\t/* Machine-readable status lines to be consumed by git-submodule.sh */\n-\tstruct string_list projectlines;\n+\t/* to be consumed by git-submodule.sh */\n+\tstruct update_clone_data *update_clone;\n+\tint update_clone_nr; int update_clone_alloc;\n \n \t/* If we want to stop as fast as possible and return an error */\n \tunsigned quickstop : 1;\n@@ -1478,7 +1485,7 @@ struct submodule_update_clone {\n #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \\\n \tSUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \\\n \tNULL, NULL, NULL, \\\n-\tSTRING_LIST_INIT_DUP, 0, NULL, 0, 0}\n+\tNULL, 0, 0, 0, NULL, 0, 0, 0}\n \n \n static void next_submodule_warn_missing(struct submodule_update_clone *suc,\n@@ -1572,10 +1579,12 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,\n \tstrbuf_addf(&sb, \"%s/.git\", ce->name);\n \tneeds_cloning = !file_exists(sb.buf);\n \n-\tstrbuf_reset(&sb);\n-\tstrbuf_addf(&sb, \"dummy %s %d\\t%s\\n\",\n-\t\t    oid_to_hex(&ce->oid), needs_cloning, ce->name);\n-\tstring_list_append(&suc->projectlines, sb.buf);\n+\tALLOC_GROW(suc->update_clone, suc->update_clone_nr + 1,\n+\t\t   suc->update_clone_alloc);\n+\toidcpy(&suc->update_clone[suc->update_clone_nr].oid, &ce->oid);\n+\tsuc->update_clone[suc->update_clone_nr].just_cloned = needs_cloning;\n+\tsuc->update_clone[suc->update_clone_nr].sub = sub;\n+\tsuc->update_clone_nr++;\n \n \tif (!needs_cloning)\n \t\tgoto cleanup;\n@@ -1718,7 +1727,8 @@ static int gitmodules_update_clone_config(const char *var, const char *value,\n \n static int update_submodules(struct submodule_update_clone *suc)\n {\n-\tstruct string_list_item *item;\n+\tint i;\n+\tstruct strbuf sb = STRBUF_INIT;\n \n \trun_processes_parallel(suc->max_jobs,\n \t\t\t       update_clone_get_next_task,\n@@ -1737,9 +1747,16 @@ static int update_submodules(struct submodule_update_clone *suc)\n \tif (suc->quickstop)\n \t\treturn 1;\n \n-\tfor_each_string_list_item(item, &suc->projectlines)\n-\t\tfprintf(stdout, \"%s\", item->string);\n+\tfor (i = 0; i < suc->update_clone_nr; i++) {\n+\t\tstrbuf_addf(&sb, \"dummy %s %d\\t%s\\n\",\n+\t\t\toid_to_hex(&suc->update_clone[i].oid),\n+\t\t\tsuc->update_clone[i].just_cloned,\n+\t\t\tsuc->update_clone[i].sub->path);\n+\t\tfprintf(stdout, \"%s\", sb.buf);\n+\t\tstrbuf_reset(&sb);\n+\t}\n \n+\tstrbuf_release(&sb);\n \treturn 0;\n }\n \n-- \n2.18.0.233.g985f88cf7e-goog\n\n"},{"id":"352969","messageId":"20180718194853.57994-6-sbeller@google.com","threadId":"48911","inReplyTo":"20180718194853.57994-1-sbeller@google.com","subject":"[PATCH 5/6] builtin/submodule--helper: factor out method to update a single submodule","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-07-18T19:48:52Z","receivedAt":"2018-07-18T19:49:15Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"In a later patch we'll find this method handy.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n builtin/submodule--helper.c | 20 ++++++++++----------\n 1 file changed, 10 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex fb54936efc7..034ba1bb2e0 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1725,10 +1725,17 @@ static int gitmodules_update_clone_config(const char *var, const char *value,\n \treturn 0;\n }\n \n+static void update_submodule(struct update_clone_data *ucd)\n+{\n+\tfprintf(stdout, \"dummy %s %d\\t%s\\n\",\n+\t\toid_to_hex(&ucd->oid),\n+\t\tucd->just_cloned,\n+\t\tucd->sub->path);\n+}\n+\n static int update_submodules(struct submodule_update_clone *suc)\n {\n \tint i;\n-\tstruct strbuf sb = STRBUF_INIT;\n \n \trun_processes_parallel(suc->max_jobs,\n \t\t\t       update_clone_get_next_task,\n@@ -1747,16 +1754,9 @@ static int update_submodules(struct submodule_update_clone *suc)\n \tif (suc->quickstop)\n \t\treturn 1;\n \n-\tfor (i = 0; i < suc->update_clone_nr; i++) {\n-\t\tstrbuf_addf(&sb, \"dummy %s %d\\t%s\\n\",\n-\t\t\toid_to_hex(&suc->update_clone[i].oid),\n-\t\t\tsuc->update_clone[i].just_cloned,\n-\t\t\tsuc->update_clone[i].sub->path);\n-\t\tfprintf(stdout, \"%s\", sb.buf);\n-\t\tstrbuf_reset(&sb);\n-\t}\n+\tfor (i = 0; i < suc->update_clone_nr; i++)\n+\t\tupdate_submodule(&suc->update_clone[i]);\n \n-\tstrbuf_release(&sb);\n \treturn 0;\n }\n \n-- \n2.18.0.233.g985f88cf7e-goog\n\n"},{"id":"352970","messageId":"20180718194853.57994-7-sbeller@google.com","threadId":"48911","inReplyTo":"20180718194853.57994-1-sbeller@google.com","subject":"[PATCH 6/6] submodule--helper: introduce new update-module-mode helper","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-07-18T19:48:53Z","receivedAt":"2018-07-18T19:49:18Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"This chews off a bit of the shell part of the update command in\ngit-submodule.sh. When writing the C code, keep in mind that the\nsubmodule--helper part will go away eventually and we want to have\na C function that is able to determine the submodule update strategy,\nit as a nicety, make determine_submodule_update_strategy accessible\nfor arbitrary repositories.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n builtin/submodule--helper.c | 61 +++++++++++++++++++++++++++++++++++++\n git-submodule.sh            | 16 +---------\n 2 files changed, 62 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 034ba1bb2e0..c7de5d1e0a0 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1444,6 +1444,66 @@ static int module_clone(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n+static void determine_submodule_update_strategy(struct repository *r,\n+\t\t\t\t\t\tint just_cloned,\n+\t\t\t\t\t\tconst char *path,\n+\t\t\t\t\t\tconst char *update,\n+\t\t\t\t\t\tstruct submodule_update_strategy *out)\n+{\n+\tconst struct submodule *sub = submodule_from_path(r, &null_oid, path);\n+\tchar *key;\n+\tconst char *val;\n+\n+\tkey = xstrfmt(\"submodule.%s.update\", sub->name);\n+\n+\tif (update) {\n+\t\ttrace_printf(\"parsing update\");\n+\t\tif (parse_submodule_update_strategy(update, out) < 0)\n+\t\t\tdie(_(\"Invalid update mode '%s' for submodule path '%s'\"),\n+\t\t\t\tupdate, path);\n+\t} else if (!repo_config_get_string_const(r, key, &val)) {\n+\t\tif (parse_submodule_update_strategy(val, out) < 0)\n+\t\t\tdie(_(\"Invalid update mode '%s' configured for submodule path '%s'\"),\n+\t\t\t\tval, path);\n+\t} else if (sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {\n+\t\ttrace_printf(\"loaded thing\");\n+\t\tout->type = sub->update_strategy.type;\n+\t\tout->command = sub->update_strategy.command;\n+\t} else\n+\t\tout->type = SM_UPDATE_CHECKOUT;\n+\n+\tif (just_cloned &&\n+\t    (out->type == SM_UPDATE_MERGE ||\n+\t     out->type == SM_UPDATE_REBASE ||\n+\t     out->type == SM_UPDATE_NONE))\n+\t\tout->type = SM_UPDATE_CHECKOUT;\n+\n+\tfree(key);\n+}\n+\n+static int module_update_module_mode(int argc, const char **argv, const char *prefix)\n+{\n+\tconst char *path, *update = NULL;\n+\tint just_cloned;\n+\tstruct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT };\n+\n+\tif (argc < 3 || argc > 4)\n+\t\tdie(\"submodule--helper update-module-clone expects <just-cloned> <path> [<update>]\");\n+\n+\tjust_cloned = git_config_int(\"just_cloned\", argv[1]);\n+\tpath = argv[2];\n+\n+\tif (argc == 4)\n+\t\tupdate = argv[3];\n+\n+\tdetermine_submodule_update_strategy(the_repository,\n+\t\t\t\t\t    just_cloned, path, update,\n+\t\t\t\t\t    &update_strategy);\n+\tfputs(submodule_strategy_to_string(&update_strategy), stdout);\n+\n+\treturn 0;\n+}\n+\n struct update_clone_data {\n \tconst struct submodule *sub;\n \tstruct object_id oid;\n@@ -2039,6 +2099,7 @@ static struct cmd_struct commands[] = {\n \t{\"list\", module_list, 0},\n \t{\"name\", module_name, 0},\n \t{\"clone\", module_clone, 0},\n+\t{\"update-module-mode\", module_update_module_mode, 0},\n \t{\"update-clone\", update_clone, 0},\n \t{\"relative-path\", resolve_relative_path, 0},\n \t{\"resolve-relative-url\", resolve_relative_url, 0},\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 56588aa304d..215760898ce 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -535,27 +535,13 @@ cmd_update()\n \tdo\n \t\tdie_if_unmatched \"$quickabort\" \"$sha1\"\n \n-\t\tname=$(git submodule--helper name \"$sm_path\") || exit\n-\t\tif ! test -z \"$update\"\n-\t\tthen\n-\t\t\tupdate_module=$update\n-\t\telse\n-\t\t\tupdate_module=$(git config submodule.\"$name\".update)\n-\t\t\tif test -z \"$update_module\"\n-\t\t\tthen\n-\t\t\t\tupdate_module=\"checkout\"\n-\t\t\tfi\n-\t\tfi\n+\t\tupdate_module=$(git submodule--helper update-module-mode $just_cloned \"$sm_path\" $update)\n \n \t\tdisplaypath=$(git submodule--helper relative-path \"$prefix$sm_path\" \"$wt_prefix\")\n \n \t\tif test $just_cloned -eq 1\n \t\tthen\n \t\t\tsubsha1=\n-\t\t\tcase \"$update_module\" in\n-\t\t\tmerge | rebase | none)\n-\t\t\t\tupdate_module=checkout ;;\n-\t\t\tesac\n \t\telse\n \t\t\tsubsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n \t\t\t\tgit rev-parse --verify HEAD) ||\n-- \n2.18.0.233.g985f88cf7e-goog\n\n"},{"id":"352993","messageId":"xmqqpnzki3mp.fsf@gitster-ct.c.googlers.com","threadId":"48911","inReplyTo":"20180718194853.57994-1-sbeller@google.com","subject":"Re: [PATCH 0/6] Resend of origin/sb/submodule-update-in-c","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-07-18T22:24:30Z","receivedAt":"2018-07-18T22:24:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> This fixes the compilation issue raised by SZEDER and Stolee,\n>\n>\n> 6:  3c156c79ae7 ! 6:  f82f24e73b6 submodule--helper: introduce new update-module-mode helper\n>     @@ -10,7 +10,6 @@\n>          for arbitrary repositories.\n>      \n>          Signed-off-by: Stefan Beller <sbeller@google.com>\n>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n>      \n>      diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\n>      --- a/builtin/submodule--helper.c\n>     @@ -74,7 +73,7 @@\n>      +\tdetermine_submodule_update_strategy(the_repository,\n>      +\t\t\t\t\t    just_cloned, path, update,\n>      +\t\t\t\t\t    &update_strategy);\n>     -+\tfprintf(stdout, submodule_strategy_to_string(&update_strategy));\n>     ++\tfputs(submodule_strategy_to_string(&update_strategy), stdout);\n>      +\n>      +\treturn 0;\n>      +}\n>\n> Thanks,\n> Stefan\n\nThanks.  \n\nThis time not from GGG?  I don't particularly care which direction\npatches come from, though ;-)\n"},{"id":"353004","messageId":"CAGZ79kbYybZ8KbaECy2oqrTH9dUKVgTfrrxbOYWxhF14_d210A@mail.gmail.com","threadId":"48911","inReplyTo":"xmqqpnzki3mp.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH 0/6] Resend of origin/sb/submodule-update-in-c","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-07-18T23:11:48Z","receivedAt":"2018-07-18T23:12:01Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Wed, Jul 18, 2018 at 3:24 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Stefan Beller <sbeller@google.com> writes:\n>\n> > This fixes the compilation issue raised by SZEDER and Stolee,\n> >\n> >\n> > 6:  3c156c79ae7 ! 6:  f82f24e73b6 submodule--helper: introduce new update-module-mode helper\n> >     @@ -10,7 +10,6 @@\n> >          for arbitrary repositories.\n> >\n> >          Signed-off-by: Stefan Beller <sbeller@google.com>\n> >     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> >\n> >      diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\n> >      --- a/builtin/submodule--helper.c\n> >     @@ -74,7 +73,7 @@\n> >      +        determine_submodule_update_strategy(the_repository,\n> >      +                                            just_cloned, path, update,\n> >      +                                            &update_strategy);\n> >     -+        fprintf(stdout, submodule_strategy_to_string(&update_strategy));\n> >     ++        fputs(submodule_strategy_to_string(&update_strategy), stdout);\n> >      +\n> >      +        return 0;\n> >      +}\n> >\n> > Thanks,\n> > Stefan\n>\n> Thanks.\n>\n> This time not from GGG?\n\nGGG = GitGitGadget?\nI have yet to try out that tool, I am still stuck on git-send-email.\n(old habits die hard)\n\nIt is even based off your branch (with all your sign offs).\n\nI just cut down aggressively on the range diff (and short stat),\nas I want to highlight the important part.\n\n>  I don't particularly care which direction\n> patches come from, though ;-)\n\nCool.\n\nThanks,\nStefan\n"}]}