]> git.ipfire.org Git - thirdparty/git.git/commitdiff
repository: move 'repository_format_worktree_config' to repo scope
authorVictoria Dye <vdye@github.com>
Fri, 26 May 2023 01:33:00 +0000 (01:33 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 26 May 2023 04:53:41 +0000 (13:53 +0900)
Move 'repository_format_worktree_config' out of the global scope and into
the 'repository' struct. This change is similar to how
'repository_format_partial_clone' was moved in ebaf3bcf1ae (repository: move
global r_f_p_c to repo struct, 2021-06-17), adding it to the 'repository'
struct and updating 'setup.c' & 'repository.c' functions to assign the value
appropriately.

The primary goal of this change is to be able to load the worktree config of
a submodule depending on whether that submodule - not its superproject - has
'extensions.worktreeConfig' enabled. To ensure 'do_git_config_sequence()'
has access to the newly repo-scoped configuration, add a 'struct repository'
argument to 'do_git_config_sequence()' and pass it the 'repo' value from
'config_with_options()'.

Finally, add/update tests in 't3007-ls-files-recurse-submodules.sh' to
verify 'extensions.worktreeConfig' is read an used independently by
superprojects and submodules.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/config.c
builtin/worktree.c
config.c
environment.c
environment.h
repository.c
repository.h
setup.c
t/t3007-ls-files-recurse-submodules.sh
worktree.c

index 8fc90288f9e7f80591c962bf42a668ee596717d5..d40fddb042a6cc34000f0135b1ccb60f284a3e18 100644 (file)
@@ -5,6 +5,7 @@
 #include "color.h"
 #include "editor.h"
 #include "environment.h"
+#include "repository.h"
 #include "gettext.h"
 #include "ident.h"
 #include "parse-options.h"
@@ -717,7 +718,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                given_config_source.scope = CONFIG_SCOPE_LOCAL;
        } else if (use_worktree_config) {
                struct worktree **worktrees = get_worktrees();
-               if (repository_format_worktree_config)
+               if (the_repository->repository_format_worktree_config)
                        given_config_source.file = git_pathdup("config.worktree");
                else if (worktrees[0] && worktrees[1])
                        die(_("--worktree cannot be used with multiple "
index f3180463be2a9801bb941eafcdf651181ac800fa..60e389aaedb20e6d13cf2233902fe32ec3f7ae20 100644 (file)
@@ -483,7 +483,7 @@ static int add_worktree(const char *path, const char *refname,
         * values from the current worktree into the new one, that way the
         * new worktree behaves the same as this one.
         */
-       if (repository_format_worktree_config)
+       if (the_repository->repository_format_worktree_config)
                copy_filtered_worktree_config(sb_repo.buf);
 
        strvec_pushf(&child_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf);
index 67e60e131c2acb35f75d388450ce09e751e33a23..f5bdac0aeedfa523b5ae1f6f0b499c5b9366ca08 100644 (file)
--- a/config.c
+++ b/config.c
@@ -2195,6 +2195,7 @@ int git_config_system(void)
 
 static int do_git_config_sequence(struct config_reader *reader,
                                  const struct config_options *opts,
+                                 const struct repository *repo,
                                  config_fn_t fn, void *data)
 {
        int ret = 0;
@@ -2243,7 +2244,7 @@ static int do_git_config_sequence(struct config_reader *reader,
 
        config_reader_set_scope(reader, CONFIG_SCOPE_WORKTREE);
        if (!opts->ignore_worktree && worktree_config &&
-           repository_format_worktree_config &&
+           repo && repo->repository_format_worktree_config &&
            !access_or_die(worktree_config, R_OK, 0)) {
                ret += git_config_from_file(fn, worktree_config, data);
        }
@@ -2296,7 +2297,7 @@ int config_with_options(config_fn_t fn, void *data,
                ret = git_config_from_blob_ref(fn, repo, config_source->blob,
                                                data);
        } else {
-               ret = do_git_config_sequence(&the_reader, opts, fn, data);
+               ret = do_git_config_sequence(&the_reader, opts, repo, fn, data);
        }
 
        if (inc.remote_urls) {
@@ -3339,7 +3340,7 @@ int repo_config_set_worktree_gently(struct repository *r,
                                    const char *key, const char *value)
 {
        /* Only use worktree-specific config if it is already enabled. */
-       if (repository_format_worktree_config) {
+       if (r->repository_format_worktree_config) {
                char *file = repo_git_path(r, "config.worktree");
                int ret = git_config_set_multivar_in_file_gently(
                                        file, key, value, NULL, 0);
index 28d18eaca8ee0a1edd33f1faebae9f8c19fbba4c..6bd001efbdec671cc5a8749725ab01fd90592749 100644 (file)
@@ -42,7 +42,6 @@ int is_bare_repository_cfg = -1; /* unspecified */
 int warn_ambiguous_refs = 1;
 int warn_on_object_refname_ambiguity = 1;
 int repository_format_precious_objects;
-int repository_format_worktree_config;
 const char *git_commit_encoding;
 const char *git_log_output_encoding;
 char *apply_default_whitespace;
index 30cb7e0fa34d35ef074167b2e7e012a887504c0c..e666807926920b4d2428fc75a224c28dfc93f86c 100644 (file)
@@ -197,7 +197,6 @@ extern char *notes_ref_name;
 extern int grafts_replace_parents;
 
 extern int repository_format_precious_objects;
-extern int repository_format_worktree_config;
 
 /*
  * Create a temporary file rooted in the object database directory, or
index c53e480e32601e0ba4ba63ea9ba31accde57a46b..104960f8f59cd7b4db0ce420bcf6005866127a78 100644 (file)
@@ -182,6 +182,7 @@ int repo_init(struct repository *repo,
                goto error;
 
        repo_set_hash_algo(repo, format.hash_algo);
+       repo->repository_format_worktree_config = format.worktree_config;
 
        /* take ownership of format.partial_clone */
        repo->repository_format_partial_clone = format.partial_clone;
index 1a13ff28677ec0db952971c48ef725347c34bda0..74ae26635a4983b4a3c78ed4ea2f4f92b04767c2 100644 (file)
@@ -163,6 +163,7 @@ struct repository {
        struct promisor_remote_config *promisor_remote_config;
 
        /* Configurations */
+       int repository_format_worktree_config;
 
        /* Indicate if a repository has a different 'commondir' from 'gitdir' */
        unsigned different_commondir:1;
diff --git a/setup.c b/setup.c
index 458582207ea7bd4aa328b94d531a98f413c7ca14..d866395435040ecd968395c34cfd5a4d55759cb9 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -650,11 +650,10 @@ static int check_repository_format_gently(const char *gitdir, struct repository_
        }
 
        repository_format_precious_objects = candidate->precious_objects;
-       repository_format_worktree_config = candidate->worktree_config;
        string_list_clear(&candidate->unknown_extensions, 0);
        string_list_clear(&candidate->v1_only_extensions, 0);
 
-       if (repository_format_worktree_config) {
+       if (candidate->worktree_config) {
                /*
                 * pick up core.bare and core.worktree from per-worktree
                 * config if present
@@ -1423,6 +1422,9 @@ int discover_git_directory(struct strbuf *commondir,
                return -1;
        }
 
+       the_repository->repository_format_worktree_config =
+               candidate.worktree_config;
+
        /* take ownership of candidate.partial_clone */
        the_repository->repository_format_partial_clone =
                candidate.partial_clone;
@@ -1560,6 +1562,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
                }
                if (startup_info->have_repository) {
                        repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
+                       the_repository->repository_format_worktree_config =
+                               repo_fmt.worktree_config;
                        /* take ownership of repo_fmt.partial_clone */
                        the_repository->repository_format_partial_clone =
                                repo_fmt.partial_clone;
@@ -1651,6 +1655,8 @@ void check_repository_format(struct repository_format *fmt)
        check_repository_format_gently(get_git_dir(), fmt, NULL);
        startup_info->have_repository = 1;
        repo_set_hash_algo(the_repository, fmt->hash_algo);
+       the_repository->repository_format_worktree_config =
+               fmt->worktree_config;
        the_repository->repository_format_partial_clone =
                xstrdup_or_null(fmt->partial_clone);
        clear_repository_format(&repo_fmt);
index a3e267514274f967abd6fc4848b7dc63dbc5e8ea..7308a3d4e25a8be915c6e2157b31c21a3585bd0c 100755 (executable)
@@ -309,14 +309,29 @@ test_expect_success '--recurse-submodules parses submodule worktree config' '
        test_config -C submodule extensions.worktreeConfig true &&
        test_config -C submodule --worktree index.sparse "invalid non-boolean value" &&
 
-       # NEEDSWORK: the extensions.worktreeConfig is set globally based on
-       # superproject, so we need to enable it in the superproject.
-       test_config extensions.worktreeConfig true &&
-
        test_must_fail git ls-files --recurse-submodules 2>err &&
        grep "bad boolean config value" err
 '
 
+test_expect_success '--recurse-submodules submodules ignore super project worktreeConfig extension' '
+       # Enable worktree config in both super project & submodule, set an
+       # invalid config in the submodule worktree config
+       test_config extensions.worktreeConfig true &&
+       test_config -C submodule extensions.worktreeConfig true &&
+       test_config -C submodule --worktree index.sparse "invalid non-boolean value" &&
+
+       # Now, disable the worktree config in the submodule. Note that we need
+       # to manually re-enable extensions.worktreeConfig when the test is
+       # finished, otherwise the test_unconfig of index.sparse will not work.
+       test_unconfig -C submodule extensions.worktreeConfig &&
+       test_when_finished "git -C submodule config extensions.worktreeConfig true" &&
+
+       # With extensions.worktreeConfig disabled in the submodule, the invalid
+       # worktree config is not picked up.
+       git ls-files --recurse-submodules 2>err &&
+       ! grep "bad boolean config value" err
+'
+
 test_incompatible_with_recurse_submodules () {
        test_expect_success "--recurse-submodules and $1 are incompatible" "
                test_must_fail git ls-files --recurse-submodules $1 2>actual &&
index b5ee71c5ebda499899e5f64209611f0484359867..c448fecd4b3a2209251228abe2e5398346e391ab 100644 (file)
@@ -806,7 +806,7 @@ int init_worktree_config(struct repository *r)
         * If the extension is already enabled, then we can skip the
         * upgrade process.
         */
-       if (repository_format_worktree_config)
+       if (r->repository_format_worktree_config)
                return 0;
        if ((res = git_config_set_gently("extensions.worktreeConfig", "true")))
                return error(_("failed to set extensions.worktreeConfig setting"));
@@ -846,7 +846,7 @@ int init_worktree_config(struct repository *r)
         * Ensure that we use worktree config for the remaining lifetime
         * of the current process.
         */
-       repository_format_worktree_config = 1;
+       r->repository_format_worktree_config = 1;
 
 cleanup:
        git_configset_clear(&cs);