diff --git a/Documentation/config.txt b/Documentation/config.txt
index 30cb946..c508386 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2,8 +2,9 @@ CONFIGURATION FILE
------------------
The Git configuration file contains a number of variables that affect
-the Git commands' behavior. The `.git/config` file in each repository
-is used to store the configuration for that repository, and
+the Git commands' behavior. The files `.git/config` and optionally
+`config.worktree` (see `extensions.worktreeConfig` below) are each
+repository is used to store the configuration for that repository, and
`$HOME/.gitconfig` is used to store a per-user configuration as
fallback values for the `.git/config` file. The file `/etc/gitconfig`
can be used to store a system-wide default configuration.
@@ -264,6 +265,12 @@ advice.*::
show directions on how to proceed from the current state.
--
+extensions.worktreeConfig::
+ If set, by default "git config" reads from both "config" and
+ "config.worktree" file in that order. In multiple working
+ directory mode, "config" file is shared while
+ "config.worktree" is per-working directory.
+
core.fileMode::
Tells Git if the executable bit of files in the working tree
is to be honored.
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index 83f86b9..806873c 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -253,6 +253,10 @@ $XDG_CONFIG_HOME/git/config::
$GIT_DIR/config::
Repository specific configuration file.
+$GIT_DIR/config.worktree::
+ This is optional and is only searched when
+ `extensions.worktreeConfig` is present in $GIT_DIR/config.
+
If no further options are given, all reading options will read all of these
files that are available. If the global or the system-wide configuration
file are not available they will be ignored. If the repository configuration
diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index e257c19..329a673 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -136,6 +136,37 @@ working trees, it can be used to identify worktrees. For example if
you only have two working trees, at "/abc/def/ghi" and "/abc/def/ggg",
then "ghi" or "def/ghi" is enough to point to the former working tree.
+CONFIGURATION FILE
+------------------
+By default, the repository "config" file is shared across all working
+directories. If the config variables `core.bare` or `core.worktree`
+are already present in the config file, they will be applied to the
+main working directory only.
+
+In order to have configuration specific to working directories, you
+can turn on "worktreeConfig" extension, e.g.:
+
+------------
+$ git config extensions.worktreeConfig true
+------------
+
+In this mode, specific configuration stays in the path pointed by `git
+rev-parse --git-path config.worktree`. You can add or update
+configuration in this file with `git config --worktree`. Git before
+version 2.13 will refuse to access repositories with this extension.
+
+Note that in this file, the exception for `core.bare` and
+`core.worktree` is gone. If you have them before, you need to move
+them to the `config.worktree` of the main working directory. You may
+also take this opportunity to move other configuration that you do not
+want to share to all working directories:
+
+ - `core.worktree` and `core.bare` should never be shared
+
+ - `core.sparseCheckout` is recommended per working directory, unless
+ you are sure you always use sparse checkout for all working
+ directories.
+
DETAILS
-------
Each linked working tree has a private sub-directory in the repository's
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index a5f99cb..fee2557 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -143,6 +143,11 @@ config::
if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/config" will be
used instead.
+config.worktree::
+ Working directory specific configuration file for the main
+ working directory in multiple working directory setup (see
+ linkgit:git-worktree[1]).
+
branches::
A slightly deprecated way to store shorthands to be used
to specify a URL to 'git fetch', 'git pull' and 'git push'.
@@ -276,6 +281,9 @@ worktrees/<id>/link::
file. It is used to detect if the linked repository is
manually removed.
+worktrees/<id>/config.worktree::
+ Working directory specific configuration file.
+
SEE ALSO
--------
linkgit:git-init[1],
diff --git a/cache.h b/cache.h
index a50a61a..c621a35 100644
--- a/cache.h
+++ b/cache.h
@@ -777,10 +777,12 @@ extern int grafts_replace_parents;
#define GIT_REPO_VERSION 0
#define GIT_REPO_VERSION_READ 1
extern int repository_format_precious_objects;
+extern int repository_format_worktree_config;
struct repository_format {
int version;
int precious_objects;
+ int worktree_config;
int is_bare;
char *work_tree;
struct string_list unknown_extensions;diff --git a/config.c b/config.c
index 83fdecb..a461e68 100644
--- a/config.c
+++ b/config.c
@@ -1307,6 +1307,13 @@ static int do_git_config_sequence(config_fn_t fn, void *data)
if (repo_config && !access_or_die(repo_config, R_OK, 0))
ret += git_config_from_file(fn, repo_config, data);
+ if (repository_format_worktree_config) {
+ char *path = git_pathdup("config.worktree");
+ if (!access_or_die(path, R_OK, 0))
+ ret += git_config_from_file(fn, path, data);
+ free(path);
+ }
+
current_parsing_scope = CONFIG_SCOPE_CMDLINE;
if (git_config_from_parameters(fn, data) < 0)
die(_("unable to parse command-line config"));diff --git a/environment.c b/environment.c
index 0935ec6..df1be15 100644
--- a/environment.c
+++ b/environment.c
@@ -26,6 +26,7 @@ int warn_ambiguous_refs = 1;
int warn_on_object_refname_ambiguity = 1;
int ref_paranoia = -1;
int repository_format_precious_objects;
+int repository_format_worktree_config;
const char *git_commit_encoding;
const char *git_log_output_encoding;
const char *apply_default_whitespace;
diff --git a/setup.c b/setup.c
index fe572b8..69efe45 100644
--- a/setup.c
+++ b/setup.c
@@ -389,6 +389,8 @@ static int check_repo_format(const char *var, const char *value, void *vdata)
;
else if (!strcmp(ext, "preciousobjects"))
data->precious_objects = git_config_bool(var, value);
+ else if (!strcmp(ext, "worktreeconfig"))
+ data->worktree_config = git_config_bool(var, value);
else
string_list_append(&data->unknown_extensions, ext);
} else if (strcmp(var, "core.bare") == 0) {@@ -432,8 +434,9 @@ static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
}
repository_format_precious_objects = candidate.precious_objects;
+ repository_format_worktree_config = candidate.worktree_config;
string_list_clear(&candidate.unknown_extensions, 0);
- if (!has_common) {
+ if (!has_common || repository_format_worktree_config) {
if (candidate.is_bare != -1) {
is_bare_repository_cfg = candidate.is_bare;
if (is_bare_repository_cfg == 1)--
2.8.2.524.g6ff3d78