{"thread":{"id":"57488","subject":"[PATCH 00/13] submodule: convert parts of 'update' to C","startedAt":"2022-03-01T00:08:23Z","lastAt":"2022-03-05T00:41:06Z","messageCount":75,"participants":["Glen Choo","Junio C Hamano","Ævar Arnfjörð Bjarmason"],"isPatch":true,"patchVersion":1,"patchTotal":13},"messages":[{"id":"449822","messageId":"20220301000816.56177-1-chooglen@google.com","threadId":"57488","inReplyTo":null,"subject":"[PATCH 00/13] submodule: convert parts of 'update' to C","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:03Z","receivedAt":"2022-03-01T00:08:23Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Original series: https://lore.kernel.org/git/20220210092833.55360-1-chooglen@google.com\n(I've trimmed the cc list down to the 'most interested' parties)\n\n= Overview\n\nThis is part 1 of 2 series that will supersede ar/submodule-update (as laid out\nin [1]). This series prepares for the eventual conversion of \"git submodule\nupdate\" to C by doing 'obvious' conversions first, and leaving more involved\nconversions for later.\n\nPart 1 is a lot simpler than the original series in its entirety, and should\nplay better with topics that Junio identified:\n\n- This series is based off a later version of 'master' that already has\n  'js/apply-partial-clone-filters-recursively' merged in [2].\n- There is only one, trivial, conflict with 'es/superproject-aware-submodules'\n  (both add tests to the end of t7406) [3].\n\nMost of these patches were originally from ar/submodule-update, but because of\nthe new organization, some commit messages have been amended to make more sense\nin context. However, patches 12 and 13 are new - they were added to handle the\n\"--filter\" option introduced by 'js/apply-partial-clone-filters-recursively'.\n\nCc-ed Josh, who might be interested in \"--filter\" changes e.g. the new\ntests.\n\n[1] https://lore.kernel.org/git/kl6lmtig40l4.fsf@chooglen-macbookpro.roam.corp.google.com\n[2] This also fixes some trivial merge conflicts with 'master'.\n[3] Part 2 has nontrival conflicts though. Offline, Emily mentioned that\n    conflicts might go away in the next iteration of\n    'es/superproject-aware-submodules', but if not, the next round of patches\n    will probably be based on a merge of this series +\n    'es/superproject-aware-submodules'.\n\n= Patch summary\n\nI'm not certain whether to keep patch 13, see the extra discussion in\nthe --- description for details.\n\n- Patch 1 adds extra tests to \"git submodule update\" to make sure we\n  don't break anything\n- Patch 2 removes dead code that used to be part of \"git submodule\n  update\"\n- Patch 3 prepares for later changes by introducing the C function that\n  will hold most of the newly converted code\n- Patch 4 moves run-update-procedure's --suboid option into C\n- Patch 5 moves ensure-core-worktree into C\n- Patches 6-8 move run-update-procedure's --remote option into C\n- Patches 9-11 move \"git submodule update\"'s --init into C\n- Patches 12-13 move \"git submodule update\"'s --filter option into C\n\nAtharva Raykar (3):\n  submodule--helper: get remote names from any repository\n  submodule--helper: refactor get_submodule_displaypath()\n  submodule--helper: allow setting superprefix for init_submodule()\n\nGlen Choo (8):\n  submodule--helper: remove update-module-mode\n  submodule--helper: reorganize code for sh to C conversion\n  submodule--helper run-update-procedure: remove --suboid\n  submodule--helper: remove ensure-core-worktree\n  submodule--helper run-update-procedure: learn --remote\n  submodule--helper update-clone: learn --init\n  submodule update: add tests for --filter\n  submodule--helper update-clone: check for --filter and --init\n\nÆvar Arnfjörð Bjarmason (2):\n  submodule tests: test for init and update failure output\n  submodule--helper: don't use bitfield indirection for parse_options()\n\n builtin/submodule--helper.c    | 230 ++++++++++++++++++++-------------\n git-submodule.sh               |  54 +-------\n t/t7406-submodule-update.sh    |  54 +++++++-\n t/t7408-submodule-reference.sh |  14 +-\n 4 files changed, 211 insertions(+), 141 deletions(-)\n\n\nbase-commit: 715d08a9e51251ad8290b181b6ac3b9e1f9719d7\n-- \n2.33.GIT\n\n"},{"id":"449823","messageId":"20220301000816.56177-2-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 01/13] submodule tests: test for init and update failure output","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:04Z","receivedAt":"2022-03-01T00:08:26Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nAmend some submodule tests to test for the failure output of \"git\nsubmodule [update|init]\". The lack of such tests hid a regression in\nan earlier version of a subsequent commit.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n t/t7406-submodule-update.sh    | 14 ++++++++++++--\n t/t7408-submodule-reference.sh | 14 +++++++++++++-\n 2 files changed, 25 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 11cccbb333..7764c1c3cb 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -205,8 +205,18 @@ test_expect_success 'submodule update should fail due to local changes' '\n \t (cd submodule &&\n \t  compare_head\n \t ) &&\n-\t test_must_fail git submodule update submodule\n-\t)\n+\t test_must_fail git submodule update submodule 2>../actual.raw\n+\t) &&\n+\tsed \"s/^> //\" >expect <<-\\EOF &&\n+\t> error: Your local changes to the following files would be overwritten by checkout:\n+\t> \tfile\n+\t> Please commit your changes or stash them before you switch branches.\n+\t> Aborting\n+\t> fatal: Unable to checkout OID in submodule path '\\''submodule'\\''\n+\tEOF\n+\tsed -e \"s/checkout $SQ[^$SQ]*$SQ/checkout OID/\" <actual.raw >actual &&\n+\ttest_cmp expect actual\n+\n '\n test_expect_success 'submodule update should throw away changes with --force ' '\n \t(cd super &&\ndiff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh\nindex a3892f494b..c3a4545510 100755\n--- a/t/t7408-submodule-reference.sh\n+++ b/t/t7408-submodule-reference.sh\n@@ -193,7 +193,19 @@ test_expect_success 'missing nested submodule alternate fails clone and submodul\n \t\tcd supersuper-clone &&\n \t\tcheck_that_two_of_three_alternates_are_used &&\n \t\t# update of the submodule fails\n-\t\ttest_must_fail git submodule update --init --recursive\n+\t\tcat >expect <<-\\EOF &&\n+\t\tfatal: submodule '\\''sub'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub'\\''. Retry scheduled\n+\t\tfatal: submodule '\\''sub-dissociate'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub-dissociate'\\''. Retry scheduled\n+\t\tfatal: submodule '\\''sub'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub'\\'' a second time, aborting\n+\t\tfatal: Failed to recurse into submodule path ...\n+\t\tEOF\n+\t\ttest_must_fail git submodule update --init --recursive 2>err &&\n+\t\tgrep -e fatal: -e ^Failed err >actual.raw &&\n+\t\tsed -e \"s/path $SQ[^$SQ]*$SQ/path .../\" <actual.raw >actual &&\n+\t\ttest_cmp expect actual\n \t)\n '\n \n-- \n2.33.GIT\n\n"},{"id":"449824","messageId":"20220301000816.56177-3-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 02/13] submodule--helper: remove update-module-mode","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:05Z","receivedAt":"2022-03-01T00:08:28Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"This is dead code - it has not been used since c51f8f94e5\n(submodule--helper: run update procedures from C, 2021-08-24).\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 24 ------------------------\n 1 file changed, 24 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex eeacefcc38..c11ee1ea2b 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1957,29 +1957,6 @@ static void determine_submodule_update_strategy(struct repository *r,\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@@ -3430,7 +3407,6 @@ static struct cmd_struct commands[] = {\n \t{\"name\", module_name, 0},\n \t{\"clone\", module_clone, 0},\n \t{\"add\", module_add, SUPPORT_SUPER_PREFIX},\n-\t{\"update-module-mode\", module_update_module_mode, 0},\n \t{\"update-clone\", update_clone, 0},\n \t{\"run-update-procedure\", run_update_procedure, 0},\n \t{\"ensure-core-worktree\", ensure_core_worktree, 0},\n-- \n2.33.GIT\n\n"},{"id":"449825","messageId":"20220301000816.56177-5-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 04/13] submodule--helper run-update-procedure: remove --suboid","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:07Z","receivedAt":"2022-03-01T00:08:33Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach run-update-procedure to determine the oid of the submodule's HEAD\ninstead of doing it in git-subomdule.sh.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 9 ++++++---\n git-submodule.sh            | 8 +-------\n 2 files changed, 7 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 1b67a3887c..77ca4270f4 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2594,9 +2594,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\tOPT_CALLBACK_F(0, \"oid\", &update_data.oid, N_(\"sha1\"),\n \t\t\t       N_(\"SHA1 expected by superproject\"), PARSE_OPT_NONEG,\n \t\t\t       parse_opt_object_id),\n-\t\tOPT_CALLBACK_F(0, \"suboid\", &update_data.suboid, N_(\"subsha1\"),\n-\t\t\t       N_(\"SHA1 of submodule's HEAD\"), PARSE_OPT_NONEG,\n-\t\t\t       parse_opt_object_id),\n \t\tOPT_END()\n \t};\n \n@@ -3032,6 +3029,12 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n /* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n static int update_submodule2(struct update_data *update_data)\n {\n+\tif (update_data->just_cloned)\n+\t\toidcpy(&update_data->suboid, null_oid());\n+\telse if (resolve_gitlink_ref(update_data->sm_path, \"HEAD\", &update_data->suboid))\n+\t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n+\t\t\tupdate_data->displaypath);\n+\n \tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n \t\treturn do_run_update_procedure(update_data);\n \ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 87772ac891..32a09302ab 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -406,14 +406,9 @@ cmd_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\tif test $just_cloned -eq 0\n \t\tthen\n-\t\t\tsubsha1=\n-\t\telse\n \t\t\tjust_cloned=\n-\t\t\tsubsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n-\t\t\t\tgit rev-parse --verify HEAD) ||\n-\t\t\tdie \"fatal: $(eval_gettext \"Unable to find current revision in submodule path '\\$displaypath'\")\"\n \t\tfi\n \n \t\tif test -n \"$remote\"\n@@ -441,7 +436,6 @@ cmd_update()\n \t\t\t  ${update:+--update \"$update\"} \\\n \t\t\t  ${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t\t  ${sha1:+--oid \"$sha1\"} \\\n-\t\t\t  ${subsha1:+--suboid \"$subsha1\"} \\\n \t\t\t  \"--\" \\\n \t\t\t  \"$sm_path\")\n \n-- \n2.33.GIT\n\n"},{"id":"449826","messageId":"20220301000816.56177-4-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 03/13] submodule--helper: reorganize code for sh to C conversion","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:06Z","receivedAt":"2022-03-01T00:08:36Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Introduce a function, update_submodule2(), that will implement the\nfunctionality of run-update-procedure and its surrounding shell code in\nsubmodule.sh. This name is temporary; it will replace update_submodule()\nwhen the sh to C conversion is complete.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 26 +++++++++++++++++++++-----\n 1 file changed, 21 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex c11ee1ea2b..1b67a3887c 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2452,6 +2452,16 @@ static int do_run_update_procedure(struct update_data *ud)\n \treturn run_update_command(ud, subforce);\n }\n \n+/*\n+ * NEEDSWORK: As we convert \"git submodule update\" to C,\n+ * update_submodule2() will invoke more and more functions, making it\n+ * difficult to preserve the function ordering without forward\n+ * declarations.\n+ *\n+ * When the conversion is complete, this forward declaration will be\n+ * unnecessary and should be removed.\n+ */\n+static int update_submodule2(struct update_data *update_data);\n static void update_submodule(struct update_clone_data *ucd)\n {\n \tfprintf(stdout, \"dummy %s %d\\t%s\\n\",\n@@ -2618,11 +2628,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t    &update_data.update_strategy);\n \n \tfree(prefixed_path);\n-\n-\tif (!oideq(&update_data.oid, &update_data.suboid) || update_data.force)\n-\t\treturn do_run_update_procedure(&update_data);\n-\n-\treturn 3;\n+\treturn update_submodule2(&update_data);\n }\n \n static int resolve_relative_path(int argc, const char **argv, const char *prefix)\n@@ -3022,6 +3028,16 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n \t\t\t\t    force, reflog, quiet, track, dry_run);\n \treturn 0;\n }\n+\n+/* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n+static int update_submodule2(struct update_data *update_data)\n+{\n+\tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n+\t\treturn do_run_update_procedure(update_data);\n+\n+\treturn 3;\n+}\n+\n struct add_data {\n \tconst char *prefix;\n \tconst char *branch;\n-- \n2.33.GIT\n\n"},{"id":"449827","messageId":"20220301000816.56177-6-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 05/13] submodule--helper: remove ensure-core-worktree","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:08Z","receivedAt":"2022-03-01T00:08:43Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Move the logic of \"git submodule--helper ensure-core-worktree\" into\nrun-update-procedure. Since the ensure-core-worktree command is\nobsolete, remove it.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 12 ++----------\n git-submodule.sh            |  2 --\n 2 files changed, 2 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 77ca4270f4..6b473fc0d2 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2771,17 +2771,11 @@ static int push_check(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int ensure_core_worktree(int argc, const char **argv, const char *prefix)\n+static void ensure_core_worktree(const char *path)\n {\n-\tconst char *path;\n \tconst char *cw;\n \tstruct repository subrepo;\n \n-\tif (argc != 2)\n-\t\tBUG(\"submodule--helper ensure-core-worktree <path>\");\n-\n-\tpath = argv[1];\n-\n \tif (repo_submodule_init(&subrepo, the_repository, path, null_oid()))\n \t\tdie(_(\"could not get a repository handle for submodule '%s'\"), path);\n \n@@ -2801,8 +2795,6 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)\n \t\tfree(abs_path);\n \t\tstrbuf_release(&sb);\n \t}\n-\n-\treturn 0;\n }\n \n static int absorb_git_dirs(int argc, const char **argv, const char *prefix)\n@@ -3029,6 +3021,7 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n /* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n static int update_submodule2(struct update_data *update_data)\n {\n+\tensure_core_worktree(update_data->sm_path);\n \tif (update_data->just_cloned)\n \t\toidcpy(&update_data->suboid, null_oid());\n \telse if (resolve_gitlink_ref(update_data->sm_path, \"HEAD\", &update_data->suboid))\n@@ -3428,7 +3421,6 @@ static struct cmd_struct commands[] = {\n \t{\"add\", module_add, SUPPORT_SUPER_PREFIX},\n \t{\"update-clone\", update_clone, 0},\n \t{\"run-update-procedure\", run_update_procedure, 0},\n-\t{\"ensure-core-worktree\", ensure_core_worktree, 0},\n \t{\"relative-path\", resolve_relative_path, 0},\n \t{\"resolve-relative-url-test\", resolve_relative_url_test, 0},\n \t{\"foreach\", module_foreach, SUPPORT_SUPER_PREFIX},\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 32a09302ab..458ce73ac6 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -402,8 +402,6 @@ cmd_update()\n \tdo\n \t\tdie_if_unmatched \"$quickabort\" \"$sha1\"\n \n-\t\tgit submodule--helper ensure-core-worktree \"$sm_path\" || exit 1\n-\n \t\tdisplaypath=$(git submodule--helper relative-path \"$prefix$sm_path\" \"$wt_prefix\")\n \n \t\tif test $just_cloned -eq 0\n-- \n2.33.GIT\n\n"},{"id":"449828","messageId":"20220301000816.56177-7-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 06/13] submodule--helper: get remote names from any repository","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:09Z","receivedAt":"2022-03-01T00:08:44Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\n`get_default_remote()` retrieves the name of a remote by resolving the\nrefs from of the current repository's ref store.\n\nThus in order to use it for retrieving the remote name of a submodule,\nwe have to start a new subprocess which runs from the submodule\ndirectory.\n\nLet's instead introduce a function called `repo_get_default_remote()`\nwhich takes any repository object and retrieves the remote accordingly.\n\n`get_default_remote()` is then defined as a call to\n`repo_get_default_remote()` with 'the_repository' passed to it.\n\nNow that we have `repo_get_default_remote()`, we no longer have to start\na subprocess that called `submodule--helper get-default-remote` from\nwithin the submodule directory.\n\nSo let's make a function called `get_default_remote_submodule()` which\ntakes a submodule path, and returns the default remote for that\nsubmodule, all within the same process.\n\nWe can now use this function to save an unnecessary subprocess spawn in\n`sync_submodule()`, and also in the next patch, which will require this\nfunctionality.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nHelped-by: Glen Choo <chooglen@google.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 39 +++++++++++++++++++++++--------------\n 1 file changed, 24 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 6b473fc0d2..f934e33c7e 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -31,11 +31,14 @@\n typedef void (*each_submodule_fn)(const struct cache_entry *list_item,\n \t\t\t\t  void *cb_data);\n \n-static char *get_default_remote(void)\n+static char *repo_get_default_remote(struct repository *repo)\n {\n \tchar *dest = NULL, *ret;\n \tstruct strbuf sb = STRBUF_INIT;\n-\tconst char *refname = resolve_ref_unsafe(\"HEAD\", 0, NULL, NULL);\n+\tstruct ref_store *store = get_main_ref_store(repo);\n+\tint ignore_errno;\n+\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL,\n+\t\t\t\t\t\t      NULL, &ignore_errno);\n \n \tif (!refname)\n \t\tdie(_(\"No such ref: %s\"), \"HEAD\");\n@@ -48,7 +51,7 @@ static char *get_default_remote(void)\n \t\tdie(_(\"Expecting a full ref name, got %s\"), refname);\n \n \tstrbuf_addf(&sb, \"branch.%s.remote\", refname);\n-\tif (git_config_get_string(sb.buf, &dest))\n+\tif (repo_config_get_string(repo, sb.buf, &dest))\n \t\tret = xstrdup(\"origin\");\n \telse\n \t\tret = dest;\n@@ -57,6 +60,19 @@ static char *get_default_remote(void)\n \treturn ret;\n }\n \n+static char *get_default_remote_submodule(const char *module_path)\n+{\n+\tstruct repository subrepo;\n+\n+\trepo_submodule_init(&subrepo, the_repository, module_path, null_oid());\n+\treturn repo_get_default_remote(&subrepo);\n+}\n+\n+static char *get_default_remote(void)\n+{\n+\treturn repo_get_default_remote(the_repository);\n+}\n+\n static int print_default_remote(int argc, const char **argv, const char *prefix)\n {\n \tchar *remote;\n@@ -1343,9 +1359,8 @@ static void sync_submodule(const char *path, const char *prefix,\n {\n \tconst struct submodule *sub;\n \tchar *remote_key = NULL;\n-\tchar *sub_origin_url, *super_config_url, *displaypath;\n+\tchar *sub_origin_url, *super_config_url, *displaypath, *default_remote;\n \tstruct strbuf sb = STRBUF_INIT;\n-\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tchar *sub_config_path = NULL;\n \n \tif (!is_submodule_active(the_repository, path))\n@@ -1384,21 +1399,15 @@ static void sync_submodule(const char *path, const char *prefix,\n \tif (!is_submodule_populated_gently(path, NULL))\n \t\tgoto cleanup;\n \n-\tprepare_submodule_repo_env(&cp.env_array);\n-\tcp.git_cmd = 1;\n-\tcp.dir = path;\n-\tstrvec_pushl(&cp.args, \"submodule--helper\",\n-\t\t     \"print-default-remote\", NULL);\n-\n \tstrbuf_reset(&sb);\n-\tif (capture_command(&cp, &sb, 0))\n+\tdefault_remote = get_default_remote_submodule(path);\n+\tif (!default_remote)\n \t\tdie(_(\"failed to get the default remote for submodule '%s'\"),\n \t\t      path);\n \n-\tstrbuf_strip_suffix(&sb, \"\\n\");\n-\tremote_key = xstrfmt(\"remote.%s.url\", sb.buf);\n+\tremote_key = xstrfmt(\"remote.%s.url\", default_remote);\n+\tfree(default_remote);\n \n-\tstrbuf_reset(&sb);\n \tsubmodule_to_gitdir(&sb, path);\n \tstrbuf_addstr(&sb, \"/config\");\n \n-- \n2.33.GIT\n\n"},{"id":"449829","messageId":"20220301000816.56177-8-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 07/13] submodule--helper: don't use bitfield indirection for parse_options()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:10Z","receivedAt":"2022-03-01T00:08:45Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nDo away with the indirection of local variables added in\nc51f8f94e5b (submodule--helper: run update procedures from C,\n2021-08-24).\n\nThese were only needed because in C you can't get a pointer to a\nsingle bit, so we were using intermediate variables instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 23 ++++++++++-------------\n 1 file changed, 10 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex f934e33c7e..5fbf8713db 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2024,10 +2024,10 @@ struct update_data {\n \tstruct object_id suboid;\n \tstruct submodule_update_strategy update_strategy;\n \tint depth;\n-\tunsigned int force: 1;\n-\tunsigned int quiet: 1;\n-\tunsigned int nofetch: 1;\n-\tunsigned int just_cloned: 1;\n+\tunsigned int force;\n+\tunsigned int quiet;\n+\tunsigned int nofetch;\n+\tunsigned int just_cloned;\n };\n #define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }\n \n@@ -2579,16 +2579,17 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \n static int run_update_procedure(int argc, const char **argv, const char *prefix)\n {\n-\tint force = 0, quiet = 0, nofetch = 0, just_cloned = 0;\n \tchar *prefixed_path, *update = NULL;\n \tstruct update_data update_data = UPDATE_DATA_INIT;\n \n \tstruct option options[] = {\n-\t\tOPT__QUIET(&quiet, N_(\"suppress output for update by rebase or merge\")),\n-\t\tOPT__FORCE(&force, N_(\"force checkout updates\"), 0),\n-\t\tOPT_BOOL('N', \"no-fetch\", &nofetch,\n+\t\tOPT__QUIET(&update_data.quiet,\n+\t\t\t   N_(\"suppress output for update by rebase or merge\")),\n+\t\tOPT__FORCE(&update_data.force, N_(\"force checkout updates\"),\n+\t\t\t   0),\n+\t\tOPT_BOOL('N', \"no-fetch\", &update_data.nofetch,\n \t\t\t N_(\"don't fetch new objects from the remote site\")),\n-\t\tOPT_BOOL(0, \"just-cloned\", &just_cloned,\n+\t\tOPT_BOOL(0, \"just-cloned\", &update_data.just_cloned,\n \t\t\t N_(\"overrides update mode in case the repository is a fresh clone\")),\n \t\tOPT_INTEGER(0, \"depth\", &update_data.depth, N_(\"depth for shallow fetch\")),\n \t\tOPT_STRING(0, \"prefix\", &prefix,\n@@ -2616,10 +2617,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \tif (argc != 1)\n \t\tusage_with_options(usage, options);\n \n-\tupdate_data.force = !!force;\n-\tupdate_data.quiet = !!quiet;\n-\tupdate_data.nofetch = !!nofetch;\n-\tupdate_data.just_cloned = !!just_cloned;\n \tupdate_data.sm_path = argv[0];\n \n \tif (update_data.recursive_prefix)\n-- \n2.33.GIT\n\n"},{"id":"449830","messageId":"20220301000816.56177-10-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 09/13] submodule--helper: refactor get_submodule_displaypath()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:12Z","receivedAt":"2022-03-01T00:08:47Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\nWe create a function called `do_get_submodule_displaypath()` that\ngenerates the display path required by several submodule functions, and\ntakes a custom superprefix parameter, instead of reading it from the\nenvironment.\n\nWe then redefine the existing `get_submodule_displaypath()` function\nas a call to this new function, where the superprefix is obtained from\nthe environment.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/submodule--helper.c | 12 ++++++++----\n 1 file changed, 8 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 1d4d9231ac..3598069de5 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -248,11 +248,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr\n \treturn 0;\n }\n \n-/* the result should be freed by the caller. */\n-static char *get_submodule_displaypath(const char *path, const char *prefix)\n+static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix)\n {\n-\tconst char *super_prefix = get_super_prefix();\n-\n \tif (prefix && super_prefix) {\n \t\tBUG(\"cannot have prefix '%s' and superprefix '%s'\",\n \t\t    prefix, super_prefix);\n@@ -268,6 +265,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix)\n \t}\n }\n \n+/* the result should be freed by the caller. */\n+static char *get_submodule_displaypath(const char *path, const char *prefix)\n+{\n+\tconst char *super_prefix = get_super_prefix();\n+\treturn do_get_submodule_displaypath(path, prefix, super_prefix);\n+}\n+\n static char *compute_rev_name(const char *sub_path, const char* object_id)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n-- \n2.33.GIT\n\n"},{"id":"449831","messageId":"20220301000816.56177-9-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 08/13] submodule--helper run-update-procedure: learn --remote","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:11Z","receivedAt":"2022-03-01T00:08:50Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach run-update-procedure to handle --remote instead of parsing\n--remote in git-submodule.sh. As a result, \"git submodule--helper\nprint-default-remote\" has no more callers, so remove it.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 39 ++++++++++++++++++++++---------------\n git-submodule.sh            | 30 +---------------------------\n 2 files changed, 24 insertions(+), 45 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 5fbf8713db..1d4d9231ac 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -73,21 +73,6 @@ static char *get_default_remote(void)\n \treturn repo_get_default_remote(the_repository);\n }\n \n-static int print_default_remote(int argc, const char **argv, const char *prefix)\n-{\n-\tchar *remote;\n-\n-\tif (argc != 1)\n-\t\tdie(_(\"submodule--helper print-default-remote takes no arguments\"));\n-\n-\tremote = get_default_remote();\n-\tif (remote)\n-\t\tprintf(\"%s\\n\", remote);\n-\n-\tfree(remote);\n-\treturn 0;\n-}\n-\n static int starts_with_dot_slash(const char *str)\n {\n \treturn str[0] == '.' && is_dir_sep(str[1]);\n@@ -2028,6 +2013,7 @@ struct update_data {\n \tunsigned int quiet;\n \tunsigned int nofetch;\n \tunsigned int just_cloned;\n+\tunsigned int remote;\n };\n #define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }\n \n@@ -2604,6 +2590,8 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\tOPT_CALLBACK_F(0, \"oid\", &update_data.oid, N_(\"sha1\"),\n \t\t\t       N_(\"SHA1 expected by superproject\"), PARSE_OPT_NONEG,\n \t\t\t       parse_opt_object_id),\n+\t\tOPT_BOOL(0, \"remote\", &update_data.remote,\n+\t\t\t N_(\"use SHA-1 of submodule's remote tracking branch\")),\n \t\tOPT_END()\n \t};\n \n@@ -3034,6 +3022,25 @@ static int update_submodule2(struct update_data *update_data)\n \t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n \t\t\tupdate_data->displaypath);\n \n+\tif (update_data->remote) {\n+\t\tchar *remote_name = get_default_remote_submodule(update_data->sm_path);\n+\t\tconst char *branch = remote_submodule_branch(update_data->sm_path);\n+\t\tchar *remote_ref = xstrfmt(\"refs/remotes/%s/%s\", remote_name, branch);\n+\n+\t\tif (!update_data->nofetch) {\n+\t\t\tif (fetch_in_submodule(update_data->sm_path, update_data->depth,\n+\t\t\t\t\t      0, NULL))\n+\t\t\t\tdie(_(\"Unable to fetch in submodule path '%s'\"),\n+\t\t\t\t    update_data->sm_path);\n+\t\t}\n+\n+\t\tif (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))\n+\t\t\tdie(_(\"Unable to find %s revision in submodule path '%s'\"),\n+\t\t\t    remote_ref, update_data->sm_path);\n+\n+\t\tfree(remote_ref);\n+\t}\n+\n \tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n \t\treturn do_run_update_procedure(update_data);\n \n@@ -3432,10 +3439,10 @@ static struct cmd_struct commands[] = {\n \t{\"foreach\", module_foreach, SUPPORT_SUPER_PREFIX},\n \t{\"init\", module_init, SUPPORT_SUPER_PREFIX},\n \t{\"status\", module_status, SUPPORT_SUPER_PREFIX},\n-\t{\"print-default-remote\", print_default_remote, 0},\n \t{\"sync\", module_sync, SUPPORT_SUPER_PREFIX},\n \t{\"deinit\", module_deinit, 0},\n \t{\"summary\", module_summary, SUPPORT_SUPER_PREFIX},\n+\t/* NEEDSWORK: remote-branch is also obsolete */\n \t{\"remote-branch\", resolve_remote_submodule_branch, 0},\n \t{\"push-check\", push_check, 0},\n \t{\"absorb-git-dirs\", absorb_git_dirs, SUPPORT_SUPER_PREFIX},\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 458ce73ac6..23ebd90892 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -247,20 +247,6 @@ cmd_deinit()\n \tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- \"$@\"\n }\n \n-# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>]\n-# Because arguments are positional, use an empty string to omit <depth>\n-# but include <sha1>.\n-fetch_in_submodule () (\n-\tsanitize_submodule_env &&\n-\tcd \"$1\" &&\n-\tif test $# -eq 3\n-\tthen\n-\t\techo \"$3\" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+\"$2\"}\n-\telse\n-\t\tgit fetch ${GIT_QUIET:+--quiet} ${2:+\"$2\"}\n-\tfi\n-)\n-\n #\n # Update each submodule path to correct revision, using clone and checkout as needed\n #\n@@ -409,21 +395,6 @@ cmd_update()\n \t\t\tjust_cloned=\n \t\tfi\n \n-\t\tif test -n \"$remote\"\n-\t\tthen\n-\t\t\tbranch=$(git submodule--helper remote-branch \"$sm_path\")\n-\t\t\tif test -z \"$nofetch\"\n-\t\t\tthen\n-\t\t\t\t# Fetch remote before determining tracking $sha1\n-\t\t\t\tfetch_in_submodule \"$sm_path\" $depth ||\n-\t\t\t\tdie \"fatal: $(eval_gettext \"Unable to fetch in submodule path '\\$sm_path'\")\"\n-\t\t\tfi\n-\t\t\tremote_name=$(sanitize_submodule_env; cd \"$sm_path\" && git submodule--helper print-default-remote)\n-\t\t\tsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n-\t\t\t\tgit rev-parse --verify \"${remote_name}/${branch}\") ||\n-\t\t\tdie \"fatal: $(eval_gettext \"Unable to find current \\${remote_name}/\\${branch} revision in submodule path '\\$sm_path'\")\"\n-\t\tfi\n-\n \t\tout=$(git submodule--helper run-update-procedure \\\n \t\t\t  ${wt_prefix:+--prefix \"$wt_prefix\"} \\\n \t\t\t  ${GIT_QUIET:+--quiet} \\\n@@ -434,6 +405,7 @@ cmd_update()\n \t\t\t  ${update:+--update \"$update\"} \\\n \t\t\t  ${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t\t  ${sha1:+--oid \"$sha1\"} \\\n+\t\t\t  ${remote:+--remote} \\\n \t\t\t  \"--\" \\\n \t\t\t  \"$sm_path\")\n \n-- \n2.33.GIT\n\n"},{"id":"449832","messageId":"20220301000816.56177-11-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 10/13] submodule--helper: allow setting superprefix for init_submodule()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:13Z","receivedAt":"2022-03-01T00:08:53Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\nWe allow callers of the `init_submodule()` function to optionally\noverride the superprefix from the environment.\n\nWe need to enable this option because in our conversion of the update\ncommand that will follow, the '--init' option will be handled through\nthis API. We will need to change the superprefix at that time to ensure\nthe display paths show correctly in the output messages.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/submodule--helper.c | 10 +++++++---\n 1 file changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 3598069de5..c3760f511d 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -593,18 +593,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix)\n \n struct init_cb {\n \tconst char *prefix;\n+\tconst char *superprefix;\n \tunsigned int flags;\n };\n #define INIT_CB_INIT { 0 }\n \n static void init_submodule(const char *path, const char *prefix,\n-\t\t\t   unsigned int flags)\n+\t\t\t   const char *superprefix, unsigned int flags)\n {\n \tconst struct submodule *sub;\n \tstruct strbuf sb = STRBUF_INIT;\n \tchar *upd = NULL, *url = NULL, *displaypath;\n \n-\tdisplaypath = get_submodule_displaypath(path, prefix);\n+\t/* try superprefix from the environment, if it is not passed explicitly */\n+\tif (!superprefix)\n+\t\tsuperprefix = get_super_prefix();\n+\tdisplaypath = do_get_submodule_displaypath(path, prefix, superprefix);\n \n \tsub = submodule_from_path(the_repository, null_oid(), path);\n \n@@ -678,7 +682,7 @@ static void init_submodule(const char *path, const char *prefix,\n static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data)\n {\n \tstruct init_cb *info = cb_data;\n-\tinit_submodule(list_item->name, info->prefix, info->flags);\n+\tinit_submodule(list_item->name, info->prefix, info->superprefix, info->flags);\n }\n \n static int module_init(int argc, const char **argv, const char *prefix)\n-- \n2.33.GIT\n\n"},{"id":"449833","messageId":"20220301000816.56177-12-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 11/13] submodule--helper update-clone: learn --init","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:14Z","receivedAt":"2022-03-01T00:08:55Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach \"git submodule--helper update-clone\" the `--init` flag and remove\nthe corresponding shell code.\n\nWhen the `--init` flag is passed to the subcommand, we do not spawn a\nnew subprocess and call `submodule--helper init` on the submodule paths,\nbecause the Git machinery is not able to pick up the configuration\nchanges introduced by that init call. So we instead run the\n`init_submodule_cb()` callback over each submodule in the same process.\n\n[1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 26 ++++++++++++++++++++++++++\n git-submodule.sh            |  9 +++------\n 2 files changed, 29 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex c3760f511d..0fc07d35ae 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1999,6 +1999,7 @@ struct submodule_update_clone {\n \tint failed_clones_nr, failed_clones_alloc;\n \n \tint max_jobs;\n+\tunsigned int init;\n };\n #define SUBMODULE_UPDATE_CLONE_INIT { \\\n \t.list = MODULE_LIST_INIT, \\\n@@ -2508,6 +2509,8 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \tint ret;\n \n \tstruct option module_update_clone_options[] = {\n+\t\tOPT_BOOL(0, \"init\", &suc.init,\n+\t\t\t N_(\"initialize uninitialized submodules before update\")),\n \t\tOPT_STRING(0, \"prefix\", &prefix,\n \t\t\t   N_(\"path\"),\n \t\t\t   N_(\"path into the working tree\")),\n@@ -2566,6 +2569,29 @@ 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+\tif (suc.init) {\n+\t\tstruct module_list list = MODULE_LIST_INIT;\n+\t\tstruct init_cb info = INIT_CB_INIT;\n+\n+\t\tif (module_list_compute(argc, argv, suc.prefix,\n+\t\t\t\t\t&pathspec, &list) < 0)\n+\t\t\treturn 1;\n+\n+\t\t/*\n+\t\t * If there are no path args and submodule.active is set then,\n+\t\t * by default, only initialize 'active' modules.\n+\t\t */\n+\t\tif (!argc && git_config_get_value_multi(\"submodule.active\"))\n+\t\t\tmodule_list_active(&list);\n+\n+\t\tinfo.prefix = suc.prefix;\n+\t\tinfo.superprefix = suc.recursive_prefix;\n+\t\tif (suc.quiet)\n+\t\t\tinfo.flags |= OPT_QUIET;\n+\n+\t\tfor_each_listed_submodule(&list, init_submodule_cb, &info);\n+\t}\n+\n \tret = update_submodules(&suc);\n \tlist_objects_filter_release(&filter_options);\n \treturn ret;\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 23ebd90892..51be7c7f7e 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -361,14 +361,11 @@ cmd_update()\n \t\tusage\n \tfi\n \n-\tif test -n \"$init\"\n-\tthen\n-\t\tcmd_init \"--\" \"$@\" || return\n-\tfi\n-\n \t{\n-\tgit submodule--helper update-clone ${GIT_QUIET:+--quiet} \\\n+\tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper update-clone \\\n+\t\t${GIT_QUIET:+--quiet} \\\n \t\t${progress:+\"--progress\"} \\\n+\t\t${init:+--init} \\\n \t\t${wt_prefix:+--prefix \"$wt_prefix\"} \\\n \t\t${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t${update:+--update \"$update\"} \\\n-- \n2.33.GIT\n\n"},{"id":"449834","messageId":"20220301000816.56177-13-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 12/13] submodule update: add tests for --filter","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:15Z","receivedAt":"2022-03-01T00:08:57Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Test the \"--filter\" option to make sure we don't break it while\nrefactoring \"git submodule update\".\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n t/t7406-submodule-update.sh | 40 +++++++++++++++++++++++++++++++++++++\n 1 file changed, 40 insertions(+)\n\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 7764c1c3cb..86616bf8c7 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -1071,4 +1071,44 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s\n \t)\n '\n \n+test_expect_success 'submodule update adds superproject gitdir to older repos' '\n+\t(cd super &&\n+\t git -C submodule config --unset submodule.superprojectGitdir &&\n+\t git submodule update &&\n+\t test-tool path-utils relative_path \\\n+\t\t\"$(git rev-parse --absolute-git-dir)\" \\\n+\t\t\"$(git -C submodule rev-parse --absolute-git-dir)\" >expect &&\n+\t git -C submodule config submodule.superprojectGitdir >actual &&\n+\t test_cmp expect actual\n+\t)\n+'\n+\n+test_expect_success 'submodule update uses config.worktree if applicable' '\n+\t(cd super &&\n+\t git -C submodule config --unset submodule.superprojectGitDir &&\n+\t git -C submodule config extensions.worktreeConfig true &&\n+\t git submodule update &&\n+\t test-tool path-utils relative_path \\\n+\t\t\"$(git rev-parse --absolute-git-dir)\" \\\n+\t\t\"$(git -C submodule rev-parse --absolute-git-dir)\" >expect &&\n+\t git -C submodule config submodule.superprojectGitdir >actual &&\n+\t test_cmp expect actual &&\n+\n+\t test_file_not_empty \"$(git -C submodule rev-parse --absolute-git-dir)/config.worktree\"\n+\t)\n+'\n+\n+test_expect_success 'submodule update --filter requires --init' '\n+\ttest_must_fail git -C super submodule update --filter blob:none 2>err &&\n+\tgrep \"usage:\" err\n+'\n+\n+test_expect_success 'submodule update --filter sets partial clone settings' '\n+\ttest_when_finished \"rm -rf super-filter\" &&\n+\tgit clone cloned super-filter &&\n+\tgit -C super-filter submodule update --init --filter blob:none &&\n+\ttest_cmp_config -C super-filter/submodule true remote.origin.promisor &&\n+\ttest_cmp_config -C super-filter/submodule blob:none remote.origin.partialclonefilter\n+'\n+\n test_done\n-- \n2.33.GIT\n\n"},{"id":"449835","messageId":"20220301000816.56177-14-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH 13/13] submodule--helper update-clone: check for --filter and --init","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T00:08:16Z","receivedAt":"2022-03-01T00:09:13Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"\"git submodule update --filter\" also requires the \"--init\" option. Teach\nupdate-clone to do this usage check in C and remove the check from\ngit-submodule.sh.\n\nIn addition, change update-clone's usage string so that it teaches users\nabout \"git submodule update\" instead of \"git submodule--helper\nupdate-clone\" (the string is copied from git-submodule.sh). This should\nbe more helpful to users since they don't invoke update-clone directly.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\nSince we expect users to act upon the usage string, I've updated it to\nreflect \"git submodule update\" [1] (since that's what users actually\ninvoke), but I feel a bit iffy about not being able to use\nusage_with_options() (because the options and usage string are for\ndifferent commands).\n\nThis might indicate that this is work we should put off until the\nconversion to C is mostly complete, but on the other hand, the usage\nstring is still more helpful than it used to be because we never\npresented users with the options anyway.\n\n[1] It's not immediately obvious which command we prefer to show - some\nother commands use \"git submodule--helper\" and others use \"git\nsubmodule\".\n\n builtin/submodule--helper.c | 20 +++++++++++++++++++-\n git-submodule.sh            |  5 -----\n 2 files changed, 19 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 0fc07d35ae..ea88f39fb4 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2544,7 +2544,12 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \t};\n \n \tconst char *const git_submodule_helper_usage[] = {\n-\t\tN_(\"git submodule--helper update-clone [--prefix=<path>] [<path>...]\"),\n+\t\tN_(\"git submodule [--quiet] update\"\n+\t\t\"[--init [--filter=<filter-spec>]] [--remote]\"\n+\t\t\"[-N|--no-fetch] [-f|--force]\"\n+\t\t\"[--checkout|--merge|--rebase]\"\n+\t\t\"[--[no-]recommend-shallow] [--reference <repository>]\"\n+\t\t\"[--recursive] [--[no-]single-branch] [--] [<path>...]\"),\n \t\tNULL\n \t};\n \tsuc.prefix = prefix;\n@@ -2555,6 +2560,19 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \tmemset(&filter_options, 0, sizeof(filter_options));\n \targc = parse_options(argc, argv, prefix, module_update_clone_options,\n \t\t\t     git_submodule_helper_usage, 0);\n+\n+\tif (filter_options.choice && !suc.init) {\n+\t\t/*\n+\t\t * NEEDSWORK: Don't use usage_with_options() because the\n+\t\t * usage string is for \"git submodule update\", but the\n+\t\t * options are for \"git submodule--helper update-clone\".\n+\t\t *\n+\t\t * This will no longer be an issue when \"update-clone\"\n+\t\t * is replaced by \"git submodule--helper update\".\n+\t\t */\n+\t\tusage(git_submodule_helper_usage[0]);\n+\t}\n+\n \tsuc.filter_options = &filter_options;\n \n \tif (update)\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 51be7c7f7e..aa8bdfca9d 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -356,11 +356,6 @@ cmd_update()\n \t\tshift\n \tdone\n \n-\tif test -n \"$filter\" && test \"$init\" != \"1\"\n-\tthen\n-\t\tusage\n-\tfi\n-\n \t{\n \tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper update-clone \\\n \t\t${GIT_QUIET:+--quiet} \\\n-- \n2.33.GIT\n\n"},{"id":"449841","messageId":"kl6l35k2pijd.fsf@chooglen-macbookpro.roam.corp.google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"Re: [PATCH 00/13] submodule: convert parts of 'update' to C","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T01:29:10Z","receivedAt":"2022-03-01T01:29:18Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Glen Choo <chooglen@google.com> writes:\n\n> Original series: https://lore.kernel.org/git/20220210092833.55360-1-chooglen@google.com\n> (I've trimmed the cc list down to the 'most interested' parties)\n>\n> = Overview\n>\n> This is part 1 of 2 series that will supersede ar/submodule-update (as laid out\n> in [1]). This series prepares for the eventual conversion of \"git submodule\n> update\" to C by doing 'obvious' conversions first, and leaving more involved\n> conversions for later.\n>\n> Part 1 is a lot simpler than the original series in its entirety, and should\n> play better with topics that Junio identified:\n>\n> - This series is based off a later version of 'master' that already has\n>   'js/apply-partial-clone-filters-recursively' merged in [2].\n> - There is only one, trivial, conflict with 'es/superproject-aware-submodules'\n>   (both add tests to the end of t7406) [3].\n>\n> Most of these patches were originally from ar/submodule-update, but because of\n> the new organization, some commit messages have been amended to make more sense\n> in context. However, patches 12 and 13 are new - they were added to handle the\n> \"--filter\" option introduced by 'js/apply-partial-clone-filters-recursively'.\n>\n> Cc-ed Josh, who might be interested in \"--filter\" changes e.g. the new\n> tests.\n>\n> [1] https://lore.kernel.org/git/kl6lmtig40l4.fsf@chooglen-macbookpro.roam.corp.google.com\n> [2] This also fixes some trivial merge conflicts with 'master'.\n> [3] Part 2 has nontrival conflicts though. Offline, Emily mentioned that\n>     conflicts might go away in the next iteration of\n>     'es/superproject-aware-submodules', but if not, the next round of patches\n>     will probably be based on a merge of this series +\n>     'es/superproject-aware-submodules'.\n>\n> = Patch summary\n>\n> I'm not certain whether to keep patch 13, see the extra discussion in\n> the --- description for details.\n>\n> - Patch 1 adds extra tests to \"git submodule update\" to make sure we\n>   don't break anything\n> - Patch 2 removes dead code that used to be part of \"git submodule\n>   update\"\n> - Patch 3 prepares for later changes by introducing the C function that\n>   will hold most of the newly converted code\n> - Patch 4 moves run-update-procedure's --suboid option into C\n> - Patch 5 moves ensure-core-worktree into C\n> - Patches 6-8 move run-update-procedure's --remote option into C\n> - Patches 9-11 move \"git submodule update\"'s --init into C\n> - Patches 12-13 move \"git submodule update\"'s --filter option into C\n>\n> Atharva Raykar (3):\n>   submodule--helper: get remote names from any repository\n>   submodule--helper: refactor get_submodule_displaypath()\n>   submodule--helper: allow setting superprefix for init_submodule()\n>\n> Glen Choo (8):\n>   submodule--helper: remove update-module-mode\n>   submodule--helper: reorganize code for sh to C conversion\n>   submodule--helper run-update-procedure: remove --suboid\n>   submodule--helper: remove ensure-core-worktree\n>   submodule--helper run-update-procedure: learn --remote\n>   submodule--helper update-clone: learn --init\n>   submodule update: add tests for --filter\n>   submodule--helper update-clone: check for --filter and --init\n>\n> Ævar Arnfjörð Bjarmason (2):\n>   submodule tests: test for init and update failure output\n>   submodule--helper: don't use bitfield indirection for parse_options()\n>\n>  builtin/submodule--helper.c    | 230 ++++++++++++++++++++-------------\n>  git-submodule.sh               |  54 +-------\n>  t/t7406-submodule-update.sh    |  54 +++++++-\n>  t/t7408-submodule-reference.sh |  14 +-\n>  4 files changed, 211 insertions(+), 141 deletions(-)\n>\n>\n> base-commit: 715d08a9e51251ad8290b181b6ac3b9e1f9719d7\n> -- \n> 2.33.GIT\n\nUgh, this version doesn't compile (I rebased it onto 'master' and forgot\nto take into account ce14de03db (refs API: remove \"failure_errno\" from\nrefs_resolve_ref_unsafe(), 2022-01-26)).\n\nThis version is still reviewable, but I'll run this through CI again\nbefore I send out v2.\n"},{"id":"449845","messageId":"xmqqilsywfsj.fsf@gitster.g","threadId":"57488","inReplyTo":"20220301000816.56177-7-chooglen@google.com","subject":"Re: [PATCH 06/13] submodule--helper: get remote names from any repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-01T02:46:36Z","receivedAt":"2022-03-01T02:46:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Glen Choo <chooglen@google.com> writes:\n\n> +\tstruct ref_store *store = get_main_ref_store(repo);\n> +\tint ignore_errno;\n> +\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL,\n> +\t\t\t\t\t\t      NULL, &ignore_errno);\n\nGiven that 00/13 says this series is based on 715d08a9 (The eighth\nbatch, 2022-02-25), which includes 03bdcfcc (Merge branch\n'ab/no-errno-from-resolve-ref-unsafe', 2022-02-11), I think the\nabove two lines are result of incorrect rebasing or something.\n\nHave you compiled after you rebased?\n\nIt seems that after applying the band-aid below, t7406 seems to fail\nfor two of its tests, too, but if this were not even compiled, that\nis to be expected X-<.\n\n\n\n\n builtin/submodule--helper.c | 4 +---\n 1 file changed, 1 insertion(+), 3 deletions(-)\n\ndiff --git c/builtin/submodule--helper.c w/builtin/submodule--helper.c\nindex ea88f39fb4..21401ad99e 100644\n--- c/builtin/submodule--helper.c\n+++ w/builtin/submodule--helper.c\n@@ -36,9 +36,7 @@ static char *repo_get_default_remote(struct repository *repo)\n \tchar *dest = NULL, *ret;\n \tstruct strbuf sb = STRBUF_INIT;\n \tstruct ref_store *store = get_main_ref_store(repo);\n-\tint ignore_errno;\n-\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL,\n-\t\t\t\t\t\t      NULL, &ignore_errno);\n+\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL, NULL);\n \n \tif (!refname)\n \t\tdie(_(\"No such ref: %s\"), \"HEAD\");\n"},{"id":"449853","messageId":"kl6ly21unvqk.fsf@chooglen-macbookpro.roam.corp.google.com","threadId":"57488","inReplyTo":"xmqqilsywfsj.fsf@gitster.g","subject":"Re: [PATCH 06/13] submodule--helper: get remote names from any repository","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:26:59Z","receivedAt":"2022-03-01T04:27:59Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Glen Choo <chooglen@google.com> writes:\n>\n>> +\tstruct ref_store *store = get_main_ref_store(repo);\n>> +\tint ignore_errno;\n>> +\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL,\n>> +\t\t\t\t\t\t      NULL, &ignore_errno);\n>\n> Given that 00/13 says this series is based on 715d08a9 (The eighth\n> batch, 2022-02-25), which includes 03bdcfcc (Merge branch\n> 'ab/no-errno-from-resolve-ref-unsafe', 2022-02-11), I think the\n> above two lines are result of incorrect rebasing or something.\n>\n> Have you compiled after you rebased?\n\nIt turns out that I didn't.. I got complacent after doing this merge a\nfew times.\n\n> It seems that after applying the band-aid below, t7406 seems to fail\n> for two of its tests, too, but if this were not even compiled, that\n> is to be expected X-<.\n\nThis is an even sillier mistake.. patch 12 accidentally includes some\ntests from es/superproject-aware-submodules (probably a bad merge\nconflict resolution).\n\n>\n>\n>\n>  builtin/submodule--helper.c | 4 +---\n>  1 file changed, 1 insertion(+), 3 deletions(-)\n>\n> diff --git c/builtin/submodule--helper.c w/builtin/submodule--helper.c\n> index ea88f39fb4..21401ad99e 100644\n> --- c/builtin/submodule--helper.c\n> +++ w/builtin/submodule--helper.c\n> @@ -36,9 +36,7 @@ static char *repo_get_default_remote(struct repository *repo)\n>  \tchar *dest = NULL, *ret;\n>  \tstruct strbuf sb = STRBUF_INIT;\n>  \tstruct ref_store *store = get_main_ref_store(repo);\n> -\tint ignore_errno;\n> -\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL,\n> -\t\t\t\t\t\t      NULL, &ignore_errno);\n> +\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL, NULL);\n>  \n>  \tif (!refname)\n>  \t\tdie(_(\"No such ref: %s\"), \"HEAD\");\n"},{"id":"449854","messageId":"20220301044132.39474-1-chooglen@google.com","threadId":"57488","inReplyTo":"20220301000816.56177-1-chooglen@google.com","subject":"[PATCH v2 00/13] submodule: convert parts of 'update' to C","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:19Z","receivedAt":"2022-03-01T04:41:42Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Original series: https://lore.kernel.org/git/20220210092833.55360-1-chooglen@google.com\n(I've trimmed the cc list down to the 'most interested' parties)\n\n= Overview\n\nThis is part 1 of 2 series that will supersede ar/submodule-update (as laid out\nin [1]). This series prepares for the eventual conversion of \"git submodule\nupdate\" to C by doing 'obvious' conversions first, and leaving more involved\nconversions for later.\n\nPart 1 is a lot simpler than the original series in its entirety, and should\nplay better with topics that Junio identified:\n\n- This series is based off a later version of 'master' that already has\n  'js/apply-partial-clone-filters-recursively' merged in [2].\n- There is only one, trivial, conflict with 'es/superproject-aware-submodules'\n  (both add tests to the end of t7406) [3].\n\nMost of these patches were originally from ar/submodule-update, but because of\nthe new organization, some commit messages have been amended to make more sense\nin context. However, patches 12 and 13 are new - they were added to handle the\n\"--filter\" option introduced by 'js/apply-partial-clone-filters-recursively'.\n\nCc-ed Josh, who might be interested in \"--filter\" changes e.g. the new\ntests.\n\n[1] https://lore.kernel.org/git/kl6lmtig40l4.fsf@chooglen-macbookpro.roam.corp.google.com\n[2] This also fixes some trivial merge conflicts with 'master'.\n[3] Part 2 has nontrival conflicts though. Offline, Emily mentioned that\n    conflicts might go away in the next iteration of\n    'es/superproject-aware-submodules', but if not, the next round of patches\n    will probably be based on a merge of this series +\n    'es/superproject-aware-submodules'.\n\n= Patch summary\n\nI'm not certain whether to keep patch 13, see the extra discussion in\nthe --- description for details.\n\n- Patch 1 adds extra tests to \"git submodule update\" to make sure we\n  don't break anything\n- Patch 2 removes dead code that used to be part of \"git submodule\n  update\"\n- Patch 3 prepares for later changes by introducing the C function that\n  will hold most of the newly converted code\n- Patch 4 moves run-update-procedure's --suboid option into C\n- Patch 5 moves ensure-core-worktree into C\n- Patches 6-8 move run-update-procedure's --remote option into C\n- Patches 9-11 move \"git submodule update\"'s --init into C\n- Patches 12-13 move \"git submodule update\"'s --filter option into C\n\n= Changes\n\nSince v1:\n- Fix compilation error due to bad rebase\n- Remove accidentally included tests\n- Fix a NEEDSWORK (it was a leftover from ar/submodule-update)\n\nAtharva Raykar (3):\n  submodule--helper: get remote names from any repository\n  submodule--helper: refactor get_submodule_displaypath()\n  submodule--helper: allow setting superprefix for init_submodule()\n\nGlen Choo (8):\n  submodule--helper: remove update-module-mode\n  submodule--helper: reorganize code for sh to C conversion\n  submodule--helper run-update-procedure: remove --suboid\n  submodule--helper: remove ensure-core-worktree\n  submodule--helper run-update-procedure: learn --remote\n  submodule--helper update-clone: learn --init\n  submodule update: add tests for --filter\n  submodule--helper update-clone: check for --filter and --init\n\nÆvar Arnfjörð Bjarmason (2):\n  submodule tests: test for init and update failure output\n  submodule--helper: don't use bitfield indirection for parse_options()\n\n builtin/submodule--helper.c    | 246 +++++++++++++++++++--------------\n git-submodule.sh               |  54 +-------\n t/t7406-submodule-update.sh    |  27 +++-\n t/t7408-submodule-reference.sh |  14 +-\n 4 files changed, 182 insertions(+), 159 deletions(-)\n\nRange-diff against v1:\n 1:  6138f4682c =  1:  6138f4682c submodule tests: test for init and update failure output\n 2:  6c83c78819 =  2:  6c83c78819 submodule--helper: remove update-module-mode\n 3:  9524986096 =  3:  9524986096 submodule--helper: reorganize code for sh to C conversion\n 4:  f42f3de2b7 =  4:  f42f3de2b7 submodule--helper run-update-procedure: remove --suboid\n 5:  b0a0cae633 =  5:  b0a0cae633 submodule--helper: remove ensure-core-worktree\n 6:  976cfa6d24 !  6:  3bde7ccd61 submodule--helper: get remote names from any repository\n    @@ builtin/submodule--helper.c\n      \tstruct strbuf sb = STRBUF_INIT;\n     -\tconst char *refname = resolve_ref_unsafe(\"HEAD\", 0, NULL, NULL);\n     +\tstruct ref_store *store = get_main_ref_store(repo);\n    -+\tint ignore_errno;\n     +\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL,\n    -+\t\t\t\t\t\t      NULL, &ignore_errno);\n    ++\t\t\t\t\t\t      NULL);\n      \n      \tif (!refname)\n      \t\tdie(_(\"No such ref: %s\"), \"HEAD\");\n 7:  4a3c07aa4f =  7:  3b2caf7a35 submodule--helper: don't use bitfield indirection for parse_options()\n 8:  bbfc2278c5 !  8:  81e9da8d42 submodule--helper run-update-procedure: learn --remote\n    @@ Commit message\n     \n         Teach run-update-procedure to handle --remote instead of parsing\n         --remote in git-submodule.sh. As a result, \"git submodule--helper\n    -    print-default-remote\" has no more callers, so remove it.\n    +    [print-default-remote|remote-branch]\" have no more callers, so remove\n    +    them.\n     \n         Signed-off-by: Glen Choo <chooglen@google.com>\n     \n    @@ builtin/submodule--helper.c: static int run_update_procedure(int argc, const cha\n      \t\tOPT_END()\n      \t};\n      \n    +@@ builtin/submodule--helper.c: static const char *remote_submodule_branch(const char *path)\n    + \treturn branch;\n    + }\n    + \n    +-static int resolve_remote_submodule_branch(int argc, const char **argv,\n    +-\t\tconst char *prefix)\n    +-{\n    +-\tconst char *ret;\n    +-\tstruct strbuf sb = STRBUF_INIT;\n    +-\tif (argc != 2)\n    +-\t\tdie(\"submodule--helper remote-branch takes exactly one arguments, got %d\", argc);\n    +-\n    +-\tret = remote_submodule_branch(argv[1]);\n    +-\tif (!ret)\n    +-\t\tdie(\"submodule %s doesn't exist\", argv[1]);\n    +-\n    +-\tprintf(\"%s\", ret);\n    +-\tstrbuf_release(&sb);\n    +-\treturn 0;\n    +-}\n    +-\n    + static int push_check(int argc, const char **argv, const char *prefix)\n    + {\n    + \tstruct remote *remote;\n     @@ builtin/submodule--helper.c: static int update_submodule2(struct update_data *update_data)\n      \t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n      \t\t\tupdate_data->displaypath);\n    @@ builtin/submodule--helper.c: static struct cmd_struct commands[] = {\n      \t{\"sync\", module_sync, SUPPORT_SUPER_PREFIX},\n      \t{\"deinit\", module_deinit, 0},\n      \t{\"summary\", module_summary, SUPPORT_SUPER_PREFIX},\n    -+\t/* NEEDSWORK: remote-branch is also obsolete */\n    - \t{\"remote-branch\", resolve_remote_submodule_branch, 0},\n    +-\t{\"remote-branch\", resolve_remote_submodule_branch, 0},\n      \t{\"push-check\", push_check, 0},\n      \t{\"absorb-git-dirs\", absorb_git_dirs, SUPPORT_SUPER_PREFIX},\n    + \t{\"is-active\", is_active, 0},\n     \n      ## git-submodule.sh ##\n     @@ git-submodule.sh: cmd_deinit()\n 9:  765cd21505 =  9:  122da84ce4 submodule--helper: refactor get_submodule_displaypath()\n10:  0c5e922f32 = 10:  fd52d6a2c3 submodule--helper: allow setting superprefix for init_submodule()\n11:  287f36122a = 11:  9422c2ecac submodule--helper update-clone: learn --init\n12:  91cac6e236 ! 12:  0a3e93998d submodule update: add tests for --filter\n    @@ t/t7406-submodule-update.sh: test_expect_success 'submodule update --quiet passe\n      \t)\n      '\n      \n    -+test_expect_success 'submodule update adds superproject gitdir to older repos' '\n    -+\t(cd super &&\n    -+\t git -C submodule config --unset submodule.superprojectGitdir &&\n    -+\t git submodule update &&\n    -+\t test-tool path-utils relative_path \\\n    -+\t\t\"$(git rev-parse --absolute-git-dir)\" \\\n    -+\t\t\"$(git -C submodule rev-parse --absolute-git-dir)\" >expect &&\n    -+\t git -C submodule config submodule.superprojectGitdir >actual &&\n    -+\t test_cmp expect actual\n    -+\t)\n    -+'\n    -+\n    -+test_expect_success 'submodule update uses config.worktree if applicable' '\n    -+\t(cd super &&\n    -+\t git -C submodule config --unset submodule.superprojectGitDir &&\n    -+\t git -C submodule config extensions.worktreeConfig true &&\n    -+\t git submodule update &&\n    -+\t test-tool path-utils relative_path \\\n    -+\t\t\"$(git rev-parse --absolute-git-dir)\" \\\n    -+\t\t\"$(git -C submodule rev-parse --absolute-git-dir)\" >expect &&\n    -+\t git -C submodule config submodule.superprojectGitdir >actual &&\n    -+\t test_cmp expect actual &&\n    -+\n    -+\t test_file_not_empty \"$(git -C submodule rev-parse --absolute-git-dir)/config.worktree\"\n    -+\t)\n    -+'\n    -+\n     +test_expect_success 'submodule update --filter requires --init' '\n     +\ttest_must_fail git -C super submodule update --filter blob:none 2>err &&\n     +\tgrep \"usage:\" err\n13:  f637c23a48 = 13:  6e1ef27191 submodule--helper update-clone: check for --filter and --init\n\nbase-commit: 715d08a9e51251ad8290b181b6ac3b9e1f9719d7\n-- \n2.33.GIT\n\n"},{"id":"449855","messageId":"20220301044132.39474-2-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 01/13] submodule tests: test for init and update failure output","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:20Z","receivedAt":"2022-03-01T04:41:46Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nAmend some submodule tests to test for the failure output of \"git\nsubmodule [update|init]\". The lack of such tests hid a regression in\nan earlier version of a subsequent commit.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n t/t7406-submodule-update.sh    | 14 ++++++++++++--\n t/t7408-submodule-reference.sh | 14 +++++++++++++-\n 2 files changed, 25 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 11cccbb333..7764c1c3cb 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -205,8 +205,18 @@ test_expect_success 'submodule update should fail due to local changes' '\n \t (cd submodule &&\n \t  compare_head\n \t ) &&\n-\t test_must_fail git submodule update submodule\n-\t)\n+\t test_must_fail git submodule update submodule 2>../actual.raw\n+\t) &&\n+\tsed \"s/^> //\" >expect <<-\\EOF &&\n+\t> error: Your local changes to the following files would be overwritten by checkout:\n+\t> \tfile\n+\t> Please commit your changes or stash them before you switch branches.\n+\t> Aborting\n+\t> fatal: Unable to checkout OID in submodule path '\\''submodule'\\''\n+\tEOF\n+\tsed -e \"s/checkout $SQ[^$SQ]*$SQ/checkout OID/\" <actual.raw >actual &&\n+\ttest_cmp expect actual\n+\n '\n test_expect_success 'submodule update should throw away changes with --force ' '\n \t(cd super &&\ndiff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh\nindex a3892f494b..c3a4545510 100755\n--- a/t/t7408-submodule-reference.sh\n+++ b/t/t7408-submodule-reference.sh\n@@ -193,7 +193,19 @@ test_expect_success 'missing nested submodule alternate fails clone and submodul\n \t\tcd supersuper-clone &&\n \t\tcheck_that_two_of_three_alternates_are_used &&\n \t\t# update of the submodule fails\n-\t\ttest_must_fail git submodule update --init --recursive\n+\t\tcat >expect <<-\\EOF &&\n+\t\tfatal: submodule '\\''sub'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub'\\''. Retry scheduled\n+\t\tfatal: submodule '\\''sub-dissociate'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub-dissociate'\\''. Retry scheduled\n+\t\tfatal: submodule '\\''sub'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub'\\'' a second time, aborting\n+\t\tfatal: Failed to recurse into submodule path ...\n+\t\tEOF\n+\t\ttest_must_fail git submodule update --init --recursive 2>err &&\n+\t\tgrep -e fatal: -e ^Failed err >actual.raw &&\n+\t\tsed -e \"s/path $SQ[^$SQ]*$SQ/path .../\" <actual.raw >actual &&\n+\t\ttest_cmp expect actual\n \t)\n '\n \n-- \n2.33.GIT\n\n"},{"id":"449856","messageId":"20220301044132.39474-3-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 02/13] submodule--helper: remove update-module-mode","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:21Z","receivedAt":"2022-03-01T04:41:50Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"This is dead code - it has not been used since c51f8f94e5\n(submodule--helper: run update procedures from C, 2021-08-24).\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 24 ------------------------\n 1 file changed, 24 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex eeacefcc38..c11ee1ea2b 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1957,29 +1957,6 @@ static void determine_submodule_update_strategy(struct repository *r,\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@@ -3430,7 +3407,6 @@ static struct cmd_struct commands[] = {\n \t{\"name\", module_name, 0},\n \t{\"clone\", module_clone, 0},\n \t{\"add\", module_add, SUPPORT_SUPER_PREFIX},\n-\t{\"update-module-mode\", module_update_module_mode, 0},\n \t{\"update-clone\", update_clone, 0},\n \t{\"run-update-procedure\", run_update_procedure, 0},\n \t{\"ensure-core-worktree\", ensure_core_worktree, 0},\n-- \n2.33.GIT\n\n"},{"id":"449858","messageId":"20220301044132.39474-4-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 03/13] submodule--helper: reorganize code for sh to C conversion","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:22Z","receivedAt":"2022-03-01T04:42:01Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Introduce a function, update_submodule2(), that will implement the\nfunctionality of run-update-procedure and its surrounding shell code in\nsubmodule.sh. This name is temporary; it will replace update_submodule()\nwhen the sh to C conversion is complete.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 26 +++++++++++++++++++++-----\n 1 file changed, 21 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex c11ee1ea2b..1b67a3887c 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2452,6 +2452,16 @@ static int do_run_update_procedure(struct update_data *ud)\n \treturn run_update_command(ud, subforce);\n }\n \n+/*\n+ * NEEDSWORK: As we convert \"git submodule update\" to C,\n+ * update_submodule2() will invoke more and more functions, making it\n+ * difficult to preserve the function ordering without forward\n+ * declarations.\n+ *\n+ * When the conversion is complete, this forward declaration will be\n+ * unnecessary and should be removed.\n+ */\n+static int update_submodule2(struct update_data *update_data);\n static void update_submodule(struct update_clone_data *ucd)\n {\n \tfprintf(stdout, \"dummy %s %d\\t%s\\n\",\n@@ -2618,11 +2628,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t    &update_data.update_strategy);\n \n \tfree(prefixed_path);\n-\n-\tif (!oideq(&update_data.oid, &update_data.suboid) || update_data.force)\n-\t\treturn do_run_update_procedure(&update_data);\n-\n-\treturn 3;\n+\treturn update_submodule2(&update_data);\n }\n \n static int resolve_relative_path(int argc, const char **argv, const char *prefix)\n@@ -3022,6 +3028,16 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n \t\t\t\t    force, reflog, quiet, track, dry_run);\n \treturn 0;\n }\n+\n+/* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n+static int update_submodule2(struct update_data *update_data)\n+{\n+\tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n+\t\treturn do_run_update_procedure(update_data);\n+\n+\treturn 3;\n+}\n+\n struct add_data {\n \tconst char *prefix;\n \tconst char *branch;\n-- \n2.33.GIT\n\n"},{"id":"449857","messageId":"20220301044132.39474-5-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 04/13] submodule--helper run-update-procedure: remove --suboid","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:23Z","receivedAt":"2022-03-01T04:42:04Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach run-update-procedure to determine the oid of the submodule's HEAD\ninstead of doing it in git-subomdule.sh.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 9 ++++++---\n git-submodule.sh            | 8 +-------\n 2 files changed, 7 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 1b67a3887c..77ca4270f4 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2594,9 +2594,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\tOPT_CALLBACK_F(0, \"oid\", &update_data.oid, N_(\"sha1\"),\n \t\t\t       N_(\"SHA1 expected by superproject\"), PARSE_OPT_NONEG,\n \t\t\t       parse_opt_object_id),\n-\t\tOPT_CALLBACK_F(0, \"suboid\", &update_data.suboid, N_(\"subsha1\"),\n-\t\t\t       N_(\"SHA1 of submodule's HEAD\"), PARSE_OPT_NONEG,\n-\t\t\t       parse_opt_object_id),\n \t\tOPT_END()\n \t};\n \n@@ -3032,6 +3029,12 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n /* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n static int update_submodule2(struct update_data *update_data)\n {\n+\tif (update_data->just_cloned)\n+\t\toidcpy(&update_data->suboid, null_oid());\n+\telse if (resolve_gitlink_ref(update_data->sm_path, \"HEAD\", &update_data->suboid))\n+\t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n+\t\t\tupdate_data->displaypath);\n+\n \tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n \t\treturn do_run_update_procedure(update_data);\n \ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 87772ac891..32a09302ab 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -406,14 +406,9 @@ cmd_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\tif test $just_cloned -eq 0\n \t\tthen\n-\t\t\tsubsha1=\n-\t\telse\n \t\t\tjust_cloned=\n-\t\t\tsubsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n-\t\t\t\tgit rev-parse --verify HEAD) ||\n-\t\t\tdie \"fatal: $(eval_gettext \"Unable to find current revision in submodule path '\\$displaypath'\")\"\n \t\tfi\n \n \t\tif test -n \"$remote\"\n@@ -441,7 +436,6 @@ cmd_update()\n \t\t\t  ${update:+--update \"$update\"} \\\n \t\t\t  ${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t\t  ${sha1:+--oid \"$sha1\"} \\\n-\t\t\t  ${subsha1:+--suboid \"$subsha1\"} \\\n \t\t\t  \"--\" \\\n \t\t\t  \"$sm_path\")\n \n-- \n2.33.GIT\n\n"},{"id":"449859","messageId":"20220301044132.39474-6-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 05/13] submodule--helper: remove ensure-core-worktree","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:24Z","receivedAt":"2022-03-01T04:42:06Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Move the logic of \"git submodule--helper ensure-core-worktree\" into\nrun-update-procedure. Since the ensure-core-worktree command is\nobsolete, remove it.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 12 ++----------\n git-submodule.sh            |  2 --\n 2 files changed, 2 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 77ca4270f4..6b473fc0d2 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2771,17 +2771,11 @@ static int push_check(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int ensure_core_worktree(int argc, const char **argv, const char *prefix)\n+static void ensure_core_worktree(const char *path)\n {\n-\tconst char *path;\n \tconst char *cw;\n \tstruct repository subrepo;\n \n-\tif (argc != 2)\n-\t\tBUG(\"submodule--helper ensure-core-worktree <path>\");\n-\n-\tpath = argv[1];\n-\n \tif (repo_submodule_init(&subrepo, the_repository, path, null_oid()))\n \t\tdie(_(\"could not get a repository handle for submodule '%s'\"), path);\n \n@@ -2801,8 +2795,6 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)\n \t\tfree(abs_path);\n \t\tstrbuf_release(&sb);\n \t}\n-\n-\treturn 0;\n }\n \n static int absorb_git_dirs(int argc, const char **argv, const char *prefix)\n@@ -3029,6 +3021,7 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n /* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n static int update_submodule2(struct update_data *update_data)\n {\n+\tensure_core_worktree(update_data->sm_path);\n \tif (update_data->just_cloned)\n \t\toidcpy(&update_data->suboid, null_oid());\n \telse if (resolve_gitlink_ref(update_data->sm_path, \"HEAD\", &update_data->suboid))\n@@ -3428,7 +3421,6 @@ static struct cmd_struct commands[] = {\n \t{\"add\", module_add, SUPPORT_SUPER_PREFIX},\n \t{\"update-clone\", update_clone, 0},\n \t{\"run-update-procedure\", run_update_procedure, 0},\n-\t{\"ensure-core-worktree\", ensure_core_worktree, 0},\n \t{\"relative-path\", resolve_relative_path, 0},\n \t{\"resolve-relative-url-test\", resolve_relative_url_test, 0},\n \t{\"foreach\", module_foreach, SUPPORT_SUPER_PREFIX},\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 32a09302ab..458ce73ac6 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -402,8 +402,6 @@ cmd_update()\n \tdo\n \t\tdie_if_unmatched \"$quickabort\" \"$sha1\"\n \n-\t\tgit submodule--helper ensure-core-worktree \"$sm_path\" || exit 1\n-\n \t\tdisplaypath=$(git submodule--helper relative-path \"$prefix$sm_path\" \"$wt_prefix\")\n \n \t\tif test $just_cloned -eq 0\n-- \n2.33.GIT\n\n"},{"id":"449860","messageId":"20220301044132.39474-7-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 06/13] submodule--helper: get remote names from any repository","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:25Z","receivedAt":"2022-03-01T04:42:08Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\n`get_default_remote()` retrieves the name of a remote by resolving the\nrefs from of the current repository's ref store.\n\nThus in order to use it for retrieving the remote name of a submodule,\nwe have to start a new subprocess which runs from the submodule\ndirectory.\n\nLet's instead introduce a function called `repo_get_default_remote()`\nwhich takes any repository object and retrieves the remote accordingly.\n\n`get_default_remote()` is then defined as a call to\n`repo_get_default_remote()` with 'the_repository' passed to it.\n\nNow that we have `repo_get_default_remote()`, we no longer have to start\na subprocess that called `submodule--helper get-default-remote` from\nwithin the submodule directory.\n\nSo let's make a function called `get_default_remote_submodule()` which\ntakes a submodule path, and returns the default remote for that\nsubmodule, all within the same process.\n\nWe can now use this function to save an unnecessary subprocess spawn in\n`sync_submodule()`, and also in the next patch, which will require this\nfunctionality.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nHelped-by: Glen Choo <chooglen@google.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 38 ++++++++++++++++++++++---------------\n 1 file changed, 23 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 6b473fc0d2..a58df3e007 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -31,11 +31,13 @@\n typedef void (*each_submodule_fn)(const struct cache_entry *list_item,\n \t\t\t\t  void *cb_data);\n \n-static char *get_default_remote(void)\n+static char *repo_get_default_remote(struct repository *repo)\n {\n \tchar *dest = NULL, *ret;\n \tstruct strbuf sb = STRBUF_INIT;\n-\tconst char *refname = resolve_ref_unsafe(\"HEAD\", 0, NULL, NULL);\n+\tstruct ref_store *store = get_main_ref_store(repo);\n+\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL,\n+\t\t\t\t\t\t      NULL);\n \n \tif (!refname)\n \t\tdie(_(\"No such ref: %s\"), \"HEAD\");\n@@ -48,7 +50,7 @@ static char *get_default_remote(void)\n \t\tdie(_(\"Expecting a full ref name, got %s\"), refname);\n \n \tstrbuf_addf(&sb, \"branch.%s.remote\", refname);\n-\tif (git_config_get_string(sb.buf, &dest))\n+\tif (repo_config_get_string(repo, sb.buf, &dest))\n \t\tret = xstrdup(\"origin\");\n \telse\n \t\tret = dest;\n@@ -57,6 +59,19 @@ static char *get_default_remote(void)\n \treturn ret;\n }\n \n+static char *get_default_remote_submodule(const char *module_path)\n+{\n+\tstruct repository subrepo;\n+\n+\trepo_submodule_init(&subrepo, the_repository, module_path, null_oid());\n+\treturn repo_get_default_remote(&subrepo);\n+}\n+\n+static char *get_default_remote(void)\n+{\n+\treturn repo_get_default_remote(the_repository);\n+}\n+\n static int print_default_remote(int argc, const char **argv, const char *prefix)\n {\n \tchar *remote;\n@@ -1343,9 +1358,8 @@ static void sync_submodule(const char *path, const char *prefix,\n {\n \tconst struct submodule *sub;\n \tchar *remote_key = NULL;\n-\tchar *sub_origin_url, *super_config_url, *displaypath;\n+\tchar *sub_origin_url, *super_config_url, *displaypath, *default_remote;\n \tstruct strbuf sb = STRBUF_INIT;\n-\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tchar *sub_config_path = NULL;\n \n \tif (!is_submodule_active(the_repository, path))\n@@ -1384,21 +1398,15 @@ static void sync_submodule(const char *path, const char *prefix,\n \tif (!is_submodule_populated_gently(path, NULL))\n \t\tgoto cleanup;\n \n-\tprepare_submodule_repo_env(&cp.env_array);\n-\tcp.git_cmd = 1;\n-\tcp.dir = path;\n-\tstrvec_pushl(&cp.args, \"submodule--helper\",\n-\t\t     \"print-default-remote\", NULL);\n-\n \tstrbuf_reset(&sb);\n-\tif (capture_command(&cp, &sb, 0))\n+\tdefault_remote = get_default_remote_submodule(path);\n+\tif (!default_remote)\n \t\tdie(_(\"failed to get the default remote for submodule '%s'\"),\n \t\t      path);\n \n-\tstrbuf_strip_suffix(&sb, \"\\n\");\n-\tremote_key = xstrfmt(\"remote.%s.url\", sb.buf);\n+\tremote_key = xstrfmt(\"remote.%s.url\", default_remote);\n+\tfree(default_remote);\n \n-\tstrbuf_reset(&sb);\n \tsubmodule_to_gitdir(&sb, path);\n \tstrbuf_addstr(&sb, \"/config\");\n \n-- \n2.33.GIT\n\n"},{"id":"449861","messageId":"20220301044132.39474-8-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 07/13] submodule--helper: don't use bitfield indirection for parse_options()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:26Z","receivedAt":"2022-03-01T04:42:09Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nDo away with the indirection of local variables added in\nc51f8f94e5b (submodule--helper: run update procedures from C,\n2021-08-24).\n\nThese were only needed because in C you can't get a pointer to a\nsingle bit, so we were using intermediate variables instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 23 ++++++++++-------------\n 1 file changed, 10 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex a58df3e007..3a96c35b86 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2023,10 +2023,10 @@ struct update_data {\n \tstruct object_id suboid;\n \tstruct submodule_update_strategy update_strategy;\n \tint depth;\n-\tunsigned int force: 1;\n-\tunsigned int quiet: 1;\n-\tunsigned int nofetch: 1;\n-\tunsigned int just_cloned: 1;\n+\tunsigned int force;\n+\tunsigned int quiet;\n+\tunsigned int nofetch;\n+\tunsigned int just_cloned;\n };\n #define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }\n \n@@ -2578,16 +2578,17 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \n static int run_update_procedure(int argc, const char **argv, const char *prefix)\n {\n-\tint force = 0, quiet = 0, nofetch = 0, just_cloned = 0;\n \tchar *prefixed_path, *update = NULL;\n \tstruct update_data update_data = UPDATE_DATA_INIT;\n \n \tstruct option options[] = {\n-\t\tOPT__QUIET(&quiet, N_(\"suppress output for update by rebase or merge\")),\n-\t\tOPT__FORCE(&force, N_(\"force checkout updates\"), 0),\n-\t\tOPT_BOOL('N', \"no-fetch\", &nofetch,\n+\t\tOPT__QUIET(&update_data.quiet,\n+\t\t\t   N_(\"suppress output for update by rebase or merge\")),\n+\t\tOPT__FORCE(&update_data.force, N_(\"force checkout updates\"),\n+\t\t\t   0),\n+\t\tOPT_BOOL('N', \"no-fetch\", &update_data.nofetch,\n \t\t\t N_(\"don't fetch new objects from the remote site\")),\n-\t\tOPT_BOOL(0, \"just-cloned\", &just_cloned,\n+\t\tOPT_BOOL(0, \"just-cloned\", &update_data.just_cloned,\n \t\t\t N_(\"overrides update mode in case the repository is a fresh clone\")),\n \t\tOPT_INTEGER(0, \"depth\", &update_data.depth, N_(\"depth for shallow fetch\")),\n \t\tOPT_STRING(0, \"prefix\", &prefix,\n@@ -2615,10 +2616,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \tif (argc != 1)\n \t\tusage_with_options(usage, options);\n \n-\tupdate_data.force = !!force;\n-\tupdate_data.quiet = !!quiet;\n-\tupdate_data.nofetch = !!nofetch;\n-\tupdate_data.just_cloned = !!just_cloned;\n \tupdate_data.sm_path = argv[0];\n \n \tif (update_data.recursive_prefix)\n-- \n2.33.GIT\n\n"},{"id":"449862","messageId":"20220301044132.39474-9-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 08/13] submodule--helper run-update-procedure: learn --remote","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:27Z","receivedAt":"2022-03-01T04:42:13Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach run-update-procedure to handle --remote instead of parsing\n--remote in git-submodule.sh. As a result, \"git submodule--helper\n[print-default-remote|remote-branch]\" have no more callers, so remove\nthem.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 56 +++++++++++++++----------------------\n git-submodule.sh            | 30 +-------------------\n 2 files changed, 23 insertions(+), 63 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 3a96c35b86..99341fb343 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -72,21 +72,6 @@ static char *get_default_remote(void)\n \treturn repo_get_default_remote(the_repository);\n }\n \n-static int print_default_remote(int argc, const char **argv, const char *prefix)\n-{\n-\tchar *remote;\n-\n-\tif (argc != 1)\n-\t\tdie(_(\"submodule--helper print-default-remote takes no arguments\"));\n-\n-\tremote = get_default_remote();\n-\tif (remote)\n-\t\tprintf(\"%s\\n\", remote);\n-\n-\tfree(remote);\n-\treturn 0;\n-}\n-\n static int starts_with_dot_slash(const char *str)\n {\n \treturn str[0] == '.' && is_dir_sep(str[1]);\n@@ -2027,6 +2012,7 @@ struct update_data {\n \tunsigned int quiet;\n \tunsigned int nofetch;\n \tunsigned int just_cloned;\n+\tunsigned int remote;\n };\n #define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }\n \n@@ -2603,6 +2589,8 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\tOPT_CALLBACK_F(0, \"oid\", &update_data.oid, N_(\"sha1\"),\n \t\t\t       N_(\"SHA1 expected by superproject\"), PARSE_OPT_NONEG,\n \t\t\t       parse_opt_object_id),\n+\t\tOPT_BOOL(0, \"remote\", &update_data.remote,\n+\t\t\t N_(\"use SHA-1 of submodule's remote tracking branch\")),\n \t\tOPT_END()\n \t};\n \n@@ -2682,23 +2670,6 @@ static const char *remote_submodule_branch(const char *path)\n \treturn branch;\n }\n \n-static int resolve_remote_submodule_branch(int argc, const char **argv,\n-\t\tconst char *prefix)\n-{\n-\tconst char *ret;\n-\tstruct strbuf sb = STRBUF_INIT;\n-\tif (argc != 2)\n-\t\tdie(\"submodule--helper remote-branch takes exactly one arguments, got %d\", argc);\n-\n-\tret = remote_submodule_branch(argv[1]);\n-\tif (!ret)\n-\t\tdie(\"submodule %s doesn't exist\", argv[1]);\n-\n-\tprintf(\"%s\", ret);\n-\tstrbuf_release(&sb);\n-\treturn 0;\n-}\n-\n static int push_check(int argc, const char **argv, const char *prefix)\n {\n \tstruct remote *remote;\n@@ -3033,6 +3004,25 @@ static int update_submodule2(struct update_data *update_data)\n \t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n \t\t\tupdate_data->displaypath);\n \n+\tif (update_data->remote) {\n+\t\tchar *remote_name = get_default_remote_submodule(update_data->sm_path);\n+\t\tconst char *branch = remote_submodule_branch(update_data->sm_path);\n+\t\tchar *remote_ref = xstrfmt(\"refs/remotes/%s/%s\", remote_name, branch);\n+\n+\t\tif (!update_data->nofetch) {\n+\t\t\tif (fetch_in_submodule(update_data->sm_path, update_data->depth,\n+\t\t\t\t\t      0, NULL))\n+\t\t\t\tdie(_(\"Unable to fetch in submodule path '%s'\"),\n+\t\t\t\t    update_data->sm_path);\n+\t\t}\n+\n+\t\tif (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))\n+\t\t\tdie(_(\"Unable to find %s revision in submodule path '%s'\"),\n+\t\t\t    remote_ref, update_data->sm_path);\n+\n+\t\tfree(remote_ref);\n+\t}\n+\n \tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n \t\treturn do_run_update_procedure(update_data);\n \n@@ -3431,11 +3421,9 @@ static struct cmd_struct commands[] = {\n \t{\"foreach\", module_foreach, SUPPORT_SUPER_PREFIX},\n \t{\"init\", module_init, SUPPORT_SUPER_PREFIX},\n \t{\"status\", module_status, SUPPORT_SUPER_PREFIX},\n-\t{\"print-default-remote\", print_default_remote, 0},\n \t{\"sync\", module_sync, SUPPORT_SUPER_PREFIX},\n \t{\"deinit\", module_deinit, 0},\n \t{\"summary\", module_summary, SUPPORT_SUPER_PREFIX},\n-\t{\"remote-branch\", resolve_remote_submodule_branch, 0},\n \t{\"push-check\", push_check, 0},\n \t{\"absorb-git-dirs\", absorb_git_dirs, SUPPORT_SUPER_PREFIX},\n \t{\"is-active\", is_active, 0},\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 458ce73ac6..23ebd90892 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -247,20 +247,6 @@ cmd_deinit()\n \tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- \"$@\"\n }\n \n-# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>]\n-# Because arguments are positional, use an empty string to omit <depth>\n-# but include <sha1>.\n-fetch_in_submodule () (\n-\tsanitize_submodule_env &&\n-\tcd \"$1\" &&\n-\tif test $# -eq 3\n-\tthen\n-\t\techo \"$3\" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+\"$2\"}\n-\telse\n-\t\tgit fetch ${GIT_QUIET:+--quiet} ${2:+\"$2\"}\n-\tfi\n-)\n-\n #\n # Update each submodule path to correct revision, using clone and checkout as needed\n #\n@@ -409,21 +395,6 @@ cmd_update()\n \t\t\tjust_cloned=\n \t\tfi\n \n-\t\tif test -n \"$remote\"\n-\t\tthen\n-\t\t\tbranch=$(git submodule--helper remote-branch \"$sm_path\")\n-\t\t\tif test -z \"$nofetch\"\n-\t\t\tthen\n-\t\t\t\t# Fetch remote before determining tracking $sha1\n-\t\t\t\tfetch_in_submodule \"$sm_path\" $depth ||\n-\t\t\t\tdie \"fatal: $(eval_gettext \"Unable to fetch in submodule path '\\$sm_path'\")\"\n-\t\t\tfi\n-\t\t\tremote_name=$(sanitize_submodule_env; cd \"$sm_path\" && git submodule--helper print-default-remote)\n-\t\t\tsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n-\t\t\t\tgit rev-parse --verify \"${remote_name}/${branch}\") ||\n-\t\t\tdie \"fatal: $(eval_gettext \"Unable to find current \\${remote_name}/\\${branch} revision in submodule path '\\$sm_path'\")\"\n-\t\tfi\n-\n \t\tout=$(git submodule--helper run-update-procedure \\\n \t\t\t  ${wt_prefix:+--prefix \"$wt_prefix\"} \\\n \t\t\t  ${GIT_QUIET:+--quiet} \\\n@@ -434,6 +405,7 @@ cmd_update()\n \t\t\t  ${update:+--update \"$update\"} \\\n \t\t\t  ${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t\t  ${sha1:+--oid \"$sha1\"} \\\n+\t\t\t  ${remote:+--remote} \\\n \t\t\t  \"--\" \\\n \t\t\t  \"$sm_path\")\n \n-- \n2.33.GIT\n\n"},{"id":"449863","messageId":"20220301044132.39474-10-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 09/13] submodule--helper: refactor get_submodule_displaypath()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:28Z","receivedAt":"2022-03-01T04:42:17Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\nWe create a function called `do_get_submodule_displaypath()` that\ngenerates the display path required by several submodule functions, and\ntakes a custom superprefix parameter, instead of reading it from the\nenvironment.\n\nWe then redefine the existing `get_submodule_displaypath()` function\nas a call to this new function, where the superprefix is obtained from\nthe environment.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/submodule--helper.c | 12 ++++++++----\n 1 file changed, 8 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 99341fb343..11afdeea8a 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -247,11 +247,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr\n \treturn 0;\n }\n \n-/* the result should be freed by the caller. */\n-static char *get_submodule_displaypath(const char *path, const char *prefix)\n+static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix)\n {\n-\tconst char *super_prefix = get_super_prefix();\n-\n \tif (prefix && super_prefix) {\n \t\tBUG(\"cannot have prefix '%s' and superprefix '%s'\",\n \t\t    prefix, super_prefix);\n@@ -267,6 +264,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix)\n \t}\n }\n \n+/* the result should be freed by the caller. */\n+static char *get_submodule_displaypath(const char *path, const char *prefix)\n+{\n+\tconst char *super_prefix = get_super_prefix();\n+\treturn do_get_submodule_displaypath(path, prefix, super_prefix);\n+}\n+\n static char *compute_rev_name(const char *sub_path, const char* object_id)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n-- \n2.33.GIT\n\n"},{"id":"449864","messageId":"20220301044132.39474-11-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 10/13] submodule--helper: allow setting superprefix for init_submodule()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:29Z","receivedAt":"2022-03-01T04:42:17Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\nWe allow callers of the `init_submodule()` function to optionally\noverride the superprefix from the environment.\n\nWe need to enable this option because in our conversion of the update\ncommand that will follow, the '--init' option will be handled through\nthis API. We will need to change the superprefix at that time to ensure\nthe display paths show correctly in the output messages.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/submodule--helper.c | 10 +++++++---\n 1 file changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 11afdeea8a..052b247726 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -592,18 +592,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix)\n \n struct init_cb {\n \tconst char *prefix;\n+\tconst char *superprefix;\n \tunsigned int flags;\n };\n #define INIT_CB_INIT { 0 }\n \n static void init_submodule(const char *path, const char *prefix,\n-\t\t\t   unsigned int flags)\n+\t\t\t   const char *superprefix, unsigned int flags)\n {\n \tconst struct submodule *sub;\n \tstruct strbuf sb = STRBUF_INIT;\n \tchar *upd = NULL, *url = NULL, *displaypath;\n \n-\tdisplaypath = get_submodule_displaypath(path, prefix);\n+\t/* try superprefix from the environment, if it is not passed explicitly */\n+\tif (!superprefix)\n+\t\tsuperprefix = get_super_prefix();\n+\tdisplaypath = do_get_submodule_displaypath(path, prefix, superprefix);\n \n \tsub = submodule_from_path(the_repository, null_oid(), path);\n \n@@ -677,7 +681,7 @@ static void init_submodule(const char *path, const char *prefix,\n static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data)\n {\n \tstruct init_cb *info = cb_data;\n-\tinit_submodule(list_item->name, info->prefix, info->flags);\n+\tinit_submodule(list_item->name, info->prefix, info->superprefix, info->flags);\n }\n \n static int module_init(int argc, const char **argv, const char *prefix)\n-- \n2.33.GIT\n\n"},{"id":"449865","messageId":"20220301044132.39474-13-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 12/13] submodule update: add tests for --filter","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:31Z","receivedAt":"2022-03-01T04:42:22Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Test the \"--filter\" option to make sure we don't break anything while\nrefactoring \"git submodule update\".\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n t/t7406-submodule-update.sh | 13 +++++++++++++\n 1 file changed, 13 insertions(+)\n\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 7764c1c3cb..6cc60ff5e5 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -1071,4 +1071,17 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s\n \t)\n '\n \n+test_expect_success 'submodule update --filter requires --init' '\n+\ttest_must_fail git -C super submodule update --filter blob:none 2>err &&\n+\tgrep \"usage:\" err\n+'\n+\n+test_expect_success 'submodule update --filter sets partial clone settings' '\n+\ttest_when_finished \"rm -rf super-filter\" &&\n+\tgit clone cloned super-filter &&\n+\tgit -C super-filter submodule update --init --filter blob:none &&\n+\ttest_cmp_config -C super-filter/submodule true remote.origin.promisor &&\n+\ttest_cmp_config -C super-filter/submodule blob:none remote.origin.partialclonefilter\n+'\n+\n test_done\n-- \n2.33.GIT\n\n"},{"id":"449866","messageId":"20220301044132.39474-12-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 11/13] submodule--helper update-clone: learn --init","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:30Z","receivedAt":"2022-03-01T04:42:25Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach \"git submodule--helper update-clone\" the --init flag and remove\nthe corresponding shell code.\n\nWhen the `--init` flag is passed to the subcommand, we do not spawn a\nnew subprocess and call `submodule--helper init` on the submodule paths,\nbecause the Git machinery is not able to pick up the configuration\nchanges introduced by that init call. So we instead run the\n`init_submodule_cb()` callback over each submodule in the same process.\n\n[1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 26 ++++++++++++++++++++++++++\n git-submodule.sh            |  9 +++------\n 2 files changed, 29 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 052b247726..2ffc070319 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1998,6 +1998,7 @@ struct submodule_update_clone {\n \tint failed_clones_nr, failed_clones_alloc;\n \n \tint max_jobs;\n+\tunsigned int init;\n };\n #define SUBMODULE_UPDATE_CLONE_INIT { \\\n \t.list = MODULE_LIST_INIT, \\\n@@ -2507,6 +2508,8 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \tint ret;\n \n \tstruct option module_update_clone_options[] = {\n+\t\tOPT_BOOL(0, \"init\", &suc.init,\n+\t\t\t N_(\"initialize uninitialized submodules before update\")),\n \t\tOPT_STRING(0, \"prefix\", &prefix,\n \t\t\t   N_(\"path\"),\n \t\t\t   N_(\"path into the working tree\")),\n@@ -2565,6 +2568,29 @@ 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+\tif (suc.init) {\n+\t\tstruct module_list list = MODULE_LIST_INIT;\n+\t\tstruct init_cb info = INIT_CB_INIT;\n+\n+\t\tif (module_list_compute(argc, argv, suc.prefix,\n+\t\t\t\t\t&pathspec, &list) < 0)\n+\t\t\treturn 1;\n+\n+\t\t/*\n+\t\t * If there are no path args and submodule.active is set then,\n+\t\t * by default, only initialize 'active' modules.\n+\t\t */\n+\t\tif (!argc && git_config_get_value_multi(\"submodule.active\"))\n+\t\t\tmodule_list_active(&list);\n+\n+\t\tinfo.prefix = suc.prefix;\n+\t\tinfo.superprefix = suc.recursive_prefix;\n+\t\tif (suc.quiet)\n+\t\t\tinfo.flags |= OPT_QUIET;\n+\n+\t\tfor_each_listed_submodule(&list, init_submodule_cb, &info);\n+\t}\n+\n \tret = update_submodules(&suc);\n \tlist_objects_filter_release(&filter_options);\n \treturn ret;\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 23ebd90892..51be7c7f7e 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -361,14 +361,11 @@ cmd_update()\n \t\tusage\n \tfi\n \n-\tif test -n \"$init\"\n-\tthen\n-\t\tcmd_init \"--\" \"$@\" || return\n-\tfi\n-\n \t{\n-\tgit submodule--helper update-clone ${GIT_QUIET:+--quiet} \\\n+\tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper update-clone \\\n+\t\t${GIT_QUIET:+--quiet} \\\n \t\t${progress:+\"--progress\"} \\\n+\t\t${init:+--init} \\\n \t\t${wt_prefix:+--prefix \"$wt_prefix\"} \\\n \t\t${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t${update:+--update \"$update\"} \\\n-- \n2.33.GIT\n\n"},{"id":"449867","messageId":"20220301044132.39474-14-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v2 13/13] submodule--helper update-clone: check for --filter and --init","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T04:41:32Z","receivedAt":"2022-03-01T04:42:28Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"\"git submodule update --filter\" also requires the \"--init\" option. Teach\nupdate-clone to do this usage check in C and remove the check from\ngit-submodule.sh.\n\nIn addition, change update-clone's usage string so that it teaches users\nabout \"git submodule update\" instead of \"git submodule--helper\nupdate-clone\" (the string is copied from git-submodule.sh). This should\nbe more helpful to users since they don't invoke update-clone directly.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\nSince we expect users to act upon the usage string, I've updated it to\nreflect \"git submodule update\" [1] (since that's what users actually\ninvoke), but I feel a bit iffy about not being able to use\nusage_with_options() (because the options and usage string are for\ndifferent commands).\n\nThis might indicate that this is work we should put off until the\nconversion to C is mostly complete, but on the other hand, the usage\nstring is still more helpful than it used to be because we never\npresented users with the options anyway.\n\n[1] It's not immediately obvious which command we prefer to show - some\nother commands use \"git submodule--helper\" and others use \"git\nsubmodule\".\n\n builtin/submodule--helper.c | 20 +++++++++++++++++++-\n git-submodule.sh            |  5 -----\n 2 files changed, 19 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 2ffc070319..3e8a05a052 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2543,7 +2543,12 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \t};\n \n \tconst char *const git_submodule_helper_usage[] = {\n-\t\tN_(\"git submodule--helper update-clone [--prefix=<path>] [<path>...]\"),\n+\t\tN_(\"git submodule [--quiet] update\"\n+\t\t\"[--init [--filter=<filter-spec>]] [--remote]\"\n+\t\t\"[-N|--no-fetch] [-f|--force]\"\n+\t\t\"[--checkout|--merge|--rebase]\"\n+\t\t\"[--[no-]recommend-shallow] [--reference <repository>]\"\n+\t\t\"[--recursive] [--[no-]single-branch] [--] [<path>...]\"),\n \t\tNULL\n \t};\n \tsuc.prefix = prefix;\n@@ -2554,6 +2559,19 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \tmemset(&filter_options, 0, sizeof(filter_options));\n \targc = parse_options(argc, argv, prefix, module_update_clone_options,\n \t\t\t     git_submodule_helper_usage, 0);\n+\n+\tif (filter_options.choice && !suc.init) {\n+\t\t/*\n+\t\t * NEEDSWORK: Don't use usage_with_options() because the\n+\t\t * usage string is for \"git submodule update\", but the\n+\t\t * options are for \"git submodule--helper update-clone\".\n+\t\t *\n+\t\t * This will no longer be an issue when \"update-clone\"\n+\t\t * is replaced by \"git submodule--helper update\".\n+\t\t */\n+\t\tusage(git_submodule_helper_usage[0]);\n+\t}\n+\n \tsuc.filter_options = &filter_options;\n \n \tif (update)\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 51be7c7f7e..aa8bdfca9d 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -356,11 +356,6 @@ cmd_update()\n \t\tshift\n \tdone\n \n-\tif test -n \"$filter\" && test \"$init\" != \"1\"\n-\tthen\n-\t\tusage\n-\tfi\n-\n \t{\n \tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper update-clone \\\n \t\t${GIT_QUIET:+--quiet} \\\n-- \n2.33.GIT\n\n"},{"id":"449877","messageId":"220301.86o82q16ib.gmgdl@evledraar.gmail.com","threadId":"57488","inReplyTo":"20220301044132.39474-14-chooglen@google.com","subject":"Re: [PATCH v2 13/13] submodule--helper update-clone: check for --filter and --init","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-01T07:21:58Z","receivedAt":"2022-03-01T07:23:00Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, Feb 28 2022, Glen Choo wrote:\n\n> \"git submodule update --filter\" also requires the \"--init\" option. Teach\n> update-clone to do this usage check in C and remove the check from\n> git-submodule.sh.\n>\n> In addition, change update-clone's usage string so that it teaches users\n> about \"git submodule update\" instead of \"git submodule--helper\n> update-clone\" (the string is copied from git-submodule.sh). This should\n> be more helpful to users since they don't invoke update-clone directly.\n>\n> Signed-off-by: Glen Choo <chooglen@google.com>\n> ---\n> Since we expect users to act upon the usage string, I've updated it to\n> reflect \"git submodule update\" [1] (since that's what users actually\n> invoke), but I feel a bit iffy about not being able to use\n> usage_with_options() (because the options and usage string are for\n> different commands).\n>\n> This might indicate that this is work we should put off until the\n> conversion to C is mostly complete, but on the other hand, the usage\n> string is still more helpful than it used to be because we never\n> presented users with the options anyway.\n>\n> [1] It's not immediately obvious which command we prefer to show - some\n> other commands use \"git submodule--helper\" and others use \"git\n> submodule\".\n>\n>  builtin/submodule--helper.c | 20 +++++++++++++++++++-\n>  git-submodule.sh            |  5 -----\n>  2 files changed, 19 insertions(+), 6 deletions(-)\n>\n> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\n> index 2ffc070319..3e8a05a052 100644\n> --- a/builtin/submodule--helper.c\n> +++ b/builtin/submodule--helper.c\n> @@ -2543,7 +2543,12 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n>  \t};\n>  \n>  \tconst char *const git_submodule_helper_usage[] = {\n> -\t\tN_(\"git submodule--helper update-clone [--prefix=<path>] [<path>...]\"),\n> +\t\tN_(\"git submodule [--quiet] update\"\n> +\t\t\"[--init [--filter=<filter-spec>]] [--remote]\"\n> +\t\t\"[-N|--no-fetch] [-f|--force]\"\n> +\t\t\"[--checkout|--merge|--rebase]\"\n> +\t\t\"[--[no-]recommend-shallow] [--reference <repository>]\"\n> +\t\t\"[--recursive] [--[no-]single-branch] [--] [<path>...]\"),\n\nSince this has <repository>, <path> etc. it should still be marked for\ntranslation with N_().\n"},{"id":"449879","messageId":"xmqqbkyqt9b2.fsf@gitster.g","threadId":"57488","inReplyTo":"220301.86o82q16ib.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH v2 13/13] submodule--helper update-clone: check for --filter and --init","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-01T07:34:57Z","receivedAt":"2022-03-01T07:35:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n>> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\n>> index 2ffc070319..3e8a05a052 100644\n>> --- a/builtin/submodule--helper.c\n>> +++ b/builtin/submodule--helper.c\n>> @@ -2543,7 +2543,12 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n>>  \t};\n>>  \n>>  \tconst char *const git_submodule_helper_usage[] = {\n>> -\t\tN_(\"git submodule--helper update-clone [--prefix=<path>] [<path>...]\"),\n>> +\t\tN_(\"git submodule [--quiet] update\"\n>> +\t\t\"[--init [--filter=<filter-spec>]] [--remote]\"\n>> +\t\t\"[-N|--no-fetch] [-f|--force]\"\n>> +\t\t\"[--checkout|--merge|--rebase]\"\n>> +\t\t\"[--[no-]recommend-shallow] [--reference <repository>]\"\n>> +\t\t\"[--recursive] [--[no-]single-branch] [--] [<path>...]\"),\n>\n> Since this has <repository>, <path> etc. it should still be marked for\n> translation with N_().\n\nYeah, that sounds like a good idea.  Isn't it already inside N_()?\n"},{"id":"449880","messageId":"220301.86k0de14mf.gmgdl@evledraar.gmail.com","threadId":"57488","inReplyTo":"20220301044132.39474-7-chooglen@google.com","subject":"Re: [PATCH v2 06/13] submodule--helper: get remote names from any repository","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-01T08:01:28Z","receivedAt":"2022-03-01T08:03:43Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, Feb 28 2022, Glen Choo wrote:\n\n> From: Atharva Raykar <raykar.ath@gmail.com>\n> [...]\n> We can now use this function to save an unnecessary subprocess spawn in\n> `sync_submodule()`, and also in the next patch, which will require this\n> functionality.\n\nThe \"next patch\" is now an intermediate cleanup, so narrowly: s/next/a\nsubsequent commit/ or similar.\n"},{"id":"449881","messageId":"220301.86fso214i0.gmgdl@evledraar.gmail.com","threadId":"57488","inReplyTo":"20220301044132.39474-10-chooglen@google.com","subject":"Re: [PATCH v2 09/13] submodule--helper: refactor get_submodule_displaypath()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-01T08:05:05Z","receivedAt":"2022-03-01T08:06:22Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, Feb 28 2022, Glen Choo wrote:\n\n> From: Atharva Raykar <raykar.ath@gmail.com>\n>\n> We create a function called `do_get_submodule_displaypath()` that\n> generates the display path required by several submodule functions, and\n> takes a custom superprefix parameter, instead of reading it from the\n> environment.\n>\n> We then redefine the existing `get_submodule_displaypath()` function\n> as a call to this new function, where the superprefix is obtained from\n> the environment.\n>\n> Mentored-by: Christian Couder <christian.couder@gmail.com>\n> Mentored-by: Shourya Shukla <periperidip@gmail.com>\n> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  builtin/submodule--helper.c | 12 ++++++++----\n>  1 file changed, 8 insertions(+), 4 deletions(-)\n>\n> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\n> index 99341fb343..11afdeea8a 100644\n> --- a/builtin/submodule--helper.c\n> +++ b/builtin/submodule--helper.c\n> @@ -247,11 +247,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr\n>  \treturn 0;\n>  }\n>  \n> -/* the result should be freed by the caller. */\n\nnit: I think it's better to retain this comment here...\n\n> -static char *get_submodule_displaypath(const char *path, const char *prefix)\n> +static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix)\n>  {\n> -\tconst char *super_prefix = get_super_prefix();\n> -\n>  \tif (prefix && super_prefix) {\n>  \t\tBUG(\"cannot have prefix '%s' and superprefix '%s'\",\n>  \t\t    prefix, super_prefix);\n> @@ -267,6 +264,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix)\n>  \t}\n>  }\n>  \n> +/* the result should be freed by the caller. */\n\n..than have it here, where we don't do the xstrfmt() but just call this wrapper.:\n\n> +static char *get_submodule_displaypath(const char *path, const char *prefix)\n> +{\n> +\tconst char *super_prefix = get_super_prefix();\n> +\treturn do_get_submodule_displaypath(path, prefix, super_prefix);\n> +}\n> +\n>  static char *compute_rev_name(const char *sub_path, const char* object_id)\n>  {\n>  \tstruct strbuf sb = STRBUF_INIT;\n\n"},{"id":"449882","messageId":"220301.86bkyq14e9.gmgdl@evledraar.gmail.com","threadId":"57488","inReplyTo":"20220301044132.39474-13-chooglen@google.com","subject":"Re: [PATCH v2 12/13] submodule update: add tests for --filter","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-01T08:07:34Z","receivedAt":"2022-03-01T08:08:36Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, Feb 28 2022, Glen Choo wrote:\n\n> Test the \"--filter\" option to make sure we don't break anything while\n> refactoring \"git submodule update\".\n>\n> Signed-off-by: Glen Choo <chooglen@google.com>\n> ---\n>  t/t7406-submodule-update.sh | 13 +++++++++++++\n>  1 file changed, 13 insertions(+)\n>\n> diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\n> index 7764c1c3cb..6cc60ff5e5 100755\n> --- a/t/t7406-submodule-update.sh\n> +++ b/t/t7406-submodule-update.sh\n> @@ -1071,4 +1071,17 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s\n>  \t)\n>  '\n>  \n> +test_expect_success 'submodule update --filter requires --init' '\n> +\ttest_must_fail git -C super submodule update --filter blob:none 2>err &&\n\nShould be \"test_expect_code 129\" (presumably, or is it 128). In any case\nother similar \"usage\" test check for that:\n\n> +\tgrep \"usage:\" err\n\nWe could retain this then, but FWIW if it's 129 other tests consider it\nredundant.\n"},{"id":"449952","messageId":"kl6lo82pedan.fsf@chooglen-macbookpro.roam.corp.google.com","threadId":"57488","inReplyTo":"220301.86bkyq14e9.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH v2 12/13] submodule update: add tests for --filter","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T18:30:08Z","receivedAt":"2022-03-01T18:30:16Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> On Mon, Feb 28 2022, Glen Choo wrote:\n>\n>> Test the \"--filter\" option to make sure we don't break anything while\n>> refactoring \"git submodule update\".\n>>\n>> Signed-off-by: Glen Choo <chooglen@google.com>\n>> ---\n>>  t/t7406-submodule-update.sh | 13 +++++++++++++\n>>  1 file changed, 13 insertions(+)\n>>\n>> diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\n>> index 7764c1c3cb..6cc60ff5e5 100755\n>> --- a/t/t7406-submodule-update.sh\n>> +++ b/t/t7406-submodule-update.sh\n>> @@ -1071,4 +1071,17 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s\n>>  \t)\n>>  '\n>>  \n>> +test_expect_success 'submodule update --filter requires --init' '\n>> +\ttest_must_fail git -C super submodule update --filter blob:none 2>err &&\n>\n> Should be \"test_expect_code 129\" (presumably, or is it 128). In any case\n> other similar \"usage\" test check for that:\n>\n>> +\tgrep \"usage:\" err\n>\n> We could retain this then, but FWIW if it's 129 other tests consider it\n> redundant.\n\nAh, thanks for the tip. I forgot that this is how we check for usage.\n"},{"id":"449954","messageId":"kl6llexted2t.fsf@chooglen-macbookpro.roam.corp.google.com","threadId":"57488","inReplyTo":"xmqqbkyqt9b2.fsf@gitster.g","subject":"Re: [PATCH v2 13/13] submodule--helper update-clone: check for --filter and --init","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-01T18:34:50Z","receivedAt":"2022-03-01T18:34:54Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n>\n>>> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\n>>> index 2ffc070319..3e8a05a052 100644\n>>> --- a/builtin/submodule--helper.c\n>>> +++ b/builtin/submodule--helper.c\n>>> @@ -2543,7 +2543,12 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n>>>  \t};\n>>>  \n>>>  \tconst char *const git_submodule_helper_usage[] = {\n>>> -\t\tN_(\"git submodule--helper update-clone [--prefix=<path>] [<path>...]\"),\n>>> +\t\tN_(\"git submodule [--quiet] update\"\n>>> +\t\t\"[--init [--filter=<filter-spec>]] [--remote]\"\n>>> +\t\t\"[-N|--no-fetch] [-f|--force]\"\n>>> +\t\t\"[--checkout|--merge|--rebase]\"\n>>> +\t\t\"[--[no-]recommend-shallow] [--reference <repository>]\"\n>>> +\t\t\"[--recursive] [--[no-]single-branch] [--] [<path>...]\"),\n>>\n>> Since this has <repository>, <path> etc. it should still be marked for\n>> translation with N_().\n>\n> Yeah, that sounds like a good idea.  Isn't it already inside N_()?\n\nDid I do this correctly? e.g. an alternative interpretation is that Ævar\nmisread this as:\n\n  \tconst char *const git_submodule_helper_usage[] = {\n      N_(\"git submodule [--quiet] update\"),\n      \"[--init [--filter=<filter-spec>]] [--remote]\",\n      \"[-N|--no-fetch] [-f|--force]\",\n      \"[--checkout|--merge|--rebase]\",\n      \"[--[no-]recommend-shallow] [--reference <repository>]\",\n      \"[--recursive] [--[no-]single-branch] [--] [<path>...]\",\n"},{"id":"450223","messageId":"20220303005727.69270-1-chooglen@google.com","threadId":"57488","inReplyTo":"20220301044132.39474-1-chooglen@google.com","subject":"[PATCH v3 00/13] submodule: convert parts of 'update' to C","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:14Z","receivedAt":"2022-03-03T00:57:45Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Original series: https://lore.kernel.org/git/20220210092833.55360-1-chooglen@google.com\n(I've trimmed the cc list down to the 'most interested' parties)\n\nThanks for the input, Ævar :) This just fixes up a few small issues in\nthe previous version.\n\n= Patch summary\n\n- Patch 1 adds extra tests to \"git submodule update\" to make sure we\n  don't break anything\n- Patch 2 removes dead code that used to be part of \"git submodule\n  update\"\n- Patch 3 prepares for later changes by introducing the C function that\n  will hold most of the newly converted code\n- Patch 4 moves run-update-procedure's --suboid option into C\n- Patch 5 moves ensure-core-worktree into C\n- Patches 6-8 move run-update-procedure's --remote option into C\n- Patches 9-11 move \"git submodule update\"'s --init into C\n- Patches 12-13 move \"git submodule update\"'s --filter option into C\n\n= Changes\n\nSince v2:\n- Patch 6: Fix a stale commit message that said 'in the next patch'.\n- Patch 9: Fix an overly long line (spotted by Ævar in an older iteration of\n  ar/submodule-update)\n- Patch 12: Test for usage using test_expect_code\n- Patch 13: Add missing spaces to the usage string\n\nSince v1:\n- Fix compilation error due to bad rebase\n- Remove accidentally included tests\n- Fix a NEEDSWORK (it was a leftover from ar/submodule-update)\n\nAtharva Raykar (3):\n  submodule--helper: get remote names from any repository\n  submodule--helper: refactor get_submodule_displaypath()\n  submodule--helper: allow setting superprefix for init_submodule()\n\nGlen Choo (8):\n  submodule--helper: remove update-module-mode\n  submodule--helper: reorganize code for sh to C conversion\n  submodule--helper run-update-procedure: remove --suboid\n  submodule--helper: remove ensure-core-worktree\n  submodule--helper run-update-procedure: learn --remote\n  submodule--helper update-clone: learn --init\n  submodule update: add tests for --filter\n  submodule--helper update-clone: check for --filter and --init\n\nÆvar Arnfjörð Bjarmason (2):\n  submodule tests: test for init and update failure output\n  submodule--helper: don't use bitfield indirection for parse_options()\n\n builtin/submodule--helper.c    | 248 +++++++++++++++++++--------------\n git-submodule.sh               |  54 +------\n t/t7406-submodule-update.sh    |  26 +++-\n t/t7408-submodule-reference.sh |  14 +-\n 4 files changed, 183 insertions(+), 159 deletions(-)\n\nRange-diff against v2:\n 1:  6138f4682c =  1:  6138f4682c submodule tests: test for init and update failure output\n 2:  6c83c78819 =  2:  6c83c78819 submodule--helper: remove update-module-mode\n 3:  9524986096 =  3:  9524986096 submodule--helper: reorganize code for sh to C conversion\n 4:  f42f3de2b7 =  4:  f42f3de2b7 submodule--helper run-update-procedure: remove --suboid\n 5:  b0a0cae633 =  5:  b0a0cae633 submodule--helper: remove ensure-core-worktree\n 6:  3bde7ccd61 !  6:  8dc7bc5894 submodule--helper: get remote names from any repository\n    @@ Commit message\n         submodule, all within the same process.\n     \n         We can now use this function to save an unnecessary subprocess spawn in\n    -    `sync_submodule()`, and also in the next patch, which will require this\n    -    functionality.\n    +    `sync_submodule()`, and also in a subsequent patch, which will require\n    +    this functionality.\n     \n         Mentored-by: Christian Couder <christian.couder@gmail.com>\n         Mentored-by: Shourya Shukla <periperidip@gmail.com>\n 7:  3b2caf7a35 =  7:  feaf9f45d8 submodule--helper: don't use bitfield indirection for parse_options()\n 8:  81e9da8d42 =  8:  91e8e1a007 submodule--helper run-update-procedure: learn --remote\n 9:  122da84ce4 !  9:  aba851e71e submodule--helper: refactor get_submodule_displaypath()\n    @@ builtin/submodule--helper.c: static int resolve_relative_url_test(int argc, cons\n      \n     -/* the result should be freed by the caller. */\n     -static char *get_submodule_displaypath(const char *path, const char *prefix)\n    -+static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix)\n    ++static char *do_get_submodule_displaypath(const char *path,\n    ++\t\t\t\t\t  const char *prefix,\n    ++\t\t\t\t\t  const char *super_prefix)\n      {\n     -\tconst char *super_prefix = get_super_prefix();\n     -\n10:  fd52d6a2c3 = 10:  2155c049a2 submodule--helper: allow setting superprefix for init_submodule()\n11:  9422c2ecac = 11:  03bbc39a06 submodule--helper update-clone: learn --init\n12:  0a3e93998d ! 12:  e49b26ad94 submodule update: add tests for --filter\n    @@ t/t7406-submodule-update.sh: test_expect_success 'submodule update --quiet passe\n      '\n      \n     +test_expect_success 'submodule update --filter requires --init' '\n    -+\ttest_must_fail git -C super submodule update --filter blob:none 2>err &&\n    -+\tgrep \"usage:\" err\n    ++\ttest_expect_code 129 git -C super submodule update --filter blob:none\n     +'\n     +\n     +test_expect_success 'submodule update --filter sets partial clone settings' '\n13:  6e1ef27191 ! 13:  c97c97948a submodule--helper update-clone: check for --filter and --init\n    @@ builtin/submodule--helper.c: static int update_clone(int argc, const char **argv\n      \tconst char *const git_submodule_helper_usage[] = {\n     -\t\tN_(\"git submodule--helper update-clone [--prefix=<path>] [<path>...]\"),\n     +\t\tN_(\"git submodule [--quiet] update\"\n    -+\t\t\"[--init [--filter=<filter-spec>]] [--remote]\"\n    -+\t\t\"[-N|--no-fetch] [-f|--force]\"\n    -+\t\t\"[--checkout|--merge|--rebase]\"\n    -+\t\t\"[--[no-]recommend-shallow] [--reference <repository>]\"\n    -+\t\t\"[--recursive] [--[no-]single-branch] [--] [<path>...]\"),\n    ++\t\t\" [--init [--filter=<filter-spec>]] [--remote]\"\n    ++\t\t\" [-N|--no-fetch] [-f|--force]\"\n    ++\t\t\" [--checkout|--merge|--rebase]\"\n    ++\t\t\" [--[no-]recommend-shallow] [--reference <repository>]\"\n    ++\t\t\" [--recursive] [--[no-]single-branch] [--] [<path>...]\"),\n      \t\tNULL\n      \t};\n      \tsuc.prefix = prefix;\n\nbase-commit: 715d08a9e51251ad8290b181b6ac3b9e1f9719d7\n-- \n2.33.GIT\n\n"},{"id":"450224","messageId":"20220303005727.69270-2-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 01/13] submodule tests: test for init and update failure output","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:15Z","receivedAt":"2022-03-03T00:57:50Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nAmend some submodule tests to test for the failure output of \"git\nsubmodule [update|init]\". The lack of such tests hid a regression in\nan earlier version of a subsequent commit.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n t/t7406-submodule-update.sh    | 14 ++++++++++++--\n t/t7408-submodule-reference.sh | 14 +++++++++++++-\n 2 files changed, 25 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 11cccbb333..7764c1c3cb 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -205,8 +205,18 @@ test_expect_success 'submodule update should fail due to local changes' '\n \t (cd submodule &&\n \t  compare_head\n \t ) &&\n-\t test_must_fail git submodule update submodule\n-\t)\n+\t test_must_fail git submodule update submodule 2>../actual.raw\n+\t) &&\n+\tsed \"s/^> //\" >expect <<-\\EOF &&\n+\t> error: Your local changes to the following files would be overwritten by checkout:\n+\t> \tfile\n+\t> Please commit your changes or stash them before you switch branches.\n+\t> Aborting\n+\t> fatal: Unable to checkout OID in submodule path '\\''submodule'\\''\n+\tEOF\n+\tsed -e \"s/checkout $SQ[^$SQ]*$SQ/checkout OID/\" <actual.raw >actual &&\n+\ttest_cmp expect actual\n+\n '\n test_expect_success 'submodule update should throw away changes with --force ' '\n \t(cd super &&\ndiff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh\nindex a3892f494b..c3a4545510 100755\n--- a/t/t7408-submodule-reference.sh\n+++ b/t/t7408-submodule-reference.sh\n@@ -193,7 +193,19 @@ test_expect_success 'missing nested submodule alternate fails clone and submodul\n \t\tcd supersuper-clone &&\n \t\tcheck_that_two_of_three_alternates_are_used &&\n \t\t# update of the submodule fails\n-\t\ttest_must_fail git submodule update --init --recursive\n+\t\tcat >expect <<-\\EOF &&\n+\t\tfatal: submodule '\\''sub'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub'\\''. Retry scheduled\n+\t\tfatal: submodule '\\''sub-dissociate'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub-dissociate'\\''. Retry scheduled\n+\t\tfatal: submodule '\\''sub'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub'\\'' a second time, aborting\n+\t\tfatal: Failed to recurse into submodule path ...\n+\t\tEOF\n+\t\ttest_must_fail git submodule update --init --recursive 2>err &&\n+\t\tgrep -e fatal: -e ^Failed err >actual.raw &&\n+\t\tsed -e \"s/path $SQ[^$SQ]*$SQ/path .../\" <actual.raw >actual &&\n+\t\ttest_cmp expect actual\n \t)\n '\n \n-- \n2.33.GIT\n\n"},{"id":"450225","messageId":"20220303005727.69270-4-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 03/13] submodule--helper: reorganize code for sh to C conversion","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:17Z","receivedAt":"2022-03-03T00:57:52Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Introduce a function, update_submodule2(), that will implement the\nfunctionality of run-update-procedure and its surrounding shell code in\nsubmodule.sh. This name is temporary; it will replace update_submodule()\nwhen the sh to C conversion is complete.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 26 +++++++++++++++++++++-----\n 1 file changed, 21 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex c11ee1ea2b..1b67a3887c 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2452,6 +2452,16 @@ static int do_run_update_procedure(struct update_data *ud)\n \treturn run_update_command(ud, subforce);\n }\n \n+/*\n+ * NEEDSWORK: As we convert \"git submodule update\" to C,\n+ * update_submodule2() will invoke more and more functions, making it\n+ * difficult to preserve the function ordering without forward\n+ * declarations.\n+ *\n+ * When the conversion is complete, this forward declaration will be\n+ * unnecessary and should be removed.\n+ */\n+static int update_submodule2(struct update_data *update_data);\n static void update_submodule(struct update_clone_data *ucd)\n {\n \tfprintf(stdout, \"dummy %s %d\\t%s\\n\",\n@@ -2618,11 +2628,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t    &update_data.update_strategy);\n \n \tfree(prefixed_path);\n-\n-\tif (!oideq(&update_data.oid, &update_data.suboid) || update_data.force)\n-\t\treturn do_run_update_procedure(&update_data);\n-\n-\treturn 3;\n+\treturn update_submodule2(&update_data);\n }\n \n static int resolve_relative_path(int argc, const char **argv, const char *prefix)\n@@ -3022,6 +3028,16 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n \t\t\t\t    force, reflog, quiet, track, dry_run);\n \treturn 0;\n }\n+\n+/* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n+static int update_submodule2(struct update_data *update_data)\n+{\n+\tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n+\t\treturn do_run_update_procedure(update_data);\n+\n+\treturn 3;\n+}\n+\n struct add_data {\n \tconst char *prefix;\n \tconst char *branch;\n-- \n2.33.GIT\n\n"},{"id":"450226","messageId":"20220303005727.69270-3-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 02/13] submodule--helper: remove update-module-mode","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:16Z","receivedAt":"2022-03-03T00:57:53Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"This is dead code - it has not been used since c51f8f94e5\n(submodule--helper: run update procedures from C, 2021-08-24).\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 24 ------------------------\n 1 file changed, 24 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex eeacefcc38..c11ee1ea2b 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1957,29 +1957,6 @@ static void determine_submodule_update_strategy(struct repository *r,\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@@ -3430,7 +3407,6 @@ static struct cmd_struct commands[] = {\n \t{\"name\", module_name, 0},\n \t{\"clone\", module_clone, 0},\n \t{\"add\", module_add, SUPPORT_SUPER_PREFIX},\n-\t{\"update-module-mode\", module_update_module_mode, 0},\n \t{\"update-clone\", update_clone, 0},\n \t{\"run-update-procedure\", run_update_procedure, 0},\n \t{\"ensure-core-worktree\", ensure_core_worktree, 0},\n-- \n2.33.GIT\n\n"},{"id":"450227","messageId":"20220303005727.69270-5-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 04/13] submodule--helper run-update-procedure: remove --suboid","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:18Z","receivedAt":"2022-03-03T00:57:58Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach run-update-procedure to determine the oid of the submodule's HEAD\ninstead of doing it in git-subomdule.sh.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 9 ++++++---\n git-submodule.sh            | 8 +-------\n 2 files changed, 7 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 1b67a3887c..77ca4270f4 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2594,9 +2594,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\tOPT_CALLBACK_F(0, \"oid\", &update_data.oid, N_(\"sha1\"),\n \t\t\t       N_(\"SHA1 expected by superproject\"), PARSE_OPT_NONEG,\n \t\t\t       parse_opt_object_id),\n-\t\tOPT_CALLBACK_F(0, \"suboid\", &update_data.suboid, N_(\"subsha1\"),\n-\t\t\t       N_(\"SHA1 of submodule's HEAD\"), PARSE_OPT_NONEG,\n-\t\t\t       parse_opt_object_id),\n \t\tOPT_END()\n \t};\n \n@@ -3032,6 +3029,12 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n /* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n static int update_submodule2(struct update_data *update_data)\n {\n+\tif (update_data->just_cloned)\n+\t\toidcpy(&update_data->suboid, null_oid());\n+\telse if (resolve_gitlink_ref(update_data->sm_path, \"HEAD\", &update_data->suboid))\n+\t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n+\t\t\tupdate_data->displaypath);\n+\n \tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n \t\treturn do_run_update_procedure(update_data);\n \ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 87772ac891..32a09302ab 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -406,14 +406,9 @@ cmd_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\tif test $just_cloned -eq 0\n \t\tthen\n-\t\t\tsubsha1=\n-\t\telse\n \t\t\tjust_cloned=\n-\t\t\tsubsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n-\t\t\t\tgit rev-parse --verify HEAD) ||\n-\t\t\tdie \"fatal: $(eval_gettext \"Unable to find current revision in submodule path '\\$displaypath'\")\"\n \t\tfi\n \n \t\tif test -n \"$remote\"\n@@ -441,7 +436,6 @@ cmd_update()\n \t\t\t  ${update:+--update \"$update\"} \\\n \t\t\t  ${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t\t  ${sha1:+--oid \"$sha1\"} \\\n-\t\t\t  ${subsha1:+--suboid \"$subsha1\"} \\\n \t\t\t  \"--\" \\\n \t\t\t  \"$sm_path\")\n \n-- \n2.33.GIT\n\n"},{"id":"450228","messageId":"20220303005727.69270-6-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 05/13] submodule--helper: remove ensure-core-worktree","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:19Z","receivedAt":"2022-03-03T00:58:00Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Move the logic of \"git submodule--helper ensure-core-worktree\" into\nrun-update-procedure. Since the ensure-core-worktree command is\nobsolete, remove it.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 12 ++----------\n git-submodule.sh            |  2 --\n 2 files changed, 2 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 77ca4270f4..6b473fc0d2 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2771,17 +2771,11 @@ static int push_check(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int ensure_core_worktree(int argc, const char **argv, const char *prefix)\n+static void ensure_core_worktree(const char *path)\n {\n-\tconst char *path;\n \tconst char *cw;\n \tstruct repository subrepo;\n \n-\tif (argc != 2)\n-\t\tBUG(\"submodule--helper ensure-core-worktree <path>\");\n-\n-\tpath = argv[1];\n-\n \tif (repo_submodule_init(&subrepo, the_repository, path, null_oid()))\n \t\tdie(_(\"could not get a repository handle for submodule '%s'\"), path);\n \n@@ -2801,8 +2795,6 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)\n \t\tfree(abs_path);\n \t\tstrbuf_release(&sb);\n \t}\n-\n-\treturn 0;\n }\n \n static int absorb_git_dirs(int argc, const char **argv, const char *prefix)\n@@ -3029,6 +3021,7 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n /* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n static int update_submodule2(struct update_data *update_data)\n {\n+\tensure_core_worktree(update_data->sm_path);\n \tif (update_data->just_cloned)\n \t\toidcpy(&update_data->suboid, null_oid());\n \telse if (resolve_gitlink_ref(update_data->sm_path, \"HEAD\", &update_data->suboid))\n@@ -3428,7 +3421,6 @@ static struct cmd_struct commands[] = {\n \t{\"add\", module_add, SUPPORT_SUPER_PREFIX},\n \t{\"update-clone\", update_clone, 0},\n \t{\"run-update-procedure\", run_update_procedure, 0},\n-\t{\"ensure-core-worktree\", ensure_core_worktree, 0},\n \t{\"relative-path\", resolve_relative_path, 0},\n \t{\"resolve-relative-url-test\", resolve_relative_url_test, 0},\n \t{\"foreach\", module_foreach, SUPPORT_SUPER_PREFIX},\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 32a09302ab..458ce73ac6 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -402,8 +402,6 @@ cmd_update()\n \tdo\n \t\tdie_if_unmatched \"$quickabort\" \"$sha1\"\n \n-\t\tgit submodule--helper ensure-core-worktree \"$sm_path\" || exit 1\n-\n \t\tdisplaypath=$(git submodule--helper relative-path \"$prefix$sm_path\" \"$wt_prefix\")\n \n \t\tif test $just_cloned -eq 0\n-- \n2.33.GIT\n\n"},{"id":"450229","messageId":"20220303005727.69270-7-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 06/13] submodule--helper: get remote names from any repository","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:20Z","receivedAt":"2022-03-03T00:58:01Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\n`get_default_remote()` retrieves the name of a remote by resolving the\nrefs from of the current repository's ref store.\n\nThus in order to use it for retrieving the remote name of a submodule,\nwe have to start a new subprocess which runs from the submodule\ndirectory.\n\nLet's instead introduce a function called `repo_get_default_remote()`\nwhich takes any repository object and retrieves the remote accordingly.\n\n`get_default_remote()` is then defined as a call to\n`repo_get_default_remote()` with 'the_repository' passed to it.\n\nNow that we have `repo_get_default_remote()`, we no longer have to start\na subprocess that called `submodule--helper get-default-remote` from\nwithin the submodule directory.\n\nSo let's make a function called `get_default_remote_submodule()` which\ntakes a submodule path, and returns the default remote for that\nsubmodule, all within the same process.\n\nWe can now use this function to save an unnecessary subprocess spawn in\n`sync_submodule()`, and also in a subsequent patch, which will require\nthis functionality.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nHelped-by: Glen Choo <chooglen@google.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 38 ++++++++++++++++++++++---------------\n 1 file changed, 23 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 6b473fc0d2..a58df3e007 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -31,11 +31,13 @@\n typedef void (*each_submodule_fn)(const struct cache_entry *list_item,\n \t\t\t\t  void *cb_data);\n \n-static char *get_default_remote(void)\n+static char *repo_get_default_remote(struct repository *repo)\n {\n \tchar *dest = NULL, *ret;\n \tstruct strbuf sb = STRBUF_INIT;\n-\tconst char *refname = resolve_ref_unsafe(\"HEAD\", 0, NULL, NULL);\n+\tstruct ref_store *store = get_main_ref_store(repo);\n+\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL,\n+\t\t\t\t\t\t      NULL);\n \n \tif (!refname)\n \t\tdie(_(\"No such ref: %s\"), \"HEAD\");\n@@ -48,7 +50,7 @@ static char *get_default_remote(void)\n \t\tdie(_(\"Expecting a full ref name, got %s\"), refname);\n \n \tstrbuf_addf(&sb, \"branch.%s.remote\", refname);\n-\tif (git_config_get_string(sb.buf, &dest))\n+\tif (repo_config_get_string(repo, sb.buf, &dest))\n \t\tret = xstrdup(\"origin\");\n \telse\n \t\tret = dest;\n@@ -57,6 +59,19 @@ static char *get_default_remote(void)\n \treturn ret;\n }\n \n+static char *get_default_remote_submodule(const char *module_path)\n+{\n+\tstruct repository subrepo;\n+\n+\trepo_submodule_init(&subrepo, the_repository, module_path, null_oid());\n+\treturn repo_get_default_remote(&subrepo);\n+}\n+\n+static char *get_default_remote(void)\n+{\n+\treturn repo_get_default_remote(the_repository);\n+}\n+\n static int print_default_remote(int argc, const char **argv, const char *prefix)\n {\n \tchar *remote;\n@@ -1343,9 +1358,8 @@ static void sync_submodule(const char *path, const char *prefix,\n {\n \tconst struct submodule *sub;\n \tchar *remote_key = NULL;\n-\tchar *sub_origin_url, *super_config_url, *displaypath;\n+\tchar *sub_origin_url, *super_config_url, *displaypath, *default_remote;\n \tstruct strbuf sb = STRBUF_INIT;\n-\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tchar *sub_config_path = NULL;\n \n \tif (!is_submodule_active(the_repository, path))\n@@ -1384,21 +1398,15 @@ static void sync_submodule(const char *path, const char *prefix,\n \tif (!is_submodule_populated_gently(path, NULL))\n \t\tgoto cleanup;\n \n-\tprepare_submodule_repo_env(&cp.env_array);\n-\tcp.git_cmd = 1;\n-\tcp.dir = path;\n-\tstrvec_pushl(&cp.args, \"submodule--helper\",\n-\t\t     \"print-default-remote\", NULL);\n-\n \tstrbuf_reset(&sb);\n-\tif (capture_command(&cp, &sb, 0))\n+\tdefault_remote = get_default_remote_submodule(path);\n+\tif (!default_remote)\n \t\tdie(_(\"failed to get the default remote for submodule '%s'\"),\n \t\t      path);\n \n-\tstrbuf_strip_suffix(&sb, \"\\n\");\n-\tremote_key = xstrfmt(\"remote.%s.url\", sb.buf);\n+\tremote_key = xstrfmt(\"remote.%s.url\", default_remote);\n+\tfree(default_remote);\n \n-\tstrbuf_reset(&sb);\n \tsubmodule_to_gitdir(&sb, path);\n \tstrbuf_addstr(&sb, \"/config\");\n \n-- \n2.33.GIT\n\n"},{"id":"450230","messageId":"20220303005727.69270-8-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 07/13] submodule--helper: don't use bitfield indirection for parse_options()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:21Z","receivedAt":"2022-03-03T00:58:07Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nDo away with the indirection of local variables added in\nc51f8f94e5b (submodule--helper: run update procedures from C,\n2021-08-24).\n\nThese were only needed because in C you can't get a pointer to a\nsingle bit, so we were using intermediate variables instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 23 ++++++++++-------------\n 1 file changed, 10 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex a58df3e007..3a96c35b86 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2023,10 +2023,10 @@ struct update_data {\n \tstruct object_id suboid;\n \tstruct submodule_update_strategy update_strategy;\n \tint depth;\n-\tunsigned int force: 1;\n-\tunsigned int quiet: 1;\n-\tunsigned int nofetch: 1;\n-\tunsigned int just_cloned: 1;\n+\tunsigned int force;\n+\tunsigned int quiet;\n+\tunsigned int nofetch;\n+\tunsigned int just_cloned;\n };\n #define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }\n \n@@ -2578,16 +2578,17 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \n static int run_update_procedure(int argc, const char **argv, const char *prefix)\n {\n-\tint force = 0, quiet = 0, nofetch = 0, just_cloned = 0;\n \tchar *prefixed_path, *update = NULL;\n \tstruct update_data update_data = UPDATE_DATA_INIT;\n \n \tstruct option options[] = {\n-\t\tOPT__QUIET(&quiet, N_(\"suppress output for update by rebase or merge\")),\n-\t\tOPT__FORCE(&force, N_(\"force checkout updates\"), 0),\n-\t\tOPT_BOOL('N', \"no-fetch\", &nofetch,\n+\t\tOPT__QUIET(&update_data.quiet,\n+\t\t\t   N_(\"suppress output for update by rebase or merge\")),\n+\t\tOPT__FORCE(&update_data.force, N_(\"force checkout updates\"),\n+\t\t\t   0),\n+\t\tOPT_BOOL('N', \"no-fetch\", &update_data.nofetch,\n \t\t\t N_(\"don't fetch new objects from the remote site\")),\n-\t\tOPT_BOOL(0, \"just-cloned\", &just_cloned,\n+\t\tOPT_BOOL(0, \"just-cloned\", &update_data.just_cloned,\n \t\t\t N_(\"overrides update mode in case the repository is a fresh clone\")),\n \t\tOPT_INTEGER(0, \"depth\", &update_data.depth, N_(\"depth for shallow fetch\")),\n \t\tOPT_STRING(0, \"prefix\", &prefix,\n@@ -2615,10 +2616,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \tif (argc != 1)\n \t\tusage_with_options(usage, options);\n \n-\tupdate_data.force = !!force;\n-\tupdate_data.quiet = !!quiet;\n-\tupdate_data.nofetch = !!nofetch;\n-\tupdate_data.just_cloned = !!just_cloned;\n \tupdate_data.sm_path = argv[0];\n \n \tif (update_data.recursive_prefix)\n-- \n2.33.GIT\n\n"},{"id":"450231","messageId":"20220303005727.69270-9-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 08/13] submodule--helper run-update-procedure: learn --remote","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:22Z","receivedAt":"2022-03-03T00:58:09Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach run-update-procedure to handle --remote instead of parsing\n--remote in git-submodule.sh. As a result, \"git submodule--helper\n[print-default-remote|remote-branch]\" have no more callers, so remove\nthem.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 56 +++++++++++++++----------------------\n git-submodule.sh            | 30 +-------------------\n 2 files changed, 23 insertions(+), 63 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 3a96c35b86..99341fb343 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -72,21 +72,6 @@ static char *get_default_remote(void)\n \treturn repo_get_default_remote(the_repository);\n }\n \n-static int print_default_remote(int argc, const char **argv, const char *prefix)\n-{\n-\tchar *remote;\n-\n-\tif (argc != 1)\n-\t\tdie(_(\"submodule--helper print-default-remote takes no arguments\"));\n-\n-\tremote = get_default_remote();\n-\tif (remote)\n-\t\tprintf(\"%s\\n\", remote);\n-\n-\tfree(remote);\n-\treturn 0;\n-}\n-\n static int starts_with_dot_slash(const char *str)\n {\n \treturn str[0] == '.' && is_dir_sep(str[1]);\n@@ -2027,6 +2012,7 @@ struct update_data {\n \tunsigned int quiet;\n \tunsigned int nofetch;\n \tunsigned int just_cloned;\n+\tunsigned int remote;\n };\n #define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }\n \n@@ -2603,6 +2589,8 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\tOPT_CALLBACK_F(0, \"oid\", &update_data.oid, N_(\"sha1\"),\n \t\t\t       N_(\"SHA1 expected by superproject\"), PARSE_OPT_NONEG,\n \t\t\t       parse_opt_object_id),\n+\t\tOPT_BOOL(0, \"remote\", &update_data.remote,\n+\t\t\t N_(\"use SHA-1 of submodule's remote tracking branch\")),\n \t\tOPT_END()\n \t};\n \n@@ -2682,23 +2670,6 @@ static const char *remote_submodule_branch(const char *path)\n \treturn branch;\n }\n \n-static int resolve_remote_submodule_branch(int argc, const char **argv,\n-\t\tconst char *prefix)\n-{\n-\tconst char *ret;\n-\tstruct strbuf sb = STRBUF_INIT;\n-\tif (argc != 2)\n-\t\tdie(\"submodule--helper remote-branch takes exactly one arguments, got %d\", argc);\n-\n-\tret = remote_submodule_branch(argv[1]);\n-\tif (!ret)\n-\t\tdie(\"submodule %s doesn't exist\", argv[1]);\n-\n-\tprintf(\"%s\", ret);\n-\tstrbuf_release(&sb);\n-\treturn 0;\n-}\n-\n static int push_check(int argc, const char **argv, const char *prefix)\n {\n \tstruct remote *remote;\n@@ -3033,6 +3004,25 @@ static int update_submodule2(struct update_data *update_data)\n \t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n \t\t\tupdate_data->displaypath);\n \n+\tif (update_data->remote) {\n+\t\tchar *remote_name = get_default_remote_submodule(update_data->sm_path);\n+\t\tconst char *branch = remote_submodule_branch(update_data->sm_path);\n+\t\tchar *remote_ref = xstrfmt(\"refs/remotes/%s/%s\", remote_name, branch);\n+\n+\t\tif (!update_data->nofetch) {\n+\t\t\tif (fetch_in_submodule(update_data->sm_path, update_data->depth,\n+\t\t\t\t\t      0, NULL))\n+\t\t\t\tdie(_(\"Unable to fetch in submodule path '%s'\"),\n+\t\t\t\t    update_data->sm_path);\n+\t\t}\n+\n+\t\tif (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))\n+\t\t\tdie(_(\"Unable to find %s revision in submodule path '%s'\"),\n+\t\t\t    remote_ref, update_data->sm_path);\n+\n+\t\tfree(remote_ref);\n+\t}\n+\n \tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n \t\treturn do_run_update_procedure(update_data);\n \n@@ -3431,11 +3421,9 @@ static struct cmd_struct commands[] = {\n \t{\"foreach\", module_foreach, SUPPORT_SUPER_PREFIX},\n \t{\"init\", module_init, SUPPORT_SUPER_PREFIX},\n \t{\"status\", module_status, SUPPORT_SUPER_PREFIX},\n-\t{\"print-default-remote\", print_default_remote, 0},\n \t{\"sync\", module_sync, SUPPORT_SUPER_PREFIX},\n \t{\"deinit\", module_deinit, 0},\n \t{\"summary\", module_summary, SUPPORT_SUPER_PREFIX},\n-\t{\"remote-branch\", resolve_remote_submodule_branch, 0},\n \t{\"push-check\", push_check, 0},\n \t{\"absorb-git-dirs\", absorb_git_dirs, SUPPORT_SUPER_PREFIX},\n \t{\"is-active\", is_active, 0},\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 458ce73ac6..23ebd90892 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -247,20 +247,6 @@ cmd_deinit()\n \tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- \"$@\"\n }\n \n-# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>]\n-# Because arguments are positional, use an empty string to omit <depth>\n-# but include <sha1>.\n-fetch_in_submodule () (\n-\tsanitize_submodule_env &&\n-\tcd \"$1\" &&\n-\tif test $# -eq 3\n-\tthen\n-\t\techo \"$3\" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+\"$2\"}\n-\telse\n-\t\tgit fetch ${GIT_QUIET:+--quiet} ${2:+\"$2\"}\n-\tfi\n-)\n-\n #\n # Update each submodule path to correct revision, using clone and checkout as needed\n #\n@@ -409,21 +395,6 @@ cmd_update()\n \t\t\tjust_cloned=\n \t\tfi\n \n-\t\tif test -n \"$remote\"\n-\t\tthen\n-\t\t\tbranch=$(git submodule--helper remote-branch \"$sm_path\")\n-\t\t\tif test -z \"$nofetch\"\n-\t\t\tthen\n-\t\t\t\t# Fetch remote before determining tracking $sha1\n-\t\t\t\tfetch_in_submodule \"$sm_path\" $depth ||\n-\t\t\t\tdie \"fatal: $(eval_gettext \"Unable to fetch in submodule path '\\$sm_path'\")\"\n-\t\t\tfi\n-\t\t\tremote_name=$(sanitize_submodule_env; cd \"$sm_path\" && git submodule--helper print-default-remote)\n-\t\t\tsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n-\t\t\t\tgit rev-parse --verify \"${remote_name}/${branch}\") ||\n-\t\t\tdie \"fatal: $(eval_gettext \"Unable to find current \\${remote_name}/\\${branch} revision in submodule path '\\$sm_path'\")\"\n-\t\tfi\n-\n \t\tout=$(git submodule--helper run-update-procedure \\\n \t\t\t  ${wt_prefix:+--prefix \"$wt_prefix\"} \\\n \t\t\t  ${GIT_QUIET:+--quiet} \\\n@@ -434,6 +405,7 @@ cmd_update()\n \t\t\t  ${update:+--update \"$update\"} \\\n \t\t\t  ${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t\t  ${sha1:+--oid \"$sha1\"} \\\n+\t\t\t  ${remote:+--remote} \\\n \t\t\t  \"--\" \\\n \t\t\t  \"$sm_path\")\n \n-- \n2.33.GIT\n\n"},{"id":"450232","messageId":"20220303005727.69270-10-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 09/13] submodule--helper: refactor get_submodule_displaypath()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:23Z","receivedAt":"2022-03-03T00:58:09Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\nWe create a function called `do_get_submodule_displaypath()` that\ngenerates the display path required by several submodule functions, and\ntakes a custom superprefix parameter, instead of reading it from the\nenvironment.\n\nWe then redefine the existing `get_submodule_displaypath()` function\nas a call to this new function, where the superprefix is obtained from\nthe environment.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/submodule--helper.c | 14 ++++++++++----\n 1 file changed, 10 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 99341fb343..e6df99a884 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -247,11 +247,10 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr\n \treturn 0;\n }\n \n-/* the result should be freed by the caller. */\n-static char *get_submodule_displaypath(const char *path, const char *prefix)\n+static char *do_get_submodule_displaypath(const char *path,\n+\t\t\t\t\t  const char *prefix,\n+\t\t\t\t\t  const char *super_prefix)\n {\n-\tconst char *super_prefix = get_super_prefix();\n-\n \tif (prefix && super_prefix) {\n \t\tBUG(\"cannot have prefix '%s' and superprefix '%s'\",\n \t\t    prefix, super_prefix);\n@@ -267,6 +266,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix)\n \t}\n }\n \n+/* the result should be freed by the caller. */\n+static char *get_submodule_displaypath(const char *path, const char *prefix)\n+{\n+\tconst char *super_prefix = get_super_prefix();\n+\treturn do_get_submodule_displaypath(path, prefix, super_prefix);\n+}\n+\n static char *compute_rev_name(const char *sub_path, const char* object_id)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n-- \n2.33.GIT\n\n"},{"id":"450233","messageId":"20220303005727.69270-11-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 10/13] submodule--helper: allow setting superprefix for init_submodule()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:24Z","receivedAt":"2022-03-03T00:58:12Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\nWe allow callers of the `init_submodule()` function to optionally\noverride the superprefix from the environment.\n\nWe need to enable this option because in our conversion of the update\ncommand that will follow, the '--init' option will be handled through\nthis API. We will need to change the superprefix at that time to ensure\nthe display paths show correctly in the output messages.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/submodule--helper.c | 10 +++++++---\n 1 file changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex e6df99a884..69ada7f914 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -594,18 +594,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix)\n \n struct init_cb {\n \tconst char *prefix;\n+\tconst char *superprefix;\n \tunsigned int flags;\n };\n #define INIT_CB_INIT { 0 }\n \n static void init_submodule(const char *path, const char *prefix,\n-\t\t\t   unsigned int flags)\n+\t\t\t   const char *superprefix, unsigned int flags)\n {\n \tconst struct submodule *sub;\n \tstruct strbuf sb = STRBUF_INIT;\n \tchar *upd = NULL, *url = NULL, *displaypath;\n \n-\tdisplaypath = get_submodule_displaypath(path, prefix);\n+\t/* try superprefix from the environment, if it is not passed explicitly */\n+\tif (!superprefix)\n+\t\tsuperprefix = get_super_prefix();\n+\tdisplaypath = do_get_submodule_displaypath(path, prefix, superprefix);\n \n \tsub = submodule_from_path(the_repository, null_oid(), path);\n \n@@ -679,7 +683,7 @@ static void init_submodule(const char *path, const char *prefix,\n static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data)\n {\n \tstruct init_cb *info = cb_data;\n-\tinit_submodule(list_item->name, info->prefix, info->flags);\n+\tinit_submodule(list_item->name, info->prefix, info->superprefix, info->flags);\n }\n \n static int module_init(int argc, const char **argv, const char *prefix)\n-- \n2.33.GIT\n\n"},{"id":"450234","messageId":"20220303005727.69270-12-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 11/13] submodule--helper update-clone: learn --init","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:25Z","receivedAt":"2022-03-03T00:58:14Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach \"git submodule--helper update-clone\" the --init flag and remove\nthe corresponding shell code.\n\nWhen the `--init` flag is passed to the subcommand, we do not spawn a\nnew subprocess and call `submodule--helper init` on the submodule paths,\nbecause the Git machinery is not able to pick up the configuration\nchanges introduced by that init call. So we instead run the\n`init_submodule_cb()` callback over each submodule in the same process.\n\n[1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 26 ++++++++++++++++++++++++++\n git-submodule.sh            |  9 +++------\n 2 files changed, 29 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 69ada7f914..296ab80bf2 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2000,6 +2000,7 @@ struct submodule_update_clone {\n \tint failed_clones_nr, failed_clones_alloc;\n \n \tint max_jobs;\n+\tunsigned int init;\n };\n #define SUBMODULE_UPDATE_CLONE_INIT { \\\n \t.list = MODULE_LIST_INIT, \\\n@@ -2509,6 +2510,8 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \tint ret;\n \n \tstruct option module_update_clone_options[] = {\n+\t\tOPT_BOOL(0, \"init\", &suc.init,\n+\t\t\t N_(\"initialize uninitialized submodules before update\")),\n \t\tOPT_STRING(0, \"prefix\", &prefix,\n \t\t\t   N_(\"path\"),\n \t\t\t   N_(\"path into the working tree\")),\n@@ -2567,6 +2570,29 @@ 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+\tif (suc.init) {\n+\t\tstruct module_list list = MODULE_LIST_INIT;\n+\t\tstruct init_cb info = INIT_CB_INIT;\n+\n+\t\tif (module_list_compute(argc, argv, suc.prefix,\n+\t\t\t\t\t&pathspec, &list) < 0)\n+\t\t\treturn 1;\n+\n+\t\t/*\n+\t\t * If there are no path args and submodule.active is set then,\n+\t\t * by default, only initialize 'active' modules.\n+\t\t */\n+\t\tif (!argc && git_config_get_value_multi(\"submodule.active\"))\n+\t\t\tmodule_list_active(&list);\n+\n+\t\tinfo.prefix = suc.prefix;\n+\t\tinfo.superprefix = suc.recursive_prefix;\n+\t\tif (suc.quiet)\n+\t\t\tinfo.flags |= OPT_QUIET;\n+\n+\t\tfor_each_listed_submodule(&list, init_submodule_cb, &info);\n+\t}\n+\n \tret = update_submodules(&suc);\n \tlist_objects_filter_release(&filter_options);\n \treturn ret;\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 23ebd90892..51be7c7f7e 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -361,14 +361,11 @@ cmd_update()\n \t\tusage\n \tfi\n \n-\tif test -n \"$init\"\n-\tthen\n-\t\tcmd_init \"--\" \"$@\" || return\n-\tfi\n-\n \t{\n-\tgit submodule--helper update-clone ${GIT_QUIET:+--quiet} \\\n+\tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper update-clone \\\n+\t\t${GIT_QUIET:+--quiet} \\\n \t\t${progress:+\"--progress\"} \\\n+\t\t${init:+--init} \\\n \t\t${wt_prefix:+--prefix \"$wt_prefix\"} \\\n \t\t${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t${update:+--update \"$update\"} \\\n-- \n2.33.GIT\n\n"},{"id":"450235","messageId":"20220303005727.69270-13-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 12/13] submodule update: add tests for --filter","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:26Z","receivedAt":"2022-03-03T00:58:25Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Test the \"--filter\" option to make sure we don't break anything while\nrefactoring \"git submodule update\".\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n t/t7406-submodule-update.sh | 12 ++++++++++++\n 1 file changed, 12 insertions(+)\n\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 7764c1c3cb..000e055811 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -1071,4 +1071,16 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s\n \t)\n '\n \n+test_expect_success 'submodule update --filter requires --init' '\n+\ttest_expect_code 129 git -C super submodule update --filter blob:none\n+'\n+\n+test_expect_success 'submodule update --filter sets partial clone settings' '\n+\ttest_when_finished \"rm -rf super-filter\" &&\n+\tgit clone cloned super-filter &&\n+\tgit -C super-filter submodule update --init --filter blob:none &&\n+\ttest_cmp_config -C super-filter/submodule true remote.origin.promisor &&\n+\ttest_cmp_config -C super-filter/submodule blob:none remote.origin.partialclonefilter\n+'\n+\n test_done\n-- \n2.33.GIT\n\n"},{"id":"450236","messageId":"20220303005727.69270-14-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v3 13/13] submodule--helper update-clone: check for --filter and --init","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-03T00:57:27Z","receivedAt":"2022-03-03T00:58:27Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"\"git submodule update --filter\" also requires the \"--init\" option. Teach\nupdate-clone to do this usage check in C and remove the check from\ngit-submodule.sh.\n\nIn addition, change update-clone's usage string so that it teaches users\nabout \"git submodule update\" instead of \"git submodule--helper\nupdate-clone\" (the string is copied from git-submodule.sh). This should\nbe more helpful to users since they don't invoke update-clone directly.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 20 +++++++++++++++++++-\n git-submodule.sh            |  5 -----\n 2 files changed, 19 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 296ab80bf2..bef9ab22d4 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2545,7 +2545,12 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \t};\n \n \tconst char *const git_submodule_helper_usage[] = {\n-\t\tN_(\"git submodule--helper update-clone [--prefix=<path>] [<path>...]\"),\n+\t\tN_(\"git submodule [--quiet] update\"\n+\t\t\" [--init [--filter=<filter-spec>]] [--remote]\"\n+\t\t\" [-N|--no-fetch] [-f|--force]\"\n+\t\t\" [--checkout|--merge|--rebase]\"\n+\t\t\" [--[no-]recommend-shallow] [--reference <repository>]\"\n+\t\t\" [--recursive] [--[no-]single-branch] [--] [<path>...]\"),\n \t\tNULL\n \t};\n \tsuc.prefix = prefix;\n@@ -2556,6 +2561,19 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \tmemset(&filter_options, 0, sizeof(filter_options));\n \targc = parse_options(argc, argv, prefix, module_update_clone_options,\n \t\t\t     git_submodule_helper_usage, 0);\n+\n+\tif (filter_options.choice && !suc.init) {\n+\t\t/*\n+\t\t * NEEDSWORK: Don't use usage_with_options() because the\n+\t\t * usage string is for \"git submodule update\", but the\n+\t\t * options are for \"git submodule--helper update-clone\".\n+\t\t *\n+\t\t * This will no longer be an issue when \"update-clone\"\n+\t\t * is replaced by \"git submodule--helper update\".\n+\t\t */\n+\t\tusage(git_submodule_helper_usage[0]);\n+\t}\n+\n \tsuc.filter_options = &filter_options;\n \n \tif (update)\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 51be7c7f7e..aa8bdfca9d 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -356,11 +356,6 @@ cmd_update()\n \t\tshift\n \tdone\n \n-\tif test -n \"$filter\" && test \"$init\" != \"1\"\n-\tthen\n-\t\tusage\n-\tfi\n-\n \t{\n \tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper update-clone \\\n \t\t${GIT_QUIET:+--quiet} \\\n-- \n2.33.GIT\n\n"},{"id":"450252","messageId":"220303.86sfrz5p9t.gmgdl@evledraar.gmail.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"Re: [PATCH v3 00/13] submodule: convert parts of 'update' to C","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-03T09:58:57Z","receivedAt":"2022-03-03T10:00:54Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Mar 02 2022, Glen Choo wrote:\n\n> Original series: https://lore.kernel.org/git/20220210092833.55360-1-chooglen@google.com\n> (I've trimmed the cc list down to the 'most interested' parties)\n>\n> Thanks for the input, Ævar :) This just fixes up a few small issues in\n> the previous version.\n\nAnd thanks for working on this, there was a reason I was down to\nnitpicking in v2, this is looking really good & I can't find any issues\nwith this iteration at all.\n\nSo I'm happy to give this my:\n\nReviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nJunio: It would be great to get this advancing to \"next\" so that the\nsubsequent set of migrations to submodule-in-C advancing.\n"},{"id":"450253","messageId":"220303.86o82n5oyp.gmgdl@evledraar.gmail.com","threadId":"57488","inReplyTo":"kl6llexted2t.fsf@chooglen-macbookpro.roam.corp.google.com","subject":"Re: [PATCH v2 13/13] submodule--helper update-clone: check for --filter and --init","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-03T10:06:58Z","receivedAt":"2022-03-03T10:07:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Mar 01 2022, Glen Choo wrote:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n>>\n>>>> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\n>>>> index 2ffc070319..3e8a05a052 100644\n>>>> --- a/builtin/submodule--helper.c\n>>>> +++ b/builtin/submodule--helper.c\n>>>> @@ -2543,7 +2543,12 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n>>>>  \t};\n>>>>  \n>>>>  \tconst char *const git_submodule_helper_usage[] = {\n>>>> -\t\tN_(\"git submodule--helper update-clone [--prefix=<path>] [<path>...]\"),\n>>>> +\t\tN_(\"git submodule [--quiet] update\"\n>>>> +\t\t\"[--init [--filter=<filter-spec>]] [--remote]\"\n>>>> +\t\t\"[-N|--no-fetch] [-f|--force]\"\n>>>> +\t\t\"[--checkout|--merge|--rebase]\"\n>>>> +\t\t\"[--[no-]recommend-shallow] [--reference <repository>]\"\n>>>> +\t\t\"[--recursive] [--[no-]single-branch] [--] [<path>...]\"),\n>>>\n>>> Since this has <repository>, <path> etc. it should still be marked for\n>>> translation with N_().\n>>\n>> Yeah, that sounds like a good idea.  Isn't it already inside N_()?\n>\n> Did I do this correctly? e.g. an alternative interpretation is that Ævar\n> misread this as:\n>\n>   \tconst char *const git_submodule_helper_usage[] = {\n>       N_(\"git submodule [--quiet] update\"),\n>       \"[--init [--filter=<filter-spec>]] [--remote]\",\n>       \"[-N|--no-fetch] [-f|--force]\",\n>       \"[--checkout|--merge|--rebase]\",\n>       \"[--[no-]recommend-shallow] [--reference <repository>]\",\n>       \"[--recursive] [--[no-]single-branch] [--] [<path>...]\",\n\n(Even if a v3 has already been sent out). Yes, sorry. I just misread\nthis. The pre-image is correct.\n"},{"id":"450305","messageId":"xmqqilsuagkw.fsf@gitster.g","threadId":"57488","inReplyTo":"20220303005727.69270-5-chooglen@google.com","subject":"Re: [PATCH v3 04/13] submodule--helper run-update-procedure: remove --suboid","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-03T21:09:35Z","receivedAt":"2022-03-03T21:09:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Glen Choo <chooglen@google.com> writes:\n\n> Teach run-update-procedure to determine the oid of the submodule's HEAD\n> instead of doing it in git-subomdule.sh.\n\nsubomdule -> submodule.\n\n> @@ -3032,6 +3029,12 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n>  /* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n>  static int update_submodule2(struct update_data *update_data)\n>  {\n> +\tif (update_data->just_cloned)\n> +\t\toidcpy(&update_data->suboid, null_oid());\n> +\telse if (resolve_gitlink_ref(update_data->sm_path, \"HEAD\", &update_data->suboid))\n> +\t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n> +\t\t\tupdate_data->displaypath);\n> +\n>  \tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n>  \t\treturn do_run_update_procedure(update_data);\n\nMakes sense.\n"},{"id":"450307","messageId":"xmqqbkymaftr.fsf@gitster.g","threadId":"57488","inReplyTo":"20220303005727.69270-6-chooglen@google.com","subject":"Re: [PATCH v3 05/13] submodule--helper: remove ensure-core-worktree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-03T21:25:52Z","receivedAt":"2022-03-03T21:25:59Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Glen Choo <chooglen@google.com> writes:\n\n> Move the logic of \"git submodule--helper ensure-core-worktree\" into\n> run-update-procedure. Since the ensure-core-worktree command is\n\nI take it as \"... command is now obsolete\", or \"... has become\nobsolete\"?\n\n> obsolete, remove it.\n>\n> Signed-off-by: Glen Choo <chooglen@google.com>\n> ---\n>  builtin/submodule--helper.c | 12 ++----------\n>  git-submodule.sh            |  2 --\n>  2 files changed, 2 insertions(+), 12 deletions(-)\n\nOn the script side, the removed call to ensure-core-worktree used\nto precede these invocations of the helper\n\n    submodule--helper relative-path\n    submodule--helper remote-branch\n    submodule--helper print-default-remote\n\nbefore we triggered run-update-procedure, so these helper calls were\ndone only after we made sure we have a submodule there at the path\nand its configuration file has core.worktree set correctly.  If we\nfailed to do so, we wouldn't have made these calls.\n\nNow we call them unprotected.  It is not immediately obvious if that\nis a safe/sensible thing to do.\n\nI would imagine that we would lose more and more code from the\nscript in the \"while\" loop before run-update-procedure is triggered,\nand presumably the equivalent code will be added _after_ the call to\nensure_core_worktree() this patch adds to the beginning of\nupdate_submodule2(), so in the end, the above will presumably become\na non-issue, but the series structure still feels iffy because of it.\n\n"},{"id":"450309","messageId":"xmqq4k4eafdf.fsf@gitster.g","threadId":"57488","inReplyTo":"20220303005727.69270-9-chooglen@google.com","subject":"Re: [PATCH v3 08/13] submodule--helper run-update-procedure: learn --remote","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-03T21:35:40Z","receivedAt":"2022-03-03T21:35:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Glen Choo <chooglen@google.com> writes:\n\n> @@ -3033,6 +3004,25 @@ static int update_submodule2(struct update_data *update_data)\n>  \t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n>  \t\t\tupdate_data->displaypath);\n>  \n> +\tif (update_data->remote) {\n> +\t\tchar *remote_name = get_default_remote_submodule(update_data->sm_path);\n> +\t\tconst char *branch = remote_submodule_branch(update_data->sm_path);\n> +\t\tchar *remote_ref = xstrfmt(\"refs/remotes/%s/%s\", remote_name, branch);\n> +\n> +\t\tif (!update_data->nofetch) {\n> +\t\t\tif (fetch_in_submodule(update_data->sm_path, update_data->depth,\n> +\t\t\t\t\t      0, NULL))\n> +\t\t\t\tdie(_(\"Unable to fetch in submodule path '%s'\"),\n> +\t\t\t\t    update_data->sm_path);\n> +\t\t}\n> +\n> +\t\tif (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))\n> +\t\t\tdie(_(\"Unable to find %s revision in submodule path '%s'\"),\n> +\t\t\t    remote_ref, update_data->sm_path);\n> +\n> +\t\tfree(remote_ref);\n> +\t}\n\nThis, and ...\n\n> @@ -409,21 +395,6 @@ cmd_update()\n>  \t\t\tjust_cloned=\n>  \t\tfi\n>  \n> -\t\tif test -n \"$remote\"\n> -\t\tthen\n> -\t\t\tbranch=$(git submodule--helper remote-branch \"$sm_path\")\n> -\t\t\tif test -z \"$nofetch\"\n> -\t\t\tthen\n> -\t\t\t\t# Fetch remote before determining tracking $sha1\n> -\t\t\t\tfetch_in_submodule \"$sm_path\" $depth ||\n> -\t\t\t\tdie \"fatal: $(eval_gettext \"Unable to fetch in submodule path '\\$sm_path'\")\"\n> -\t\t\tfi\n> -\t\t\tremote_name=$(sanitize_submodule_env; cd \"$sm_path\" && git submodule--helper print-default-remote)\n> -\t\t\tsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n> -\t\t\t\tgit rev-parse --verify \"${remote_name}/${branch}\") ||\n> -\t\t\tdie \"fatal: $(eval_gettext \"Unable to find current \\${remote_name}/\\${branch} revision in submodule path '\\$sm_path'\")\"\n> -\t\tfi\n\n... this change would \"fix\" the temporary breakage [05/13] may have\nbrought us.  From the series structure's point of view, doing\n[05/13] after this would be more sensible.  If we leave the call to\n\"displaypath\" still in the script after this series, [05/13] or its\nequivalent should mention that ensure-core-worktree does not matter\nfor that particular call when it delays the call to it by moving it\nto the beginning of the update_submodule2() from the much earlier\npart of the script.\n\n>  \t\tout=$(git submodule--helper run-update-procedure \\\n>  \t\t\t  ${wt_prefix:+--prefix \"$wt_prefix\"} \\\n>  \t\t\t  ${GIT_QUIET:+--quiet} \\\n> @@ -434,6 +405,7 @@ cmd_update()\n>  \t\t\t  ${update:+--update \"$update\"} \\\n>  \t\t\t  ${prefix:+--recursive-prefix \"$prefix\"} \\\n>  \t\t\t  ${sha1:+--oid \"$sha1\"} \\\n> +\t\t\t  ${remote:+--remote} \\\n>  \t\t\t  \"--\" \\\n>  \t\t\t  \"$sm_path\")\n"},{"id":"450310","messageId":"xmqqzgm690iu.fsf@gitster.g","threadId":"57488","inReplyTo":"220303.86sfrz5p9t.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH v3 00/13] submodule: convert parts of 'update' to C","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-03T21:41:45Z","receivedAt":"2022-03-03T21:41:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> On Wed, Mar 02 2022, Glen Choo wrote:\n>\n>> Original series: https://lore.kernel.org/git/20220210092833.55360-1-chooglen@google.com\n>> (I've trimmed the cc list down to the 'most interested' parties)\n>>\n>> Thanks for the input, Ævar :) This just fixes up a few small issues in\n>> the previous version.\n>\n> And thanks for working on this, there was a reason I was down to\n> nitpicking in v2, this is looking really good & I can't find any issues\n> with this iteration at all.\n>\n> So I'm happy to give this my:\n>\n> Reviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nThanks for reviewing.\n\nI found that the safety of doing [05/13] that early was\nquestionable, but other than that, it was a pleasant read.\n"},{"id":"450442","messageId":"kl6lfsnx4ddl.fsf@chooglen-macbookpro.roam.corp.google.com","threadId":"57488","inReplyTo":"xmqqbkymaftr.fsf@gitster.g","subject":"Re: [PATCH v3 05/13] submodule--helper: remove ensure-core-worktree","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-04T21:27:34Z","receivedAt":"2022-03-04T21:27:39Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Glen Choo <chooglen@google.com> writes:\n>\n>> Move the logic of \"git submodule--helper ensure-core-worktree\" into\n>> run-update-procedure. Since the ensure-core-worktree command is\n>\n> I take it as \"... command is now obsolete\", or \"... has become\n> obsolete\"?\n\nYes, that's a better phrasing.\n\n> On the script side, the removed call to ensure-core-worktree used\n> to precede these invocations of the helper\n>\n>     submodule--helper relative-path\n>     submodule--helper remote-branch\n>     submodule--helper print-default-remote\n>\n> before we triggered run-update-procedure, so these helper calls were\n> done only after we made sure we have a submodule there at the path\n> and its configuration file has core.worktree set correctly.  If we\n> failed to do so, we wouldn't have made these calls.\n>\n> Now we call them unprotected.  It is not immediately obvious if that\n> is a safe/sensible thing to do.\n>\n> I would imagine that we would lose more and more code from the\n> script in the \"while\" loop before run-update-procedure is triggered,\n> and presumably the equivalent code will be added _after_ the call to\n> ensure_core_worktree() this patch adds to the beginning of\n> update_submodule2(), so in the end, the above will presumably become\n> a non-issue, but the series structure still feels iffy because of it.\n\nI could restructure this series so that this patch is as late as\npossible, so we don't have to worry about safety for 'remote-branch' and\n'print-default-remote', but we still have to consider 'relative-path'\nbecause that's still around by the end of this series.\n\nFortunately, relative_path is just a wrapper around dir.h's\nrelative_path(), which AFAICT is just general purpose string\nmanipulation and has nothing to do with Git.\n\n(I'm also certain that the other two commands don't interact with\ncore.worktree either, but I'll just restructure the series so that the\npoint is moot.)\n"},{"id":"450443","messageId":"kl6lczj14dac.fsf@chooglen-macbookpro.roam.corp.google.com","threadId":"57488","inReplyTo":"xmqq4k4eafdf.fsf@gitster.g","subject":"Re: [PATCH v3 08/13] submodule--helper run-update-procedure: learn --remote","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-04T21:29:31Z","receivedAt":"2022-03-04T21:29:37Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Glen Choo <chooglen@google.com> writes:\n>\n>> @@ -3033,6 +3004,25 @@ static int update_submodule2(struct update_data *update_data)\n>>  \t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n>>  \t\t\tupdate_data->displaypath);\n>>  \n>> +\tif (update_data->remote) {\n>> +\t\tchar *remote_name = get_default_remote_submodule(update_data->sm_path);\n>> +\t\tconst char *branch = remote_submodule_branch(update_data->sm_path);\n>> +\t\tchar *remote_ref = xstrfmt(\"refs/remotes/%s/%s\", remote_name, branch);\n>> +\n>> +\t\tif (!update_data->nofetch) {\n>> +\t\t\tif (fetch_in_submodule(update_data->sm_path, update_data->depth,\n>> +\t\t\t\t\t      0, NULL))\n>> +\t\t\t\tdie(_(\"Unable to fetch in submodule path '%s'\"),\n>> +\t\t\t\t    update_data->sm_path);\n>> +\t\t}\n>> +\n>> +\t\tif (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))\n>> +\t\t\tdie(_(\"Unable to find %s revision in submodule path '%s'\"),\n>> +\t\t\t    remote_ref, update_data->sm_path);\n>> +\n>> +\t\tfree(remote_ref);\n>> +\t}\n>\n> This, and ...\n>\n>> @@ -409,21 +395,6 @@ cmd_update()\n>>  \t\t\tjust_cloned=\n>>  \t\tfi\n>>  \n>> -\t\tif test -n \"$remote\"\n>> -\t\tthen\n>> -\t\t\tbranch=$(git submodule--helper remote-branch \"$sm_path\")\n>> -\t\t\tif test -z \"$nofetch\"\n>> -\t\t\tthen\n>> -\t\t\t\t# Fetch remote before determining tracking $sha1\n>> -\t\t\t\tfetch_in_submodule \"$sm_path\" $depth ||\n>> -\t\t\t\tdie \"fatal: $(eval_gettext \"Unable to fetch in submodule path '\\$sm_path'\")\"\n>> -\t\t\tfi\n>> -\t\t\tremote_name=$(sanitize_submodule_env; cd \"$sm_path\" && git submodule--helper print-default-remote)\n>> -\t\t\tsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n>> -\t\t\t\tgit rev-parse --verify \"${remote_name}/${branch}\") ||\n>> -\t\t\tdie \"fatal: $(eval_gettext \"Unable to find current \\${remote_name}/\\${branch} revision in submodule path '\\$sm_path'\")\"\n>> -\t\tfi\n>\n> ... this change would \"fix\" the temporary breakage [05/13] may have\n> brought us.  From the series structure's point of view, doing\n> [05/13] after this would be more sensible.  If we leave the call to\n> \"displaypath\" still in the script after this series, [05/13] or its\n> equivalent should mention that ensure-core-worktree does not matter\n> for that particular call when it delays the call to it by moving it\n> to the beginning of the update_submodule2() from the much earlier\n> part of the script.\n>\n\nI should've read this in full before sending my reply on [05/13]. Makes\nsense, thanks for the pointer :)\n\n>>  \t\tout=$(git submodule--helper run-update-procedure \\\n>>  \t\t\t  ${wt_prefix:+--prefix \"$wt_prefix\"} \\\n>>  \t\t\t  ${GIT_QUIET:+--quiet} \\\n>> @@ -434,6 +405,7 @@ cmd_update()\n>>  \t\t\t  ${update:+--update \"$update\"} \\\n>>  \t\t\t  ${prefix:+--recursive-prefix \"$prefix\"} \\\n>>  \t\t\t  ${sha1:+--oid \"$sha1\"} \\\n>> +\t\t\t  ${remote:+--remote} \\\n>>  \t\t\t  \"--\" \\\n>>  \t\t\t  \"$sm_path\")\n"},{"id":"450466","messageId":"20220305001401.20888-1-chooglen@google.com","threadId":"57488","inReplyTo":"20220303005727.69270-1-chooglen@google.com","subject":"[PATCH v4 00/13] submodule: convert parts of 'update' to C","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:48Z","receivedAt":"2022-03-05T00:14:59Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Original series: https://lore.kernel.org/git/20220210092833.55360-1-chooglen@google.com\n\n= Patch summary\n\n- Patch 1 adds extra tests to \"git submodule update\" to make sure we\n  don't break anything\n- Patch 2 removes dead code that used to be part of \"git submodule\n  update\"\n- Patch 3 prepares for later changes by introducing the C function that\n  will hold most of the newly converted code\n- Patch 4 moves run-update-procedure's --suboid option into C\n- Patch 5 moves ensure-core-worktree into C\n- Patches 6-8 move run-update-procedure's --remote option into C\n- Patches 9-11 move \"git submodule update\"'s --init into C\n- Patches 12-13 move \"git submodule update\"'s --filter option into C\n\n= Changes\n\nSince v3:\n- Move 'remove ensure-core-worktree' towards the end (see\n  xmqqbkymaftr.fsf@gitster.g).\n- Fix typo\n\nSince v2:\n- Patch 6: Fix a stale commit message that said 'in the next patch'.\n- Patch 9: Fix an overly long line (spotted by Ævar in an older iteration of\n  ar/submodule-update)\n- Patch 12: Test for usage using test_expect_code\n- Patch 13: Add missing spaces to the usage string\n\nSince v1:\n- Fix compilation error due to bad rebase\n- Remove accidentally included tests\n- Fix a NEEDSWORK (it was a leftover from ar/submodule-update)\n\nAtharva Raykar (3):\n  submodule--helper: get remote names from any repository\n  submodule--helper: refactor get_submodule_displaypath()\n  submodule--helper: allow setting superprefix for init_submodule()\n\nGlen Choo (8):\n  submodule--helper: remove update-module-mode\n  submodule--helper: reorganize code for sh to C conversion\n  submodule--helper run-update-procedure: remove --suboid\n  submodule--helper run-update-procedure: learn --remote\n  submodule--helper update-clone: learn --init\n  submodule--helper: remove ensure-core-worktree\n  submodule update: add tests for --filter\n  submodule--helper update-clone: check for --filter and --init\n\nÆvar Arnfjörð Bjarmason (2):\n  submodule tests: test for init and update failure output\n  submodule--helper: don't use bitfield indirection for parse_options()\n\n builtin/submodule--helper.c    | 248 +++++++++++++++++++--------------\n git-submodule.sh               |  54 +------\n t/t7406-submodule-update.sh    |  26 +++-\n t/t7408-submodule-reference.sh |  14 +-\n 4 files changed, 183 insertions(+), 159 deletions(-)\n\nRange-diff against v3:\n 1:  6138f4682c =  1:  6138f4682c submodule tests: test for init and update failure output\n 2:  6c83c78819 =  2:  6c83c78819 submodule--helper: remove update-module-mode\n 3:  9524986096 =  3:  9524986096 submodule--helper: reorganize code for sh to C conversion\n 4:  f42f3de2b7 !  4:  533de2c787 submodule--helper run-update-procedure: remove --suboid\n    @@ Commit message\n         submodule--helper run-update-procedure: remove --suboid\n     \n         Teach run-update-procedure to determine the oid of the submodule's HEAD\n    -    instead of doing it in git-subomdule.sh.\n    +    instead of doing it in git-submodule.sh.\n     \n         Signed-off-by: Glen Choo <chooglen@google.com>\n     \n 6:  8dc7bc5894 =  5:  bcc90c332b submodule--helper: get remote names from any repository\n 7:  feaf9f45d8 =  6:  93dd851882 submodule--helper: don't use bitfield indirection for parse_options()\n 8:  91e8e1a007 =  7:  1aff3622bc submodule--helper run-update-procedure: learn --remote\n 9:  aba851e71e =  8:  c59d6a9b3c submodule--helper: refactor get_submodule_displaypath()\n10:  2155c049a2 =  9:  28bc5887ea submodule--helper: allow setting superprefix for init_submodule()\n11:  03bbc39a06 = 10:  364d996481 submodule--helper update-clone: learn --init\n 5:  b0a0cae633 ! 11:  3b7d961ade submodule--helper: remove ensure-core-worktree\n    @@ Commit message\n         submodule--helper: remove ensure-core-worktree\n     \n         Move the logic of \"git submodule--helper ensure-core-worktree\" into\n    -    run-update-procedure. Since the ensure-core-worktree command is\n    -    obsolete, remove it.\n    +    run-update-procedure, and since this makes the ensure-core-worktree\n    +    command obsolete, remove it.\n    +\n    +    As a result, the order of two operations in git-submodule.sh is\n    +    reversed: 'set the value of core.worktree' now happens after the call to\n    +    \"git submodule--helper relative-path\". This is safe - \"relative-path\"\n    +    does not depend on the value of core.worktree.\n     \n         Signed-off-by: Glen Choo <chooglen@google.com>\n     \n12:  e49b26ad94 = 12:  70e00d294c submodule update: add tests for --filter\n13:  c97c97948a = 13:  ed7f8d57dc submodule--helper update-clone: check for --filter and --init\n\nbase-commit: 715d08a9e51251ad8290b181b6ac3b9e1f9719d7\n-- \n2.33.GIT\n\n"},{"id":"450467","messageId":"20220305001401.20888-2-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 01/13] submodule tests: test for init and update failure output","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:49Z","receivedAt":"2022-03-05T00:14:59Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nAmend some submodule tests to test for the failure output of \"git\nsubmodule [update|init]\". The lack of such tests hid a regression in\nan earlier version of a subsequent commit.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n t/t7406-submodule-update.sh    | 14 ++++++++++++--\n t/t7408-submodule-reference.sh | 14 +++++++++++++-\n 2 files changed, 25 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 11cccbb333..7764c1c3cb 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -205,8 +205,18 @@ test_expect_success 'submodule update should fail due to local changes' '\n \t (cd submodule &&\n \t  compare_head\n \t ) &&\n-\t test_must_fail git submodule update submodule\n-\t)\n+\t test_must_fail git submodule update submodule 2>../actual.raw\n+\t) &&\n+\tsed \"s/^> //\" >expect <<-\\EOF &&\n+\t> error: Your local changes to the following files would be overwritten by checkout:\n+\t> \tfile\n+\t> Please commit your changes or stash them before you switch branches.\n+\t> Aborting\n+\t> fatal: Unable to checkout OID in submodule path '\\''submodule'\\''\n+\tEOF\n+\tsed -e \"s/checkout $SQ[^$SQ]*$SQ/checkout OID/\" <actual.raw >actual &&\n+\ttest_cmp expect actual\n+\n '\n test_expect_success 'submodule update should throw away changes with --force ' '\n \t(cd super &&\ndiff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh\nindex a3892f494b..c3a4545510 100755\n--- a/t/t7408-submodule-reference.sh\n+++ b/t/t7408-submodule-reference.sh\n@@ -193,7 +193,19 @@ test_expect_success 'missing nested submodule alternate fails clone and submodul\n \t\tcd supersuper-clone &&\n \t\tcheck_that_two_of_three_alternates_are_used &&\n \t\t# update of the submodule fails\n-\t\ttest_must_fail git submodule update --init --recursive\n+\t\tcat >expect <<-\\EOF &&\n+\t\tfatal: submodule '\\''sub'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub'\\''. Retry scheduled\n+\t\tfatal: submodule '\\''sub-dissociate'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub-dissociate'\\''. Retry scheduled\n+\t\tfatal: submodule '\\''sub'\\'' cannot add alternate: path ... does not exist\n+\t\tFailed to clone '\\''sub'\\'' a second time, aborting\n+\t\tfatal: Failed to recurse into submodule path ...\n+\t\tEOF\n+\t\ttest_must_fail git submodule update --init --recursive 2>err &&\n+\t\tgrep -e fatal: -e ^Failed err >actual.raw &&\n+\t\tsed -e \"s/path $SQ[^$SQ]*$SQ/path .../\" <actual.raw >actual &&\n+\t\ttest_cmp expect actual\n \t)\n '\n \n-- \n2.33.GIT\n\n"},{"id":"450469","messageId":"20220305001401.20888-5-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 04/13] submodule--helper run-update-procedure: remove --suboid","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:52Z","receivedAt":"2022-03-05T00:15:10Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach run-update-procedure to determine the oid of the submodule's HEAD\ninstead of doing it in git-submodule.sh.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 9 ++++++---\n git-submodule.sh            | 8 +-------\n 2 files changed, 7 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 1b67a3887c..77ca4270f4 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2594,9 +2594,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\tOPT_CALLBACK_F(0, \"oid\", &update_data.oid, N_(\"sha1\"),\n \t\t\t       N_(\"SHA1 expected by superproject\"), PARSE_OPT_NONEG,\n \t\t\t       parse_opt_object_id),\n-\t\tOPT_CALLBACK_F(0, \"suboid\", &update_data.suboid, N_(\"subsha1\"),\n-\t\t\t       N_(\"SHA1 of submodule's HEAD\"), PARSE_OPT_NONEG,\n-\t\t\t       parse_opt_object_id),\n \t\tOPT_END()\n \t};\n \n@@ -3032,6 +3029,12 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n /* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n static int update_submodule2(struct update_data *update_data)\n {\n+\tif (update_data->just_cloned)\n+\t\toidcpy(&update_data->suboid, null_oid());\n+\telse if (resolve_gitlink_ref(update_data->sm_path, \"HEAD\", &update_data->suboid))\n+\t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n+\t\t\tupdate_data->displaypath);\n+\n \tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n \t\treturn do_run_update_procedure(update_data);\n \ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 87772ac891..32a09302ab 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -406,14 +406,9 @@ cmd_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\tif test $just_cloned -eq 0\n \t\tthen\n-\t\t\tsubsha1=\n-\t\telse\n \t\t\tjust_cloned=\n-\t\t\tsubsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n-\t\t\t\tgit rev-parse --verify HEAD) ||\n-\t\t\tdie \"fatal: $(eval_gettext \"Unable to find current revision in submodule path '\\$displaypath'\")\"\n \t\tfi\n \n \t\tif test -n \"$remote\"\n@@ -441,7 +436,6 @@ cmd_update()\n \t\t\t  ${update:+--update \"$update\"} \\\n \t\t\t  ${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t\t  ${sha1:+--oid \"$sha1\"} \\\n-\t\t\t  ${subsha1:+--suboid \"$subsha1\"} \\\n \t\t\t  \"--\" \\\n \t\t\t  \"$sm_path\")\n \n-- \n2.33.GIT\n\n"},{"id":"450470","messageId":"20220305001401.20888-4-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 03/13] submodule--helper: reorganize code for sh to C conversion","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:51Z","receivedAt":"2022-03-05T00:15:10Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Introduce a function, update_submodule2(), that will implement the\nfunctionality of run-update-procedure and its surrounding shell code in\nsubmodule.sh. This name is temporary; it will replace update_submodule()\nwhen the sh to C conversion is complete.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 26 +++++++++++++++++++++-----\n 1 file changed, 21 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex c11ee1ea2b..1b67a3887c 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2452,6 +2452,16 @@ static int do_run_update_procedure(struct update_data *ud)\n \treturn run_update_command(ud, subforce);\n }\n \n+/*\n+ * NEEDSWORK: As we convert \"git submodule update\" to C,\n+ * update_submodule2() will invoke more and more functions, making it\n+ * difficult to preserve the function ordering without forward\n+ * declarations.\n+ *\n+ * When the conversion is complete, this forward declaration will be\n+ * unnecessary and should be removed.\n+ */\n+static int update_submodule2(struct update_data *update_data);\n static void update_submodule(struct update_clone_data *ucd)\n {\n \tfprintf(stdout, \"dummy %s %d\\t%s\\n\",\n@@ -2618,11 +2628,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t    &update_data.update_strategy);\n \n \tfree(prefixed_path);\n-\n-\tif (!oideq(&update_data.oid, &update_data.suboid) || update_data.force)\n-\t\treturn do_run_update_procedure(&update_data);\n-\n-\treturn 3;\n+\treturn update_submodule2(&update_data);\n }\n \n static int resolve_relative_path(int argc, const char **argv, const char *prefix)\n@@ -3022,6 +3028,16 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n \t\t\t\t    force, reflog, quiet, track, dry_run);\n \treturn 0;\n }\n+\n+/* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n+static int update_submodule2(struct update_data *update_data)\n+{\n+\tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n+\t\treturn do_run_update_procedure(update_data);\n+\n+\treturn 3;\n+}\n+\n struct add_data {\n \tconst char *prefix;\n \tconst char *branch;\n-- \n2.33.GIT\n\n"},{"id":"450471","messageId":"20220305001401.20888-3-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 02/13] submodule--helper: remove update-module-mode","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:50Z","receivedAt":"2022-03-05T00:15:10Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"This is dead code - it has not been used since c51f8f94e5\n(submodule--helper: run update procedures from C, 2021-08-24).\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 24 ------------------------\n 1 file changed, 24 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex eeacefcc38..c11ee1ea2b 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1957,29 +1957,6 @@ static void determine_submodule_update_strategy(struct repository *r,\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@@ -3430,7 +3407,6 @@ static struct cmd_struct commands[] = {\n \t{\"name\", module_name, 0},\n \t{\"clone\", module_clone, 0},\n \t{\"add\", module_add, SUPPORT_SUPER_PREFIX},\n-\t{\"update-module-mode\", module_update_module_mode, 0},\n \t{\"update-clone\", update_clone, 0},\n \t{\"run-update-procedure\", run_update_procedure, 0},\n \t{\"ensure-core-worktree\", ensure_core_worktree, 0},\n-- \n2.33.GIT\n\n"},{"id":"450472","messageId":"20220305001401.20888-6-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 05/13] submodule--helper: get remote names from any repository","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:53Z","receivedAt":"2022-03-05T00:15:12Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\n`get_default_remote()` retrieves the name of a remote by resolving the\nrefs from of the current repository's ref store.\n\nThus in order to use it for retrieving the remote name of a submodule,\nwe have to start a new subprocess which runs from the submodule\ndirectory.\n\nLet's instead introduce a function called `repo_get_default_remote()`\nwhich takes any repository object and retrieves the remote accordingly.\n\n`get_default_remote()` is then defined as a call to\n`repo_get_default_remote()` with 'the_repository' passed to it.\n\nNow that we have `repo_get_default_remote()`, we no longer have to start\na subprocess that called `submodule--helper get-default-remote` from\nwithin the submodule directory.\n\nSo let's make a function called `get_default_remote_submodule()` which\ntakes a submodule path, and returns the default remote for that\nsubmodule, all within the same process.\n\nWe can now use this function to save an unnecessary subprocess spawn in\n`sync_submodule()`, and also in a subsequent patch, which will require\nthis functionality.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nHelped-by: Glen Choo <chooglen@google.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 38 ++++++++++++++++++++++---------------\n 1 file changed, 23 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 77ca4270f4..b5a2d83029 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -31,11 +31,13 @@\n typedef void (*each_submodule_fn)(const struct cache_entry *list_item,\n \t\t\t\t  void *cb_data);\n \n-static char *get_default_remote(void)\n+static char *repo_get_default_remote(struct repository *repo)\n {\n \tchar *dest = NULL, *ret;\n \tstruct strbuf sb = STRBUF_INIT;\n-\tconst char *refname = resolve_ref_unsafe(\"HEAD\", 0, NULL, NULL);\n+\tstruct ref_store *store = get_main_ref_store(repo);\n+\tconst char *refname = refs_resolve_ref_unsafe(store, \"HEAD\", 0, NULL,\n+\t\t\t\t\t\t      NULL);\n \n \tif (!refname)\n \t\tdie(_(\"No such ref: %s\"), \"HEAD\");\n@@ -48,7 +50,7 @@ static char *get_default_remote(void)\n \t\tdie(_(\"Expecting a full ref name, got %s\"), refname);\n \n \tstrbuf_addf(&sb, \"branch.%s.remote\", refname);\n-\tif (git_config_get_string(sb.buf, &dest))\n+\tif (repo_config_get_string(repo, sb.buf, &dest))\n \t\tret = xstrdup(\"origin\");\n \telse\n \t\tret = dest;\n@@ -57,6 +59,19 @@ static char *get_default_remote(void)\n \treturn ret;\n }\n \n+static char *get_default_remote_submodule(const char *module_path)\n+{\n+\tstruct repository subrepo;\n+\n+\trepo_submodule_init(&subrepo, the_repository, module_path, null_oid());\n+\treturn repo_get_default_remote(&subrepo);\n+}\n+\n+static char *get_default_remote(void)\n+{\n+\treturn repo_get_default_remote(the_repository);\n+}\n+\n static int print_default_remote(int argc, const char **argv, const char *prefix)\n {\n \tchar *remote;\n@@ -1343,9 +1358,8 @@ static void sync_submodule(const char *path, const char *prefix,\n {\n \tconst struct submodule *sub;\n \tchar *remote_key = NULL;\n-\tchar *sub_origin_url, *super_config_url, *displaypath;\n+\tchar *sub_origin_url, *super_config_url, *displaypath, *default_remote;\n \tstruct strbuf sb = STRBUF_INIT;\n-\tstruct child_process cp = CHILD_PROCESS_INIT;\n \tchar *sub_config_path = NULL;\n \n \tif (!is_submodule_active(the_repository, path))\n@@ -1384,21 +1398,15 @@ static void sync_submodule(const char *path, const char *prefix,\n \tif (!is_submodule_populated_gently(path, NULL))\n \t\tgoto cleanup;\n \n-\tprepare_submodule_repo_env(&cp.env_array);\n-\tcp.git_cmd = 1;\n-\tcp.dir = path;\n-\tstrvec_pushl(&cp.args, \"submodule--helper\",\n-\t\t     \"print-default-remote\", NULL);\n-\n \tstrbuf_reset(&sb);\n-\tif (capture_command(&cp, &sb, 0))\n+\tdefault_remote = get_default_remote_submodule(path);\n+\tif (!default_remote)\n \t\tdie(_(\"failed to get the default remote for submodule '%s'\"),\n \t\t      path);\n \n-\tstrbuf_strip_suffix(&sb, \"\\n\");\n-\tremote_key = xstrfmt(\"remote.%s.url\", sb.buf);\n+\tremote_key = xstrfmt(\"remote.%s.url\", default_remote);\n+\tfree(default_remote);\n \n-\tstrbuf_reset(&sb);\n \tsubmodule_to_gitdir(&sb, path);\n \tstrbuf_addstr(&sb, \"/config\");\n \n-- \n2.33.GIT\n\n"},{"id":"450473","messageId":"20220305001401.20888-7-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 06/13] submodule--helper: don't use bitfield indirection for parse_options()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:54Z","receivedAt":"2022-03-05T00:15:13Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n\nDo away with the indirection of local variables added in\nc51f8f94e5b (submodule--helper: run update procedures from C,\n2021-08-24).\n\nThese were only needed because in C you can't get a pointer to a\nsingle bit, so we were using intermediate variables instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 23 ++++++++++-------------\n 1 file changed, 10 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex b5a2d83029..3832dccae5 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2023,10 +2023,10 @@ struct update_data {\n \tstruct object_id suboid;\n \tstruct submodule_update_strategy update_strategy;\n \tint depth;\n-\tunsigned int force: 1;\n-\tunsigned int quiet: 1;\n-\tunsigned int nofetch: 1;\n-\tunsigned int just_cloned: 1;\n+\tunsigned int force;\n+\tunsigned int quiet;\n+\tunsigned int nofetch;\n+\tunsigned int just_cloned;\n };\n #define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }\n \n@@ -2578,16 +2578,17 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \n static int run_update_procedure(int argc, const char **argv, const char *prefix)\n {\n-\tint force = 0, quiet = 0, nofetch = 0, just_cloned = 0;\n \tchar *prefixed_path, *update = NULL;\n \tstruct update_data update_data = UPDATE_DATA_INIT;\n \n \tstruct option options[] = {\n-\t\tOPT__QUIET(&quiet, N_(\"suppress output for update by rebase or merge\")),\n-\t\tOPT__FORCE(&force, N_(\"force checkout updates\"), 0),\n-\t\tOPT_BOOL('N', \"no-fetch\", &nofetch,\n+\t\tOPT__QUIET(&update_data.quiet,\n+\t\t\t   N_(\"suppress output for update by rebase or merge\")),\n+\t\tOPT__FORCE(&update_data.force, N_(\"force checkout updates\"),\n+\t\t\t   0),\n+\t\tOPT_BOOL('N', \"no-fetch\", &update_data.nofetch,\n \t\t\t N_(\"don't fetch new objects from the remote site\")),\n-\t\tOPT_BOOL(0, \"just-cloned\", &just_cloned,\n+\t\tOPT_BOOL(0, \"just-cloned\", &update_data.just_cloned,\n \t\t\t N_(\"overrides update mode in case the repository is a fresh clone\")),\n \t\tOPT_INTEGER(0, \"depth\", &update_data.depth, N_(\"depth for shallow fetch\")),\n \t\tOPT_STRING(0, \"prefix\", &prefix,\n@@ -2615,10 +2616,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \tif (argc != 1)\n \t\tusage_with_options(usage, options);\n \n-\tupdate_data.force = !!force;\n-\tupdate_data.quiet = !!quiet;\n-\tupdate_data.nofetch = !!nofetch;\n-\tupdate_data.just_cloned = !!just_cloned;\n \tupdate_data.sm_path = argv[0];\n \n \tif (update_data.recursive_prefix)\n-- \n2.33.GIT\n\n"},{"id":"450474","messageId":"20220305001401.20888-8-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 07/13] submodule--helper run-update-procedure: learn --remote","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:55Z","receivedAt":"2022-03-05T00:15:16Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach run-update-procedure to handle --remote instead of parsing\n--remote in git-submodule.sh. As a result, \"git submodule--helper\n[print-default-remote|remote-branch]\" have no more callers, so remove\nthem.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 56 +++++++++++++++----------------------\n git-submodule.sh            | 30 +-------------------\n 2 files changed, 23 insertions(+), 63 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 3832dccae5..f673f7ebbf 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -72,21 +72,6 @@ static char *get_default_remote(void)\n \treturn repo_get_default_remote(the_repository);\n }\n \n-static int print_default_remote(int argc, const char **argv, const char *prefix)\n-{\n-\tchar *remote;\n-\n-\tif (argc != 1)\n-\t\tdie(_(\"submodule--helper print-default-remote takes no arguments\"));\n-\n-\tremote = get_default_remote();\n-\tif (remote)\n-\t\tprintf(\"%s\\n\", remote);\n-\n-\tfree(remote);\n-\treturn 0;\n-}\n-\n static int starts_with_dot_slash(const char *str)\n {\n \treturn str[0] == '.' && is_dir_sep(str[1]);\n@@ -2027,6 +2012,7 @@ struct update_data {\n \tunsigned int quiet;\n \tunsigned int nofetch;\n \tunsigned int just_cloned;\n+\tunsigned int remote;\n };\n #define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }\n \n@@ -2603,6 +2589,8 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)\n \t\tOPT_CALLBACK_F(0, \"oid\", &update_data.oid, N_(\"sha1\"),\n \t\t\t       N_(\"SHA1 expected by superproject\"), PARSE_OPT_NONEG,\n \t\t\t       parse_opt_object_id),\n+\t\tOPT_BOOL(0, \"remote\", &update_data.remote,\n+\t\t\t N_(\"use SHA-1 of submodule's remote tracking branch\")),\n \t\tOPT_END()\n \t};\n \n@@ -2682,23 +2670,6 @@ static const char *remote_submodule_branch(const char *path)\n \treturn branch;\n }\n \n-static int resolve_remote_submodule_branch(int argc, const char **argv,\n-\t\tconst char *prefix)\n-{\n-\tconst char *ret;\n-\tstruct strbuf sb = STRBUF_INIT;\n-\tif (argc != 2)\n-\t\tdie(\"submodule--helper remote-branch takes exactly one arguments, got %d\", argc);\n-\n-\tret = remote_submodule_branch(argv[1]);\n-\tif (!ret)\n-\t\tdie(\"submodule %s doesn't exist\", argv[1]);\n-\n-\tprintf(\"%s\", ret);\n-\tstrbuf_release(&sb);\n-\treturn 0;\n-}\n-\n static int push_check(int argc, const char **argv, const char *prefix)\n {\n \tstruct remote *remote;\n@@ -3040,6 +3011,25 @@ static int update_submodule2(struct update_data *update_data)\n \t\tdie(_(\"Unable to find current revision in submodule path '%s'\"),\n \t\t\tupdate_data->displaypath);\n \n+\tif (update_data->remote) {\n+\t\tchar *remote_name = get_default_remote_submodule(update_data->sm_path);\n+\t\tconst char *branch = remote_submodule_branch(update_data->sm_path);\n+\t\tchar *remote_ref = xstrfmt(\"refs/remotes/%s/%s\", remote_name, branch);\n+\n+\t\tif (!update_data->nofetch) {\n+\t\t\tif (fetch_in_submodule(update_data->sm_path, update_data->depth,\n+\t\t\t\t\t      0, NULL))\n+\t\t\t\tdie(_(\"Unable to fetch in submodule path '%s'\"),\n+\t\t\t\t    update_data->sm_path);\n+\t\t}\n+\n+\t\tif (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))\n+\t\t\tdie(_(\"Unable to find %s revision in submodule path '%s'\"),\n+\t\t\t    remote_ref, update_data->sm_path);\n+\n+\t\tfree(remote_ref);\n+\t}\n+\n \tif (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)\n \t\treturn do_run_update_procedure(update_data);\n \n@@ -3439,11 +3429,9 @@ static struct cmd_struct commands[] = {\n \t{\"foreach\", module_foreach, SUPPORT_SUPER_PREFIX},\n \t{\"init\", module_init, SUPPORT_SUPER_PREFIX},\n \t{\"status\", module_status, SUPPORT_SUPER_PREFIX},\n-\t{\"print-default-remote\", print_default_remote, 0},\n \t{\"sync\", module_sync, SUPPORT_SUPER_PREFIX},\n \t{\"deinit\", module_deinit, 0},\n \t{\"summary\", module_summary, SUPPORT_SUPER_PREFIX},\n-\t{\"remote-branch\", resolve_remote_submodule_branch, 0},\n \t{\"push-check\", push_check, 0},\n \t{\"absorb-git-dirs\", absorb_git_dirs, SUPPORT_SUPER_PREFIX},\n \t{\"is-active\", is_active, 0},\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 32a09302ab..882bf097d5 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -247,20 +247,6 @@ cmd_deinit()\n \tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- \"$@\"\n }\n \n-# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>]\n-# Because arguments are positional, use an empty string to omit <depth>\n-# but include <sha1>.\n-fetch_in_submodule () (\n-\tsanitize_submodule_env &&\n-\tcd \"$1\" &&\n-\tif test $# -eq 3\n-\tthen\n-\t\techo \"$3\" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+\"$2\"}\n-\telse\n-\t\tgit fetch ${GIT_QUIET:+--quiet} ${2:+\"$2\"}\n-\tfi\n-)\n-\n #\n # Update each submodule path to correct revision, using clone and checkout as needed\n #\n@@ -411,21 +397,6 @@ cmd_update()\n \t\t\tjust_cloned=\n \t\tfi\n \n-\t\tif test -n \"$remote\"\n-\t\tthen\n-\t\t\tbranch=$(git submodule--helper remote-branch \"$sm_path\")\n-\t\t\tif test -z \"$nofetch\"\n-\t\t\tthen\n-\t\t\t\t# Fetch remote before determining tracking $sha1\n-\t\t\t\tfetch_in_submodule \"$sm_path\" $depth ||\n-\t\t\t\tdie \"fatal: $(eval_gettext \"Unable to fetch in submodule path '\\$sm_path'\")\"\n-\t\t\tfi\n-\t\t\tremote_name=$(sanitize_submodule_env; cd \"$sm_path\" && git submodule--helper print-default-remote)\n-\t\t\tsha1=$(sanitize_submodule_env; cd \"$sm_path\" &&\n-\t\t\t\tgit rev-parse --verify \"${remote_name}/${branch}\") ||\n-\t\t\tdie \"fatal: $(eval_gettext \"Unable to find current \\${remote_name}/\\${branch} revision in submodule path '\\$sm_path'\")\"\n-\t\tfi\n-\n \t\tout=$(git submodule--helper run-update-procedure \\\n \t\t\t  ${wt_prefix:+--prefix \"$wt_prefix\"} \\\n \t\t\t  ${GIT_QUIET:+--quiet} \\\n@@ -436,6 +407,7 @@ cmd_update()\n \t\t\t  ${update:+--update \"$update\"} \\\n \t\t\t  ${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t\t  ${sha1:+--oid \"$sha1\"} \\\n+\t\t\t  ${remote:+--remote} \\\n \t\t\t  \"--\" \\\n \t\t\t  \"$sm_path\")\n \n-- \n2.33.GIT\n\n"},{"id":"450475","messageId":"20220305001401.20888-9-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 08/13] submodule--helper: refactor get_submodule_displaypath()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:56Z","receivedAt":"2022-03-05T00:15:17Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\nWe create a function called `do_get_submodule_displaypath()` that\ngenerates the display path required by several submodule functions, and\ntakes a custom superprefix parameter, instead of reading it from the\nenvironment.\n\nWe then redefine the existing `get_submodule_displaypath()` function\nas a call to this new function, where the superprefix is obtained from\nthe environment.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/submodule--helper.c | 14 ++++++++++----\n 1 file changed, 10 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex f673f7ebbf..52d4f47ffc 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -247,11 +247,10 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr\n \treturn 0;\n }\n \n-/* the result should be freed by the caller. */\n-static char *get_submodule_displaypath(const char *path, const char *prefix)\n+static char *do_get_submodule_displaypath(const char *path,\n+\t\t\t\t\t  const char *prefix,\n+\t\t\t\t\t  const char *super_prefix)\n {\n-\tconst char *super_prefix = get_super_prefix();\n-\n \tif (prefix && super_prefix) {\n \t\tBUG(\"cannot have prefix '%s' and superprefix '%s'\",\n \t\t    prefix, super_prefix);\n@@ -267,6 +266,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix)\n \t}\n }\n \n+/* the result should be freed by the caller. */\n+static char *get_submodule_displaypath(const char *path, const char *prefix)\n+{\n+\tconst char *super_prefix = get_super_prefix();\n+\treturn do_get_submodule_displaypath(path, prefix, super_prefix);\n+}\n+\n static char *compute_rev_name(const char *sub_path, const char* object_id)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n-- \n2.33.GIT\n\n"},{"id":"450476","messageId":"20220305001401.20888-10-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 09/13] submodule--helper: allow setting superprefix for init_submodule()","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:57Z","receivedAt":"2022-03-05T00:15:28Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"From: Atharva Raykar <raykar.ath@gmail.com>\n\nWe allow callers of the `init_submodule()` function to optionally\noverride the superprefix from the environment.\n\nWe need to enable this option because in our conversion of the update\ncommand that will follow, the '--init' option will be handled through\nthis API. We will need to change the superprefix at that time to ensure\nthe display paths show correctly in the output messages.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Shourya Shukla <periperidip@gmail.com>\nSigned-off-by: Atharva Raykar <raykar.ath@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/submodule--helper.c | 10 +++++++---\n 1 file changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 52d4f47ffc..c6df64bf6a 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -594,18 +594,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix)\n \n struct init_cb {\n \tconst char *prefix;\n+\tconst char *superprefix;\n \tunsigned int flags;\n };\n #define INIT_CB_INIT { 0 }\n \n static void init_submodule(const char *path, const char *prefix,\n-\t\t\t   unsigned int flags)\n+\t\t\t   const char *superprefix, unsigned int flags)\n {\n \tconst struct submodule *sub;\n \tstruct strbuf sb = STRBUF_INIT;\n \tchar *upd = NULL, *url = NULL, *displaypath;\n \n-\tdisplaypath = get_submodule_displaypath(path, prefix);\n+\t/* try superprefix from the environment, if it is not passed explicitly */\n+\tif (!superprefix)\n+\t\tsuperprefix = get_super_prefix();\n+\tdisplaypath = do_get_submodule_displaypath(path, prefix, superprefix);\n \n \tsub = submodule_from_path(the_repository, null_oid(), path);\n \n@@ -679,7 +683,7 @@ static void init_submodule(const char *path, const char *prefix,\n static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data)\n {\n \tstruct init_cb *info = cb_data;\n-\tinit_submodule(list_item->name, info->prefix, info->flags);\n+\tinit_submodule(list_item->name, info->prefix, info->superprefix, info->flags);\n }\n \n static int module_init(int argc, const char **argv, const char *prefix)\n-- \n2.33.GIT\n\n"},{"id":"450477","messageId":"20220305001401.20888-11-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 10/13] submodule--helper update-clone: learn --init","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:58Z","receivedAt":"2022-03-05T00:15:29Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Teach \"git submodule--helper update-clone\" the --init flag and remove\nthe corresponding shell code.\n\nWhen the `--init` flag is passed to the subcommand, we do not spawn a\nnew subprocess and call `submodule--helper init` on the submodule paths,\nbecause the Git machinery is not able to pick up the configuration\nchanges introduced by that init call. So we instead run the\n`init_submodule_cb()` callback over each submodule in the same process.\n\n[1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 26 ++++++++++++++++++++++++++\n git-submodule.sh            |  9 +++------\n 2 files changed, 29 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex c6df64bf6a..17dabf3d12 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2000,6 +2000,7 @@ struct submodule_update_clone {\n \tint failed_clones_nr, failed_clones_alloc;\n \n \tint max_jobs;\n+\tunsigned int init;\n };\n #define SUBMODULE_UPDATE_CLONE_INIT { \\\n \t.list = MODULE_LIST_INIT, \\\n@@ -2509,6 +2510,8 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \tint ret;\n \n \tstruct option module_update_clone_options[] = {\n+\t\tOPT_BOOL(0, \"init\", &suc.init,\n+\t\t\t N_(\"initialize uninitialized submodules before update\")),\n \t\tOPT_STRING(0, \"prefix\", &prefix,\n \t\t\t   N_(\"path\"),\n \t\t\t   N_(\"path into the working tree\")),\n@@ -2567,6 +2570,29 @@ 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+\tif (suc.init) {\n+\t\tstruct module_list list = MODULE_LIST_INIT;\n+\t\tstruct init_cb info = INIT_CB_INIT;\n+\n+\t\tif (module_list_compute(argc, argv, suc.prefix,\n+\t\t\t\t\t&pathspec, &list) < 0)\n+\t\t\treturn 1;\n+\n+\t\t/*\n+\t\t * If there are no path args and submodule.active is set then,\n+\t\t * by default, only initialize 'active' modules.\n+\t\t */\n+\t\tif (!argc && git_config_get_value_multi(\"submodule.active\"))\n+\t\t\tmodule_list_active(&list);\n+\n+\t\tinfo.prefix = suc.prefix;\n+\t\tinfo.superprefix = suc.recursive_prefix;\n+\t\tif (suc.quiet)\n+\t\t\tinfo.flags |= OPT_QUIET;\n+\n+\t\tfor_each_listed_submodule(&list, init_submodule_cb, &info);\n+\t}\n+\n \tret = update_submodules(&suc);\n \tlist_objects_filter_release(&filter_options);\n \treturn ret;\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 882bf097d5..16dea0ca59 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -361,14 +361,11 @@ cmd_update()\n \t\tusage\n \tfi\n \n-\tif test -n \"$init\"\n-\tthen\n-\t\tcmd_init \"--\" \"$@\" || return\n-\tfi\n-\n \t{\n-\tgit submodule--helper update-clone ${GIT_QUIET:+--quiet} \\\n+\tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper update-clone \\\n+\t\t${GIT_QUIET:+--quiet} \\\n \t\t${progress:+\"--progress\"} \\\n+\t\t${init:+--init} \\\n \t\t${wt_prefix:+--prefix \"$wt_prefix\"} \\\n \t\t${prefix:+--recursive-prefix \"$prefix\"} \\\n \t\t${update:+--update \"$update\"} \\\n-- \n2.33.GIT\n\n"},{"id":"450478","messageId":"20220305001401.20888-12-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 11/13] submodule--helper: remove ensure-core-worktree","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:13:59Z","receivedAt":"2022-03-05T00:15:31Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Move the logic of \"git submodule--helper ensure-core-worktree\" into\nrun-update-procedure, and since this makes the ensure-core-worktree\ncommand obsolete, remove it.\n\nAs a result, the order of two operations in git-submodule.sh is\nreversed: 'set the value of core.worktree' now happens after the call to\n\"git submodule--helper relative-path\". This is safe - \"relative-path\"\ndoes not depend on the value of core.worktree.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 12 ++----------\n git-submodule.sh            |  2 --\n 2 files changed, 2 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 17dabf3d12..296ab80bf2 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2783,17 +2783,11 @@ static int push_check(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int ensure_core_worktree(int argc, const char **argv, const char *prefix)\n+static void ensure_core_worktree(const char *path)\n {\n-\tconst char *path;\n \tconst char *cw;\n \tstruct repository subrepo;\n \n-\tif (argc != 2)\n-\t\tBUG(\"submodule--helper ensure-core-worktree <path>\");\n-\n-\tpath = argv[1];\n-\n \tif (repo_submodule_init(&subrepo, the_repository, path, null_oid()))\n \t\tdie(_(\"could not get a repository handle for submodule '%s'\"), path);\n \n@@ -2813,8 +2807,6 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)\n \t\tfree(abs_path);\n \t\tstrbuf_release(&sb);\n \t}\n-\n-\treturn 0;\n }\n \n static int absorb_git_dirs(int argc, const char **argv, const char *prefix)\n@@ -3041,6 +3033,7 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)\n /* NEEDSWORK: this is a temporary name until we delete update_submodule() */\n static int update_submodule2(struct update_data *update_data)\n {\n+\tensure_core_worktree(update_data->sm_path);\n \tif (update_data->just_cloned)\n \t\toidcpy(&update_data->suboid, null_oid());\n \telse if (resolve_gitlink_ref(update_data->sm_path, \"HEAD\", &update_data->suboid))\n@@ -3459,7 +3452,6 @@ static struct cmd_struct commands[] = {\n \t{\"add\", module_add, SUPPORT_SUPER_PREFIX},\n \t{\"update-clone\", update_clone, 0},\n \t{\"run-update-procedure\", run_update_procedure, 0},\n-\t{\"ensure-core-worktree\", ensure_core_worktree, 0},\n \t{\"relative-path\", resolve_relative_path, 0},\n \t{\"resolve-relative-url-test\", resolve_relative_url_test, 0},\n \t{\"foreach\", module_foreach, SUPPORT_SUPER_PREFIX},\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 16dea0ca59..51be7c7f7e 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -385,8 +385,6 @@ cmd_update()\n \tdo\n \t\tdie_if_unmatched \"$quickabort\" \"$sha1\"\n \n-\t\tgit submodule--helper ensure-core-worktree \"$sm_path\" || exit 1\n-\n \t\tdisplaypath=$(git submodule--helper relative-path \"$prefix$sm_path\" \"$wt_prefix\")\n \n \t\tif test $just_cloned -eq 0\n-- \n2.33.GIT\n\n"},{"id":"450479","messageId":"20220305001401.20888-14-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 13/13] submodule--helper update-clone: check for --filter and --init","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:14:01Z","receivedAt":"2022-03-05T00:15:35Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"\"git submodule update --filter\" also requires the \"--init\" option. Teach\nupdate-clone to do this usage check in C and remove the check from\ngit-submodule.sh.\n\nIn addition, change update-clone's usage string so that it teaches users\nabout \"git submodule update\" instead of \"git submodule--helper\nupdate-clone\" (the string is copied from git-submodule.sh). This should\nbe more helpful to users since they don't invoke update-clone directly.\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n builtin/submodule--helper.c | 20 +++++++++++++++++++-\n git-submodule.sh            |  5 -----\n 2 files changed, 19 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 296ab80bf2..bef9ab22d4 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2545,7 +2545,12 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \t};\n \n \tconst char *const git_submodule_helper_usage[] = {\n-\t\tN_(\"git submodule--helper update-clone [--prefix=<path>] [<path>...]\"),\n+\t\tN_(\"git submodule [--quiet] update\"\n+\t\t\" [--init [--filter=<filter-spec>]] [--remote]\"\n+\t\t\" [-N|--no-fetch] [-f|--force]\"\n+\t\t\" [--checkout|--merge|--rebase]\"\n+\t\t\" [--[no-]recommend-shallow] [--reference <repository>]\"\n+\t\t\" [--recursive] [--[no-]single-branch] [--] [<path>...]\"),\n \t\tNULL\n \t};\n \tsuc.prefix = prefix;\n@@ -2556,6 +2561,19 @@ static int update_clone(int argc, const char **argv, const char *prefix)\n \tmemset(&filter_options, 0, sizeof(filter_options));\n \targc = parse_options(argc, argv, prefix, module_update_clone_options,\n \t\t\t     git_submodule_helper_usage, 0);\n+\n+\tif (filter_options.choice && !suc.init) {\n+\t\t/*\n+\t\t * NEEDSWORK: Don't use usage_with_options() because the\n+\t\t * usage string is for \"git submodule update\", but the\n+\t\t * options are for \"git submodule--helper update-clone\".\n+\t\t *\n+\t\t * This will no longer be an issue when \"update-clone\"\n+\t\t * is replaced by \"git submodule--helper update\".\n+\t\t */\n+\t\tusage(git_submodule_helper_usage[0]);\n+\t}\n+\n \tsuc.filter_options = &filter_options;\n \n \tif (update)\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 51be7c7f7e..aa8bdfca9d 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -356,11 +356,6 @@ cmd_update()\n \t\tshift\n \tdone\n \n-\tif test -n \"$filter\" && test \"$init\" != \"1\"\n-\tthen\n-\t\tusage\n-\tfi\n-\n \t{\n \tgit ${wt_prefix:+-C \"$wt_prefix\"} submodule--helper update-clone \\\n \t\t${GIT_QUIET:+--quiet} \\\n-- \n2.33.GIT\n\n"},{"id":"450480","messageId":"20220305001401.20888-13-chooglen@google.com","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"[PATCH v4 12/13] submodule update: add tests for --filter","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-03-05T00:14:00Z","receivedAt":"2022-03-05T00:15:37Z","isPatch":true,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Test the \"--filter\" option to make sure we don't break anything while\nrefactoring \"git submodule update\".\n\nSigned-off-by: Glen Choo <chooglen@google.com>\n---\n t/t7406-submodule-update.sh | 12 ++++++++++++\n 1 file changed, 12 insertions(+)\n\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 7764c1c3cb..000e055811 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -1071,4 +1071,16 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s\n \t)\n '\n \n+test_expect_success 'submodule update --filter requires --init' '\n+\ttest_expect_code 129 git -C super submodule update --filter blob:none\n+'\n+\n+test_expect_success 'submodule update --filter sets partial clone settings' '\n+\ttest_when_finished \"rm -rf super-filter\" &&\n+\tgit clone cloned super-filter &&\n+\tgit -C super-filter submodule update --init --filter blob:none &&\n+\ttest_cmp_config -C super-filter/submodule true remote.origin.promisor &&\n+\ttest_cmp_config -C super-filter/submodule blob:none remote.origin.partialclonefilter\n+'\n+\n test_done\n-- \n2.33.GIT\n\n"},{"id":"450484","messageId":"xmqqfsnxw7s7.fsf@gitster.g","threadId":"57488","inReplyTo":"20220305001401.20888-1-chooglen@google.com","subject":"Re: [PATCH v4 00/13] submodule: convert parts of 'update' to C","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-05T00:40:56Z","receivedAt":"2022-03-05T00:41:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Glen Choo <chooglen@google.com> writes:\n\n> Original series: https://lore.kernel.org/git/20220210092833.55360-1-chooglen@google.com\n>\n> = Patch summary\n>\n> - Patch 1 adds extra tests to \"git submodule update\" to make sure we\n>   don't break anything\n> - Patch 2 removes dead code that used to be part of \"git submodule\n>   update\"\n> - Patch 3 prepares for later changes by introducing the C function that\n>   will hold most of the newly converted code\n> - Patch 4 moves run-update-procedure's --suboid option into C\n> - Patch 5 moves ensure-core-worktree into C\n> - Patches 6-8 move run-update-procedure's --remote option into C\n> - Patches 9-11 move \"git submodule update\"'s --init into C\n> - Patches 12-13 move \"git submodule update\"'s --filter option into C\n\nLooking good.  Will queue.\n\nLet's see if there are further comments before declaring victory and\nmerging it down to 'next' shortly.\n\nThanks.\n"}]}