{"thread":{"id":"49209","subject":"[PATCH v4 4/9] t7411: be nicer to future tests and really clean things up","startedAt":"2018-08-24T13:30:20Z","lastAt":"2018-09-04T07:11:03Z","messageCount":14,"participants":["Antonio Ospite","Ævar Arnfjörð Bjarmason"],"isPatch":true,"patchVersion":4,"patchTotal":9},"messages":[{"id":"356446","messageId":"20180824132951.8000-5-ao2@ao2.it","threadId":"49209","inReplyTo":"20180824132951.8000-1-ao2@ao2.it","subject":"[PATCH v4 4/9] t7411: be nicer to future tests and really clean things up","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T13:29:46Z","receivedAt":"2018-08-24T13:30:20Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Tests 5 and 7 in t/t7411-submodule-config.sh add two commits with\ninvalid lines in .gitmodules but then only the second commit is removed.\n\nThis may affect future subsequent tests if they assume that the\n.gitmodules file has no errors.\n\nRemove both the commits as soon as they are not needed anymore.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n t/t7411-submodule-config.sh | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh\nindex f2cd1f4a2c..b1f3c6489b 100755\n--- a/t/t7411-submodule-config.sh\n+++ b/t/t7411-submodule-config.sh\n@@ -83,6 +83,8 @@ Submodule name: 'submodule' for path 'submodule'\n EOF\n \n test_expect_success 'error in history of one submodule config lets continue, stderr message contains blob ref' '\n+\tORIG=$(git -C super rev-parse HEAD) &&\n+\ttest_when_finished \"git -C super reset --hard $ORIG\" &&\n \t(cd super &&\n \t\tcp .gitmodules .gitmodules.bak &&\n \t\techo \"\tvalue = \\\"\" >>.gitmodules &&\n@@ -115,6 +117,8 @@ test_expect_success 'using different treeishs works' '\n '\n \n test_expect_success 'error in history in fetchrecursesubmodule lets continue' '\n+\tORIG=$(git -C super rev-parse HEAD) &&\n+\ttest_when_finished \"git -C super reset --hard $ORIG\" &&\n \t(cd super &&\n \t\tgit config -f .gitmodules \\\n \t\t\tsubmodule.submodule.fetchrecursesubmodules blabla &&\n@@ -126,8 +130,7 @@ test_expect_success 'error in history in fetchrecursesubmodule lets continue' '\n \t\t\tHEAD b \\\n \t\t\tHEAD submodule \\\n \t\t\t\t>actual &&\n-\t\ttest_cmp expect_error actual  &&\n-\t\tgit reset --hard HEAD^\n+\t\ttest_cmp expect_error actual\n \t)\n '\n \n-- \n2.18.0\n\n"},{"id":"356447","messageId":"20180824132951.8000-2-ao2@ao2.it","threadId":"49209","inReplyTo":"20180824132951.8000-1-ao2@ao2.it","subject":"[PATCH v4 1/9] submodule: add a print_config_from_gitmodules() helper","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T13:29:43Z","receivedAt":"2018-08-24T13:30:20Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Add a new print_config_from_gitmodules() helper function to print values\nfrom .gitmodules just like \"git config -f .gitmodules\" would.\n\nThis will be used by a new submodule--helper subcommand to be able to\naccess the .gitmodules file in a more controlled way.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n submodule-config.c | 25 +++++++++++++++++++++++++\n submodule-config.h |  2 ++\n 2 files changed, 27 insertions(+)\n\ndiff --git a/submodule-config.c b/submodule-config.c\nindex fc2c41b947..eef96c4198 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -682,6 +682,31 @@ void submodule_free(struct repository *r)\n \t\tsubmodule_cache_clear(r->submodule_cache);\n }\n \n+static int config_print_callback(const char *key_, const char *value_, void *cb_data)\n+{\n+\tchar *key = cb_data;\n+\n+\tif (!strcmp(key, key_))\n+\t\tprintf(\"%s\\n\", value_);\n+\n+\treturn 0;\n+}\n+\n+int print_config_from_gitmodules(const char *key)\n+{\n+\tint ret;\n+\tchar *store_key;\n+\n+\tret = git_config_parse_key(key, &store_key, NULL);\n+\tif (ret < 0)\n+\t\treturn CONFIG_INVALID_KEY;\n+\n+\tconfig_from_gitmodules(config_print_callback, the_repository, store_key);\n+\n+\tfree(store_key);\n+\treturn 0;\n+}\n+\n struct fetch_config {\n \tint *max_children;\n \tint *recurse_submodules;\ndiff --git a/submodule-config.h b/submodule-config.h\nindex dc7278eea4..ed40e9a478 100644\n--- a/submodule-config.h\n+++ b/submodule-config.h\n@@ -56,6 +56,8 @@ void submodule_free(struct repository *r);\n  */\n int check_submodule_name(const char *name);\n \n+int print_config_from_gitmodules(const char *key);\n+\n /*\n  * Note: these helper functions exist solely to maintain backward\n  * compatibility with 'fetch' and 'update_clone' storing configuration in\n-- \n2.18.0\n\n"},{"id":"356448","messageId":"20180824132951.8000-10-ao2@ao2.it","threadId":"49209","inReplyTo":"20180824132951.8000-1-ao2@ao2.it","subject":"[PATCH v4 9/9] submodule: support reading .gitmodules when it's not in the working tree","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T13:29:51Z","receivedAt":"2018-08-24T13:30:21Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"When the .gitmodules file is not available in the working tree, try\nusing the content from the index and from the current branch. This\ncovers the case when the file is part of the repository but for some\nreason it is not checked out, for example because of a sparse checkout.\n\nThis makes it possible to use at least the 'git submodule' commands\nwhich *read* the gitmodules configuration file without fully populating\nthe working tree.\n\nWriting to .gitmodules will still require that the file is checked out,\nso check for that before calling config_set_in_gitmodules_file_gently.\n\nAdd a similar check also in git-submodule.sh::cmd_add() to anticipate\nthe eventual failure of the \"git submodule add\" command when .gitmodules\nis not safely writeable; this prevents the command from leaving the\nrepository in a spurious state (e.g. the submodule repository was cloned\nbut .gitmodules was not updated because\nconfig_set_in_gitmodules_file_gently failed).\n\nFinally, add t7416-submodule-sparse-gitmodules.sh to verify that reading\nfrom .gitmodules succeeds and that writing to it fails when the file is\nnot checked out.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n builtin/submodule--helper.c            |  6 +-\n git-submodule.sh                       |  5 ++\n submodule-config.c                     | 18 +++++-\n t/t7411-submodule-config.sh            | 26 ++++++++-\n t/t7416-submodule-sparse-gitmodules.sh | 78 ++++++++++++++++++++++++++\n 5 files changed, 129 insertions(+), 4 deletions(-)\n create mode 100755 t/t7416-submodule-sparse-gitmodules.sh\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 1bb168e814..6bc44d87dc 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2057,8 +2057,12 @@ static int module_config(int argc, const char **argv, const char *prefix)\n \t\treturn print_config_from_gitmodules(argv[1]);\n \n \t/* Equivalent to ACTION_SET in builtin/config.c */\n-\tif (argc == 3)\n+\tif (argc == 3) {\n+\t\tif (!is_writing_gitmodules_ok())\n+\t\t\tdie(_(\"please make sure that the .gitmodules file is in the working tree\"));\n+\n \t\treturn config_set_in_gitmodules_file_gently(argv[1], argv[2]);\n+\t}\n \n \tusage_with_options(git_submodule_helper_usage, module_config_options);\n }\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 9e47dc9574..0e44487135 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -159,6 +159,11 @@ cmd_add()\n \t\tshift\n \tdone\n \n+\tif ! git submodule--helper config --check-writeable >/dev/null 2>&1\n+\tthen\n+\t\t die \"$(eval_gettext \"please make sure that the .gitmodules file is in the working tree\")\"\n+\tfi\n+\n \tif test -n \"$reference_path\"\n \tthen\n \t\tis_absolute_path \"$reference_path\" ||\ndiff --git a/submodule-config.c b/submodule-config.c\nindex b7ef055c63..edba68ac85 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -1,4 +1,5 @@\n #include \"cache.h\"\n+#include \"dir.h\"\n #include \"repository.h\"\n #include \"config.h\"\n #include \"submodule-config.h\"\n@@ -603,8 +604,21 @@ static void submodule_cache_check_init(struct repository *repo)\n static void config_from_gitmodules(config_fn_t fn, struct repository *repo, void *data)\n {\n \tif (repo->worktree) {\n-\t\tchar *file = repo_worktree_path(repo, GITMODULES_FILE);\n-\t\tgit_config_from_file(fn, file, data);\n+\t\tstruct git_config_source config_source = { 0 };\n+\t\tconst struct config_options opts = { 0 };\n+\t\tstruct object_id oid;\n+\t\tchar *file;\n+\n+\t\tfile = repo_worktree_path(repo, GITMODULES_FILE);\n+\t\tif (file_exists(file))\n+\t\t\tconfig_source.file = file;\n+\t\telse if (get_oid(GITMODULES_INDEX, &oid) >= 0)\n+\t\t\tconfig_source.blob = GITMODULES_INDEX;\n+\t\telse if (get_oid(GITMODULES_HEAD, &oid) >= 0)\n+\t\t\tconfig_source.blob = GITMODULES_HEAD;\n+\n+\t\tconfig_with_options(fn, data, &config_source, &opts);\n+\n \t\tfree(file);\n \t}\n }\ndiff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh\nindex 45953f9300..2cfabb18bc 100755\n--- a/t/t7411-submodule-config.sh\n+++ b/t/t7411-submodule-config.sh\n@@ -134,7 +134,7 @@ test_expect_success 'error in history in fetchrecursesubmodule lets continue' '\n \t)\n '\n \n-test_expect_success 'reading submodules config with \"submodule--helper config\"' '\n+test_expect_success 'reading submodules config from the working tree with \"submodule--helper config\"' '\n \t(cd super &&\n \t\techo \"../submodule\" >expect &&\n \t\tgit submodule--helper config submodule.submodule.url >actual &&\n@@ -192,4 +192,28 @@ test_expect_success 'non-writeable .gitmodules when it is in the current branch\n \t)\n '\n \n+test_expect_success 'reading submodules config from the index when .gitmodules is not in the working tree' '\n+\tORIG=$(git -C super rev-parse HEAD) &&\n+\ttest_when_finished \"git -C super reset --hard $ORIG\" &&\n+\t(cd super &&\n+\t\tgit submodule--helper config submodule.submodule.url \"staged_url\" &&\n+\t\tgit add .gitmodules &&\n+\t\trm -f .gitmodules &&\n+\t\techo \"staged_url\" >expect &&\n+\t\tgit submodule--helper config submodule.submodule.url >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n+test_expect_success 'reading submodules config from the current branch when .gitmodules is not in the index' '\n+\tORIG=$(git -C super rev-parse HEAD) &&\n+\ttest_when_finished \"git -C super reset --hard $ORIG\" &&\n+\t(cd super &&\n+\t\tgit rm .gitmodules &&\n+\t\techo \"../submodule\" >expect &&\n+\t\tgit submodule--helper config submodule.submodule.url >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n test_done\ndiff --git a/t/t7416-submodule-sparse-gitmodules.sh b/t/t7416-submodule-sparse-gitmodules.sh\nnew file mode 100755\nindex 0000000000..908a4e6958\n--- /dev/null\n+++ b/t/t7416-submodule-sparse-gitmodules.sh\n@@ -0,0 +1,78 @@\n+#!/bin/sh\n+#\n+# Copyright (C) 2018  Antonio Ospite <ao2@ao2.it>\n+#\n+\n+test_description='Test reading/writing .gitmodules when not in the working tree\n+\n+This test verifies that, when .gitmodules is in the current branch but is not\n+in the working tree reading from it still works but writing to it does not.\n+\n+The test setup uses a sparse checkout, however the same scenario can be set up\n+also by committing .gitmodules and then just removing it from the filesystem.\n+'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'sparse checkout setup which hides .gitmodules' '\n+\techo file >file &&\n+\tgit add file &&\n+\ttest_tick &&\n+\tgit commit -m upstream &&\n+\tgit clone . super &&\n+\tgit clone super submodule &&\n+\tgit clone super new_submodule &&\n+\t(cd super &&\n+\t\tgit submodule add ../submodule &&\n+\t\ttest_tick &&\n+\t\tgit commit -m submodule &&\n+\t\tcat >.git/info/sparse-checkout <<-\\EOF &&\n+\t\t/*\n+\t\t!/.gitmodules\n+\t\tEOF\n+\t\tgit config core.sparsecheckout true &&\n+\t\tgit read-tree -m -u HEAD &&\n+\t\ttest_path_is_missing .gitmodules\n+\t)\n+'\n+\n+test_expect_success 'reading gitmodules config file when it is not checked out' '\n+\t(cd super &&\n+\t\techo \"../submodule\" >expect &&\n+\t\tgit submodule--helper config submodule.submodule.url >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n+test_expect_success 'not writing gitmodules config file when it is not checked out' '\n+\t test_must_fail git -C super submodule--helper config submodule.submodule.url newurl\n+'\n+\n+test_expect_success 'initialising submodule when the gitmodules config is not checked out' '\n+\tgit -C super submodule init\n+'\n+\n+test_expect_success 'showing submodule summary when the gitmodules config is not checked out' '\n+\tgit -C super submodule summary\n+'\n+\n+test_expect_success 'updating submodule when the gitmodules config is not checked out' '\n+\t(cd submodule &&\n+\t\techo file2 >file2 &&\n+\t\tgit add file2 &&\n+\t\tgit commit -m \"add file2 to submodule\"\n+\t) &&\n+\tgit -C super submodule update\n+'\n+\n+test_expect_success 'not adding submodules when the gitmodules config is not checked out' '\n+\ttest_must_fail git -C super submodule add ../new_submodule\n+'\n+\n+# This test checks that the previous \"git submodule add\" did not leave the\n+# repository in a spurious state when it failed.\n+test_expect_success 'init submodule still works even after the previous add failed' '\n+\tgit -C super submodule init\n+'\n+\n+test_done\n-- \n2.18.0\n\n"},{"id":"356449","messageId":"20180824132951.8000-3-ao2@ao2.it","threadId":"49209","inReplyTo":"20180824132951.8000-1-ao2@ao2.it","subject":"[PATCH v4 2/9] submodule: factor out a config_set_in_gitmodules_file_gently function","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T13:29:44Z","receivedAt":"2018-08-24T13:30:23Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Introduce a new config_set_in_gitmodules_file_gently() function to write\nconfig values to the .gitmodules file.\n\nThis is in preparation for a future change which will use the function\nto write to the .gitmodules file in a more controlled way instead of\nusing \"git config -f .gitmodules\".\n\nThe purpose of the change is mainly to centralize the code that writes\nto the .gitmodules file to avoid some duplication.\n\nThe naming follows git_config_set_in_file_gently() but the git_ prefix\nis removed to communicate that this is not a generic git-config API.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n submodule-config.c | 12 ++++++++++++\n submodule-config.h |  1 +\n submodule.c        | 10 +++-------\n 3 files changed, 16 insertions(+), 7 deletions(-)\n\ndiff --git a/submodule-config.c b/submodule-config.c\nindex eef96c4198..b7ef055c63 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -707,6 +707,18 @@ int print_config_from_gitmodules(const char *key)\n \treturn 0;\n }\n \n+int config_set_in_gitmodules_file_gently(const char *key, const char *value)\n+{\n+\tint ret;\n+\n+\tret = git_config_set_in_file_gently(GITMODULES_FILE, key, value);\n+\tif (ret < 0)\n+\t\t/* Maybe the user already did that, don't error out here */\n+\t\twarning(_(\"Could not update .gitmodules entry %s\"), key);\n+\n+\treturn ret;\n+}\n+\n struct fetch_config {\n \tint *max_children;\n \tint *recurse_submodules;\ndiff --git a/submodule-config.h b/submodule-config.h\nindex ed40e9a478..9957bcbbfa 100644\n--- a/submodule-config.h\n+++ b/submodule-config.h\n@@ -57,6 +57,7 @@ void submodule_free(struct repository *r);\n int check_submodule_name(const char *name);\n \n int print_config_from_gitmodules(const char *key);\n+int config_set_in_gitmodules_file_gently(const char *key, const char *value);\n \n /*\n  * Note: these helper functions exist solely to maintain backward\ndiff --git a/submodule.c b/submodule.c\nindex 50cbf5f13e..36a9465acb 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -89,6 +89,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)\n {\n \tstruct strbuf entry = STRBUF_INIT;\n \tconst struct submodule *submodule;\n+\tint ret;\n \n \tif (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */\n \t\treturn -1;\n@@ -104,14 +105,9 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)\n \tstrbuf_addstr(&entry, \"submodule.\");\n \tstrbuf_addstr(&entry, submodule->name);\n \tstrbuf_addstr(&entry, \".path\");\n-\tif (git_config_set_in_file_gently(GITMODULES_FILE, entry.buf, newpath) < 0) {\n-\t\t/* Maybe the user already did that, don't error out here */\n-\t\twarning(_(\"Could not update .gitmodules entry %s\"), entry.buf);\n-\t\tstrbuf_release(&entry);\n-\t\treturn -1;\n-\t}\n+\tret = config_set_in_gitmodules_file_gently(entry.buf, newpath);\n \tstrbuf_release(&entry);\n-\treturn 0;\n+\treturn ret;\n }\n \n /*\n-- \n2.18.0\n\n"},{"id":"356450","messageId":"20180824132951.8000-4-ao2@ao2.it","threadId":"49209","inReplyTo":"20180824132951.8000-1-ao2@ao2.it","subject":"[PATCH v4 3/9] t7411: merge tests 5 and 6","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T13:29:45Z","receivedAt":"2018-08-24T13:30:24Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Tests 5 and 6 check for the effects of the same commit, merge the two\ntests to make it more straightforward to clean things up after the test\nhas finished.\n\nThe cleanup will be added in a future commit.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n t/t7411-submodule-config.sh | 18 +++++-------------\n 1 file changed, 5 insertions(+), 13 deletions(-)\n\ndiff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh\nindex 0bde5850ac..f2cd1f4a2c 100755\n--- a/t/t7411-submodule-config.sh\n+++ b/t/t7411-submodule-config.sh\n@@ -82,29 +82,21 @@ Submodule name: 'a' for path 'b'\n Submodule name: 'submodule' for path 'submodule'\n EOF\n \n-test_expect_success 'error in one submodule config lets continue' '\n+test_expect_success 'error in history of one submodule config lets continue, stderr message contains blob ref' '\n \t(cd super &&\n \t\tcp .gitmodules .gitmodules.bak &&\n \t\techo \"\tvalue = \\\"\" >>.gitmodules &&\n \t\tgit add .gitmodules &&\n \t\tmv .gitmodules.bak .gitmodules &&\n \t\tgit commit -m \"add error\" &&\n-\t\ttest-tool submodule-config \\\n-\t\t\tHEAD b \\\n-\t\t\tHEAD submodule \\\n-\t\t\t\t>actual &&\n-\t\ttest_cmp expect_error actual\n-\t)\n-'\n-\n-test_expect_success 'error message contains blob reference' '\n-\t(cd super &&\n \t\tsha1=$(git rev-parse HEAD) &&\n \t\ttest-tool submodule-config \\\n \t\t\tHEAD b \\\n \t\t\tHEAD submodule \\\n-\t\t\t\t2>actual_err &&\n-\t\ttest_i18ngrep \"submodule-blob $sha1:.gitmodules\" actual_err >/dev/null\n+\t\t\t\t>actual \\\n+\t\t\t\t2>actual_stderr &&\n+\t\ttest_cmp expect_error actual &&\n+\t\ttest_i18ngrep \"submodule-blob $sha1:.gitmodules\" actual_stderr >/dev/null\n \t)\n '\n \n-- \n2.18.0\n\n"},{"id":"356451","messageId":"20180824132951.8000-7-ao2@ao2.it","threadId":"49209","inReplyTo":"20180824132951.8000-1-ao2@ao2.it","subject":"[PATCH v4 6/9] submodule: use the 'submodule--helper config' command","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T13:29:48Z","receivedAt":"2018-08-24T13:30:24Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Use the 'submodule--helper config' command in git-submodules.sh to avoid\nreferring explicitly to .gitmodules by the hardcoded file path.\n\nThis makes it possible to access the submodules configuration in a more\ncontrolled way.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n git-submodule.sh | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex f7fd80345c..9e47dc9574 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -72,7 +72,7 @@ get_submodule_config () {\n \tvalue=$(git config submodule.\"$name\".\"$option\")\n \tif test -z \"$value\"\n \tthen\n-\t\tvalue=$(git config -f .gitmodules submodule.\"$name\".\"$option\")\n+\t\tvalue=$(git submodule--helper config submodule.\"$name\".\"$option\")\n \tfi\n \tprintf '%s' \"${value:-$default}\"\n }\n@@ -283,11 +283,11 @@ or you are unsure what this means choose another name with the '--name' option.\"\n \tgit add --no-warn-embedded-repo $force \"$sm_path\" ||\n \tdie \"$(eval_gettext \"Failed to add submodule '\\$sm_path'\")\"\n \n-\tgit config -f .gitmodules submodule.\"$sm_name\".path \"$sm_path\" &&\n-\tgit config -f .gitmodules submodule.\"$sm_name\".url \"$repo\" &&\n+\tgit submodule--helper config submodule.\"$sm_name\".path \"$sm_path\" &&\n+\tgit submodule--helper config submodule.\"$sm_name\".url \"$repo\" &&\n \tif test -n \"$branch\"\n \tthen\n-\t\tgit config -f .gitmodules submodule.\"$sm_name\".branch \"$branch\"\n+\t\tgit submodule--helper config submodule.\"$sm_name\".branch \"$branch\"\n \tfi &&\n \tgit add --force .gitmodules ||\n \tdie \"$(eval_gettext \"Failed to register submodule '\\$sm_path'\")\"\n-- \n2.18.0\n\n"},{"id":"356452","messageId":"20180824132951.8000-9-ao2@ao2.it","threadId":"49209","inReplyTo":"20180824132951.8000-1-ao2@ao2.it","subject":"[PATCH v4 8/9] submodule: add a helper to check if it is safe to write to .gitmodules","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T13:29:50Z","receivedAt":"2018-08-24T13:30:25Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Introduce a helper function named is_writing_gitmodules_ok() to verify\nthat the .gitmodules file is safe to write.\n\nThe function name follows the scheme of is_staging_gitmodules_ok().\n\nThe two symbolic constants GITMODULES_INDEX and GITMODULES_HEAD are used\nto get help from the C preprocessor in preventing typos, especially for\nfuture users.\n\nThis is in preparation for a future change which teaches git how to read\n.gitmodules from the index or from the current branch if the file is not\navailable in the working tree.\n\nThe rationale behind the check is that writing to .gitmodules requires\nthe file to be present in the working tree, unless a brand new\n.gitmodules is being created (in which case the .gitmodules file would\nnot exist at all: neither in the working tree nor in the index or in the\ncurrent branch).\n\nExpose the functionality also via a \"submodule-helper config\n--check-writeable\" command, as git scripts may want to perform the check\nbefore modifying submodules configuration.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n builtin/submodule--helper.c | 24 +++++++++++++++++++++++-\n cache.h                     |  2 ++\n submodule.c                 | 18 ++++++++++++++++++\n submodule.h                 |  1 +\n t/t7411-submodule-config.sh | 31 +++++++++++++++++++++++++++++++\n 5 files changed, 75 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex a461a1107c..1bb168e814 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2030,6 +2030,28 @@ static int connect_gitdir_workingtree(int argc, const char **argv, const char *p\n \n static int module_config(int argc, const char **argv, const char *prefix)\n {\n+\tenum {\n+\t\tCHECK_WRITEABLE = 1\n+\t} command = 0;\n+\n+\tstruct option module_config_options[] = {\n+\t\tOPT_CMDMODE(0, \"check-writeable\", &command,\n+\t\t\t    N_(\"check if it is safe to write to the .gitmodules file\"),\n+\t\t\t    CHECK_WRITEABLE),\n+\t\tOPT_END()\n+\t};\n+\tconst char *const git_submodule_helper_usage[] = {\n+\t\tN_(\"git submodule--helper config name [value]\"),\n+\t\tN_(\"git submodule--helper config --check-writeable\"),\n+\t\tNULL\n+\t};\n+\n+\targc = parse_options(argc, argv, prefix, module_config_options,\n+\t\t\t     git_submodule_helper_usage, PARSE_OPT_KEEP_ARGV0);\n+\n+\tif (argc == 1 && command == CHECK_WRITEABLE)\n+\t\treturn is_writing_gitmodules_ok() ? 0 : -1;\n+\n \t/* Equivalent to ACTION_GET in builtin/config.c */\n \tif (argc == 2)\n \t\treturn print_config_from_gitmodules(argv[1]);\n@@ -2038,7 +2060,7 @@ static int module_config(int argc, const char **argv, const char *prefix)\n \tif (argc == 3)\n \t\treturn config_set_in_gitmodules_file_gently(argv[1], argv[2]);\n \n-\tdie(\"submodule--helper config takes 1 or 2 arguments: name [value]\");\n+\tusage_with_options(git_submodule_helper_usage, module_config_options);\n }\n \n #define SUPPORT_SUPER_PREFIX (1<<0)\ndiff --git a/cache.h b/cache.h\nindex b1fd3d58ab..e3fe1e6191 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -486,6 +486,8 @@ static inline enum object_type object_type(unsigned int mode)\n #define INFOATTRIBUTES_FILE \"info/attributes\"\n #define ATTRIBUTE_MACRO_PREFIX \"[attr]\"\n #define GITMODULES_FILE \".gitmodules\"\n+#define GITMODULES_INDEX \":.gitmodules\"\n+#define GITMODULES_HEAD \"HEAD:.gitmodules\"\n #define GIT_NOTES_REF_ENVIRONMENT \"GIT_NOTES_REF\"\n #define GIT_NOTES_DEFAULT_REF \"refs/notes/commits\"\n #define GIT_NOTES_DISPLAY_REF_ENVIRONMENT \"GIT_NOTES_DISPLAY_REF\"\ndiff --git a/submodule.c b/submodule.c\nindex 36a9465acb..d875b512df 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -50,6 +50,24 @@ int is_gitmodules_unmerged(const struct index_state *istate)\n \treturn 0;\n }\n \n+/*\n+ * Check if the .gitmodules file is safe to write.\n+ *\n+ * Writing to the .gitmodules file requires that the file exists in the\n+ * working tree or, if it doesn't, that a brand new .gitmodules file is going\n+ * to be created (i.e. it's neither in the index nor in the current branch).\n+ *\n+ * It is not safe to write to .gitmodules if it's not in the working tree but\n+ * it is in the index or in the current branch, because writing new values\n+ * (and staging them) would blindly overwrite ALL the old content.\n+ */\n+int is_writing_gitmodules_ok(void)\n+{\n+\tstruct object_id oid;\n+\treturn file_exists(GITMODULES_FILE) ||\n+\t\t(get_oid(GITMODULES_INDEX, &oid) < 0 && get_oid(GITMODULES_HEAD, &oid) < 0);\n+}\n+\n /*\n  * Check if the .gitmodules file has unstaged modifications.  This must be\n  * checked before allowing modifications to the .gitmodules file with the\ndiff --git a/submodule.h b/submodule.h\nindex 7d476cefa7..5106d4597a 100644\n--- a/submodule.h\n+++ b/submodule.h\n@@ -40,6 +40,7 @@ struct submodule_update_strategy {\n #define SUBMODULE_UPDATE_STRATEGY_INIT {SM_UPDATE_UNSPECIFIED, NULL}\n \n int is_gitmodules_unmerged(const struct index_state *istate);\n+int is_writing_gitmodules_ok(void);\n int is_staging_gitmodules_ok(struct index_state *istate);\n int update_path_in_gitmodules(const char *oldpath, const char *newpath);\n int remove_path_from_gitmodules(const char *path);\ndiff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh\nindex 791245f18d..45953f9300 100755\n--- a/t/t7411-submodule-config.sh\n+++ b/t/t7411-submodule-config.sh\n@@ -161,4 +161,35 @@ test_expect_success 'overwriting unstaged submodules config with \"submodule--hel\n \t)\n '\n \n+test_expect_success 'writeable .gitmodules when it is in the working tree' '\n+\tgit -C super submodule--helper config --check-writeable\n+'\n+\n+test_expect_success 'writeable .gitmodules when it is nowhere in the repository' '\n+\tORIG=$(git -C super rev-parse HEAD) &&\n+\ttest_when_finished \"git -C super reset --hard $ORIG\" &&\n+\t(cd super &&\n+\t\tgit rm .gitmodules &&\n+\t\tgit commit -m \"remove .gitmodules from the current branch\" &&\n+\t\tgit submodule--helper config --check-writeable\n+\t)\n+'\n+\n+test_expect_success 'non-writeable .gitmodules when it is in the index but not in the working tree' '\n+\ttest_when_finished \"git -C super checkout .gitmodules\" &&\n+\t(cd super &&\n+\t\trm -f .gitmodules &&\n+\t\ttest_must_fail git submodule--helper config --check-writeable\n+\t)\n+'\n+\n+test_expect_success 'non-writeable .gitmodules when it is in the current branch but not in the index' '\n+\tORIG=$(git -C super rev-parse HEAD) &&\n+\ttest_when_finished \"git -C super reset --hard $ORIG\" &&\n+\t(cd super &&\n+\t\tgit rm .gitmodules &&\n+\t\ttest_must_fail git submodule--helper config --check-writeable\n+\t)\n+'\n+\n test_done\n-- \n2.18.0\n\n"},{"id":"356453","messageId":"20180824132951.8000-8-ao2@ao2.it","threadId":"49209","inReplyTo":"20180824132951.8000-1-ao2@ao2.it","subject":"[PATCH v4 7/9] t7506: clean up .gitmodules properly before setting up new scenario","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T13:29:49Z","receivedAt":"2018-08-24T13:30:26Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"In t/t7506-status-submodule.sh at some point a new scenario is set up to\ntest different things, in particular new submodules are added which are\nmeant to completely replace the previous ones.\n\nHowever before calling the \"git submodule add\" commands for the new\nlayout, the .gitmodules file is removed only from the working tree still\nleaving the previous content in current branch.\n\nThis can break if, in the future, \"git submodule add\" starts\ndifferentiating between the following two cases:\n\n  - .gitmodules is not in the working tree but it is in the current\n    branch (it may not be safe to add new submodules in this case);\n\n  - .gitmodules is neither in the working tree nor anywhere in the\n    current branch (it is safe to add new submodules).\n\nSince the test intends to get rid of .gitmodules anyways, let's\ncompletely remove it from the current branch, to actually start afresh\nin the new scenario.\n\nThis is more future-proof and does not break current tests.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n t/t7506-status-submodule.sh | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh\nindex 943708fb04..08629a6e70 100755\n--- a/t/t7506-status-submodule.sh\n+++ b/t/t7506-status-submodule.sh\n@@ -325,7 +325,8 @@ test_expect_success 'setup superproject with untracked file in nested submodule'\n \t(\n \t\tcd super &&\n \t\tgit clean -dfx &&\n-\t\trm .gitmodules &&\n+\t\tgit rm .gitmodules &&\n+\t\tgit commit -m \"remove .gitmodules\" &&\n \t\tgit submodule add -f ./sub1 &&\n \t\tgit submodule add -f ./sub2 &&\n \t\tgit submodule add -f ./sub1 sub3 &&\n-- \n2.18.0\n\n"},{"id":"356454","messageId":"20180824132951.8000-6-ao2@ao2.it","threadId":"49209","inReplyTo":"20180824132951.8000-1-ao2@ao2.it","subject":"[PATCH v4 5/9] submodule--helper: add a new 'config' subcommand","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T13:29:47Z","receivedAt":"2018-08-24T13:30:28Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Add a new 'config' subcommand to 'submodule--helper', this extra level\nof indirection makes it possible to add some flexibility to how the\nsubmodules configuration is handled.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n builtin/submodule--helper.c | 14 ++++++++++++++\n t/t7411-submodule-config.sh | 27 +++++++++++++++++++++++++++\n 2 files changed, 41 insertions(+)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 2bcc70fdfe..a461a1107c 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2028,6 +2028,19 @@ static int connect_gitdir_workingtree(int argc, const char **argv, const char *p\n \treturn 0;\n }\n \n+static int module_config(int argc, const char **argv, const char *prefix)\n+{\n+\t/* Equivalent to ACTION_GET in builtin/config.c */\n+\tif (argc == 2)\n+\t\treturn print_config_from_gitmodules(argv[1]);\n+\n+\t/* Equivalent to ACTION_SET in builtin/config.c */\n+\tif (argc == 3)\n+\t\treturn config_set_in_gitmodules_file_gently(argv[1], argv[2]);\n+\n+\tdie(\"submodule--helper config takes 1 or 2 arguments: name [value]\");\n+}\n+\n #define SUPPORT_SUPER_PREFIX (1<<0)\n \n struct cmd_struct {\n@@ -2056,6 +2069,7 @@ static struct cmd_struct commands[] = {\n \t{\"absorb-git-dirs\", absorb_git_dirs, SUPPORT_SUPER_PREFIX},\n \t{\"is-active\", is_active, 0},\n \t{\"check-name\", check_name, 0},\n+\t{\"config\", module_config, 0},\n };\n \n int cmd_submodule__helper(int argc, const char **argv, const char *prefix)\ndiff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh\nindex b1f3c6489b..791245f18d 100755\n--- a/t/t7411-submodule-config.sh\n+++ b/t/t7411-submodule-config.sh\n@@ -134,4 +134,31 @@ test_expect_success 'error in history in fetchrecursesubmodule lets continue' '\n \t)\n '\n \n+test_expect_success 'reading submodules config with \"submodule--helper config\"' '\n+\t(cd super &&\n+\t\techo \"../submodule\" >expect &&\n+\t\tgit submodule--helper config submodule.submodule.url >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n+test_expect_success 'writing submodules config with \"submodule--helper config\"' '\n+\t(cd super &&\n+\t\techo \"new_url\" >expect &&\n+\t\tgit submodule--helper config submodule.submodule.url \"new_url\" &&\n+\t\tgit submodule--helper config submodule.submodule.url >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n+test_expect_success 'overwriting unstaged submodules config with \"submodule--helper config\"' '\n+\ttest_when_finished \"git -C super checkout .gitmodules\" &&\n+\t(cd super &&\n+\t\techo \"newer_url\" >expect &&\n+\t\tgit submodule--helper config submodule.submodule.url \"newer_url\" &&\n+\t\tgit submodule--helper config submodule.submodule.url >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n test_done\n-- \n2.18.0\n\n"},{"id":"356455","messageId":"20180824132951.8000-1-ao2@ao2.it","threadId":"49209","inReplyTo":null,"subject":"[PATCH v4 0/9] Make submodules work if .gitmodules is not checked out","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T13:29:42Z","receivedAt":"2018-08-24T13:30:30Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Hi,\n\nthis series teaches git to try and read the .gitmodules file from the\nindex (:.gitmodules) and the current branch (HEAD:.gitmodules) when it\nis not readily available in the working tree.\n\nThis can be used, together with sparse checkouts, to enable submodule\nusage with programs like vcsh[1] which manage multiple repositories with\ntheir working trees sharing the same path.\n\n[1] https://github.com/RichiH/vcsh\n\nIn v4 patches 1, 2, 5, 6, and 7 are basically the same as in the\nprevious series; the review can concentrate on patches 3, 4, 8, and 9.\n\nv3 of the series is here:\nhttps://public-inbox.org/git/20180814110525.17801-1-ao2@ao2.it/\n\nv2 of the series is here:\nhttps://public-inbox.org/git/20180802134634.10300-1-ao2@ao2.it/\n\nv1 of the series, with some background info, is here:\nhttps://public-inbox.org/git/20180514105823.8378-1-ao2@ao2.it/\n\nChanges since v3:\n\n  * Improve robustness of current tests in t7411-submodule-config.sh:\n      - merge two tests that check for effects of the same commit.\n      - reset to a well defined point in history when exiting the tests.\n\n  * Fix style issues in new tests added to t7411-submodule-config.sh:\n      - use test_when_finished in new tests.\n      - name the output file 'expect' instead of 'expected'.\n\n  * Add a new \"submodule--helper config --check-writeable\" command.\n\n  * Use \"s--h config --check-wrteable\" in git-submodule.sh to share the\n    code with the C implementation instead of duplicating the safety\n    check in shell script.\n\n  * Add the ability to read .gitmodules from the index and then\n    fall-back to the current branch if the file is not in the index.\n    Add also more tests to validate all the possible scenarios.\n\n  * Fix style issues in t7416-submodule-sparse-gitmodules.sh:\n      - name the output file 'expect' instead of 'expected'.\n      - remove white space after the redirection operator.\n      - indent the HEREDOC block.\n      - use \"git -C super\" instead of a subshell when there is only one\n        command in the test.\n\n  * Remove a stale file named 'new' which erroneusly slipped in\n    a commit.\n\n  * Update some comments and commit messages.\n\n\nThanks,\n   Antonio\n\nAntonio Ospite (9):\n  submodule: add a print_config_from_gitmodules() helper\n  submodule: factor out a config_set_in_gitmodules_file_gently function\n  t7411: merge tests 5 and 6\n  t7411: be nicer to future tests and really clean things up\n  submodule--helper: add a new 'config' subcommand\n  submodule: use the 'submodule--helper config' command\n  t7506: clean up .gitmodules properly before setting up new scenario\n  submodule: add a helper to check if it is safe to write to .gitmodules\n  submodule: support reading .gitmodules when it's not in the working\n    tree\n\n builtin/submodule--helper.c            |  40 +++++++++\n cache.h                                |   2 +\n git-submodule.sh                       |  13 ++-\n submodule-config.c                     |  55 ++++++++++++-\n submodule-config.h                     |   3 +\n submodule.c                            |  28 +++++--\n submodule.h                            |   1 +\n t/t7411-submodule-config.sh            | 107 +++++++++++++++++++++----\n t/t7416-submodule-sparse-gitmodules.sh |  78 ++++++++++++++++++\n t/t7506-status-submodule.sh            |   3 +-\n 10 files changed, 301 insertions(+), 29 deletions(-)\n create mode 100755 t/t7416-submodule-sparse-gitmodules.sh\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"},{"id":"356457","messageId":"87wosfesxl.fsf@evledraar.gmail.com","threadId":"49209","inReplyTo":"20180824132951.8000-2-ao2@ao2.it","subject":"Re: [PATCH v4 1/9] submodule: add a print_config_from_gitmodules() helper","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-08-24T14:32:38Z","receivedAt":"2018-08-24T14:32:44Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Aug 24 2018, Antonio Ospite wrote:\n\n> Add a new print_config_from_gitmodules() helper function to print values\n> from .gitmodules just like \"git config -f .gitmodules\" would.\n>\n> This will be used by a new submodule--helper subcommand to be able to\n> access the .gitmodules file in a more controlled way.\n>\n> Signed-off-by: Antonio Ospite <ao2@ao2.it>\n> ---\n>  submodule-config.c | 25 +++++++++++++++++++++++++\n>  submodule-config.h |  2 ++\n>  2 files changed, 27 insertions(+)\n>\n> diff --git a/submodule-config.c b/submodule-config.c\n> index fc2c41b947..eef96c4198 100644\n> --- a/submodule-config.c\n> +++ b/submodule-config.c\n> @@ -682,6 +682,31 @@ void submodule_free(struct repository *r)\n>  \t\tsubmodule_cache_clear(r->submodule_cache);\n>  }\n>\n> +static int config_print_callback(const char *key_, const char *value_, void *cb_data)\n> +{\n> +\tchar *key = cb_data;\n> +\n> +\tif (!strcmp(key, key_))\n> +\t\tprintf(\"%s\\n\", value_);\n> +\n> +\treturn 0;\n> +}\n\nNo problem with the code itself, but I'd find this a lot easier to read\nin context if it was:\n\n    key_ -> var\n    value_ -> value\n    key -> wanted_key, perhaps?\n\nI.e. the rest of the file uses the convention of the\nconfig_from_gitmodules callbacks getting \"var\" and \"value\",\nrespectively.\n\nWe don't use this convention of suffixing variables with \"_\" if they're\narguments to the function anywhere else.\n\n> +int print_config_from_gitmodules(const char *key)\n> +{\n> +\tint ret;\n> +\tchar *store_key;\n> +\n> +\tret = git_config_parse_key(key, &store_key, NULL);\n> +\tif (ret < 0)\n> +\t\treturn CONFIG_INVALID_KEY;\n\nIsn't this a memory leak? I.e. we should free() and return here, no?\n\n> +\tconfig_from_gitmodules(config_print_callback, the_repository, store_key);\n> +\n> +\tfree(store_key);\n> +\treturn 0;\n> +}\n> +\n>  struct fetch_config {\n>  \tint *max_children;\n>  \tint *recurse_submodules;\n> diff --git a/submodule-config.h b/submodule-config.h\n> index dc7278eea4..ed40e9a478 100644\n> --- a/submodule-config.h\n> +++ b/submodule-config.h\n> @@ -56,6 +56,8 @@ void submodule_free(struct repository *r);\n>   */\n>  int check_submodule_name(const char *name);\n>\n> +int print_config_from_gitmodules(const char *key);\n> +\n>  /*\n>   * Note: these helper functions exist solely to maintain backward\n>   * compatibility with 'fetch' and 'update_clone' storing configuration in\n\nAnother style nit: Makes more sense to put this new function right\nunderneath \"submodule_free\" above, instead of under 1/2 of the functions\nthat have a big comment describing how they work, since that comment\ndoesn't apply to this new function.\n"},{"id":"356458","messageId":"87va7zesn2.fsf@evledraar.gmail.com","threadId":"49209","inReplyTo":"20180824132951.8000-1-ao2@ao2.it","subject":"Re: [PATCH v4 0/9] Make submodules work if .gitmodules is not checked out","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-08-24T14:38:57Z","receivedAt":"2018-08-24T14:39:02Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Aug 24 2018, Antonio Ospite wrote:\n\n> this series teaches git to try and read the .gitmodules file from the\n> index (:.gitmodules) and the current branch (HEAD:.gitmodules) when it\n> is not readily available in the working tree.\n\nFWIW I didn't read any of the earlier series's, and I'm not that\nfamiliar with the submodule code, but having skimmed this all (not live\ntested at all) nothing jumped out at me as an issue, I just had some\nminor style / potential memory leak nits on 1/9.\n"},{"id":"356480","messageId":"20180824185251.be9374239a7a9ec0a796afe7@ao2.it","threadId":"49209","inReplyTo":"87wosfesxl.fsf@evledraar.gmail.com","subject":"Re: [PATCH v4 1/9] submodule: add a print_config_from_gitmodules() helper","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-08-24T16:52:51Z","receivedAt":"2018-08-24T16:52:56Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"On Fri, 24 Aug 2018 16:32:38 +0200\nÆvar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n\n> \n> On Fri, Aug 24 2018, Antonio Ospite wrote:\n[...]\n> > +static int config_print_callback(const char *key_, const char *value_, void *cb_data)\n> > +{\n> > +\tchar *key = cb_data;\n> > +\n> > +\tif (!strcmp(key, key_))\n> > +\t\tprintf(\"%s\\n\", value_);\n> > +\n> > +\treturn 0;\n> > +}\n> \n> No problem with the code itself, but I'd find this a lot easier to read\n> in context if it was:\n> \n>     key_ -> var\n>     value_ -> value\n>     key -> wanted_key, perhaps?\n> \n> I.e. the rest of the file uses the convention of the\n> config_from_gitmodules callbacks getting \"var\" and \"value\",\n> respectively.\n> \n> We don't use this convention of suffixing variables with \"_\" if they're\n> arguments to the function anywhere else.\n>\n\nI was new to git when I firstly wrote the code, I picked up the style\nby copying from builtin/config.c (collect_config() and\nshow_all_config()) because I was focusing more on the functionality and\ndidn't bother to harmonize the style with the destination file.\n\n> > +int print_config_from_gitmodules(const char *key)\n> > +{\n> > +\tint ret;\n> > +\tchar *store_key;\n> > +\n> > +\tret = git_config_parse_key(key, &store_key, NULL);\n> > +\tif (ret < 0)\n> > +\t\treturn CONFIG_INVALID_KEY;\n> \n> Isn't this a memory leak? I.e. we should free() and return here, no?\n>\n\nIt is true that git_config_parse_key_1() allocates some storage even\nfor an invalid key, and uses the space to lowercase the key as the\nparsing progresses, however it also frees the memory in the *error*\npath.\n\nSo unless I am missing something I don't think there is a leak here.\n\n[...]\n> > diff --git a/submodule-config.h b/submodule-config.h\n> > index dc7278eea4..ed40e9a478 100644\n> > --- a/submodule-config.h\n> > +++ b/submodule-config.h\n> > @@ -56,6 +56,8 @@ void submodule_free(struct repository *r);\n> >   */\n> >  int check_submodule_name(const char *name);\n> >\n> > +int print_config_from_gitmodules(const char *key);\n> > +\n> >  /*\n> >   * Note: these helper functions exist solely to maintain backward\n> >   * compatibility with 'fetch' and 'update_clone' storing configuration in\n> \n> Another style nit: Makes more sense to put this new function right\n> underneath \"submodule_free\" above, instead of under 1/2 of the functions\n> that have a big comment describing how they work, since that comment\n> doesn't apply to this new function.\n\nYou are probably right, IIRC the function was firstly written before\ncheck_submodule_name() was there. And I didn't think of moving it up\nwhen I rebased after check_submodule_name() was added.\n\nYour same remark may apply to the new function added in patch 02.\n\nI'll wait for other comments to see if a v5 is really needed.\n\nThanks for the review Ævar.\n\nCiao,\n   Antonio\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"},{"id":"357287","messageId":"20180904091059.3474f58873f82f4e160e06aa@ao2.it","threadId":"49209","inReplyTo":"20180824185251.be9374239a7a9ec0a796afe7@ao2.it","subject":"Re: [PATCH v4 1/9] submodule: add a print_config_from_gitmodules() helper","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-09-04T07:10:59Z","receivedAt":"2018-09-04T07:11:03Z","isPatch":true,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"On Fri, 24 Aug 2018 18:52:51 +0200\nAntonio Ospite <ao2@ao2.it> wrote:\n\n[...] \n> I'll wait for other comments to see if a v5 is really needed.\n> \n\nPing. In case someone missed v4.\n\nThanks,\n   Antonio\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"}]}