From c996ef0b06faf83ffcc4559833a31d0e529a1905 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Thu, 4 Jun 2026 16:40:59 -0400 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 --- 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 00545b20542c60..044d7766131fa9 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 b48fe9f7abe794864ac4470c2620048c2e5e6b53 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Thu, 4 Jun 2026 16:46:43 -0400 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 --- 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 044d7766131fa9..c9b5159501e111 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 a1b92fe083cf43..85edd05672d709 100644 --- a/config.c +++ b/config.c @@ -1595,9 +1595,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 9eb97b3869c9b1..2c57ae2533a2c9 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 f3892578e4ff86..270e4b89ab42ed 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 1b4ae3cc0b9bc18f0b001587e93ce83cf3dfa819 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Thu, 4 Jun 2026 16:57:57 -0400 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 --- 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 8a5cdd3b3d22c5..f220427930afba 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 36f08891ef5476..52cfbf0e23e2a1 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 270e4b89ab42ed..b636e5ae7b1dc2 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 ) '