From 5dda6a61fbaa9cdcd988ba8746c2fc11ebb25aea Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Wed, 24 Mar 2021 09:15:59 +0000 Subject: [PATCH] git: drop config --show-scope option usage The Git config `--show-scope` option was only introduced in Git from version 2.26 onwards. The latest version of Git available in some distributions of Linux (or macOS) is often older. We only needed to know the scope of configuration values in one particular call site: reading all Azure Repos user bindinds. Replace the single `IGitConfiguration::Enumerate` call with two calls to `Enumerate`, one for the global scope, and one for the local one. Drop the --show-scope option parsing. --- .../AzureReposBindingManager.cs | 44 ++++++++++--------- .../GitConfiguration.cs | 38 +--------------- .../GitConfigurationEntry.cs | 4 +- .../Objects/TestGitConfiguration.cs | 2 +- 4 files changed, 27 insertions(+), 61 deletions(-) diff --git a/src/shared/Microsoft.AzureRepos/AzureReposBindingManager.cs b/src/shared/Microsoft.AzureRepos/AzureReposBindingManager.cs index 4219eb11d..bd43065ec 100644 --- a/src/shared/Microsoft.AzureRepos/AzureReposBindingManager.cs +++ b/src/shared/Microsoft.AzureRepos/AzureReposBindingManager.cs @@ -174,31 +174,33 @@ public IEnumerable GetBindings(string orgName = null) string orgPrefix = $"{AzureDevOpsConstants.UrnOrgPrefix}/"; - config.Enumerate( - Constants.GitConfiguration.Credential.SectionName, - Constants.GitConfiguration.Credential.UserName, - entry => + bool ExtractUserBinding(GitConfigurationEntry entry, IDictionary dict) + { + if (GitConfigurationKeyComparer.TrySplit(entry.Key, out _, out string scope, out _) && + Uri.TryCreate(scope, UriKind.Absolute, out Uri uri) && + uri.Scheme == AzureDevOpsConstants.UrnScheme && uri.AbsolutePath.StartsWith(orgPrefix)) { - if (GitConfigurationKeyComparer.TrySplit(entry.Key, out _, out string scope, out _) && - Uri.TryCreate(scope, UriKind.Absolute, out Uri uri) && - uri.Scheme == AzureDevOpsConstants.UrnScheme && uri.AbsolutePath.StartsWith(orgPrefix)) + string entryOrgName = uri.AbsolutePath.Substring(orgPrefix.Length); + if (orgName is null || StringComparer.OrdinalIgnoreCase.Equals(entryOrgName, orgName)) { - string entryOrgName = uri.AbsolutePath.Substring(orgPrefix.Length); - if (orgName is null || StringComparer.OrdinalIgnoreCase.Equals(entryOrgName, orgName)) - { - if (entry.Level == GitConfigurationLevel.Local) - { - localUsers[entryOrgName] = entry.Value; - } - else - { - globalUsers[entryOrgName] = entry.Value; - } - } + dict[entryOrgName] = entry.Value; } + } + + return true; + } - return true; - }); + config.Enumerate( + GitConfigurationLevel.Local, + Constants.GitConfiguration.Credential.SectionName, + Constants.GitConfiguration.Credential.UserName, + entry => ExtractUserBinding(entry, localUsers)); + + config.Enumerate( + GitConfigurationLevel.Global, + Constants.GitConfiguration.Credential.SectionName, + Constants.GitConfiguration.Credential.UserName, + entry => ExtractUserBinding(entry, globalUsers)); foreach (string org in globalUsers.Keys.Union(localUsers.Keys)) { diff --git a/src/shared/Microsoft.Git.CredentialManager/GitConfiguration.cs b/src/shared/Microsoft.Git.CredentialManager/GitConfiguration.cs index 3fef4f9fe..a73c8bfa1 100644 --- a/src/shared/Microsoft.Git.CredentialManager/GitConfiguration.cs +++ b/src/shared/Microsoft.Git.CredentialManager/GitConfiguration.cs @@ -117,7 +117,7 @@ internal GitProcessConfiguration(ITrace trace, GitProcess git) public void Enumerate(GitConfigurationLevel level, GitConfigurationEnumerationCallback cb) { string levelArg = GetLevelFilterArg(level); - using (Process git = _git.CreateProcess($"config --null {levelArg} --list --show-scope")) + using (Process git = _git.CreateProcess($"config --null {levelArg} --list")) { git.Start(); // To avoid deadlocks, always read the output stream first and then wait @@ -134,31 +134,14 @@ public void Enumerate(GitConfigurationLevel level, GitConfigurationEnumerationCa throw GitProcess.CreateGitException(git, "Failed to enumerate all Git configuration entries"); } - var scope = new StringBuilder(); var name = new StringBuilder(); var value = new StringBuilder(); int i = 0; while (i < data.Length) { - scope.Clear(); name.Clear(); value.Clear(); - // Read config scope (null terminated) - while (i < data.Length && data[i] != '\0') - { - scope.Append(data[i++]); - } - - if (i >= data.Length) - { - _trace.WriteLine("Invalid Git configuration output. Expected null terminator (\\0) after scope."); - break; - } - - // Skip the null terminator - i++; - // Read key name (LF terminated) while (i < data.Length && data[i] != '\n') { @@ -189,24 +172,7 @@ public void Enumerate(GitConfigurationLevel level, GitConfigurationEnumerationCa // Skip the null terminator i++; - GitConfigurationLevel entryLevel; - switch (scope.ToString()) - { - case "system": - entryLevel = GitConfigurationLevel.System; - break; - case "global": - entryLevel = GitConfigurationLevel.Global; - break; - case "local": - entryLevel = GitConfigurationLevel.Local; - break; - default: - entryLevel = GitConfigurationLevel.Unknown; - break; - } - - var entry = new GitConfigurationEntry(entryLevel, name.ToString(), value.ToString()); + var entry = new GitConfigurationEntry(name.ToString(), value.ToString()); if (!cb(entry)) { diff --git a/src/shared/Microsoft.Git.CredentialManager/GitConfigurationEntry.cs b/src/shared/Microsoft.Git.CredentialManager/GitConfigurationEntry.cs index 0dddf70df..e57c855e4 100644 --- a/src/shared/Microsoft.Git.CredentialManager/GitConfigurationEntry.cs +++ b/src/shared/Microsoft.Git.CredentialManager/GitConfigurationEntry.cs @@ -4,14 +4,12 @@ namespace Microsoft.Git.CredentialManager { public class GitConfigurationEntry { - public GitConfigurationEntry(GitConfigurationLevel level, string key, string value) + public GitConfigurationEntry(string key, string value) { - Level = level; Key = key; Value = value; } - public GitConfigurationLevel Level { get; } public string Key { get; } public string Value { get; } } diff --git a/src/shared/TestInfrastructure/Objects/TestGitConfiguration.cs b/src/shared/TestInfrastructure/Objects/TestGitConfiguration.cs index af9dee1d5..c9a15a6ce 100644 --- a/src/shared/TestInfrastructure/Objects/TestGitConfiguration.cs +++ b/src/shared/TestInfrastructure/Objects/TestGitConfiguration.cs @@ -26,7 +26,7 @@ public void Enumerate(GitConfigurationLevel level, GitConfigurationEnumerationCa { foreach (var value in kvp.Value) { - var entry = new GitConfigurationEntry(dictLevel, kvp.Key, value); + var entry = new GitConfigurationEntry(kvp.Key, value); if (!cb(entry)) { break;