private void MountAndStartWorkingDirectoryCallbacks(GVFSContext context) { HttpGitObjects httpGitObjects = new HttpGitObjects(context.Tracer, context.Enlistment, Environment.ProcessorCount); if (!httpGitObjects.TryRefreshCredentials()) { this.FailMountAndExit("Failed to obtain git credentials"); } this.gitObjects = new GVFSGitObjects(context, httpGitObjects); this.gvfltCallbacks = this.CreateOrReportAndExit(() => new GVFltCallbacks(context, this.gitObjects), "Failed to create src folder callbacks"); try { string error; if (!this.gvfltCallbacks.TryStart(out error)) { this.FailMountAndExit("Error: {0}. \r\nPlease confirm that gvfs clone completed without error.", error); } } catch (Exception e) { this.FailMountAndExit("Failed to initialize src folder callbacks. {0}", e.ToString()); } this.AcquireFolderLocks(context); this.heartbeat = new HeartbeatThread(this.tracer); this.heartbeat.Start(); }
public void GetPlaceholderInformationHandlerCancelledDuringNetworkRequest() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test.txt" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, new MockBlobSizes(), gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); MockTracer mockTracker = this.Repo.Context.Tracer as MockTracer; mockTracker.WaitRelatedEventName = "GVFltGetPlaceholderInformationAsyncHandler_GetProjectedGVFltFileInfoAndShaCancelled"; gitIndexProjection.ThrowOperationCanceledExceptionOnProjectionRequest = true; mockGvFlt.OnGetPlaceholderInformation(1, "test.txt", 0, 0, 0, 0, 1, "UnitTests").ShouldEqual(HResult.Pending); // Cancelling in the middle of GetPlaceholderInformation in the middle of a network request should not result in placeholder // getting created mockTracker.WaitForRelatedEvent(); mockGvFlt.CreatedPlaceholders.ShouldNotContain(entry => entry == "test.txt"); gitIndexProjection.PlaceholdersCreated.ShouldNotContain(entry => entry == "test.txt"); callbacks.Stop(); } }
public void GetPlaceholderInformationHandlerCancelledDuringAsyncCallback() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test.txt" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, new MockBlobSizes(), gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); gitIndexProjection.BlockGetProjectedFileInfo(willWaitForRequest: true); mockGvFlt.OnGetPlaceholderInformation(1, "test.txt", 0, 0, 0, 0, 1, "UnitTests").ShouldEqual(HResult.Pending); gitIndexProjection.WaitForGetProjectedFileInfo(); mockGvFlt.OnCancelCommand(1); gitIndexProjection.UnblockGetProjectedFileInfo(); // Cancelling in the middle of GetPlaceholderInformation still allows it to create placeholders when the cancellation does not // interrupt network requests mockGvFlt.WaitForPlaceholderCreate(); gitIndexProjection.WaitForPlaceholderCreate(); mockGvFlt.CreatedPlaceholders.ShouldContain(entry => entry == "test.txt"); gitIndexProjection.PlaceholdersCreated.ShouldContain(entry => entry == "test.txt"); callbacks.Stop(); } }
public void OnStartDirectoryEnumerationReturnsPendingWhenResultsNotInMemory() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test.txt" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, new MockBlobSizes(), gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); Guid enumerationGuid = Guid.NewGuid(); gitIndexProjection.EnumerationInMemory = false; mockGvFlt.OnStartDirectoryEnumeration(1, enumerationGuid, "test").ShouldEqual(HResult.Pending); mockGvFlt.WaitForCompletionStatus().ShouldEqual(HResult.Ok); mockGvFlt.OnEndDirectoryEnumeration(enumerationGuid).ShouldEqual(HResult.Ok); callbacks.Stop(); } }
public void OnGetFileStreamReturnsInternalErrorWhenPlaceholderVersionDoesNotMatchExpected() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test.txt" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, blobSizes: null, gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); Guid enumerationGuid = Guid.NewGuid(); byte[] contentId = GVFltCallbacks.ConvertShaToContentId("0123456789012345678901234567890123456789"); byte[] epochId = new byte[] { GVFltCallbacks.PlaceholderVersion + 1 }; mockGvFlt.OnGetFileStream( commandId: 1, relativePath: "test.txt", byteOffset: 0, length: 100, streamGuid: Guid.NewGuid(), contentId: contentId, epochId: epochId, triggeringProcessId: 2, triggeringProcessImageFileName: "UnitTest").ShouldEqual(NtStatus.InternalError); } }
public void GetPlaceholderInformationHandlerPathProjected() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test.txt" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, new MockBlobSizes(), gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); mockGvFlt.OnGetPlaceholderInformation(1, "test.txt", 0, 0, 0, 0, 1, "UnitTests").ShouldEqual(HResult.Pending); mockGvFlt.WaitForCompletionStatus().ShouldEqual(HResult.Ok); mockGvFlt.CreatedPlaceholders.ShouldContain(entry => entry == "test.txt"); gitIndexProjection.PlaceholdersCreated.ShouldContain(entry => entry == "test.txt"); callbacks.Stop(); } }
private void PrepareSrcFolder(ITracer tracer, GVFSEnlistment enlistment) { string error; if (!GVFltCallbacks.TryPrepareFolderForGVFltCallbacks(enlistment.WorkingDirectoryRoot, out error)) { this.WriteErrorAndExit(tracer, "Failed to recreate the virtualization root: " + error); } }
private void UnmountAndStopWorkingDirectoryCallbacks() { this.ReleaseFolderLocks(); if (this.gvfltCallbacks != null) { this.gvfltCallbacks.Stop(); this.gvfltCallbacks.Dispose(); this.gvfltCallbacks = null; } }
public void CannotDeleteIndexOrPacks() { GVFltCallbacks.DoesPathAllowDelete(string.Empty).ShouldEqual(true); GVFltCallbacks.DoesPathAllowDelete(@".git\index").ShouldEqual(false); GVFltCallbacks.DoesPathAllowDelete(@".git\INDEX").ShouldEqual(false); GVFltCallbacks.DoesPathAllowDelete(@".git\index.lock").ShouldEqual(true); GVFltCallbacks.DoesPathAllowDelete(@".git\INDEX.lock").ShouldEqual(true); GVFltCallbacks.DoesPathAllowDelete(@".git\objects\pack").ShouldEqual(true); GVFltCallbacks.DoesPathAllowDelete(@".git\objects\pack-temp").ShouldEqual(true); GVFltCallbacks.DoesPathAllowDelete(@".git\objects\pack\pack-1e88df2a4e234c82858cfe182070645fb96d6131.pack").ShouldEqual(true); GVFltCallbacks.DoesPathAllowDelete(@".git\objects\pack\pack-1e88df2a4e234c82858cfe182070645fb96d6131.idx").ShouldEqual(true); }
private void MountAndStartWorkingDirectoryCallbacks(GVFSContext context) { HttpGitObjects httpGitObjects = new HttpGitObjects(context.Tracer, context.Enlistment, Environment.ProcessorCount); if (!httpGitObjects.TryRefreshCredentials()) { this.FailMountAndExit("Failed to obtain git credentials"); } // Checking the disk layout version is done before this point in GVFS.CommandLine.MountVerb.PreExecute RepoMetadata repoMetadata = new RepoMetadata(this.enlistment.DotGVFSRoot); this.gitObjects = new GVFSGitObjects(context, httpGitObjects); this.gvfltCallbacks = this.CreateOrReportAndExit(() => new GVFltCallbacks(context, this.gitObjects, repoMetadata), "Failed to create src folder callbacks"); int persistedVersion; string error; if (!repoMetadata.TryGetOnDiskLayoutVersion(out persistedVersion, out error)) { this.FailMountAndExit("Error: {0}", error); } if (!repoMetadata.OnDiskVersionUsesAlwaysExclude()) { // Want this as close to repoMetadata.SaveCurrentDiskLayoutVersion() as possible to avoid possible corrupt states. this.UpdateToAlwaysExcludeFile(repoMetadata); } try { if (!this.gvfltCallbacks.TryStart(out error)) { this.FailMountAndExit("Error: {0}. \r\nPlease confirm that gvfs clone completed without error.", error); } } catch (Exception e) { this.FailMountAndExit("Failed to initialize src folder callbacks. {0}", e.ToString()); } repoMetadata.SaveCurrentDiskLayoutVersion(); repoMetadata.SetAlwaysExcludeInvalid(false); this.AcquireFolderLocks(context); this.heartbeat = new HeartbeatThread(this.tracer, this.gvfltCallbacks); this.heartbeat.Start(); }
public void OnGetFileStreamHandlesCancellationDuringWriteAction() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test.txt" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, new MockBlobSizes(), gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); Guid enumerationGuid = Guid.NewGuid(); byte[] contentId = GVFltCallbacks.ConvertShaToContentId("0123456789012345678901234567890123456789"); byte[] placeholderVersion = GVFltCallbacks.GetPlaceholderVersionId(); uint fileLength = 100; MockGVFSGitObjects mockGVFSGitObjects = this.Repo.GitObjects as MockGVFSGitObjects; mockGVFSGitObjects.FileLength = fileLength; MockTracer mockTracker = this.Repo.Context.Tracer as MockTracer; mockTracker.WaitRelatedEventName = "GVFltGetFileStreamHandlerAsyncHandler_OperationCancelled"; mockGvFlt.BlockCreateWriteBuffer(willWaitForRequest: true); mockGvFlt.OnGetFileStream( commandId: 1, relativePath: "test.txt", byteOffset: 0, length: fileLength, streamGuid: Guid.NewGuid(), contentId: contentId, providerId: placeholderVersion, triggeringProcessId: 2, triggeringProcessImageFileName: "UnitTest").ShouldEqual(HResult.Pending); mockGvFlt.WaitForCreateWriteBuffer(); mockGvFlt.OnCancelCommand(1); mockGvFlt.UnblockCreateWriteBuffer(); mockTracker.WaitForRelatedEvent(); callbacks.Stop(); } }
private void MountAndStartWorkingDirectoryCallbacks(GVFSContext context, CacheServerInfo cache) { string error; if (!context.Enlistment.Authentication.TryRefreshCredentials(context.Tracer, out error)) { this.FailMountAndExit("Failed to obtain git credentials: " + error); } // Checking the disk layout version is done before this point in GVFS.CommandLine.MountVerb RepoMetadata repoMetadata = new RepoMetadata(this.enlistment.DotGVFSRoot); GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(context.Tracer, context.Enlistment, cache, this.retryConfig); this.gitObjects = new GVFSGitObjects(context, objectRequestor); this.gvfltCallbacks = this.CreateOrReportAndExit(() => new GVFltCallbacks(context, this.gitObjects, repoMetadata), "Failed to create src folder callbacks"); int persistedVersion; if (!repoMetadata.TryGetOnDiskLayoutVersion(out persistedVersion, out error)) { this.FailMountAndExit("Error: {0}", error); } try { if (!this.gvfltCallbacks.TryStart(out error)) { this.FailMountAndExit("Error: {0}. \r\nPlease confirm that gvfs clone completed without error.", error); } } catch (Exception e) { this.FailMountAndExit("Failed to initialize src folder callbacks. {0}", e.ToString()); } try { repoMetadata.SaveCurrentDiskLayoutVersion(); } catch (Exception ex) { this.FailMountAndExit("Failed to update repo disk layout version: {0}", ex.ToString()); } this.AcquireFolderLocks(context); this.heartbeat = new HeartbeatThread(this.tracer, this.gvfltCallbacks); this.heartbeat.Start(); }
private void MountAndStartWorkingDirectoryCallbacks(CacheServerInfo cache) { string error; if (!this.context.Enlistment.Authentication.TryRefreshCredentials(this.context.Tracer, out error)) { this.FailMountAndExit("Failed to obtain git credentials: " + error); } GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(this.context.Tracer, this.context.Enlistment, cache, this.retryConfig); this.gitObjects = new GVFSGitObjects(this.context, objectRequestor); this.gvfltCallbacks = this.CreateOrReportAndExit(() => new GVFltCallbacks(this.context, this.gitObjects, RepoMetadata.Instance), "Failed to create src folder callbacks"); int majorVersion; int minorVersion; if (!RepoMetadata.Instance.TryGetOnDiskLayoutVersion(out majorVersion, out minorVersion, out error)) { this.FailMountAndExit("Error: {0}", error); } if (majorVersion != RepoMetadata.DiskLayoutVersion.CurrentMajorVersion) { this.FailMountAndExit( "Error: On disk version ({0}) does not match current version ({1})", majorVersion, RepoMetadata.DiskLayoutVersion.CurrentMajorVersion); } try { if (!this.gvfltCallbacks.TryStart(out error)) { this.FailMountAndExit("Error: {0}. \r\nPlease confirm that gvfs clone completed without error.", error); } } catch (Exception e) { this.FailMountAndExit("Failed to initialize src folder callbacks. {0}", e.ToString()); } this.AcquireFolderLocks(); this.heartbeat = new HeartbeatThread(this.tracer, this.gvfltCallbacks); this.heartbeat.Start(); }
public void OnGetFileStreamHandlesGvWriteFailure() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test.txt" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, blobSizes: null, gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); Guid enumerationGuid = Guid.NewGuid(); byte[] contentId = GVFltCallbacks.ConvertShaToContentId("0123456789012345678901234567890123456789"); byte[] epochId = GVFltCallbacks.GetEpochId(); uint fileLength = 100; MockGVFSGitObjects mockGVFSGitObjects = this.Repo.GitObjects as MockGVFSGitObjects; mockGVFSGitObjects.FileLength = fileLength; MockTracer mockTracker = this.Repo.Context.Tracer as MockTracer; mockTracker.WaitRelatedEventName = "GVFltGetFileStreamHandlerAsyncHandler_OperationCancelled"; mockGvFlt.WriteFileReturnStatus = NtStatus.InternalError; mockGvFlt.OnGetFileStream( commandId: 1, relativePath: "test.txt", byteOffset: 0, length: fileLength, streamGuid: Guid.NewGuid(), contentId: contentId, epochId: epochId, triggeringProcessId: 2, triggeringProcessImageFileName: "UnitTest").ShouldEqual(NtStatus.Pending); mockGvFlt.WaitForCompletionStatus().ShouldEqual(mockGvFlt.WriteFileReturnStatus); callbacks.Stop(); } }
public void IsPathMonitoredForWrites() { GVFltCallbacks.IsPathMonitoredForWrites(string.Empty).ShouldEqual(false); GVFltCallbacks.IsPathMonitoredForWrites(@".git\index").ShouldEqual(true); GVFltCallbacks.IsPathMonitoredForWrites(@".git\INDEX").ShouldEqual(true); GVFltCallbacks.IsPathMonitoredForWrites(@".git\index.lock").ShouldEqual(false); GVFltCallbacks.IsPathMonitoredForWrites(@".git\INDEX.lock").ShouldEqual(false); GVFltCallbacks.IsPathMonitoredForWrites(@".git\head").ShouldEqual(true); GVFltCallbacks.IsPathMonitoredForWrites(@".git\HEAD").ShouldEqual(true); GVFltCallbacks.IsPathMonitoredForWrites(@".git\head.lock").ShouldEqual(false); GVFltCallbacks.IsPathMonitoredForWrites(@".git\HEAD.lock").ShouldEqual(false); GVFltCallbacks.IsPathMonitoredForWrites(@".git\refs\heads\master").ShouldEqual(true); GVFltCallbacks.IsPathMonitoredForWrites(@".git\refs\heads\users\testuser\feature_branch").ShouldEqual(true); GVFltCallbacks.IsPathMonitoredForWrites(@".git\refs\remotes").ShouldEqual(false); GVFltCallbacks.IsPathMonitoredForWrites(@".git\refs\remotes\master").ShouldEqual(false); GVFltCallbacks.IsPathMonitoredForWrites(@".git\objects\pack").ShouldEqual(false); GVFltCallbacks.IsPathMonitoredForWrites(@".git\objects").ShouldEqual(false); }
public void OnGetFileStreamReturnsPendingAndCompletesWithSuccessWhenNoFailures() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test.txt" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, new MockBlobSizes(), gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); Guid enumerationGuid = Guid.NewGuid(); byte[] contentId = GVFltCallbacks.ConvertShaToContentId("0123456789012345678901234567890123456789"); byte[] placeholderVersion = GVFltCallbacks.GetPlaceholderVersionId(); uint fileLength = 100; MockGVFSGitObjects mockGVFSGitObjects = this.Repo.GitObjects as MockGVFSGitObjects; mockGVFSGitObjects.FileLength = fileLength; mockGvFlt.WriteFileReturnResult = HResult.Ok; mockGvFlt.OnGetFileStream( commandId: 1, relativePath: "test.txt", byteOffset: 0, length: fileLength, streamGuid: Guid.NewGuid(), contentId: contentId, providerId: placeholderVersion, triggeringProcessId: 2, triggeringProcessImageFileName: "UnitTest").ShouldEqual(HResult.Pending); mockGvFlt.WaitForCompletionStatus().ShouldEqual(HResult.Ok); callbacks.Stop(); } }
private void FailMountAndExit(string error, params object[] args) { this.currentState = MountState.MountFailed; this.tracer.RelatedError(error, args); if (this.showDebugWindow) { Console.WriteLine("\nPress Enter to Exit"); Console.ReadLine(); } if (this.gvfltCallbacks != null) { this.gvfltCallbacks.Dispose(); this.gvfltCallbacks = null; } Environment.Exit((int)ReturnCode.GenericError); }
public void GetPlaceholderInformationHandlerPathNotProjected() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test.txt" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, blobSizes: null, gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); mockGvFlt.OnGetPlaceholderInformation(1, "doesNotExist", 0, 0, 0, 0, 1, "UnitTests").ShouldEqual(NtStatus.ObjectNameNotFound); } }
public void GetPlaceholderInformationHandlerCancelledBeforeSchedulingAsync() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test.txt" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, new MockBlobSizes(), gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); gitIndexProjection.BlockIsPathProjected(willWaitForRequest: true); Task.Run(() => { // Wait for OnGetPlaceholderInformation to call IsPathProjected and then while it's blocked there // call OnCancelCommand gitIndexProjection.WaitForIsPathProjected(); mockGvFlt.OnCancelCommand(1); gitIndexProjection.UnblockIsPathProjected(); }); mockGvFlt.OnGetPlaceholderInformation(1, "test.txt", 0, 0, 0, 0, 1, "UnitTests").ShouldEqual(HResult.Pending); // Cancelling before GetPlaceholderInformation has registered the command results in placeholders being created mockGvFlt.WaitForPlaceholderCreate(); gitIndexProjection.WaitForPlaceholderCreate(); mockGvFlt.CreatedPlaceholders.ShouldContain(entry => entry == "test.txt"); gitIndexProjection.PlaceholdersCreated.ShouldContain(entry => entry == "test.txt"); callbacks.Stop(); } }
public void OnStartDirectoryEnumerationReturnsSuccessWhenResultsInMemory() { using (MockVirtualizationInstance mockGvFlt = new MockVirtualizationInstance()) using (MockGitIndexProjection gitIndexProjection = new MockGitIndexProjection(new[] { "test" })) { GVFltCallbacks callbacks = new GVFltCallbacks( this.Repo.Context, this.Repo.GitObjects, RepoMetadata.Instance, blobSizes: null, gvflt: mockGvFlt, gitIndexProjection: gitIndexProjection, reliableBackgroundOperations: new MockReliableBackgroundOperations()); string error; callbacks.TryStart(out error).ShouldEqual(true); Guid enumerationGuid = Guid.NewGuid(); gitIndexProjection.EnumerationInMemory = true; mockGvFlt.OnStartDirectoryEnumeration(1, enumerationGuid, "test").ShouldEqual(NtStatus.Success); mockGvFlt.OnEndDirectoryEnumeration(enumerationGuid).ShouldEqual(NtStatus.Success); } }
public CloneVerb.Result CreateClone(GitRefs refs, string branch) { GitObjects gitObjects = new GitObjects(this.tracer, this.enlistment, this.objectRequestor); CloneVerb.Result initRepoResult = this.TryInitRepo(refs, this.enlistment); if (!initRepoResult.Success) { return(initRepoResult); } string errorMessage; if (!this.enlistment.TryConfigureAlternate(out errorMessage)) { return(new CloneVerb.Result("Error configuring alternate: " + errorMessage)); } if (!gitObjects.TryDownloadAndSaveCommit(refs.GetTipCommitId(branch), commitDepth: 2)) { return(new CloneVerb.Result("Could not download tip commits from: " + Uri.EscapeUriString(this.objectRequestor.CacheServer.ObjectsEndpointUrl))); } GitProcess git = new GitProcess(this.enlistment); if (!this.SetConfigSettings(git, this.objectRequestor.CacheServer)) { return(new CloneVerb.Result("Unable to configure git repo")); } string originBranchName = "origin/" + branch; GitProcess.Result createBranchResult = git.CreateBranchWithUpstream(branch, originBranchName); if (createBranchResult.HasErrors) { return(new CloneVerb.Result("Unable to create branch '" + originBranchName + "': " + createBranchResult.Errors + "\r\n" + createBranchResult.Output)); } File.WriteAllText( Path.Combine(this.enlistment.WorkingDirectoryRoot, GVFSConstants.DotGit.Head), "ref: refs/heads/" + branch); File.AppendAllText( Path.Combine(this.enlistment.WorkingDirectoryRoot, GVFSConstants.DotGit.Info.SparseCheckoutPath), GVFSConstants.GitPathSeparatorString + GVFSConstants.SpecialGitFiles.GitAttributes + "\n"); CloneVerb.Result hydrateResult = this.HydrateRootGitAttributes(gitObjects, branch); if (!hydrateResult.Success) { return(hydrateResult); } this.CreateGitScript(); GitProcess.Result forceCheckoutResult = git.ForceCheckout(branch); if (forceCheckoutResult.HasErrors) { string[] errorLines = forceCheckoutResult.Errors.Split('\n'); StringBuilder checkoutErrors = new StringBuilder(); foreach (string gitError in errorLines) { if (IsForceCheckoutErrorCloneFailure(gitError)) { checkoutErrors.AppendLine(gitError); } } if (checkoutErrors.Length > 0) { string error = "Could not complete checkout of branch: " + branch + ", " + checkoutErrors.ToString(); this.tracer.RelatedError(error); return(new CloneVerb.Result(error)); } } GitProcess.Result updateIndexresult = git.UpdateIndexVersion4(); if (updateIndexresult.HasErrors) { string error = "Could not update index, error: " + updateIndexresult.Errors; this.tracer.RelatedError(error); return(new CloneVerb.Result(error)); } string installHooksError; if (!HooksInstaller.InstallHooks(this.enlistment, out installHooksError)) { this.tracer.RelatedError(installHooksError); return(new CloneVerb.Result(installHooksError)); } using (RepoMetadata repoMetadata = new RepoMetadata(this.enlistment.DotGVFSRoot)) { repoMetadata.SaveCurrentDiskLayoutVersion(); } // Prepare the working directory folder for GVFS last to ensure that gvfs mount will fail if gvfs clone has failed string prepGVFltError; if (!GVFltCallbacks.TryPrepareFolderForGVFltCallbacks(this.enlistment.WorkingDirectoryRoot, out prepGVFltError)) { this.tracer.RelatedError(prepGVFltError); return(new CloneVerb.Result(prepGVFltError)); } return(new CloneVerb.Result(true)); }
private Result CreateClone( ITracer tracer, GVFSEnlistment enlistment, GitObjectsHttpRequestor objectRequestor, GitRefs refs, string branch) { Result initRepoResult = this.TryInitRepo(tracer, refs, enlistment); if (!initRepoResult.Success) { return(initRepoResult); } PhysicalFileSystem fileSystem = new PhysicalFileSystem(); string errorMessage; if (!this.TryCreateAlternatesFile(fileSystem, enlistment, out errorMessage)) { return(new Result("Error configuring alternate: " + errorMessage)); } GitRepo gitRepo = new GitRepo(tracer, enlistment, fileSystem); GVFSGitObjects gitObjects = new GVFSGitObjects(new GVFSContext(tracer, fileSystem, gitRepo, enlistment), objectRequestor); if (!this.TryDownloadCommit( refs.GetTipCommitId(branch), enlistment, objectRequestor, gitObjects, gitRepo, out errorMessage)) { return(new Result(errorMessage)); } if (!GVFSVerb.TrySetRequiredGitConfigSettings(enlistment) || !GVFSVerb.TrySetOptionalGitConfigSettings(enlistment)) { return(new Result("Unable to configure git repo")); } CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment); if (!cacheServerResolver.TrySaveUrlToLocalConfig(objectRequestor.CacheServer, out errorMessage)) { return(new Result("Unable to configure cache server: " + errorMessage)); } GitProcess git = new GitProcess(enlistment); string originBranchName = "origin/" + branch; GitProcess.Result createBranchResult = git.CreateBranchWithUpstream(branch, originBranchName); if (createBranchResult.HasErrors) { return(new Result("Unable to create branch '" + originBranchName + "': " + createBranchResult.Errors + "\r\n" + createBranchResult.Output)); } File.WriteAllText( Path.Combine(enlistment.WorkingDirectoryRoot, GVFSConstants.DotGit.Head), "ref: refs/heads/" + branch); File.AppendAllText( Path.Combine(enlistment.WorkingDirectoryRoot, GVFSConstants.DotGit.Info.SparseCheckoutPath), GVFSConstants.GitPathSeparatorString + GVFSConstants.SpecialGitFiles.GitAttributes + "\n"); if (!this.TryDownloadRootGitAttributes(enlistment, gitObjects, gitRepo, out errorMessage)) { return(new Result(errorMessage)); } this.CreateGitScript(enlistment); GitProcess.Result forceCheckoutResult = git.ForceCheckout(branch); if (forceCheckoutResult.HasErrors) { string[] errorLines = forceCheckoutResult.Errors.Split('\n'); StringBuilder checkoutErrors = new StringBuilder(); foreach (string gitError in errorLines) { if (IsForceCheckoutErrorCloneFailure(gitError)) { checkoutErrors.AppendLine(gitError); } } if (checkoutErrors.Length > 0) { string error = "Could not complete checkout of branch: " + branch + ", " + checkoutErrors.ToString(); tracer.RelatedError(error); return(new Result(error)); } } GitProcess.Result updateIndexresult = git.UpdateIndexVersion4(); if (updateIndexresult.HasErrors) { string error = "Could not update index, error: " + updateIndexresult.Errors; tracer.RelatedError(error); return(new Result(error)); } string installHooksError; if (!HooksInstaller.InstallHooks(enlistment, out installHooksError)) { tracer.RelatedError(installHooksError); return(new Result(installHooksError)); } if (!RepoMetadata.TryInitialize(tracer, enlistment.DotGVFSRoot, out errorMessage)) { tracer.RelatedError(errorMessage); return(new Result(errorMessage)); } try { RepoMetadata.Instance.SaveCloneMetadata(tracer, enlistment); EventMetadata metadata = new EventMetadata(); metadata.Add(nameof(RepoMetadata.Instance.EnlistmentId), RepoMetadata.Instance.EnlistmentId); metadata.Add("Enlistment", enlistment); tracer.RelatedEvent(EventLevel.Informational, "EnlistmentInfo", metadata, Keywords.Telemetry); GitProcess.Result configResult = git.SetInLocalConfig(GVFSConstants.GitConfig.EnlistmentId, RepoMetadata.Instance.EnlistmentId, replaceAll: true); if (configResult.HasErrors) { string error = "Could not update config with enlistment id, error: " + configResult.Errors; tracer.RelatedWarning(error); } } catch (Exception e) { tracer.RelatedError(e.ToString()); return(new Result(e.Message)); } finally { RepoMetadata.Shutdown(); } // Prepare the working directory folder for GVFS last to ensure that gvfs mount will fail if gvfs clone has failed string prepGVFltError; if (!GVFltCallbacks.TryPrepareFolderForGVFltCallbacks(enlistment.WorkingDirectoryRoot, out prepGVFltError)) { tracer.RelatedError(prepGVFltError); return(new Result(prepGVFltError)); } return(new Result(true)); }