From fa32180c13707c34b3ce847136fd8a53cf66d2e7 Mon Sep 17 00:00:00 2001 From: Tyrie Vella Date: Tue, 13 Jan 2026 11:14:51 -0800 Subject: [PATCH 1/2] Replace some git config calls with libgit2 --- GVFS/FastFetch/FastFetchLibGit2Repo.cs | 2 +- GVFS/GVFS.Common/Enlistment.cs | 26 ---- GVFS/GVFS.Common/GVFSConstants.cs | 1 + GVFS/GVFS.Common/Git/GitObjects.cs | 3 +- GVFS/GVFS.Common/Git/GitRepo.cs | 5 + GVFS/GVFS.Common/Git/LibGit2Exception.cs | 19 +++ GVFS/GVFS.Common/Git/LibGit2Repo.cs | 99 +++++++++++++-- GVFS/GVFS.Common/Git/LibGit2RepoInvoker.cs | 16 +++ GVFS/GVFS.Common/GitStatusCache.cs | 3 +- GVFS/GVFS.Common/Maintenance/PrefetchStep.cs | 4 +- GVFS/GVFS.Common/Tracing/NullTracer.cs | 115 ++++++++++++++++++ GVFS/GVFS.Hooks/GVFS.Hooks.csproj | 38 +++++- GVFS/GVFS.Hooks/Program.cs | 17 +-- .../Mock/Git/MockGVFSGitObjects.cs | 2 +- GVFS/GVFS/CommandLine/CloneVerb.cs | 7 +- 15 files changed, 298 insertions(+), 59 deletions(-) create mode 100644 GVFS/GVFS.Common/Git/LibGit2Exception.cs create mode 100644 GVFS/GVFS.Common/Tracing/NullTracer.cs diff --git a/GVFS/FastFetch/FastFetchLibGit2Repo.cs b/GVFS/FastFetch/FastFetchLibGit2Repo.cs index 8c77164158..d278baa5af 100644 --- a/GVFS/FastFetch/FastFetchLibGit2Repo.cs +++ b/GVFS/FastFetch/FastFetchLibGit2Repo.cs @@ -18,7 +18,7 @@ public FastFetchLibGit2Repo(ITracer tracer, string repoPath) public virtual bool TryCopyBlobToFile(string sha, IEnumerable destinations, out long bytesWritten) { IntPtr objHandle; - if (Native.RevParseSingle(out objHandle, this.RepoHandle, sha) != Native.SuccessCode) + if (Native.RevParseSingle(out objHandle, this.RepoHandle, sha) != Native.ResultCode.Success) { bytesWritten = 0; EventMetadata metadata = new EventMetadata(); diff --git a/GVFS/GVFS.Common/Enlistment.cs b/GVFS/GVFS.Common/Enlistment.cs index 9e40b309ca..3f061257fb 100644 --- a/GVFS/GVFS.Common/Enlistment.cs +++ b/GVFS/GVFS.Common/Enlistment.cs @@ -109,31 +109,5 @@ public virtual GitProcess CreateGitProcess() { return new GitProcess(this); } - - public bool GetTrustPackIndexesConfig() - { - var gitProcess = this.CreateGitProcess(); - bool trustPackIndexes = true; - if (gitProcess.TryGetFromConfig(GVFSConstants.GitConfig.TrustPackIndexes, forceOutsideEnlistment: false, out var valueString) - && bool.TryParse(valueString, out var trustPackIndexesConfig)) - { - trustPackIndexes = trustPackIndexesConfig; - } - - return trustPackIndexes; - } - - public bool GetStatusHydrationConfig() - { - var gitProcess = this.CreateGitProcess(); - - if (gitProcess.TryGetFromConfig(GVFSConstants.GitConfig.ShowHydrationStatus, forceOutsideEnlistment: false, out var valueString) - && bool.TryParse(valueString, out var statusHydrationConfig)) - { - return statusHydrationConfig; - } - - return GVFSConstants.GitConfig.ShowHydrationStatusDefault; - } } } diff --git a/GVFS/GVFS.Common/GVFSConstants.cs b/GVFS/GVFS.Common/GVFSConstants.cs index 3f3abecc42..cf52e1fbbd 100644 --- a/GVFS/GVFS.Common/GVFSConstants.cs +++ b/GVFS/GVFS.Common/GVFSConstants.cs @@ -42,6 +42,7 @@ public static class GitConfig /* Intended to be a temporary config to allow testing of distrusting pack indexes from cache server * before it is enabled by default. */ public const string TrustPackIndexes = GVFSPrefix + "trust-pack-indexes"; + public const bool TrustPackIndexesDefault = true; public const string ShowHydrationStatus = GVFSPrefix + "show-hydration-status"; public const bool ShowHydrationStatusDefault = false; diff --git a/GVFS/GVFS.Common/Git/GitObjects.cs b/GVFS/GVFS.Common/Git/GitObjects.cs index 6807494dfc..da68656c84 100644 --- a/GVFS/GVFS.Common/Git/GitObjects.cs +++ b/GVFS/GVFS.Common/Git/GitObjects.cs @@ -153,7 +153,7 @@ public virtual void DeleteTemporaryFiles() } } - public virtual bool TryDownloadPrefetchPacks(GitProcess gitProcess, long latestTimestamp, out List packIndexes) + public virtual bool TryDownloadPrefetchPacks(GitProcess gitProcess, long latestTimestamp, bool trustPackIndexes, out List packIndexes) { EventMetadata metadata = CreateEventMetadata(); metadata.Add("latestTimestamp", latestTimestamp); @@ -166,7 +166,6 @@ public virtual bool TryDownloadPrefetchPacks(GitProcess gitProcess, long latestT * pack file and an index file that do not match. * Eventually we will make this the default, but it has a high performance cost for the first prefetch after * cloning a large repository, so it must be explicitly enabled for now. */ - bool trustPackIndexes = this.Enlistment.GetTrustPackIndexesConfig(); metadata.Add("trustPackIndexes", trustPackIndexes); long requestId = HttpRequestor.GetNewRequestId(); diff --git a/GVFS/GVFS.Common/Git/GitRepo.cs b/GVFS/GVFS.Common/Git/GitRepo.cs index cd11436d8c..b2b3ad7b38 100644 --- a/GVFS/GVFS.Common/Git/GitRepo.cs +++ b/GVFS/GVFS.Common/Git/GitRepo.cs @@ -51,6 +51,11 @@ public GVFSLock GVFSLock private set; } + internal LibGit2RepoInvoker LibGit2RepoInvoker + { + get { return this.libgit2RepoInvoker; } + } + public void CloseActiveRepo() { this.libgit2RepoInvoker?.DisposeSharedRepo(); diff --git a/GVFS/GVFS.Common/Git/LibGit2Exception.cs b/GVFS/GVFS.Common/Git/LibGit2Exception.cs new file mode 100644 index 0000000000..27034e513e --- /dev/null +++ b/GVFS/GVFS.Common/Git/LibGit2Exception.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GVFS.Common.Git +{ + public class LibGit2Exception : Exception + { + public LibGit2Exception(string message) : base(message) + { + } + + public LibGit2Exception(string message, Exception innerException) : base(message, innerException) + { + } + } +} diff --git a/GVFS/GVFS.Common/Git/LibGit2Repo.cs b/GVFS/GVFS.Common/Git/LibGit2Repo.cs index f9edcce64a..86415ea5c3 100644 --- a/GVFS/GVFS.Common/Git/LibGit2Repo.cs +++ b/GVFS/GVFS.Common/Git/LibGit2Repo.cs @@ -17,7 +17,7 @@ public LibGit2Repo(ITracer tracer, string repoPath) Native.Init(); IntPtr repoHandle; - if (Native.Repo.Open(out repoHandle, repoPath) != Native.SuccessCode) + if (Native.Repo.Open(out repoHandle, repoPath) != Native.ResultCode.Success) { string reason = Native.GetLastError(); string message = "Couldn't open repo at " + repoPath + ": " + reason; @@ -45,7 +45,7 @@ protected LibGit2Repo() public Native.ObjectTypes? GetObjectType(string sha) { IntPtr objHandle; - if (Native.RevParseSingle(out objHandle, this.RepoHandle, sha) != Native.SuccessCode) + if (Native.RevParseSingle(out objHandle, this.RepoHandle, sha) != Native.ResultCode.Success) { return null; } @@ -63,7 +63,7 @@ protected LibGit2Repo() public virtual string GetTreeSha(string commitish) { IntPtr objHandle; - if (Native.RevParseSingle(out objHandle, this.RepoHandle, commitish) != Native.SuccessCode) + if (Native.RevParseSingle(out objHandle, this.RepoHandle, commitish) != Native.ResultCode.Success) { return null; } @@ -99,7 +99,7 @@ public virtual bool CommitAndRootTreeExists(string commitish, out string treeSha public virtual bool ObjectExists(string sha) { IntPtr objHandle; - if (Native.RevParseSingle(out objHandle, this.RepoHandle, sha) != Native.SuccessCode) + if (Native.RevParseSingle(out objHandle, this.RepoHandle, sha) != Native.ResultCode.Success) { return false; } @@ -111,7 +111,7 @@ public virtual bool ObjectExists(string sha) public virtual bool TryCopyBlob(string sha, Action writeAction) { IntPtr objHandle; - if (Native.RevParseSingle(out objHandle, this.RepoHandle, sha) != Native.SuccessCode) + if (Native.RevParseSingle(out objHandle, this.RepoHandle, sha) != Native.ResultCode.Success) { return false; } @@ -157,7 +157,7 @@ public virtual string[] GetMissingSubTrees(string treeSha) { List missingSubtreesList = new List(); IntPtr treeHandle; - if (Native.RevParseSingle(out treeHandle, this.RepoHandle, treeSha) != Native.SuccessCode + if (Native.RevParseSingle(out treeHandle, this.RepoHandle, treeSha) != Native.ResultCode.Success || treeHandle == IntPtr.Zero) { return Array.Empty(); @@ -187,6 +187,68 @@ public virtual string[] GetMissingSubTrees(string treeSha) return missingSubtreesList.ToArray(); } + /// + /// Get a config value from the repo's git config. + /// + /// Name of the config entry + /// The config value, or null if not found. + public virtual string GetConfigString(string name) + { + IntPtr configHandle; + if (Native.Config.GetConfig(out configHandle, this.RepoHandle) != Native.ResultCode.Success) + { + throw new LibGit2Exception($"Failed to get config handle: {Native.GetLastError()}"); + } + try + { + string value; + Native.ResultCode resultCode = Native.Config.GetString(out value, configHandle, name); + if (resultCode == Native.ResultCode.NotFound) + { + return null; + } + else if (resultCode != Native.ResultCode.Success) + { + throw new LibGit2Exception($"Failed to get config value for '{name}': {Native.GetLastError()}"); + } + + return value; + } + finally + { + Native.Config.Free(configHandle); + } + } + + public virtual bool? GetConfigBool(string name) + { + IntPtr configHandle; + if (Native.Config.GetConfig(out configHandle, this.RepoHandle) != Native.ResultCode.Success) + { + throw new LibGit2Exception($"Failed to get config handle: {Native.GetLastError()}"); + } + try + { + bool value; + Native.ResultCode resultCode = Native.Config.GetBool(out value, configHandle, name); + if (resultCode == Native.ResultCode.NotFound) + { + return null; + } + else if (resultCode != Native.ResultCode.Success) + { + throw new LibGit2Exception($"Failed to get config value for '{name}': {Native.GetLastError()}"); + } + + return value; + } + finally + { + Native.Config.Free(configHandle); + } + + } + /// /// Determine if the given index of a tree is a subtree and if it is missing. /// If it is a missing subtree, return the SHA of the subtree. @@ -242,7 +304,11 @@ protected virtual void Dispose(bool disposing) public static class Native { - public const uint SuccessCode = 0; + public enum ResultCode : int + { + Success = 0, + NotFound = -3, + } public const string Git2NativeLibName = GVFSConstants.LibGit2LibraryName; @@ -265,7 +331,7 @@ public static GitOid IntPtrToGitOid(IntPtr oidPtr) public static extern int Shutdown(); [DllImport(Git2NativeLibName, EntryPoint = "git_revparse_single")] - public static extern uint RevParseSingle(out IntPtr objectHandle, IntPtr repoHandle, string oid); + public static extern ResultCode RevParseSingle(out IntPtr objectHandle, IntPtr repoHandle, string oid); public static string GetLastError() { @@ -293,12 +359,27 @@ private struct GitError public static class Repo { [DllImport(Git2NativeLibName, EntryPoint = "git_repository_open")] - public static extern uint Open(out IntPtr repoHandle, string path); + public static extern ResultCode Open(out IntPtr repoHandle, string path); [DllImport(Git2NativeLibName, EntryPoint = "git_repository_free")] public static extern void Free(IntPtr repoHandle); } + public static class Config + { + [DllImport(Git2NativeLibName, EntryPoint = "git_repository_config")] + public static extern ResultCode GetConfig(out IntPtr configHandle, IntPtr repoHandle); + + [DllImport(Git2NativeLibName, EntryPoint = "git_config_get_string")] + public static extern ResultCode GetString(out string value, IntPtr configHandle, string name); + + [DllImport(Git2NativeLibName, EntryPoint = "git_config_get_bool")] + public static extern ResultCode GetBool(out bool value, IntPtr configHandle, string name); + + [DllImport(Git2NativeLibName, EntryPoint = "git_config_free")] + public static extern void Free(IntPtr configHandle); + } + public static class Object { [DllImport(Git2NativeLibName, EntryPoint = "git_object_type")] diff --git a/GVFS/GVFS.Common/Git/LibGit2RepoInvoker.cs b/GVFS/GVFS.Common/Git/LibGit2RepoInvoker.cs index 8d3ec2e06c..ea160e4983 100644 --- a/GVFS/GVFS.Common/Git/LibGit2RepoInvoker.cs +++ b/GVFS/GVFS.Common/Git/LibGit2RepoInvoker.cs @@ -13,6 +13,11 @@ public class LibGit2RepoInvoker : IDisposable private volatile int activeCallers; private LibGit2Repo sharedRepo; + public LibGit2RepoInvoker(ITracer tracer, string repoPath) + : this(tracer, () => new LibGit2Repo(tracer, repoPath)) + { + } + public LibGit2RepoInvoker(ITracer tracer, Func createRepo) { this.tracer = tracer; @@ -82,6 +87,17 @@ public void InitializeSharedRepo() this.GetSharedRepo()?.ObjectExists("30380be3963a75e4a34e10726795d644659e1129"); } + public bool GetConfigBoolWithFallback(string key, bool defaultValue) + { + bool? value = defaultValue; + if (this.TryInvoke(repo => repo.GetConfigBool(key), out value)) + { + return value ?? defaultValue; + } + + return defaultValue; + } + private LibGit2Repo GetSharedRepo() { lock (this.sharedRepoLock) diff --git a/GVFS/GVFS.Common/GitStatusCache.cs b/GVFS/GVFS.Common/GitStatusCache.cs index 8ef6b37434..bae306c379 100644 --- a/GVFS/GVFS.Common/GitStatusCache.cs +++ b/GVFS/GVFS.Common/GitStatusCache.cs @@ -341,7 +341,8 @@ private void RebuildStatusCacheIfNeeded(bool ignoreBackoff) private void UpdateHydrationSummary() { - bool enabled = TEST_EnableHydrationSummaryOverride ?? this.context.Enlistment.GetStatusHydrationConfig(); + bool enabled = TEST_EnableHydrationSummaryOverride + ?? this.context.Repository.LibGit2RepoInvoker.GetConfigBoolWithFallback(GVFSConstants.GitConfig.ShowHydrationStatus, GVFSConstants.GitConfig.ShowHydrationStatusDefault); if (!enabled) { return; diff --git a/GVFS/GVFS.Common/Maintenance/PrefetchStep.cs b/GVFS/GVFS.Common/Maintenance/PrefetchStep.cs index a494ac6cc7..5d37d6e5c4 100644 --- a/GVFS/GVFS.Common/Maintenance/PrefetchStep.cs +++ b/GVFS/GVFS.Common/Maintenance/PrefetchStep.cs @@ -56,7 +56,9 @@ public bool TryPrefetchCommitsAndTrees(out string error, GitProcess gitProcess = return false; } - if (!this.GitObjects.TryDownloadPrefetchPacks(gitProcess, maxGoodTimeStamp, out packIndexes)) + var trustPackIndexes = this.Context.Repository.LibGit2RepoInvoker.GetConfigBoolWithFallback(GVFSConstants.GitConfig.TrustPackIndexes, GVFSConstants.GitConfig.TrustPackIndexesDefault); + + if (!this.GitObjects.TryDownloadPrefetchPacks(gitProcess, maxGoodTimeStamp, trustPackIndexes, out packIndexes)) { error = "Failed to download prefetch packs"; return false; diff --git a/GVFS/GVFS.Common/Tracing/NullTracer.cs b/GVFS/GVFS.Common/Tracing/NullTracer.cs new file mode 100644 index 0000000000..8cd5566428 --- /dev/null +++ b/GVFS/GVFS.Common/Tracing/NullTracer.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GVFS.Common.Tracing +{ + /// + /// Empty implementation of ITracer that does nothing + /// + public sealed class NullTracer : ITracer + { + private NullTracer() + { + } + + public static ITracer Instance { get; } = new NullTracer(); + + void IDisposable.Dispose() + { + + } + + void ITracer.RelatedError(EventMetadata metadata, string message) + { + + } + + void ITracer.RelatedError(EventMetadata metadata, string message, Keywords keywords) + { + + } + + void ITracer.RelatedError(string message) + { + + } + + void ITracer.RelatedError(string format, params object[] args) + { + + } + + void ITracer.RelatedEvent(EventLevel level, string eventName, EventMetadata metadata) + { + + } + + void ITracer.RelatedEvent(EventLevel level, string eventName, EventMetadata metadata, Keywords keywords) + { + + } + + void ITracer.RelatedInfo(string message) + { + + } + + void ITracer.RelatedInfo(string format, params object[] args) + { + + } + + void ITracer.RelatedInfo(EventMetadata metadata, string message) + { + + } + + void ITracer.RelatedWarning(EventMetadata metadata, string message) + { + + } + + void ITracer.RelatedWarning(EventMetadata metadata, string message, Keywords keywords) + { + + } + + void ITracer.RelatedWarning(string message) + { + + } + + void ITracer.RelatedWarning(string format, params object[] args) + { + + } + + void ITracer.SetGitCommandSessionId(string sessionId) + { + + } + + ITracer ITracer. StartActivity(string activityName, EventLevel level) + { + return this; + } + + ITracer ITracer. StartActivity(string activityName, EventLevel level, EventMetadata metadata) + { + return this; + } + + ITracer ITracer. StartActivity(string activityName, EventLevel level, Keywords startStopKeywords, EventMetadata metadata) + { + return this; + } + + TimeSpan ITracer.Stop(EventMetadata metadata) + { + return TimeSpan.Zero; + } + } +} diff --git a/GVFS/GVFS.Hooks/GVFS.Hooks.csproj b/GVFS/GVFS.Hooks/GVFS.Hooks.csproj index 23dd6ea97a..9c0956b8bb 100644 --- a/GVFS/GVFS.Hooks/GVFS.Hooks.csproj +++ b/GVFS/GVFS.Hooks/GVFS.Hooks.csproj @@ -3,8 +3,13 @@ Exe net471 + true + + + + + + + + + + + + + diff --git a/GVFS/GVFS.Hooks/Program.cs b/GVFS/GVFS.Hooks/Program.cs index d48230a2ab..9aba77d017 100644 --- a/GVFS/GVFS.Hooks/Program.cs +++ b/GVFS/GVFS.Hooks/Program.cs @@ -1,5 +1,7 @@ using GVFS.Common; +using GVFS.Common.Git; using GVFS.Common.NamedPipes; +using GVFS.Common.Tracing; using GVFS.Hooks.HooksPlatform; using System; using System.Collections.Generic; @@ -19,6 +21,7 @@ public class Program private static string enlistmentRoot; private static string enlistmentPipename; + private static string normalizedCurrentDirectory; private static Random random = new Random(); private delegate void LockRequestDelegate(bool unattended, string[] args, int pid, NamedPipeClient pipeClient); @@ -35,7 +38,6 @@ public static void Main(string[] args) bool unattended = GVFSEnlistment.IsUnattended(tracer: null); string errorMessage; - string normalizedCurrentDirectory; if (!GVFSHooksPlatform.TryGetNormalizedPath(Environment.CurrentDirectory, out normalizedCurrentDirectory, out errorMessage)) { ExitWithError($"Failed to determine final path for current directory {Environment.CurrentDirectory}. Error: {errorMessage}"); @@ -108,19 +110,10 @@ private static bool ArgsBlockHydrationStatus(string[] args) private static bool ConfigurationAllowsHydrationStatus() { - try - { - ProcessResult result = ProcessHelper.Run("git", $"config --get {GVFSConstants.GitConfig.ShowHydrationStatus}"); - bool hydrationStatusEnabled; - if (bool.TryParse(result.Output.Trim(), out hydrationStatusEnabled)) - { - return hydrationStatusEnabled; - } - } - catch (Exception) + using (LibGit2RepoInvoker repo = new LibGit2RepoInvoker(NullTracer.Instance, normalizedCurrentDirectory)) { + return repo.GetConfigBoolWithFallback(GVFSConstants.GitConfig.ShowHydrationStatus, GVFSConstants.GitConfig.ShowHydrationStatusDefault); } - return GVFSConstants.GitConfig.ShowHydrationStatusDefault; } private static void ExitWithError(params string[] messages) diff --git a/GVFS/GVFS.UnitTests/Mock/Git/MockGVFSGitObjects.cs b/GVFS/GVFS.UnitTests/Mock/Git/MockGVFSGitObjects.cs index 47c30d35ea..b95984ecce 100644 --- a/GVFS/GVFS.UnitTests/Mock/Git/MockGVFSGitObjects.cs +++ b/GVFS/GVFS.UnitTests/Mock/Git/MockGVFSGitObjects.cs @@ -71,7 +71,7 @@ public override void DeleteStaleTempPrefetchPackAndIdxs() { } - public override bool TryDownloadPrefetchPacks(GitProcess gitProcess, long latestTimestamp, out List packIndexes) + public override bool TryDownloadPrefetchPacks(GitProcess gitProcess, long latestTimestamp, bool trustPackIndexes, out List packIndexes) { packIndexes = new List(); return true; diff --git a/GVFS/GVFS/CommandLine/CloneVerb.cs b/GVFS/GVFS/CommandLine/CloneVerb.cs index e0d8583609..7a69d3e483 100644 --- a/GVFS/GVFS/CommandLine/CloneVerb.cs +++ b/GVFS/GVFS/CommandLine/CloneVerb.cs @@ -222,7 +222,12 @@ public override void Execute() { if (!this.NoPrefetch) { - bool trustPackIndexes = enlistment.GetTrustPackIndexesConfig(); + bool trustPackIndexes; + using (var repo = new LibGit2RepoInvoker(NullTracer.Instance, enlistment.WorkingDirectoryBackingRoot)) + { + trustPackIndexes = repo.GetConfigBoolWithFallback(GVFSConstants.GitConfig.TrustPackIndexes, GVFSConstants.GitConfig.TrustPackIndexesDefault); + } + /* If pack indexes are not trusted, the prefetch can take a long time. * We will run the prefetch command in the background. */ From 80f5df6d64d68d48a29ce93be875b80bde64e45a Mon Sep 17 00:00:00 2001 From: Tyrie Vella Date: Wed, 14 Jan 2026 15:31:37 -0800 Subject: [PATCH 2/2] PR feedback --- GVFS/GVFS.Common/Git/LibGit2RepoInvoker.cs | 2 +- GVFS/GVFS.Common/GitStatusCache.cs | 2 +- GVFS/GVFS.Common/Maintenance/PrefetchStep.cs | 2 +- GVFS/GVFS.Hooks/Program.cs | 2 +- GVFS/GVFS/CommandLine/CloneVerb.cs | 12 ++++++------ 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/GVFS/GVFS.Common/Git/LibGit2RepoInvoker.cs b/GVFS/GVFS.Common/Git/LibGit2RepoInvoker.cs index ea160e4983..44b0840498 100644 --- a/GVFS/GVFS.Common/Git/LibGit2RepoInvoker.cs +++ b/GVFS/GVFS.Common/Git/LibGit2RepoInvoker.cs @@ -87,7 +87,7 @@ public void InitializeSharedRepo() this.GetSharedRepo()?.ObjectExists("30380be3963a75e4a34e10726795d644659e1129"); } - public bool GetConfigBoolWithFallback(string key, bool defaultValue) + public bool GetConfigBoolOrDefault(string key, bool defaultValue) { bool? value = defaultValue; if (this.TryInvoke(repo => repo.GetConfigBool(key), out value)) diff --git a/GVFS/GVFS.Common/GitStatusCache.cs b/GVFS/GVFS.Common/GitStatusCache.cs index bae306c379..e8f5a0f4fb 100644 --- a/GVFS/GVFS.Common/GitStatusCache.cs +++ b/GVFS/GVFS.Common/GitStatusCache.cs @@ -342,7 +342,7 @@ private void RebuildStatusCacheIfNeeded(bool ignoreBackoff) private void UpdateHydrationSummary() { bool enabled = TEST_EnableHydrationSummaryOverride - ?? this.context.Repository.LibGit2RepoInvoker.GetConfigBoolWithFallback(GVFSConstants.GitConfig.ShowHydrationStatus, GVFSConstants.GitConfig.ShowHydrationStatusDefault); + ?? this.context.Repository.LibGit2RepoInvoker.GetConfigBoolOrDefault(GVFSConstants.GitConfig.ShowHydrationStatus, GVFSConstants.GitConfig.ShowHydrationStatusDefault); if (!enabled) { return; diff --git a/GVFS/GVFS.Common/Maintenance/PrefetchStep.cs b/GVFS/GVFS.Common/Maintenance/PrefetchStep.cs index 5d37d6e5c4..163089afb3 100644 --- a/GVFS/GVFS.Common/Maintenance/PrefetchStep.cs +++ b/GVFS/GVFS.Common/Maintenance/PrefetchStep.cs @@ -56,7 +56,7 @@ public bool TryPrefetchCommitsAndTrees(out string error, GitProcess gitProcess = return false; } - var trustPackIndexes = this.Context.Repository.LibGit2RepoInvoker.GetConfigBoolWithFallback(GVFSConstants.GitConfig.TrustPackIndexes, GVFSConstants.GitConfig.TrustPackIndexesDefault); + var trustPackIndexes = this.Context.Repository.LibGit2RepoInvoker.GetConfigBoolOrDefault(GVFSConstants.GitConfig.TrustPackIndexes, GVFSConstants.GitConfig.TrustPackIndexesDefault); if (!this.GitObjects.TryDownloadPrefetchPacks(gitProcess, maxGoodTimeStamp, trustPackIndexes, out packIndexes)) { diff --git a/GVFS/GVFS.Hooks/Program.cs b/GVFS/GVFS.Hooks/Program.cs index 9aba77d017..151cba9b50 100644 --- a/GVFS/GVFS.Hooks/Program.cs +++ b/GVFS/GVFS.Hooks/Program.cs @@ -112,7 +112,7 @@ private static bool ConfigurationAllowsHydrationStatus() { using (LibGit2RepoInvoker repo = new LibGit2RepoInvoker(NullTracer.Instance, normalizedCurrentDirectory)) { - return repo.GetConfigBoolWithFallback(GVFSConstants.GitConfig.ShowHydrationStatus, GVFSConstants.GitConfig.ShowHydrationStatusDefault); + return repo.GetConfigBoolOrDefault(GVFSConstants.GitConfig.ShowHydrationStatus, GVFSConstants.GitConfig.ShowHydrationStatusDefault); } } diff --git a/GVFS/GVFS/CommandLine/CloneVerb.cs b/GVFS/GVFS/CommandLine/CloneVerb.cs index 7a69d3e483..8bbc5b9fb7 100644 --- a/GVFS/GVFS/CommandLine/CloneVerb.cs +++ b/GVFS/GVFS/CommandLine/CloneVerb.cs @@ -121,6 +121,7 @@ public override void Execute() CacheServerInfo cacheServer = null; ServerGVFSConfig serverGVFSConfig = null; + bool trustPackIndexes; using (JsonTracer tracer = new JsonTracer(GVFSConstants.GVFSEtwProviderName, "GVFSClone")) { @@ -216,18 +217,17 @@ public override void Execute() { tracer.RelatedError(cloneResult.ErrorMessage); } + + using (var repo = new LibGit2RepoInvoker(tracer, enlistment.WorkingDirectoryBackingRoot)) + { + trustPackIndexes = repo.GetConfigBoolOrDefault(GVFSConstants.GitConfig.TrustPackIndexes, GVFSConstants.GitConfig.TrustPackIndexesDefault); + } } if (cloneResult.Success) { if (!this.NoPrefetch) { - bool trustPackIndexes; - using (var repo = new LibGit2RepoInvoker(NullTracer.Instance, enlistment.WorkingDirectoryBackingRoot)) - { - trustPackIndexes = repo.GetConfigBoolWithFallback(GVFSConstants.GitConfig.TrustPackIndexes, GVFSConstants.GitConfig.TrustPackIndexesDefault); - } - /* If pack indexes are not trusted, the prefetch can take a long time. * We will run the prefetch command in the background. */