From 4c486f0becbacc34127a8f446c741122a4ecc068 Mon Sep 17 00:00:00 2001 From: Marc Becker Date: Fri, 15 May 2026 00:10:24 +0200 Subject: [PATCH 1/2] fix(config): enable file include in scoped query add parameter to make file include behavior in config read consistent retain existing parameters on write, always uses "primary" scope file --- src/shared/Core/GitConfiguration.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shared/Core/GitConfiguration.cs b/src/shared/Core/GitConfiguration.cs index 83a10d591..81f501a06 100644 --- a/src/shared/Core/GitConfiguration.cs +++ b/src/shared/Core/GitConfiguration.cs @@ -463,7 +463,7 @@ public void Enumerate(GitConfigurationLevel level, GitConfigurationEnumerationCa // Fall back to original implementation string levelArg = GetLevelFilterArg(level); - using (ChildProcess git = _git.CreateProcess($"config --null {levelArg} --list")) + using (ChildProcess git = _git.CreateProcess($"config --null {levelArg} --includes --list")) { git.Start(Trace2ProcessClass.Git); // To avoid deadlocks, always read the output stream first and then wait @@ -545,7 +545,7 @@ public bool TryGet(GitConfigurationLevel level, GitConfigurationType type, strin // Fall back to individual git config command if cache not available string levelArg = GetLevelFilterArg(level); string typeArg = GetCanonicalizeTypeArg(type); - using (ChildProcess git = _git.CreateProcess($"config --null {levelArg} {typeArg} {QuoteCmdArg(name)}")) + using (ChildProcess git = _git.CreateProcess($"config --null {levelArg} --includes {typeArg} {QuoteCmdArg(name)}")) { git.Start(Trace2ProcessClass.Git); // To avoid deadlocks, always read the output stream first and then wait @@ -667,7 +667,7 @@ public IEnumerable GetAll(GitConfigurationLevel level, GitConfigurationT string levelArg = GetLevelFilterArg(level); string typeArg = GetCanonicalizeTypeArg(type); - var gitArgs = $"config --null {levelArg} {typeArg} --get-all {QuoteCmdArg(name)}"; + var gitArgs = $"config --null {levelArg} --includes {typeArg} --get-all {QuoteCmdArg(name)}"; using (ChildProcess git = _git.CreateProcess(gitArgs)) { @@ -705,7 +705,7 @@ public IEnumerable GetRegex(GitConfigurationLevel level, GitConfiguratio string levelArg = GetLevelFilterArg(level); string typeArg = GetCanonicalizeTypeArg(type); - var gitArgs = $"config --null {levelArg} {typeArg} --get-regex {QuoteCmdArg(nameRegex)}"; + var gitArgs = $"config --null {levelArg} --includes {typeArg} --get-regex {QuoteCmdArg(nameRegex)}"; if (valueRegex != null) { gitArgs += $" {QuoteCmdArg(valueRegex)}"; From 2e036924b6e90f16050718d0d897186297bb311e Mon Sep 17 00:00:00 2001 From: Marc Becker Date: Fri, 22 May 2026 18:14:13 +0200 Subject: [PATCH 2/2] test(config): verify settings of included files configuration queries should process include statements consistently --- .../Core.Tests/GitConfigurationTests.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/shared/Core.Tests/GitConfigurationTests.cs b/src/shared/Core.Tests/GitConfigurationTests.cs index 5005cf431..369e366cd 100644 --- a/src/shared/Core.Tests/GitConfigurationTests.cs +++ b/src/shared/Core.Tests/GitConfigurationTests.cs @@ -656,5 +656,31 @@ public void GitConfiguration_TypedQuery_CanonicalizesValues() // Value should be canonicalized path, not raw "~/example" Assert.NotEqual("~/example", value); } + + [Fact] + public void GitConfiguration_ScopedConfig_ProcessesIncludes() + { + const string configKey = "test.value"; + const string configValue = "foo123"; + string repoPath = CreateRepository(out string workDirPath); + ExecGit(repoPath, workDirPath, $"config --file {workDirPath}/git.config {configKey} {configValue}").AssertSuccess(); + ExecGit(repoPath, workDirPath, $"config --global include.path {workDirPath}/git.config").AssertSuccess(); + ExecGit(repoPath, workDirPath, $"config --local include.path {workDirPath}/git.config").AssertSuccess(); + + string gitPath = GetGitPath(); + var trace = new NullTrace(); + var trace2 = new NullTrace2(); + var processManager = new TestProcessManager(); + + var git = new GitProcess(trace, trace2, processManager, gitPath, repoPath); + IGitConfiguration config = git.GetConfiguration(); + + // value of included file set in scopes + foreach (var scope in new GitConfigurationLevel[] { GitConfigurationLevel.Global, GitConfigurationLevel.Local }) + { + Assert.True(config.TryGet(scope, GitConfigurationType.Raw, configKey, out string value)); + Assert.Equal(configValue, value); + } + } } }