protected ServerGVFSConfig QueryGVFSConfig(ITracer tracer, GVFSEnlistment enlistment, RetryConfig retryConfig) { ServerGVFSConfig serverGVFSConfig = null; if (!this.ShowStatusWhileRunning( () => { using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(tracer, enlistment, retryConfig)) { const bool LogErrors = true; return(configRequestor.TryQueryGVFSConfig(LogErrors, out serverGVFSConfig, out _)); } }, "Querying remote for config", suppressGvfsLogMessage: true)) { this.ReportErrorAndExit(tracer, "Unable to query /gvfs/config"); } return(serverGVFSConfig); }
protected bool TryDownloadCommit( string commitId, GVFSEnlistment enlistment, GitObjectsHttpRequestor objectRequestor, GVFSGitObjects gitObjects, GitRepo repo, out string error, bool checkLocalObjectCache = true) { if (!checkLocalObjectCache || !repo.CommitAndRootTreeExists(commitId)) { if (!gitObjects.TryDownloadCommit(commitId)) { error = "Could not download commit " + commitId + " from: " + Uri.EscapeUriString(objectRequestor.CacheServer.ObjectsEndpointUrl); return(false); } } error = null; return(true); }
private bool TryPrefetchCommitsAndTrees(ITracer tracer, GVFSEnlistment enlistment, GitObjectsHttpRequestor objectRequestor) { PhysicalFileSystem fileSystem = new PhysicalFileSystem(); GitRepo repo = new GitRepo(tracer, enlistment, fileSystem); GVFSContext context = new GVFSContext(tracer, fileSystem, repo, enlistment); GitObjects gitObjects = new GVFSGitObjects(context, objectRequestor); string[] packs = gitObjects.ReadPackFileNames(GVFSConstants.PrefetchPackPrefix); long max = -1; foreach (string pack in packs) { long?timestamp = this.GetTimestamp(pack); if (timestamp.HasValue && timestamp > max) { max = timestamp.Value; } } return(gitObjects.TryDownloadPrefetchPacks(max)); }
private void CheckGitStatus(ITracer tracer, GVFSEnlistment enlistment, HashSet <string> sparseFolders) { GitProcess.Result statusResult = null; if (!this.ShowStatusWhileRunning( () => { GitProcess git = new GitProcess(enlistment); statusResult = git.StatusPorcelain(); if (statusResult.ExitCodeIsFailure) { return(false); } if (this.ContainsPathNotCoveredBySparseFolders(statusResult.Output, sparseFolders)) { return(false); } return(true); }, "Running git status", suppressGvfsLogMessage: true)) { this.Output.WriteLine(); if (statusResult.ExitCodeIsFailure) { this.WriteMessage(tracer, "Failed to run git status: " + statusResult.Errors); } else { this.WriteMessage(tracer, statusResult.Output); this.WriteMessage(tracer, "git status reported that you have dirty files"); this.WriteMessage(tracer, "Either commit your changes or reset and clean"); } this.Output.WriteLine(); this.ReportErrorAndExit(tracer, "Sparse was aborted."); } }
public bool TryWriteMultiPackIndex(ITracer tracer, GVFSEnlistment enlistment, PhysicalFileSystem fileSystem) { using (ITracer activity = tracer.StartActivity(nameof(this.TryWriteMultiPackIndex), EventLevel.Informational, Keywords.Telemetry, metadata: null)) { GitProcess process = new GitProcess(enlistment); GitProcess.Result result = process.WriteMultiPackIndex(enlistment.GitPackRoot); if (!result.HasErrors) { string midxHash = result.Output.Trim(); activity.RelatedInfo("Updated midx-head to hash {0}", midxHash); string expectedMidxHead = Path.Combine(enlistment.GitPackRoot, "midx-" + midxHash + ".midx"); List <string> midxFiles = new List <string>(); midxFiles.AddRange(fileSystem.GetFiles(enlistment.GitPackRoot, "midx-*.midx")); midxFiles.AddRange(fileSystem.GetFiles(enlistment.GitPackRoot, "tmp_midx_*")); foreach (string midxFile in midxFiles) { if (!midxFile.Equals(expectedMidxHead, StringComparison.OrdinalIgnoreCase) && !fileSystem.TryDeleteFile(midxFile)) { activity.RelatedWarning("Failed to delete MIDX file {0}", midxFile); } } } else { EventMetadata errorMetadata = new EventMetadata(); errorMetadata.Add("Operation", nameof(this.TryWriteMultiPackIndex)); errorMetadata.Add("packDir", enlistment.GitPackRoot); errorMetadata.Add("Errors", result.Errors); errorMetadata.Add("Output", result.Output.Length > 1024 ? result.Output.Substring(1024) : result.Output); activity.RelatedError(errorMetadata, result.Errors, Keywords.Telemetry); } return(!result.HasErrors); } }
private void InitializeCachePathsFromRepoMetadata( ITracer tracer, GVFSEnlistment enlistment) { string error; string gitObjectsRoot; if (!RepoMetadata.Instance.TryGetGitObjectsRoot(out gitObjectsRoot, out error)) { this.ReportErrorAndExit(tracer, "Failed to determine git objects root from repo metadata: " + error); } if (string.IsNullOrWhiteSpace(gitObjectsRoot)) { this.ReportErrorAndExit(tracer, "Invalid git objects root (empty or whitespace)"); } string localCacheRoot; if (!RepoMetadata.Instance.TryGetLocalCacheRoot(out localCacheRoot, out error)) { this.ReportErrorAndExit(tracer, "Failed to determine local cache path from repo metadata: " + error); } // Note: localCacheRoot is allowed to be empty, this can occur when upgrading from disk layout version 11 to 12 string blobSizesRoot; if (!RepoMetadata.Instance.TryGetBlobSizesRoot(out blobSizesRoot, out error)) { this.ReportErrorAndExit(tracer, "Failed to determine blob sizes root from repo metadata: " + error); } if (string.IsNullOrWhiteSpace(blobSizesRoot)) { this.ReportErrorAndExit(tracer, "Invalid blob sizes root (empty or whitespace)"); } enlistment.InitializeCachePaths(localCacheRoot, gitObjectsRoot, blobSizesRoot); }
private bool IsValidRepo(string repoRoot) { if (!Directory.Exists(repoRoot)) { return(false); } string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); string hooksVersion = null; string error = null; if (GVFSPlatform.Instance.TryGetGVFSHooksVersion(out hooksVersion, out error)) { try { GVFSEnlistment enlistment = GVFSEnlistment.CreateFromDirectory( repoRoot, gitBinPath, authentication: null); } catch (InvalidRepoException e) { EventMetadata metadata = new EventMetadata(); metadata.Add(nameof(repoRoot), repoRoot); metadata.Add(nameof(gitBinPath), gitBinPath); metadata.Add("Exception", e.ToString()); this.tracer.RelatedInfo(metadata, $"{nameof(this.IsValidRepo)}: Found invalid repo"); return(false); } } else { this.tracer.RelatedError($"{nameof(this.IsValidRepo)}: {nameof(GVFSPlatform.Instance.TryGetGVFSHooksVersion)} failed. {error}"); return(false); } return(true); }
public CommonRepoSetup() { MockTracer tracer = new MockTracer(); string enlistmentRoot = Path.Combine("mock:", "GVFS", "UnitTests", "Repo"); GVFSEnlistment enlistment = new GVFSEnlistment(enlistmentRoot, "fake://repoUrl", "fake://gitBinPath", null); enlistment.InitializeCachePathsFromKey("fake:\\gvfsSharedCache", "fakeCacheKey"); this.GitParentPath = enlistment.WorkingDirectoryRoot; this.GVFSMetadataPath = enlistment.DotGVFSRoot; MockDirectory enlistmentDirectory = new MockDirectory( enlistmentRoot, new MockDirectory[] { new MockDirectory(this.GitParentPath, folders: null, files: null), }, null); enlistmentDirectory.CreateFile(Path.Combine(this.GitParentPath, ".git", "config"), ".git config Contents", createDirectories: true); enlistmentDirectory.CreateFile(Path.Combine(this.GitParentPath, ".git", "HEAD"), ".git HEAD Contents", createDirectories: true); enlistmentDirectory.CreateFile(Path.Combine(this.GitParentPath, ".git", "logs", "HEAD"), "HEAD Contents", createDirectories: true); enlistmentDirectory.CreateFile(Path.Combine(this.GitParentPath, ".git", "info", "always_exclude"), "always_exclude Contents", createDirectories: true); enlistmentDirectory.CreateDirectory(Path.Combine(this.GitParentPath, ".git", "objects", "pack")); MockFileSystem fileSystem = new MockFileSystem(enlistmentDirectory); this.Repository = new MockGitRepo( tracer, enlistment, fileSystem); CreateStandardGitTree(this.Repository); this.Context = new GVFSContext(tracer, fileSystem, this.Repository, enlistment); this.HttpObjects = new MockHttpGitObjects(tracer, enlistment); this.GitObjects = new MockGVFSGitObjects(this.Context, this.HttpObjects); }
private bool IsValidRepo(string repoRoot) { string gitBinPath = GitProcess.GetInstalledGitBinPath(); string hooksPath = ProcessHelper.WhereDirectory(GVFSConstants.GVFSHooksExecutableName); GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory(repoRoot, gitBinPath, hooksPath); } catch (InvalidRepoException) { return(false); } if (enlistment == null) { return(false); } return(true); }
private bool IsValidRepo(string repoRoot) { string gitBinPath = GitProcess.GetInstalledGitBinPath(); string hooksPath = this.GetGVFSHooksPathAndCheckVersion(tracer: null); GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory(repoRoot, gitBinPath, hooksPath); } catch (InvalidRepoException) { return(false); } if (enlistment == null) { return(false); } return(true); }
private static bool TryInstallGitCommandHooks(GVFSEnlistment enlistment, string hookName, string commandHookPath, out string errorMessage) { // The GitHooksLoader requires the following setup to invoke a hook: // Copy GithooksLoader.exe to hook-name.exe // Create a text file named hook-name.hooks that lists the applications to execute for the hook, one application per line string gitHooksloaderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), GVFSConstants.DotGit.Hooks.LoaderExecutable); if (!TryAction(() => CopyGitHooksLoader(gitHooksloaderPath, commandHookPath), out errorMessage)) { errorMessage = "Failed to copy " + GVFSConstants.DotGit.Hooks.LoaderExecutable + " to " + commandHookPath + GVFSConstants.ExecutableExtension + "\n" + errorMessage; return(false); } if (!TryAction(() => CreateHookCommandConfig(enlistment, hookName, commandHookPath), out errorMessage)) { errorMessage = "Failed to create " + commandHookPath + GVFSConstants.DotGit.Hooks.ConfigExtension + "\n" + errorMessage; return(false); } return(true); }
public static bool InstallHooks(GVFSEnlistment enlistment, out string error) { error = string.Empty; try { string installedReadObjectHookPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), GVFSConstants.GVFSReadObjectHookExecutableName); TryActionAndThrow(() => CopyReadObjectHook(enlistment, installedReadObjectHookPath), "Failed to copy" + installedReadObjectHookPath); string precommandHookPath = Path.Combine(enlistment.WorkingDirectoryRoot, GVFSConstants.DotGit.Hooks.PreCommandPath); InstallGitCommandHooks(enlistment, GVFSConstants.DotGit.Hooks.PreCommandHookName, precommandHookPath); string postcommandHookPath = Path.Combine(enlistment.WorkingDirectoryRoot, GVFSConstants.DotGit.Hooks.PostCommandPath); InstallGitCommandHooks(enlistment, GVFSConstants.DotGit.Hooks.PostCommandHookName, postcommandHookPath); } catch (Exception e) { error = e.ToString(); return(false); } return(true); }
protected void CheckAntiVirusExclusion(GVFSEnlistment enlistment) { bool isExcluded; if (AntiVirusExclusions.TryGetIsPathExcluded(enlistment.EnlistmentRoot, out isExcluded)) { if (!isExcluded) { if (ProcessHelper.IsAdminElevated()) { AntiVirusExclusions.AddAntiVirusExclusion(enlistment.EnlistmentRoot); if (!AntiVirusExclusions.TryGetIsPathExcluded(enlistment.EnlistmentRoot, out isExcluded) || !isExcluded) { this.ReportErrorAndExit( "This repo is not excluded from antivirus and we were unable to add it. Add '{0}' to your exclusion list and then run {1} again.", enlistment.EnlistmentRoot, this.VerbName); } } else { this.ReportErrorAndExit( "This repo is not excluded from antivirus. Either re-run {1} with elevated privileges, or add '{0}' to your exclusion list and then run {1} again.", enlistment.EnlistmentRoot, this.VerbName); } } } else { this.Output.WriteLine(); this.Output.WriteLine( "WARNING: Unable to determine if this repo is excluded from antivirus. Please check to ensure that '{0}' is excluded.", enlistment.EnlistmentRoot); this.Output.WriteLine(); } }
private void InitializeServerConnection( ITracer tracer, GVFSEnlistment enlistment, string cacheServerUrl, out GitObjectsHttpRequestor objectRequestor, out CacheServerInfo cacheServer) { RetryConfig retryConfig = this.GetRetryConfig(tracer, enlistment, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes)); cacheServer = this.ResolvedCacheServer; ServerGVFSConfig serverGVFSConfig = this.ServerGVFSConfig; if (!this.SkipVersionCheck) { string authErrorMessage; if (!this.TryAuthenticate(tracer, enlistment, out authErrorMessage)) { this.ReportErrorAndExit(tracer, "Unable to prefetch because authentication failed: " + authErrorMessage); } if (serverGVFSConfig == null) { serverGVFSConfig = this.QueryGVFSConfig(tracer, enlistment, retryConfig); } if (cacheServer == null) { CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment); cacheServer = cacheServerResolver.ResolveNameFromRemote(cacheServerUrl, serverGVFSConfig); } this.ValidateClientVersions(tracer, enlistment, serverGVFSConfig, showWarnings: false); // this.Output.WriteLine("Configured cache server: " + cacheServer); } this.InitializeLocalCacheAndObjectsPaths(tracer, enlistment, retryConfig, serverGVFSConfig, cacheServer); objectRequestor = new GitObjectsHttpRequestor(tracer, enlistment, cacheServer, retryConfig); }
private void CheckGitStatus(ITracer tracer, GVFSEnlistment enlistment) { GitProcess.Result statusResult = null; if (!this.ShowStatusWhileRunning( () => { GitProcess git = new GitProcess(enlistment); statusResult = git.Status(allowObjectDownloads: false, useStatusCache: false, showUntracked: true); if (statusResult.ExitCodeIsFailure) { return(false); } if (!statusResult.Output.Contains("nothing to commit, working tree clean")) { return(false); } return(true); }, "Running git status", suppressGvfsLogMessage: true)) { this.Output.WriteLine(); if (statusResult.ExitCodeIsFailure) { this.WriteMessage(tracer, "Failed to run git status: " + statusResult.Errors); } else { this.WriteMessage(tracer, statusResult.Output); this.WriteMessage(tracer, "git status reported that you have dirty files"); this.WriteMessage(tracer, "Either commit your changes or reset and clean"); } this.ReportErrorAndExit(tracer, SparseVerbName + " was aborted"); } }
public void Execute() { GVFSEnlistment enlistment = this.CreateEnlistment(this.EnlistmentRootPath); EventLevel verbosity; Keywords keywords; this.ParseEnumArgs(out verbosity, out keywords); ITracer tracer = this.CreateTracer(enlistment, verbosity, keywords); InProcessMount mountHelper = new InProcessMount(tracer, enlistment, this.ShowDebugWindow); try { mountHelper.Mount(verbosity, keywords); } catch (Exception ex) { tracer.RelatedError("Failed to mount: {0}", ex.ToString()); this.ReportErrorAndExit("Failed to mount: {0}", ex.Message); } }
protected bool TrySetGitConfig(ITracer tracer, string enlistmentRoot, Dictionary <string, string> configSettings, out string errorMessage) { errorMessage = null; GVFSEnlistment enlistment = GVFSEnlistment.CreateFromDirectory( enlistmentRoot, GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(), ProcessHelper.GetCurrentProcessLocation()); GitProcess git = enlistment.CreateGitProcess(); foreach (string key in configSettings.Keys) { GitProcess.Result result = git.SetInLocalConfig(key, configSettings[key]); if (result.HasErrors) { tracer.RelatedError("Could not set git config setting {0}. Error: {1}", key, result.Errors); return(false); } } return(true); }
protected override void OnStart(string[] args) { if (this.serviceThread != null) { throw new InvalidOperationException("Cannot start service twice in a row."); } // TODO: 865304 Used for functional tests and development only. Replace with a smarter appConfig-based solution string serviceName = args.FirstOrDefault(arg => arg.StartsWith(ServiceNameArgPrefix)); if (serviceName != null) { this.serviceName = serviceName.Substring(ServiceNameArgPrefix.Length); } string serviceLogsDirectoryPath = Path.Combine( GVFSPlatform.Instance.GetDataRootForGVFSComponent(this.serviceName), GVFSConstants.Service.LogDirectory); // Create the logs directory explicitly *before* creating a log file event listener to ensure that it // and its ancestor directories are created with the correct ACLs. this.CreateServiceLogsDirectory(serviceLogsDirectoryPath); this.tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(serviceLogsDirectoryPath, GVFSConstants.LogFileTypes.Service), EventLevel.Verbose, Keywords.Any); try { this.serviceDataLocation = GVFSPlatform.Instance.GetDataRootForGVFSComponent(this.serviceName); this.CreateAndConfigureProgramDataDirectories(); this.Start(); } catch (Exception e) { this.LogExceptionAndExit(e, nameof(this.OnStart)); } }
private GVFSEnlistment CreateEnlistment(string enlistmentRootPath) { string gitBinPath = GitProcess.GetInstalledGitBinPath(); if (string.IsNullOrWhiteSpace(gitBinPath)) { this.ReportErrorAndExit("Error: " + GVFSConstants.GitIsNotInstalledError); } string hooksPath = ProcessHelper.WhereDirectory(GVFSConstants.GVFSHooksExecutableName); if (hooksPath == null) { this.ReportErrorAndExit("Could not find " + GVFSConstants.GVFSHooksExecutableName); } GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory(enlistmentRootPath, gitBinPath, hooksPath); if (enlistment == null) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment", enlistmentRootPath); } } catch (InvalidRepoException e) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment. {1}", enlistmentRootPath, e.Message); } return(enlistment); }
public static bool TryPrefetchCommitsAndTrees( ITracer tracer, GVFSEnlistment enlistment, PhysicalFileSystem fileSystem, GitObjects gitObjects, out string error) { List <string> packIndexes; using (FileBasedLock prefetchLock = GVFSPlatform.Instance.CreateFileBasedLock( fileSystem, tracer, Path.Combine(enlistment.GitPackRoot, PrefetchCommitsAndTreesLock))) { WaitUntilLockIsAcquired(tracer, prefetchLock); long maxGoodTimeStamp; gitObjects.DeleteStaleTempPrefetchPackAndIdxs(); if (!TryGetMaxGoodPrefetchTimestamp(tracer, enlistment, fileSystem, gitObjects, out maxGoodTimeStamp, out error)) { return(false); } if (!gitObjects.TryDownloadPrefetchPacks(maxGoodTimeStamp, out packIndexes)) { error = "Failed to download prefetch packs"; return(false); } } if (packIndexes?.Count > 0) { TrySchedulePostFetchJob(tracer, enlistment.NamedPipeName, packIndexes); } return(true); }
protected ReturnCode Execute <TVerb>( GVFSEnlistment enlistment, Action <TVerb> configureVerb = null) where TVerb : GVFSVerb.ForExistingEnlistment, new() { TVerb verb = new TVerb(); verb.EnlistmentRootPathParameter = enlistment.EnlistmentRoot; verb.ServiceName = this.ServiceName; verb.Unattended = this.Unattended; configureVerb?.Invoke(verb); try { verb.Execute(enlistment.Authentication); } catch (VerbAbortedException) { } return(verb.ReturnCode); }
public GVFSService(JsonTracer tracer) { string logFilePath = Path.Combine( GVFSPlatform.Instance.GetDataRootForGVFSComponent(GVFSConstants.Service.ServiceName), GVFSConstants.Service.LogDirectory); Directory.CreateDirectory(logFilePath); this.tracer = tracer; this.tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(logFilePath, GVFSConstants.LogFileTypes.Service), EventLevel.Verbose, Keywords.Any); this.serviceName = GVFSConstants.Service.ServiceName; this.serviceStopped = new ManualResetEvent(false); this.serviceThread = new Thread(this.ServiceThreadMain); this.repoRegistry = new RepoRegistry( this.tracer, new PhysicalFileSystem(), GVFSPlatform.Instance.GetDataRootForGVFSComponent(this.serviceName)); this.requestHandler = new RequestHandler(this.tracer, EtwArea, this.repoRegistry); }
protected bool TryCreateAlternatesFile(PhysicalFileSystem fileSystem, GVFSEnlistment enlistment, out string errorMessage) { try { string alternatesFilePath = this.GetAlternatesPath(enlistment); string tempFilePath = alternatesFilePath + ".tmp"; fileSystem.WriteAllText(tempFilePath, enlistment.GitObjectsRoot); fileSystem.MoveAndOverwriteFile(tempFilePath, alternatesFilePath); } catch (SecurityException e) { errorMessage = e.Message; return(false); } catch (IOException e) { errorMessage = e.Message; return(false); } errorMessage = null; return(true); }
protected void ValidateClientVersions(ITracer tracer, GVFSEnlistment enlistment, GVFSConfig gvfsConfig, bool showWarnings) { this.CheckGitVersion(tracer, enlistment); this.GetGVFSHooksPathAndCheckVersion(tracer); this.CheckVolumeSupportsDeleteNotifications(tracer, enlistment); string errorMessage = null; bool errorIsFatal = false; if (!this.TryValidateGVFSVersion(enlistment, tracer, gvfsConfig, out errorMessage, out errorIsFatal)) { if (errorIsFatal) { this.ReportErrorAndExit(tracer, errorMessage); } else if (showWarnings) { this.Output.WriteLine(); this.Output.WriteLine(errorMessage); this.Output.WriteLine(); } } }
private bool IsValidRepo(string repoRoot) { WindowsGitInstallation windowsGitInstallation = new WindowsGitInstallation(); string gitBinPath = windowsGitInstallation.GetInstalledGitBinPath(); string hooksPath = ProcessHelper.WhereDirectory(GVFSPlatform.Instance.Constants.GVFSHooksExecutableName); GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory(repoRoot, gitBinPath, hooksPath, authentication: null); } catch (InvalidRepoException) { return(false); } if (enlistment == null) { return(false); } return(true); }
private Result TryCreateEnlistment( string fullEnlistmentRootPathParameter, string normalizedEnlistementRootPath, out GVFSEnlistment enlistment) { enlistment = null; // Check that EnlistmentRootPath is empty before creating a tracer and LogFileEventListener as // LogFileEventListener will create a file in EnlistmentRootPath if (Directory.Exists(normalizedEnlistementRootPath) && Directory.EnumerateFileSystemEntries(normalizedEnlistementRootPath).Any()) { if (fullEnlistmentRootPathParameter.Equals(normalizedEnlistementRootPath, StringComparison.OrdinalIgnoreCase)) { return(new Result($"Clone directory '{fullEnlistmentRootPathParameter}' exists and is not empty")); } return(new Result($"Clone directory '{fullEnlistmentRootPathParameter}' ['{normalizedEnlistementRootPath}'] exists and is not empty")); } string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); if (string.IsNullOrWhiteSpace(gitBinPath)) { return(new Result(GVFSConstants.GitIsNotInstalledError)); } string hooksPath = this.GetGVFSHooksPathAndCheckVersion(tracer: null, hooksVersion: out _); enlistment = new GVFSEnlistment( normalizedEnlistementRootPath, this.RepositoryURL, gitBinPath, hooksPath, authentication: null); return(new Result(true)); }
public bool Mount(string repoRoot) { string error; if (!GvFltFilter.IsHealthy(out error, this.tracer)) { return(false); } // Ensure the repo is excluded from antivirus before calling 'gvfs mount' // to reduce chatter between GVFS.exe and GVFS.Service.exe string errorMessage; bool isExcluded; ExcludeFromAntiVirusHandler.CheckAntiVirusExclusion(this.tracer, repoRoot, out isExcluded, out errorMessage); string unusedMessage; if (!GvFltFilter.TryAttach(this.tracer, repoRoot, out unusedMessage)) { return(false); } if (!this.CallGVFSMount(repoRoot)) { this.tracer.RelatedError("Unable to start the GVFS.exe process."); return(false); } if (!GVFSEnlistment.WaitUntilMounted(repoRoot, false, out errorMessage)) { this.tracer.RelatedError(errorMessage); return(false); } return(true); }
private void SendDehydrateMessage(ITracer tracer, GVFSEnlistment enlistment, List <string> folderErrors, string[] folders) { NamedPipeMessages.DehydrateFolders.Response response = null; try { using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName)) { if (!pipeClient.Connect()) { this.ReportErrorAndExit("Unable to connect to GVFS. Try running 'gvfs mount'"); } NamedPipeMessages.DehydrateFolders.Request request = new NamedPipeMessages.DehydrateFolders.Request(string.Join(FolderListSeparator, folders)); pipeClient.SendRequest(request.CreateMessage()); response = NamedPipeMessages.DehydrateFolders.Response.FromMessage(NamedPipeMessages.Message.FromString(pipeClient.ReadRawResponse())); } } catch (BrokenPipeException e) { this.ReportErrorAndExit("Unable to communicate with GVFS: " + e.ToString()); } if (response != null) { foreach (string folder in response.SuccessfulFolders) { this.WriteMessage(tracer, $"{folder} folder {this.ActionName} successful."); } foreach (string folder in response.FailedFolders) { this.WriteMessage(tracer, $"{folder} folder failed to {this.ActionName}. You may need to reset the working directory by deleting {folder}, running `git reset --hard`, and retry the {this.ActionName}."); folderErrors.Add(folder); } } }
private bool TryDetermineLocalCacheAndInitializePaths( ITracer tracer, GVFSEnlistment enlistment, ServerGVFSConfig serverGVFSConfig, CacheServerInfo currentCacheServer, string localCacheRoot, out string errorMessage) { errorMessage = null; LocalCacheResolver localCacheResolver = new LocalCacheResolver(enlistment); string error; string localCacheKey; if (!localCacheResolver.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers( tracer, serverGVFSConfig, currentCacheServer, localCacheRoot, localCacheKey: out localCacheKey, errorMessage: out error)) { errorMessage = "Error determining local cache key: " + error; return(false); } EventMetadata metadata = new EventMetadata(); metadata.Add("localCacheRoot", localCacheRoot); metadata.Add("localCacheKey", localCacheKey); metadata.Add(TracingConstants.MessageKey.InfoMessage, "Initializing cache paths"); tracer.RelatedEvent(EventLevel.Informational, "CloneVerb_TryDetermineLocalCacheAndInitializePaths", metadata); enlistment.InitializeCachePathsFromKey(localCacheRoot, localCacheKey); return(true); }
private bool RequestMount(GVFSEnlistment enlistment, out string errorMessage) { this.CheckGitVersion(enlistment); this.CheckGVFSHooksVersion(enlistment, null); if (!this.SkipVersionCheck) { using (ITracer mountTracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "Mount")) { this.CheckVolumeSupportsDeleteNotifications(mountTracer, enlistment); using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(mountTracer, enlistment)) { GVFSConfig config = configRequestor.QueryGVFSConfig(); this.ValidateGVFSVersion(enlistment, config, mountTracer); } } } // We have to parse these parameters here to make sure they are valid before // handing them to the background process which cannot tell the user when they are bad EventLevel verbosity; Keywords keywords; this.ParseEnumArgs(out verbosity, out keywords); GitProcess git = new GitProcess(enlistment); if (!git.IsValidRepo()) { errorMessage = "The physical git repo is missing or invalid"; return(false); } this.SetGitConfigSettings(git); return(this.SendMountRequest(enlistment, verbosity, keywords, out errorMessage)); }