[PATCH v6 05/10] submodule: allow runtime enabling extensions.submodulePathConfig
- From
Adrian Ratiu <adrian.ratiu@collabora.com>
- Date
- Dec 13, 2025, 08:08 UTC
- Message-ID
- <20251213080817.347922-6-adrian.ratiu@collabora.com>
- In-Reply-To
- <20251213080817.347922-1-adrian.ratiu@collabora.com>
This adds the ability to enable the new extension via a runtime config to avoid having to enable it in each repo configuration.
Suggested-by: Patrick Steinhardt <ps@pks.im> Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> --- Documentation/config/extensions.adoc | 2 + builtin/submodule--helper.c | 8 +++- submodule.c | 4 +- submodule.h | 2 + t/t7425-submodule-gitdir-path-extension.sh | 46 ++++++++++++++++++++++ 5 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/Documentation/config/extensions.adoc b/Documentation/config/extensions.adoc index 6ce1dcc98b..929e4e1bf1 100644 --- a/Documentation/config/extensions.adoc +++ b/Documentation/config/extensions.adoc @@ -77,6 +77,8 @@ submodulePathConfig::: If enabled, the submodule.<name>.gitdir config is the single source of truth for submodule gitdir paths and is always set for new submodules. Git will error if a module does not have submodule.<name>.gitdir set. + This extension can also be enabled as a global runtime config, with + the local repository config having precedence (overwrites it). Existing pre-extension submodules need to be migrated by adding the missing config entries. This is done manually for now, e.g. for each submodule: "git config submodule.<name>.gitdir .git/modules/<name>". diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 699ac32004..2b5b4f575b 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -466,7 +466,8 @@ static void create_default_gitdir_config(const char *submodule_name) struct strbuf gitdir_path = STRBUF_INIT; /* The config is set only when extensions.submodulePathConfig is enabled */ - if (!the_repository->repository_format_submodule_path_cfg) + if (!the_repository->repository_format_submodule_path_cfg && + !submodule_path_config_enabled) return; repo_git_path_append(the_repository, &gitdir_path, "modules/%s", submodule_name); @@ -3483,7 +3484,7 @@ static void die_on_repo_without_commits(const char *path) static int module_add(int argc, const char **argv, const char *prefix, struct repository *repo UNUSED) { - int force = 0, quiet = 0, progress = 0, dissociate = 0; + int force = 0, quiet = 0, progress = 0, dissociate = 0, path_cfg_ext = 0; struct add_data add_data = ADD_DATA_INIT; const char *ref_storage_format = NULL; char *to_free = NULL; @@ -3517,6 +3518,9 @@ static int module_add(int argc, const char **argv, const char *prefix, argc = parse_options(argc, argv, prefix, options, usage, 0); + if (!repo_config_get_bool(the_repository, "extensions.submodulepathconfig", &path_cfg_ext)) + submodule_path_config_enabled = path_cfg_ext; + if (!is_writing_gitmodules_ok()) die(_("please make sure that the .gitmodules file is in the working tree")); diff --git a/submodule.c b/submodule.c index 85ca7ea0fb..5752909999 100644 --- a/submodule.c +++ b/submodule.c @@ -32,6 +32,8 @@ #include "read-cache-ll.h" #include "setup.h" +int submodule_path_config_enabled; + static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF; static int initialized_fetch_ref_tips; static struct oid_array ref_tips_before_fetch; @@ -2575,7 +2577,7 @@ void submodule_name_to_gitdir(struct strbuf *buf, struct repository *r, int ret; /* If extensions.submodulePathConfig is disabled, continue to use the plain path */ - if (!r->repository_format_submodule_path_cfg) { + if (!r->repository_format_submodule_path_cfg && !submodule_path_config_enabled) { repo_git_path_append(r, buf, "modules/%s", submodule_name); if (validate_submodule_git_dir(buf->buf, submodule_name) < 0) die(_("refusing to create/use '%s' in another submodule's " diff --git a/submodule.h b/submodule.h index b10e16e6c0..c15630bf26 100644 --- a/submodule.h +++ b/submodule.h @@ -172,4 +172,6 @@ void absorb_git_dir_into_superproject(const char *path, */ int get_superproject_working_tree(struct strbuf *buf); +extern int submodule_path_config_enabled; + #endif diff --git a/t/t7425-submodule-gitdir-path-extension.sh b/t/t7425-submodule-gitdir-path-extension.sh index 5d52a289f8..2f198bff82 100755 --- a/t/t7425-submodule-gitdir-path-extension.sh +++ b/t/t7425-submodule-gitdir-path-extension.sh @@ -135,4 +135,50 @@ test_expect_success 'fetch mixed submodule changes and verify updates' ' ) ' +test_expect_success 'runtime config extensions.submodulePathConfig on new repo' ' + git config --global extensions.submodulePathConfig true && + git init -b main runtime-test-new-repo && + ( + cd runtime-test-new-repo && + + git init -b main sub && + test_commit -C sub sub-initial && + + git submodule add ./sub sub && + + # Verify that the gitdir config was created correctly + git config submodule.sub.gitdir > actual && + echo ".git/modules/sub" > expect && + test_cmp expect actual + ) +' + +test_expect_success 'runtime config extensions.submodulePathConfig on existing repo' ' + # create a repo with the extension disabled then enable it + git config --global extensions.submodulePathConfig false && + git init -b main runtime-test-existing-repo && + ( + cd runtime-test-existing-repo && + + git init -b main sub && + test_commit -C sub sub-initial && + + git submodule add ./sub sub && + + # gitdir should not exist for this repo: it must be migrated + test_must_fail git config submodule.sub.gitdir + ) && + git config --global extensions.submodulePathConfig true && + ( + cd runtime-test-existing-repo && + + git submodule add ./sub sub2 && + + # gitdir should exist after enabling the global config + git config submodule.sub2.gitdir > actual && + echo ".git/modules/sub2" > expect && + test_cmp expect actual + ) +' + test_done
-- 2.51.2