Skip to content

Commit af1e234

Browse files
authored
Merge pull request #1839 from microsoft/milestones/m257
M257 release
2 parents 2b6bf5d + 6b8e93b commit af1e234

10 files changed

Lines changed: 56 additions & 39 deletions

File tree

GVFS/GVFS.Common/FileSystem/HooksInstaller.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ static HooksInstaller()
2828
public static string MergeHooksData(string[] defaultHooksLines, string filename, string hookName)
2929
{
3030
IEnumerable<string> valuableHooksLines = defaultHooksLines.Where(line => !string.IsNullOrEmpty(line.Trim()));
31-
string absolutePathToHooksExecutable = Path.Combine(ExecutingDirectory, GVFSPlatform.Instance.Constants.GVFSHooksExecutableName);
31+
/* Wrap in quotes to handle spaces in the path */
32+
string absolutePathToHooksExecutable = $"\"{Path.Combine(ExecutingDirectory, GVFSPlatform.Instance.Constants.GVFSHooksExecutableName)}\"";
3233

3334
if (valuableHooksLines.Contains(GVFSPlatform.Instance.Constants.GVFSHooksExecutableName, GVFSPlatform.Instance.Constants.PathComparer))
3435
{

GVFS/GVFS.Common/GVFSPlatform.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ public abstract class GVFSPlatformConstants
143143

144144
public abstract string GVFSExecutableName { get; }
145145

146-
public abstract string ProgramLocaterCommand { get; }
147146

148147
/// <summary>
149148
/// Different platforms can have different requirements

GVFS/GVFS.Common/Git/GitProcess.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,9 @@ public bool TryGetFromConfig(string settingName, bool forceOutsideEnlistment, ou
462462

463463
public ConfigResult GetOriginUrl()
464464
{
465-
return new ConfigResult(this.InvokeGitAgainstDotGitFolder("config --local remote.origin.url"), "remote.origin.url");
465+
/* Disable precommand hook because this config call is used during mounting process
466+
* which needs to be able to fix a bad precommand hook configuration. */
467+
return new ConfigResult(this.InvokeGitAgainstDotGitFolder("config --local remote.origin.url", usePreCommandHook: false), "remote.origin.url");
466468
}
467469

468470
public Result DiffTree(string sourceTreeish, string targetTreeish, Action<string> onResult)
@@ -670,7 +672,7 @@ public Result MultiPackIndexRepack(string gitObjectDirectory, string batchSize)
670672
return this.InvokeGitAgainstDotGitFolder($"-c pack.threads=1 -c repack.packKeptObjects=true multi-pack-index repack --object-dir=\"{gitObjectDirectory}\" --batch-size={batchSize} --no-progress");
671673
}
672674

673-
public Process GetGitProcess(string command, string workingDirectory, string dotGitDirectory, bool useReadObjectHook, bool redirectStandardError, string gitObjectsDirectory)
675+
public Process GetGitProcess(string command, string workingDirectory, string dotGitDirectory, bool useReadObjectHook, bool redirectStandardError, string gitObjectsDirectory, bool usePreCommandHook)
674676
{
675677
ProcessStartInfo processInfo = new ProcessStartInfo(this.gitBinPath);
676678
processInfo.WorkingDirectory = workingDirectory;
@@ -719,6 +721,11 @@ public Process GetGitProcess(string command, string workingDirectory, string dot
719721
command = "-c " + GitConfigSetting.CoreVirtualizeObjectsName + "=false " + command;
720722
}
721723

724+
if (!usePreCommandHook)
725+
{
726+
processInfo.EnvironmentVariables["COMMAND_HOOK_LOCK"] = "true";
727+
}
728+
722729
if (!string.IsNullOrEmpty(dotGitDirectory))
723730
{
724731
command = "--git-dir=\"" + dotGitDirectory + "\" " + command;
@@ -740,7 +747,8 @@ protected virtual Result InvokeGitImpl(
740747
Action<StreamWriter> writeStdIn,
741748
Action<string> parseStdOutLine,
742749
int timeoutMs,
743-
string gitObjectsDirectory = null)
750+
string gitObjectsDirectory = null,
751+
bool usePreCommandHook = true)
744752
{
745753
if (failedToSetEncoding && writeStdIn != null)
746754
{
@@ -752,7 +760,7 @@ protected virtual Result InvokeGitImpl(
752760
// From https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx
753761
// To avoid deadlocks, use asynchronous read operations on at least one of the streams.
754762
// Do not perform a synchronous read to the end of both redirected streams.
755-
using (this.executingProcess = this.GetGitProcess(command, workingDirectory, dotGitDirectory, useReadObjectHook, redirectStandardError: true, gitObjectsDirectory: gitObjectsDirectory))
763+
using (this.executingProcess = this.GetGitProcess(command, workingDirectory, dotGitDirectory, useReadObjectHook, redirectStandardError: true, gitObjectsDirectory: gitObjectsDirectory, usePreCommandHook: usePreCommandHook))
756764
{
757765
StringBuilder output = new StringBuilder();
758766
StringBuilder errors = new StringBuilder();
@@ -904,15 +912,16 @@ private Result InvokeGitInWorkingDirectoryRoot(
904912
/// Invokes git.exe against an enlistment's .git folder.
905913
/// This method should be used only with git-commands that ignore the working directory
906914
/// </summary>
907-
private Result InvokeGitAgainstDotGitFolder(string command)
915+
private Result InvokeGitAgainstDotGitFolder(string command, bool usePreCommandHook = true)
908916
{
909-
return this.InvokeGitAgainstDotGitFolder(command, null, null);
917+
return this.InvokeGitAgainstDotGitFolder(command, null, null, usePreCommandHook: usePreCommandHook);
910918
}
911919

912920
private Result InvokeGitAgainstDotGitFolder(
913921
string command,
914922
Action<StreamWriter> writeStdIn,
915923
Action<string> parseStdOutLine,
924+
bool usePreCommandHook = true,
916925
string gitObjectsDirectory = null)
917926
{
918927
// This git command should not need/use the working directory of the repo.
@@ -926,7 +935,8 @@ private Result InvokeGitAgainstDotGitFolder(
926935
writeStdIn: writeStdIn,
927936
parseStdOutLine: parseStdOutLine,
928937
timeoutMs: -1,
929-
gitObjectsDirectory: gitObjectsDirectory);
938+
gitObjectsDirectory: gitObjectsDirectory,
939+
usePreCommandHook: usePreCommandHook);
930940
}
931941

932942
public class Result

GVFS/GVFS.Common/ProcessHelper.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,16 @@ public static string GetCurrentProcessVersion()
5757

5858
public static bool IsDevelopmentVersion()
5959
{
60-
Version currentVersion = new Version(ProcessHelper.GetCurrentProcessVersion());
60+
string version = ProcessHelper.GetCurrentProcessVersion();
61+
/* When debugging local version with VS, the version will include +{commitId} suffix,
62+
* which is not valid for Version class. */
63+
var plusIndex = version.IndexOf('+');
64+
if (plusIndex >= 0)
65+
{
66+
version = version.Substring(0, plusIndex);
67+
}
68+
69+
Version currentVersion = new Version(version);
6170

6271
return currentVersion.Major == 0;
6372
}

GVFS/GVFS.Platform.Windows/WindowsGitInstallation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public bool GitExists(string gitBinPath)
1919
return File.Exists(gitBinPath);
2020
}
2121

22-
return ProcessHelper.GetProgramLocation(GVFSPlatform.Instance.Constants.ProgramLocaterCommand, GitProcessName) != null;
22+
return !string.IsNullOrEmpty(GetInstalledGitBinPath());
2323
}
2424

2525
public string GetInstalledGitBinPath()

GVFS/GVFS.Platform.Windows/WindowsPlatform.cs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -220,25 +220,28 @@ public override void ConfigureVisualStudio(string gitBinPath, ITracer tracer)
220220
try
221221
{
222222
const string GitBinPathEnd = "\\cmd\\git.exe";
223-
string[] gitVSRegistryKeyNames =
224-
{
225-
"HKEY_CURRENT_USER\\Software\\Microsoft\\VSCommon\\15.0\\TeamFoundation\\GitSourceControl",
226-
"HKEY_CURRENT_USER\\Software\\Microsoft\\VSCommon\\16.0\\TeamFoundation\\GitSourceControl"
227-
};
223+
const string VSRegistryKeyRoot = @"Software\Microsoft\VSCommon";
224+
const string GitVSRegistrySubKey = @"TeamFoundation\GitSourceControl";
228225
const string GitVSRegistryValueName = "GitPath";
229226

230227
if (!gitBinPath.EndsWith(GitBinPathEnd))
231228
{
232-
tracer.RelatedWarning(
233-
"Unable to configure Visual Studio’s GitSourceControl regkey because invalid git.exe path found: " + gitBinPath,
234-
Keywords.Telemetry);
235-
236229
return;
237230
}
238231

239232
string regKeyValue = gitBinPath.Substring(0, gitBinPath.Length - GitBinPathEnd.Length);
240-
foreach (string registryKeyName in gitVSRegistryKeyNames)
233+
234+
/* Get all versions of Visual Studio that exist in the registry at least 15.0.
235+
* This attempts to future proof (current version is 17.0), but may need to be
236+
* revisited in the future if VS changes how it stores this. */
237+
var vsVersions = Registry.CurrentUser.OpenSubKey(VSRegistryKeyRoot)
238+
?.GetSubKeyNames()
239+
.Where(name => Version.TryParse(name, out var version) && version.Major >= 15)
240+
.ToArray() ?? Array.Empty<string>();
241+
242+
foreach (string version in vsVersions)
241243
{
244+
var registryKeyName = $@"{Registry.CurrentUser.Name}\{VSRegistryKeyRoot}\{version}\{GitVSRegistrySubKey}";
242245
Registry.SetValue(registryKeyName, GitVSRegistryValueName, regKeyValue);
243246
}
244247
}
@@ -255,14 +258,14 @@ public override bool TryGetGVFSHooksVersion(out string hooksVersion, out string
255258
{
256259
error = null;
257260
hooksVersion = null;
258-
string hooksPath = ProcessHelper.GetProgramLocation(GVFSPlatform.Instance.Constants.ProgramLocaterCommand, GVFSPlatform.Instance.Constants.GVFSHooksExecutableName);
259-
if (hooksPath == null)
261+
string hooksPath = Path.Combine(ProcessHelper.GetCurrentProcessLocation(), GVFSPlatform.Instance.Constants.GVFSHooksExecutableName);
262+
if (hooksPath == null || !File.Exists(hooksPath))
260263
{
261264
error = "Could not find " + GVFSPlatform.Instance.Constants.GVFSHooksExecutableName;
262265
return false;
263266
}
264267

265-
FileVersionInfo hooksFileVersionInfo = FileVersionInfo.GetVersionInfo(Path.Combine(hooksPath, GVFSPlatform.Instance.Constants.GVFSHooksExecutableName));
268+
FileVersionInfo hooksFileVersionInfo = FileVersionInfo.GetVersionInfo(hooksPath);
266269
hooksVersion = hooksFileVersionInfo.ProductVersion;
267270
return true;
268271
}
@@ -441,11 +444,6 @@ public override string GVFSExecutableName
441444
get { return "GVFS" + this.ExecutableExtension; }
442445
}
443446

444-
public override string ProgramLocaterCommand
445-
{
446-
get { return "where"; }
447-
}
448-
449447
public override HashSet<string> UpgradeBlockingProcesses
450448
{
451449
get { return new HashSet<string>(GVFSPlatform.Instance.Constants.PathComparer) { "GVFS", "GVFS.Mount", "git", "ssh-agent", "wish", "bash" }; }

GVFS/GVFS.UnitTests/CommandLine/HooksInstallerTests.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ public class HooksInstallerTests
1616
{
1717
private const string Filename = "hooksfile";
1818
private readonly string expectedAbsoluteGvfsHookPath =
19-
Path.Combine(
20-
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
21-
GVFSPlatform.Instance.Constants.GVFSHooksExecutableName);
19+
$"\"{Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), GVFSPlatform.Instance.Constants.GVFSHooksExecutableName)}\"";
2220

2321
[TestCase]
2422
[Category(CategoryConstants.ExceptionExpected)]

GVFS/GVFS.UnitTests/Mock/Common/MockPlatform.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,6 @@ public override string GVFSExecutableName
221221
{
222222
get { return "MockGVFS" + this.ExecutableExtension; }
223223
}
224-
225-
public override string ProgramLocaterCommand
226-
{
227-
get { return "MockWhere"; }
228-
}
229224

230225
public override HashSet<string> UpgradeBlockingProcesses
231226
{

GVFS/GVFS.UnitTests/Mock/Git/MockGitProcess.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ protected override Result InvokeGitImpl(
8383
Action<StreamWriter> writeStdIn,
8484
Action<string> parseStdOutLine,
8585
int timeoutMs,
86-
string gitObjectsDirectory = null)
86+
string gitObjectsDirectory = null,
87+
bool usePrecommandHook = true)
8788
{
8889
this.CommandsRun.Add(command);
8990

GVFS/GVFS/CommandLine/GVFSVerb.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,8 +926,14 @@ private bool TryValidateGVFSVersion(GVFSEnlistment enlistment, ITracer tracer, S
926926

927927
using (ITracer activity = tracer.StartActivity("ValidateGVFSVersion", EventLevel.Informational))
928928
{
929-
Version currentVersion = new Version(ProcessHelper.GetCurrentProcessVersion());
929+
if (ProcessHelper.IsDevelopmentVersion())
930+
{
931+
/* Development Version will start with 0 and include a "+{commitID}" suffix
932+
* so it won't ever be valid, but it needs to be able to run so we can test it. */
933+
return true;
934+
}
930935

936+
Version currentVersion = new Version(ProcessHelper.GetCurrentProcessVersion());
931937
IEnumerable<ServerGVFSConfig.VersionRange> allowedGvfsClientVersions =
932938
config != null
933939
? config.AllowedGVFSClientVersions

0 commit comments

Comments
 (0)