aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Ratiu <adrian.ratiu@collabora.com>2026-01-12 20:46:26 +0200
committerJunio C Hamano <gitster@pobox.com>2026-01-12 11:56:56 -0800
commitc349bad72969d59758e1294b4e9964dccd967fa0 (patch)
treeb301ddfb62dea30168158d4db4c7614a64e146a5
parent4173df5187c8ba8bc2cc1a215f25b284d70631da (diff)
downloadgit-c349bad72969d59758e1294b4e9964dccd967fa0.tar.xz
submodule: allow runtime enabling extensions.submodulePathConfig
Add a new config `init.defaultSubmodulePathConfig` which allows enabling `extensions.submodulePathConfig` for new submodules by default (those created via git init or clone). Important: setting init.defaultSubmodulePathConfig = true does not globally enable `extensions.submodulePathConfig`. Existing repositories will still have the extension disabled and will require migration (for example via git submodule--helper command added in the next commit). Suggested-by: Patrick Steinhardt <ps@pks.im> Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Documentation/config/extensions.adoc4
-rw-r--r--Documentation/config/init.adoc6
-rw-r--r--setup.c10
-rwxr-xr-xt/t7425-submodule-gitdir-path-extension.sh122
4 files changed, 142 insertions, 0 deletions
diff --git a/Documentation/config/extensions.adoc b/Documentation/config/extensions.adoc
index f4f57c9114..e8d9d9a19a 100644
--- a/Documentation/config/extensions.adoc
+++ b/Documentation/config/extensions.adoc
@@ -95,6 +95,10 @@ Git will error out if a module does not have a corresponding
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>`.
++
+The extension can be enabled automatically for new repositories by setting
+`init.defaultSubmodulePathConfig` to `true`, for example by running
+`git config --global init.defaultSubmodulePathConfig true`.
worktreeConfig:::
If enabled, then worktrees will load config settings from the
diff --git a/Documentation/config/init.adoc b/Documentation/config/init.adoc
index e45b2a8121..7b4abdaf8b 100644
--- a/Documentation/config/init.adoc
+++ b/Documentation/config/init.adoc
@@ -18,3 +18,9 @@ endif::[]
See `--ref-format=` in linkgit:git-init[1]. Both the command line
option and the `GIT_DEFAULT_REF_FORMAT` environment variable take
precedence over this config.
+
+init.defaultSubmodulePathConfig::
+ A boolean that specifies if `git init` and `git clone` should
+ automatically set `extensions.submodulePathConfig` to `true`. This
+ allows all new repositories to automatically use the submodule path
+ extension. Defaults to `false` when unset.
diff --git a/setup.c b/setup.c
index 207fa36e10..3f91a4aaec 100644
--- a/setup.c
+++ b/setup.c
@@ -2228,6 +2228,7 @@ void initialize_repository_version(int hash_algo,
{
struct strbuf repo_version = STRBUF_INIT;
int target_version = GIT_REPO_VERSION;
+ int default_submodule_path_config = 0;
/*
* Note that we initialize the repository version to 1 when the ref
@@ -2266,6 +2267,15 @@ void initialize_repository_version(int hash_algo,
clear_repository_format(&repo_fmt);
}
+ repo_config_get_bool(the_repository, "init.defaultSubmodulePathConfig",
+ &default_submodule_path_config);
+ if (default_submodule_path_config) {
+ /* extensions.submodulepathconfig requires at least version 1 */
+ if (target_version == 0)
+ target_version = 1;
+ repo_config_set(the_repository, "extensions.submodulepathconfig", "true");
+ }
+
strbuf_addf(&repo_version, "%d", target_version);
repo_config_set(the_repository, "core.repositoryformatversion", repo_version.buf);
diff --git a/t/t7425-submodule-gitdir-path-extension.sh b/t/t7425-submodule-gitdir-path-extension.sh
index 453183e27c..03ac165de9 100755
--- a/t/t7425-submodule-gitdir-path-extension.sh
+++ b/t/t7425-submodule-gitdir-path-extension.sh
@@ -157,4 +157,126 @@ test_expect_success 'fetch mixed submodule changes and verify updates' '
)
'
+test_expect_success '`git init` respects init.defaultSubmodulePathConfig' '
+ test_config_global init.defaultSubmodulePathConfig true &&
+ git init repo-init &&
+ git -C repo-init config extensions.submodulePathConfig >actual &&
+ echo true >expect &&
+ test_cmp expect actual &&
+ # create a submodule and check gitdir
+ (
+ cd repo-init &&
+ git init -b main sub &&
+ test_commit -C sub sub-initial &&
+ git submodule add ./sub sub &&
+ git config submodule.sub.gitdir >actual &&
+ echo ".git/modules/sub" >expect &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success '`git init` does not set extension by default' '
+ git init upstream &&
+ test_commit -C upstream initial &&
+ test_must_fail git -C upstream config extensions.submodulePathConfig &&
+ # create a pair of submodules and check gitdir is not created
+ git init -b main sub &&
+ test_commit -C sub sub-initial &&
+ (
+ cd upstream &&
+ git submodule add ../sub sub1 &&
+ test_path_is_dir .git/modules/sub1 &&
+ test_must_fail git config submodule.sub1.gitdir &&
+ git submodule add ../sub sub2 &&
+ test_path_is_dir .git/modules/sub2 &&
+ test_must_fail git config submodule.sub2.gitdir &&
+ git commit -m "Add submodules"
+ )
+'
+
+test_expect_success '`git clone` does not set extension by default' '
+ test_when_finished "rm -rf repo-clone-no-ext" &&
+ git clone upstream repo-clone-no-ext &&
+ (
+ cd repo-clone-no-ext &&
+
+ test_must_fail git config extensions.submodulePathConfig &&
+ test_path_is_missing .git/modules/sub1 &&
+ test_path_is_missing .git/modules/sub2 &&
+
+ # create a submodule and check gitdir is not created
+ git submodule add ../sub sub3 &&
+ test_must_fail git config submodule.sub3.gitdir
+ )
+'
+
+test_expect_success '`git clone --recurse-submodules` does not set extension by default' '
+ test_when_finished "rm -rf repo-clone-no-ext" &&
+ git clone --recurse-submodules upstream repo-clone-no-ext &&
+ (
+ cd repo-clone-no-ext &&
+
+ # verify that that submodules do not have gitdir set
+ test_must_fail git config extensions.submodulePathConfig &&
+ test_path_is_dir .git/modules/sub1 &&
+ test_must_fail git config submodule.sub1.gitdir &&
+ test_path_is_dir .git/modules/sub2 &&
+ test_must_fail git config submodule.sub2.gitdir &&
+
+ # create another submodule and check that gitdir is not created
+ git submodule add ../sub sub3 &&
+ test_path_is_dir .git/modules/sub3 &&
+ test_must_fail git config submodule.sub3.gitdir
+ )
+
+'
+
+test_expect_success '`git clone` respects init.defaultSubmodulePathConfig' '
+ test_when_finished "rm -rf repo-clone" &&
+ test_config_global init.defaultSubmodulePathConfig true &&
+ git clone upstream repo-clone &&
+ (
+ cd repo-clone &&
+
+ # verify new repo extension is inherited from global config
+ git config extensions.submodulePathConfig >actual &&
+ echo true >expect &&
+ test_cmp expect actual &&
+
+ # new submodule has a gitdir config
+ git submodule add ../sub sub &&
+ test_path_is_dir .git/modules/sub &&
+ git config submodule.sub.gitdir >actual &&
+ echo ".git/modules/sub" >expect &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success '`git clone --recurse-submodules` respects init.defaultSubmodulePathConfig' '
+ test_when_finished "rm -rf repo-clone-recursive" &&
+ test_config_global init.defaultSubmodulePathConfig true &&
+ git clone --recurse-submodules upstream repo-clone-recursive &&
+ (
+ cd repo-clone-recursive &&
+
+ # verify new repo extension is inherited from global config
+ git config extensions.submodulePathConfig >actual &&
+ echo true >expect &&
+ test_cmp expect actual &&
+
+ # previous submodules should exist
+ git config submodule.sub1.gitdir &&
+ git config submodule.sub2.gitdir &&
+ test_path_is_dir .git/modules/sub1 &&
+ test_path_is_dir .git/modules/sub2 &&
+
+ # create another submodule and check that gitdir is created
+ git submodule add ../sub new-sub &&
+ test_path_is_dir .git/modules/new-sub &&
+ git config submodule.new-sub.gitdir >actual &&
+ echo ".git/modules/new-sub" >expect &&
+ test_cmp expect actual
+ )
+'
+
test_done