public CommonRepoSetup() { MockTracer tracer = new MockTracer(); string gitBinPath = GitProcess.GetInstalledGitBinPath(); if (string.IsNullOrWhiteSpace(gitBinPath)) { Assert.Fail("Failed to find git.exe"); } string enlistmentRoot = @"mock:\GVFS\UnitTests\Repo"; GVFSEnlistment enlistment = new GVFSEnlistment(enlistmentRoot, "fake://repoUrl", gitBinPath, null); enlistment.InitializeLocalCacheAndObjectsPathsFromKey("fake:\\objectCache", "fakeObjectCacheKey"); 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 TryDetermineLocalCacheAndInitializePaths( ITracer tracer, GVFSEnlistment enlistment, GVFSConfig gvfsConfig, CacheServerInfo currentCacheServer, string localCacheRoot, out string errorMessage) { errorMessage = null; LocalCacheResolver localCacheResolver = new LocalCacheResolver(enlistment); string error; string localCacheKey; if (!localCacheResolver.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers( tracer, gvfsConfig, 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.InitializeLocalCacheAndObjectsPathsFromKey(localCacheRoot, localCacheKey); return(true); }
private void EnsureLocalCacheIsHealthy( ITracer tracer, GVFSEnlistment enlistment, RetryConfig retryConfig, GVFSConfig gvfsConfig, CacheServerInfo cacheServer) { if (!Directory.Exists(enlistment.LocalCacheRoot)) { try { tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: Local cache root: {enlistment.LocalCacheRoot} missing, recreating it"); Directory.CreateDirectory(enlistment.LocalCacheRoot); } catch (Exception e) { EventMetadata metadata = new EventMetadata(); metadata.Add("Exception", e.ToString()); metadata.Add("enlistment.LocalCacheRoot", enlistment.LocalCacheRoot); tracer.RelatedError(metadata, $"{nameof(this.EnsureLocalCacheIsHealthy)}: Exception while trying to create local cache root"); this.ReportErrorAndExit(tracer, "Failed to create local cache: " + enlistment.LocalCacheRoot); } } PhysicalFileSystem fileSystem = new PhysicalFileSystem(); if (Directory.Exists(enlistment.GitObjectsRoot)) { bool gitObjectsRootInAlternates = false; string alternatesFilePath = this.GetAlternatesPath(enlistment); if (File.Exists(alternatesFilePath)) { try { using (Stream stream = fileSystem.OpenFileStream( alternatesFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, callFlushFileBuffers: false)) { using (StreamReader reader = new StreamReader(stream)) { while (!reader.EndOfStream) { string alternatesLine = reader.ReadLine(); if (string.Equals(alternatesLine, enlistment.GitObjectsRoot, StringComparison.OrdinalIgnoreCase)) { gitObjectsRootInAlternates = true; } } } } } catch (Exception e) { EventMetadata exceptionMetadata = new EventMetadata(); exceptionMetadata.Add("Exception", e.ToString()); tracer.RelatedError(exceptionMetadata, $"{nameof(this.EnsureLocalCacheIsHealthy)}: Exception while trying to validate alternates file"); this.ReportErrorAndExit(tracer, $"Failed to validate that alternates file includes git objects root: {e.Message}"); } } else { tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: Alternates file not found"); } if (!gitObjectsRootInAlternates) { tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: GitObjectsRoot ({enlistment.GitObjectsRoot}) missing from alternates files, recreating alternates"); string error; if (!this.TryCreateAlternatesFile(fileSystem, enlistment, out error)) { this.ReportErrorAndExit(tracer, $"Failed to update alternates file to include git objects root: {error}"); } } } else { tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: GitObjectsRoot ({enlistment.GitObjectsRoot}) missing, determining new root"); if (cacheServer == null) { cacheServer = CacheServerResolver.GetCacheServerFromConfig(enlistment); } string error; if (gvfsConfig == null) { if (retryConfig == null) { if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out error)) { this.ReportErrorAndExit(tracer, "Failed to determine GVFS timeout and max retries: " + error); } } gvfsConfig = this.QueryGVFSConfig(tracer, enlistment, retryConfig); } string localCacheKey; LocalCacheResolver localCacheResolver = new LocalCacheResolver(enlistment); if (!localCacheResolver.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers( tracer, gvfsConfig, cacheServer, enlistment.LocalCacheRoot, localCacheKey: out localCacheKey, errorMessage: out error)) { this.ReportErrorAndExit(tracer, $"Previous git objects root ({enlistment.GitObjectsRoot}) not found, and failed to determine new local cache key: {error}"); } EventMetadata metadata = new EventMetadata(); metadata.Add("localCacheRoot", enlistment.LocalCacheRoot); metadata.Add("localCacheKey", localCacheKey); metadata.Add(TracingConstants.MessageKey.InfoMessage, "Initializing and persisting updated paths"); tracer.RelatedEvent(EventLevel.Informational, "GVFSVerb_InitializeLocalCacheAndObjectsPaths", metadata); enlistment.InitializeLocalCacheAndObjectsPathsFromKey(enlistment.LocalCacheRoot, localCacheKey); tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: Creating GitObjectsRoot ({enlistment.GitObjectsRoot}) and GitPackRoot ({enlistment.GitPackRoot})"); try { Directory.CreateDirectory(enlistment.GitObjectsRoot); Directory.CreateDirectory(enlistment.GitPackRoot); } catch (Exception e) { EventMetadata exceptionMetadata = new EventMetadata(); exceptionMetadata.Add("Exception", e.ToString()); exceptionMetadata.Add("enlistment.LocalCacheRoot", enlistment.LocalCacheRoot); exceptionMetadata.Add("enlistment.GitObjectsRoot", enlistment.GitObjectsRoot); exceptionMetadata.Add("enlistment.GitPackRoot", enlistment.GitPackRoot); tracer.RelatedError(exceptionMetadata, $"{nameof(this.InitializeLocalCacheAndObjectsPaths)}: Exception while trying to create objects and pack folders"); this.ReportErrorAndExit(tracer, "Failed to create objects and pack folders"); } tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: Creating new alternates file"); if (!this.TryCreateAlternatesFile(fileSystem, enlistment, out error)) { this.ReportErrorAndExit(tracer, $"Failed to update alterates file with new objects path: {error}"); } tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: Saving git objects root ({enlistment.GitObjectsRoot}) in repo metadata"); RepoMetadata.Instance.SetGitObjectsRoot(enlistment.GitObjectsRoot); } }