public void CheckoutBranchWithSymLinks() { GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "checkout FunctionalTests/20180925_SymLinksPart1"); GitHelpers.CheckGitCommandAgainstGSDRepo( this.Enlistment.RepoRoot, "status", "On branch FunctionalTests/20180925_SymLinksPart1", "nothing to commit, working tree clean"); string testFilePath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, TestFileName)); testFilePath.ShouldBeAFile(this.bashRunner).WithContents(TestFileContents); this.bashRunner.IsSymbolicLink(testFilePath).ShouldBeFalse($"{testFilePath} should not be a symlink"); GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + TestFileName); string testFile2Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, TestFile2Name)); testFile2Path.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); this.bashRunner.IsSymbolicLink(testFile2Path).ShouldBeFalse($"{testFile2Path} should not be a symlink"); GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + TestFile2Name); string childLinkPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildLinkName)); this.bashRunner.IsSymbolicLink(childLinkPath).ShouldBeTrue($"{childLinkPath} should be a symlink"); childLinkPath.ShouldBeAFile(this.bashRunner).WithContents(TestFileContents); GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildLinkName); string grandChildLinkPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildFolderName, GrandChildLinkName)); this.bashRunner.IsSymbolicLink(grandChildLinkPath).ShouldBeTrue($"{grandChildLinkPath} should be a symlink"); grandChildLinkPath.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildFolderName + "/" + GrandChildLinkName); }
public void GitStatusAndObjectAfterGitAdd() { string existingFilename = "test.cs"; this.Enlistment.GetVirtualPathTo(existingFilename).ShouldBeAFile(this.fileSystem); GitHelpers.CheckGitCommandAgainstGSDRepo( this.Enlistment.RepoRoot, "add " + existingFilename, new string[] { }); // Status should be correct GitHelpers.CheckGitCommandAgainstGSDRepo( this.Enlistment.RepoRoot, "status", "On branch " + Properties.Settings.Default.Commitish, "Changes to be committed:", existingFilename); // Object file for the test file should have the correct contents ProcessResult result = GitHelpers.InvokeGitAgainstGSDRepo( this.Enlistment.RepoRoot, "hash-object " + existingFilename); string objectHash = result.Output.Trim(); result.Errors.ShouldBeEmpty(); this.Enlistment.GetObjectPathTo(objectHash).ShouldBeAFile(this.fileSystem); GitHelpers.CheckGitCommandAgainstGSDRepo( this.Enlistment.RepoRoot, "cat-file -p " + objectHash, this.testFileContents); }
private void GitCommandWaitsForLock(string gitWorkingDirectory) { ManualResetEventSlim resetEvent = GitHelpers.AcquireGSDLock(this.Enlistment, out _, resetTimeout: 3000); ProcessResult statusWait = GitHelpers.InvokeGitAgainstGSDRepo(gitWorkingDirectory, "status", removeWaitingMessages: false); statusWait.Errors.ShouldContain(ExpectedStatusWaitingText); resetEvent.Set(); this.Enlistment.WaitForBackgroundOperations(); }
public void NoReminderWhenUpgradeNotAvailable() { this.EmptyDownloadDirectory(); for (int count = 0; count < 50; count++) { ProcessResult result = GitHelpers.InvokeGitAgainstGSDRepo( this.Enlistment.RepoRoot, "status"); string.IsNullOrEmpty(result.Errors).ShouldBeTrue(); } }
public void UpdateIndexRemoveAddFileOpenForWrite() { // TODO 940287: Remove this test and re-enable UpdateIndexRemoveFileOnDisk this.ValidateGitCommand("checkout " + GitRepoTests.ConflictTargetBranch); // git-status will not match because update-index --remove does not check what is on disk if the skip-worktree bit is set, // meaning it will always remove the file from the index GitProcess.InvokeProcess(this.ControlGitRepo.RootPath, "update-index --remove Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt"); GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "update-index --remove Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt"); this.FilesShouldMatchCheckoutOfTargetBranch(); // Add the files back to the index so the git-status that is run during teardown matches GitProcess.InvokeProcess(this.ControlGitRepo.RootPath, "update-index --add Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt"); GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "update-index --add Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt"); }
public void CheckoutBranchWhereFilesTransitionToSymLinks() { GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "checkout FunctionalTests/20180925_SymLinksPart3"); GitHelpers.CheckGitCommandAgainstGSDRepo( this.Enlistment.RepoRoot, "status", "On branch FunctionalTests/20180925_SymLinksPart3", "nothing to commit, working tree clean"); // In this branch testFilePath has been changed to point to newGrandChildFilePath string testFilePath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, TestFileName)); testFilePath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildFileContents); this.bashRunner.IsSymbolicLink(testFilePath).ShouldBeTrue($"{testFilePath} should be a symlink"); GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + TestFileName); // There should be a new ChildFolder2Name directory string childFolder2Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildFolder2Name)); this.bashRunner.IsSymbolicLink(childFolder2Path).ShouldBeFalse($"{childFolder2Path} should not be a symlink"); childFolder2Path.ShouldBeADirectory(this.bashRunner); GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildFolder2Name); // The rest of the files are unchanged from FunctionalTests/20180925_SymLinksPart2 string testFile2Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, TestFile2Name)); testFile2Path.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); this.bashRunner.IsSymbolicLink(testFile2Path).ShouldBeFalse($"{testFile2Path} should not be a symlink"); string childLinkPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildLinkName)); this.bashRunner.IsSymbolicLink(childLinkPath).ShouldBeTrue($"{childLinkPath} should be a symlink"); childLinkPath.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildLinkName); string grandChildLinkPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildFolderName, GrandChildLinkName)); this.bashRunner.IsSymbolicLink(grandChildLinkPath).ShouldBeFalse($"{grandChildLinkPath} should not be a symlink"); grandChildLinkPath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildLinkNowAFileContents); string newGrandChildFilePath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildFolderName, GrandChildFileName)); newGrandChildFilePath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildFileContents); this.bashRunner.IsSymbolicLink(newGrandChildFilePath).ShouldBeFalse($"{newGrandChildFilePath} should not be a symlink"); }
public void GitWithEnvironmentVariables() { // The trace info is an error, so we can't use CheckGitCommand(). // We just want to make sure this doesn't throw an exception. ProcessResult result = GitHelpers.InvokeGitAgainstGSDRepo( this.Enlistment.RepoRoot, "branch", new Dictionary <string, string> { { "GIT_TRACE_PERFORMANCE", "1" }, { "git_trace", "1" }, }, removeWaitingMessages: false); result.Output.ShouldContain("* FunctionalTests"); result.Errors.ShouldNotContain(ignoreCase: true, unexpectedSubstrings: "exception"); result.Errors.ShouldContain("trace.c:", "git command:"); }
public void CanReadFileAfterHashObject() { this.ValidateGitCommand("status"); // Validate that Scripts\RunUnitTests.bad is not on disk at all string filePath = Path.Combine("Scripts", "RunUnitTests.bat"); this.Enlistment.UnmountGSD(); this.Enlistment.GetVirtualPathTo(filePath).ShouldNotExistOnDisk(this.FileSystem); this.Enlistment.MountGSD(); // TODO 1087312: Fix 'git hash-oject' so that it works for files that aren't on disk yet GitHelpers.InvokeGitAgainstGSDRepo( this.Enlistment.RepoRoot, "hash-object " + GitHelpers.ConvertPathToGitFormat(filePath)); this.FileContentsShouldMatch(filePath); }
/* We are using the following method for these scenarios * 1. Some commands compute a new commit sha, which is dependent on time and therefore * won't match what is in the control repo. For those commands, we just ensure that * the errors match what we expect, but we skip comparing the output * 2. Using the sparse-checkout feature git will error out before checking the untracked files * so the control repo will show the untracked files as being overwritten while the GSD * repo which is using the sparse-checkout will not. * 3. GSD is returning not found for files that are outside the sparse-checkout and there * are cases when git will delete these files during a merge outputting that it removed them * which the GSD repo did not have to remove so the message is missing that output. */ protected void RunGitCommand(string command, bool ignoreErrors = false, bool checkStatus = true) { string controlRepoRoot = this.ControlGitRepo.RootPath; string gvfsRepoRoot = this.Enlistment.RepoRoot; ProcessResult expectedResult = GitProcess.InvokeProcess(controlRepoRoot, command); ProcessResult actualResult = GitHelpers.InvokeGitAgainstGSDRepo(gvfsRepoRoot, command); if (!ignoreErrors) { GitHelpers.ErrorsShouldMatch(command, expectedResult, actualResult); } if (command != "status" && checkStatus) { this.ValidateGitCommand("status"); } }
private bool ReminderMessagingEnabled() { for (int count = 0; count < 50; count++) { ProcessResult result = GitHelpers.InvokeGitAgainstGSDRepo( this.Enlistment.RepoRoot, "status", removeWaitingMessages: true, removeUpgradeMessages: false); if (!string.IsNullOrEmpty(result.Errors) && result.Errors.Contains("A new version of GSD is available.")) { return(true); } } return(false); }
public void MergeConflictEnsureStatusFailsDueToConfig() { // This is compared against the message emitted by GSD.Hooks\Program.cs string expectedErrorMessagePart = "--no-renames"; this.ValidateGitCommand("checkout " + GitRepoTests.ConflictTargetBranch); this.RunGitCommand("merge " + GitRepoTests.ConflictSourceBranch, checkStatus: false); ProcessResult result1 = GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "status"); result1.Errors.Contains(expectedErrorMessagePart); ProcessResult result2 = GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "status --no-renames"); result2.Errors.Contains(expectedErrorMessagePart); // Complete setup to ensure teardown succeeds GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "config --local test.renames false"); }
public void SecondCloneSucceedsWithMissingTrees() { string newCachePath = Path.Combine(this.localCacheParentPath, ".customGvfsCache2"); GSDFunctionalTestEnlistment enlistment1 = this.CreateNewEnlistment(localCacheRoot: newCachePath, skipPrefetch: true); File.ReadAllText(Path.Combine(enlistment1.RepoRoot, WellKnownFile)); this.AlternatesFileShouldHaveGitObjectsRoot(enlistment1); // This Git command loads the commit and root tree for WellKnownCommitSha, // but does not download any more reachable objects. string command = "cat-file -p origin/" + WellKnownBranch + "^{tree}"; ProcessResult result = GitHelpers.InvokeGitAgainstGSDRepo(enlistment1.RepoRoot, command); result.ExitCode.ShouldEqual(0, $"git {command} failed with error: " + result.Errors); // If we did not properly check the failed checkout at this step, then clone will fail during checkout. GSDFunctionalTestEnlistment enlistment2 = this.CreateNewEnlistment(localCacheRoot: newCachePath, branch: WellKnownBranch, skipPrefetch: true); File.ReadAllText(Path.Combine(enlistment2.RepoRoot, WellKnownFile)); }
public void CheckoutBranchWhereSymLinkTransistionsToFolderAndFolderTransitionsToSymlink() { GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "checkout FunctionalTests/20180925_SymLinksPart4"); GitHelpers.CheckGitCommandAgainstGSDRepo( this.Enlistment.RepoRoot, "status", "On branch FunctionalTests/20180925_SymLinksPart4", "nothing to commit, working tree clean"); // In this branch ChildLinkName has been changed to a directory and ChildFolder2Name has been changed to a link to ChildFolderName string linkNowADirectoryPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildLinkName)); this.bashRunner.IsSymbolicLink(linkNowADirectoryPath).ShouldBeFalse($"{linkNowADirectoryPath} should not be a symlink"); linkNowADirectoryPath.ShouldBeADirectory(this.bashRunner); GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildLinkName); string directoryNowALinkPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildFolder2Name)); this.bashRunner.IsSymbolicLink(directoryNowALinkPath).ShouldBeTrue($"{directoryNowALinkPath} should be a symlink"); GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildFolder2Name); }
public void CheckoutCleansUpTombstones() { const string folderToDelete = "Scripts"; // Delete directory to create the tombstone string directoryToDelete = this.Enlistment.GetVirtualPathTo(folderToDelete); this.fileSystem.DeleteDirectory(directoryToDelete); this.Enlistment.UnmountGSD(); // Remove the directory entry from modified paths so git will not keep the folder up to date string modifiedPathsFile = Path.Combine(this.Enlistment.DotGSDRoot, TestConstants.Databases.ModifiedPaths); string modifiedPathsContent = this.fileSystem.ReadAllText(modifiedPathsFile); modifiedPathsContent = string.Join(Delimiter, modifiedPathsContent.Split(new[] { Delimiter }, StringSplitOptions.RemoveEmptyEntries).Where(x => !x.StartsWith($"A {folderToDelete}/"))); this.fileSystem.WriteAllText(modifiedPathsFile, modifiedPathsContent + Delimiter); // Add tombstone folder entry to the placeholder database so the checkout will remove the tombstone // and start projecting the folder again string placeholderDatabasePath = Path.Combine(this.Enlistment.DotGSDRoot, TestConstants.Databases.GSD); GSDHelpers.AddPlaceholderFolder(placeholderDatabasePath, folderToDelete, TombstoneFolderPlaceholderType); this.Enlistment.MountGSD(); directoryToDelete.ShouldNotExistOnDisk(this.fileSystem); // checkout branch to remove tombstones and project the folder again GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "checkout -f HEAD"); directoryToDelete.ShouldBeADirectory(this.fileSystem); this.Enlistment.UnmountGSD(); string placholders = GSDHelpers.GetAllSQLitePlaceholdersAsString(placeholderDatabasePath); placholders.ShouldNotContain(ignoreCase: false, unexpectedSubstrings: $"{folderToDelete}{GSDHelpers.PlaceholderFieldDelimiter}{TombstoneFolderPlaceholderType}{GSDHelpers.PlaceholderFieldDelimiter}"); }
private ProcessResult InvokeGitAgainstGSDRepo(string command) { return(GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, command)); }