From 3a5009f576144b03598d8966b9e5b01d3ac4261c Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Wed, 3 Oct 2018 07:59:04 -0400 Subject: [PATCH] GitProcess: allow GIT_TRACE to point to full path --- GVFS/GVFS.Common/Git/GitProcess.cs | 26 ++++++++++---- .../EnlistmentPerFixture/StatusVerbTests.cs | 34 +++++++++++++++++++ .../Tools/GVFSFunctionalTestEnlistment.cs | 4 +-- .../GVFS.FunctionalTests/Tools/GVFSProcess.cs | 17 ++++++---- 4 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/StatusVerbTests.cs diff --git a/GVFS/GVFS.Common/Git/GitProcess.cs b/GVFS/GVFS.Common/Git/GitProcess.cs index 5c3bba3cde..c0937017b6 100644 --- a/GVFS/GVFS.Common/Git/GitProcess.cs +++ b/GVFS/GVFS.Common/Git/GitProcess.cs @@ -1,6 +1,5 @@ using GVFS.Common.FileSystem; using GVFS.Common.Tracing; -using Microsoft.Win32; using System; using System.Collections.Generic; using System.ComponentModel; @@ -149,7 +148,7 @@ public bool IsValidRepo() Result result = this.InvokeGitAgainstDotGitFolder("rev-parse --show-toplevel"); return !result.HasErrors; } - + public Result RevParse(string gitRef) { return this.InvokeGitAgainstDotGitFolder("rev-parse " + gitRef); @@ -405,11 +404,24 @@ public Process GetGitProcess(string command, string workingDirectory, string dot // Removing trace variables that might change git output and break parsing // List of environment variables: https://git-scm.com/book/gr/v2/Git-Internals-Environment-Variables - foreach (string key in processInfo.EnvironmentVariables.Keys.Cast() - .Where(x => x.StartsWith("GIT_TRACE", StringComparison.OrdinalIgnoreCase)) - .ToList()) + foreach (string key in processInfo.EnvironmentVariables.Keys.Cast().ToList()) { - processInfo.EnvironmentVariables.Remove(key); + // If GIT_TRACE is set to a fully-rooted path, then Git sends the trace + // output to that path instead of stdout (GIT_TRACE=1) or stderr (GIT_TRACE=2). + if (key.StartsWith("GIT_TRACE", StringComparison.OrdinalIgnoreCase)) + { + try + { + if (!Path.IsPathRooted(processInfo.EnvironmentVariables[key])) + { + processInfo.EnvironmentVariables.Remove(key); + } + } + catch (ArgumentException) + { + processInfo.EnvironmentVariables.Remove(key); + } + } } processInfo.EnvironmentVariables["GIT_TERMINAL_PROMPT"] = "0"; @@ -601,7 +613,7 @@ private Result InvokeGitAgainstDotGitFolder( parseStdOutLine: parseStdOutLine, timeoutMs: -1); } - + public class Result { public const int SuccessCode = 0; diff --git a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/StatusVerbTests.cs b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/StatusVerbTests.cs new file mode 100644 index 0000000000..c529778573 --- /dev/null +++ b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/StatusVerbTests.cs @@ -0,0 +1,34 @@ +using GVFS.FunctionalTests.FileSystemRunners; +using GVFS.Tests.Should; +using NUnit.Framework; +using System.Collections.Generic; +using System.IO; + +namespace GVFS.FunctionalTests.Tests.EnlistmentPerFixture +{ + [TestFixture] + public class StatusVerbTests : TestsWithEnlistmentPerFixture + { + private enum ExpectedReturnCode + { + Success = 0, + ParsingError = 1, + } + + [TestCase] + public void GitTrace() + { + Dictionary environmentVariables = new Dictionary(); + + this.Enlistment.Status(trace: "1"); + this.Enlistment.Status(trace: "2"); + + string logPath = Path.Combine(this.Enlistment.RepoRoot, "log-file.txt"); + this.Enlistment.Status(trace: logPath); + + FileSystemRunner fileSystem = new SystemIORunner(); + fileSystem.FileExists(logPath).ShouldBeTrue(); + string.IsNullOrWhiteSpace(fileSystem.ReadAllText(logPath)).ShouldBeFalse(); + } + } +} diff --git a/GVFS/GVFS.FunctionalTests/Tools/GVFSFunctionalTestEnlistment.cs b/GVFS/GVFS.FunctionalTests/Tools/GVFSFunctionalTestEnlistment.cs index 427fef7b28..c53ac27a43 100644 --- a/GVFS/GVFS.FunctionalTests/Tools/GVFSFunctionalTestEnlistment.cs +++ b/GVFS/GVFS.FunctionalTests/Tools/GVFSFunctionalTestEnlistment.cs @@ -207,9 +207,9 @@ public string Diagnose() return this.gvfsProcess.Diagnose(); } - public string Status() + public string Status(string trace = null) { - return this.gvfsProcess.Status(); + return this.gvfsProcess.Status(trace); } public bool WaitForBackgroundOperations(int maxWaitMilliseconds = DefaultMaxWaitMSForStatusCheck) diff --git a/GVFS/GVFS.FunctionalTests/Tools/GVFSProcess.cs b/GVFS/GVFS.FunctionalTests/Tools/GVFSProcess.cs index 51f466bb42..c0825dd798 100644 --- a/GVFS/GVFS.FunctionalTests/Tools/GVFSProcess.cs +++ b/GVFS/GVFS.FunctionalTests/Tools/GVFSProcess.cs @@ -8,14 +8,14 @@ public class GVFSProcess private readonly string pathToGVFS; private readonly string enlistmentRoot; private readonly string localCacheRoot; - + public GVFSProcess(string pathToGVFS, string enlistmentRoot, string localCacheRoot) { this.pathToGVFS = pathToGVFS; this.enlistmentRoot = enlistmentRoot; this.localCacheRoot = localCacheRoot; } - + public void Clone(string repositorySource, string branchToCheckout, bool skipPrefetch) { string args = string.Format( @@ -50,7 +50,7 @@ public string Prefetch(string args, bool failOnError) public void Repair() { this.CallGVFS( - "repair --confirm \"" + this.enlistmentRoot + "\"", + "repair --confirm \"" + this.enlistmentRoot + "\"", failOnError: true); } @@ -59,9 +59,9 @@ public string Diagnose() return this.CallGVFS("diagnose \"" + this.enlistmentRoot + "\""); } - public string Status() + public string Status(string trace = null) { - return this.CallGVFS("status " + this.enlistmentRoot); + return this.CallGVFS("status " + this.enlistmentRoot, trace: trace); } public string CacheServer(string args) @@ -89,7 +89,7 @@ public string RunServiceVerb(string argument) return this.CallGVFS("service " + argument, failOnError: true); } - private string CallGVFS(string args, bool failOnError = false) + private string CallGVFS(string args, bool failOnError = false, string trace = null) { ProcessStartInfo processInfo = null; processInfo = new ProcessStartInfo(this.pathToGVFS); @@ -99,6 +99,11 @@ private string CallGVFS(string args, bool failOnError = false) processInfo.UseShellExecute = false; processInfo.RedirectStandardOutput = true; + if (trace != null) + { + processInfo.EnvironmentVariables["GIT_TRACE"] = trace; + } + using (Process process = Process.Start(processInfo)) { string result = process.StandardOutput.ReadToEnd();