]> git.ipfire.org Git - thirdparty/git.git/commitdiff
submodule: allow runtime enabling extensions.submodulePathConfig
authorAdrian Ratiu <adrian.ratiu@collabora.com>
Sat, 20 Dec 2025 10:15:22 +0000 (12:15 +0200)
committerJunio C Hamano <gitster@pobox.com>
Sun, 21 Dec 2025 02:36:00 +0000 (11:36 +0900)
Add a new config `init.autoSetupSubmodulePathConfig` which allows
enabling `extensions.submodulePathConfig` for new submodules by
default (those created via git init or clone).

Important: setting init.autoSetupSubmodulePathConfig = 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>
Documentation/config/extensions.adoc
Documentation/config/init.adoc
setup.c
t/t7425-submodule-gitdir-path-extension.sh

index e15b93f2fb9edd68b5df3b4c41c46a14341e1718..0968ac3d5c70182be8bdbe48841cc5f9f178cf80 100644 (file)
@@ -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.autoSetupSubmodulePathConfig` to `true`, for example by running
+`git config --global init.autoSetupSubmodulePathConfig true`.
 
 worktreeConfig:::
        If enabled, then worktrees will load config settings from the
index e45b2a812151dc45755b650ecd0839f4029c5c2a..293a2ddbdfe91f89d0dba9b1c87d6274fb652e2b 100644 (file)
@@ -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.autoSetupSubmodulePathConfig::
+       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 207fa36e100b61e0a5f35d04f2e75d39ecf76457..f86ee2c991dda0ac8da41ad5329ed4c0dedc2e23 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -2579,7 +2579,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
            const char *initial_branch,
            int init_shared_repository, unsigned int flags)
 {
-       int reinit;
+       int reinit, auto_setup_submodule_path_config = 0;
        int exist_ok = flags & INIT_DB_EXIST_OK;
        char *original_git_dir = real_pathdup(git_dir, 1);
        struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
@@ -2630,6 +2630,16 @@ int init_db(const char *git_dir, const char *real_git_dir,
                                          initial_branch, flags & INIT_DB_QUIET);
        create_object_directory();
 
+       repo_config_get_bool(the_repository, "init.autoSetupSubmodulePathConfig",
+                            &auto_setup_submodule_path_config);
+       if (auto_setup_submodule_path_config) {
+               int version = 0;
+               repo_config_get_int(the_repository, "core.repositoryformatversion", &version);
+               if (version < 1)
+                       repo_config_set(the_repository, "core.repositoryformatversion", "1");
+               repo_config_set(the_repository, "extensions.submodulepathconfig", "true");
+       }
+
        if (repo_settings_get_shared_repository(the_repository)) {
                char buf[10];
                /* We do not spell "group" and such, so that
index 5d52a289f898148d65bb36e2a9716cb582f09d62..06ee1ff86ba96e6d9769fc3086f61592d7765ec9 100755 (executable)
@@ -135,4 +135,129 @@ test_expect_success 'fetch mixed submodule changes and verify updates' '
        )
 '
 
+test_expect_success '`git init` respects init.autoSetupSubmodulePathConfig' '
+       git config --global init.autoSetupSubmodulePathConfig 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
+       ) &&
+       git config --global --unset init.autoSetupSubmodulePathConfig
+'
+
+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.autoSetupSubmodulePathConfig' '
+       test_when_finished "rm -rf repo-clone" &&
+       git config --global init.autoSetupSubmodulePathConfig 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
+       ) &&
+       git config --global --unset init.autoSetupSubmodulePathConfig
+'
+
+test_expect_success '`git clone --recurse-submodules` respects init.autoSetupSubmodulePathConfig' '
+       test_when_finished "rm -rf repo-clone-recursive" &&
+       git config --global init.autoSetupSubmodulePathConfig 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
+       ) &&
+       git config --global --unset init.autoSetupSubmodulePathConfig
+'
+
 test_done