From a22610bb245dda9c18c02faf892dcf6833001473 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Mon, 8 Jun 2026 13:57:04 +0000 Subject: [PATCH 1/3] git-config.adoc: fix paragraph break The bulletted list about environment variables is missing a '+' between some paragraphs that belong to the same bullet item. Without it, the bulletted list is rendered as two separate lists with "See also FILES." as a normal paragraph between them. Adding '+' unifies the lists. Signed-off-by: Derrick Stolee Signed-off-by: Junio C Hamano --- Documentation/git-config.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-config.adoc b/Documentation/git-config.adoc index 00545b2054..044d776613 100644 --- a/Documentation/git-config.adoc +++ b/Documentation/git-config.adoc @@ -476,7 +476,7 @@ GIT_CONFIG_SYSTEM:: GIT_CONFIG_NOSYSTEM:: Whether to skip reading settings from the system-wide $(prefix)/etc/gitconfig file. See linkgit:git[1] for details. - ++ See also <>. GIT_CONFIG_COUNT:: From f2e1540172f4f4736025b1f728f70b3f6d7401a3 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Mon, 8 Jun 2026 13:57:05 +0000 Subject: [PATCH 2/3] config: add GIT_CONFIG_INCLUDES The config keys 'include.path' and 'includeIf.*' allow users to specify config stored in a location outside of the typical list of config files (system, global, local, etc.). For example, users who accept the risk can specify helpful aliases via a file checked into the repo by pointing 'include.path' to the position of that file in the working directory. This is dangerous, but people do it. What becomes tricky is that this modifies all Git behavior, including operations that are intended to be limited in activity or sandboxed in some way. These include directives can provide surprising changes to behavior, especially when expecting a specific list of allowed file accesses. This could lead to failed builds, for instance. To allow for these user-desired features when they are running commands, add a new GIT_CONFIG_INCLUDES environment variable that disables these redirections of config when set to zero. This variable can be set by automation, such as build tooling, to avoid these strange behaviors. This could be considered a recommended option for tools executing Git commands, the same as GIT_ADVICE=0. Signed-off-by: Derrick Stolee Signed-off-by: Junio C Hamano --- Documentation/git-config.adoc | 5 +++++ config.c | 7 ++++++- environment.h | 6 ++++++ t/t1305-config-include.sh | 31 +++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/Documentation/git-config.adoc b/Documentation/git-config.adoc index 044d776613..c9b5159501 100644 --- a/Documentation/git-config.adoc +++ b/Documentation/git-config.adoc @@ -502,6 +502,11 @@ GIT_CONFIG:: historical compatibility; there is generally no reason to use it instead of the `--file` option. +GIT_CONFIG_INCLUDES:: + If GIT_CONFIG_INCLUDES is set to 0, then Git will not follow + `include.path` or `includeIf.*.path` directives when reading + configuration files. + [[EXAMPLES]] EXAMPLES -------- diff --git a/config.c b/config.c index 156f2a24fa..f687d85d2e 100644 --- a/config.c +++ b/config.c @@ -1586,9 +1586,14 @@ int config_with_options(config_fn_t fn, void *data, const struct config_options *opts) { struct config_include_data inc = CONFIG_INCLUDE_INIT; + int respect_includes = opts->respect_includes; int ret; - if (opts->respect_includes) { + if (respect_includes && + !git_env_bool(CONFIG_INCLUDES_ENVIRONMENT, 1)) + respect_includes = 0; + + if (respect_includes) { inc.fn = fn; inc.data = data; inc.opts = opts; diff --git a/environment.h b/environment.h index 123a71cdc8..67dde5e5e2 100644 --- a/environment.h +++ b/environment.h @@ -52,6 +52,12 @@ */ #define GIT_ADVICE_ENVIRONMENT "GIT_ADVICE" +/* + * Environment variable used to prevent following include.path or includeIf.* + * config directives. + */ +#define CONFIG_INCLUDES_ENVIRONMENT "GIT_CONFIG_INCLUDES" + /* * Environment variable used in handshaking the wire protocol. * Contains a colon ':' separated list of keys with optional values diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh index 6e51f892f3..8a6dba983f 100755 --- a/t/t1305-config-include.sh +++ b/t/t1305-config-include.sh @@ -396,4 +396,35 @@ test_expect_success 'onbranch without repository but explicit nonexistent Git di test_must_fail nongit git --git-dir=nonexistent config get foo.bar ' +test_expect_success 'GIT_CONFIG_INCLUDES=0 disables include.path and includeIf' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git config set include.path config.inc && + git config set "includeIf.gitdir:*.path" config2.inc && + git config set -f .git/config.inc foo.bar from-include && + git config set -f .git/config2.inc foo.baz from-includeif && + git config get foo.bar && + git config get foo.baz && + test_must_fail env GIT_CONFIG_INCLUDES=0 git config get foo.bar && + test_must_fail env GIT_CONFIG_INCLUDES=0 git config get foo.baz && + git config get --includes foo.bar && + test_must_fail env GIT_CONFIG_INCLUDES=0 git config get --includes foo.bar + ) +' + +test_expect_success 'GIT_CONFIG_INCLUDES=0 blocks included alias override' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git config set alias.test false && + git config set include.path config.inc && + git config set -f .git/config.inc alias.test status && + git test && + test_must_fail env GIT_CONFIG_INCLUDES=0 git test + ) +' + test_done From 780d5e5e5dd55ca993c67d6833215850678119f3 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Mon, 8 Jun 2026 13:57:06 +0000 Subject: [PATCH 3/3] git: add --no-includes top-level option The previous change added a GIT_CONFIG_INCLUDES=0 override in the environment, similar to GIT_ADVICE=0. Follow the same model as --no-advice to add a --no-includes option to the top-level Git options. Signed-off-by: Derrick Stolee Signed-off-by: Junio C Hamano --- Documentation/git.adoc | 6 +++++- git.c | 6 +++++- t/t1305-config-include.sh | 8 ++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Documentation/git.adoc b/Documentation/git.adoc index 8a5cdd3b3d..f220427930 100644 --- a/Documentation/git.adoc +++ b/Documentation/git.adoc @@ -12,7 +12,7 @@ SYNOPSIS 'git' [-v | --version] [-h | --help] [-C ] [-c =] [--exec-path[=]] [--html-path] [--man-path] [--info-path] [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-lazy-fetch] - [--no-optional-locks] [--no-advice] [--bare] [--git-dir=] + [--no-optional-locks] [--no-advice] [--no-includes] [--bare] [--git-dir=] [--work-tree=] [--namespace=] [--config-env==] [] @@ -194,6 +194,10 @@ If you just want to run git as if it was started in `` then use --no-advice:: Disable all advice hints from being printed. +--no-includes:: + Disable all `include.path` and `includeIf.*` config directives. + See linkgit:git-config[1] for more information. + --literal-pathspecs:: Treat pathspecs literally (i.e. no globbing, no pathspec magic). This is equivalent to setting the `GIT_LITERAL_PATHSPECS` environment diff --git a/git.c b/git.c index 5a40eab8a2..7d99f6140c 100644 --- a/git.c +++ b/git.c @@ -40,7 +40,7 @@ const char git_usage_string[] = N_("git [-v | --version] [-h | --help] [-C ] [-c =]\n" " [--exec-path[=]] [--html-path] [--man-path] [--info-path]\n" " [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-lazy-fetch]\n" - " [--no-optional-locks] [--no-advice] [--bare] [--git-dir=]\n" + " [--no-optional-locks] [--no-advice] [--no-includes] [--bare] [--git-dir=]\n" " [--work-tree=] [--namespace=] [--config-env==]\n" " []"); @@ -354,6 +354,10 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) setenv(GIT_ADVICE_ENVIRONMENT, "0", 1); if (envchanged) *envchanged = 1; + } else if (!strcmp(cmd, "--no-includes")) { + setenv(CONFIG_INCLUDES_ENVIRONMENT, "0", 1); + if (envchanged) + *envchanged = 1; } else { fprintf(stderr, _("unknown option: %s\n"), cmd); usage(git_usage_string); diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh index 8a6dba983f..e6efd0f280 100755 --- a/t/t1305-config-include.sh +++ b/t/t1305-config-include.sh @@ -409,8 +409,11 @@ test_expect_success 'GIT_CONFIG_INCLUDES=0 disables include.path and includeIf' git config get foo.baz && test_must_fail env GIT_CONFIG_INCLUDES=0 git config get foo.bar && test_must_fail env GIT_CONFIG_INCLUDES=0 git config get foo.baz && + test_must_fail git --no-includes config get foo.bar && + test_must_fail git --no-includes config get foo.baz && git config get --includes foo.bar && - test_must_fail env GIT_CONFIG_INCLUDES=0 git config get --includes foo.bar + test_must_fail env GIT_CONFIG_INCLUDES=0 git config get --includes foo.bar && + test_must_fail git --no-includes config get --includes foo.bar ) ' @@ -423,7 +426,8 @@ test_expect_success 'GIT_CONFIG_INCLUDES=0 blocks included alias override' ' git config set include.path config.inc && git config set -f .git/config.inc alias.test status && git test && - test_must_fail env GIT_CONFIG_INCLUDES=0 git test + test_must_fail env GIT_CONFIG_INCLUDES=0 git test && + test_must_fail git --no-includes test ) '