]> git.ipfire.org Git - thirdparty/git.git/commitdiff
config: respect commondir
authorBrandon Williams <bmwill@google.com>
Wed, 14 Jun 2017 18:07:38 +0000 (11:07 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 15 Jun 2017 19:56:22 +0000 (12:56 -0700)
Worktrees present an interesting problem when it comes to the config.
Historically we could assume that the per-repository config lives at
'gitdir/config', but since worktrees were introduced this isn't the case
anymore.  There is currently no way to specify per-worktree
configuration, and as such the repository config is shared with all
worktrees and is located at 'commondir/config'.

Many users of the config machinery correctly set
'config_options.git_dir' with the repository's commondir, allowing the
config to be properly loaded when operating in a worktree.  But other's,
like 'read_early_config()', set 'config_options.git_dir' with the
repository's gitdir which can be incorrect when using worktrees.

To fix this issue, and to make things less ambiguous, lets add a
'commondir' field to the 'config_options' struct and have all callers
properly set both the 'git_dir' and 'commondir' fields so that the
config machinery is able to properly find the repository's config.

Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
config.c
config.h

index e8dbf9e64a36ab77b4814403d291bd95e1c94843..edc0d1770860dcfc814e698aa34d6d70d5f3a5b0 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1531,8 +1531,8 @@ static int do_git_config_sequence(const struct config_options *opts,
        char *user_config = expand_user_path("~/.gitconfig", 0);
        char *repo_config;
 
-       if (opts->git_dir)
-               repo_config = mkpathdup("%s/config", opts->git_dir);
+       if (opts->commondir)
+               repo_config = mkpathdup("%s/config", opts->commondir);
        else if (have_git_dir())
                repo_config = git_pathdup("config");
        else
@@ -1644,7 +1644,8 @@ void read_early_config(config_fn_t cb, void *data)
 
        opts.respect_includes = 1;
 
-       if (have_git_dir())
+       if (have_git_dir()) {
+               opts.commondir = get_git_common_dir();
                opts.git_dir = get_git_dir();
        /*
         * When setup_git_directory() was not yet asked to discover the
@@ -1654,8 +1655,10 @@ void read_early_config(config_fn_t cb, void *data)
         * notably, the current working directory is still the same after the
         * call).
         */
-       else if (!discover_git_directory(&commondir, &gitdir))
+       } else if (!discover_git_directory(&commondir, &gitdir)) {
+               opts.commondir = commondir.buf;
                opts.git_dir = gitdir.buf;
+       }
 
        git_config_with_options(cb, data, NULL, &opts);
 
index c70599bd5f00e876cfc7bed136a43a0c7ccbaaf4..63b92784cd6cbe0f32a521e6edafc577ac7b24eb 100644 (file)
--- a/config.h
+++ b/config.h
@@ -30,6 +30,7 @@ enum config_origin_type {
 
 struct config_options {
        unsigned int respect_includes : 1;
+       const char *commondir;
        const char *git_dir;
 };