public void DeletedFolderAndChildrenAddedToToModifiedPathsFile()
        {
            string folderToDelete = "Scripts";

            string[] filesToDelete = new string[]
            {
                "Scripts/CreateCommonAssemblyVersion.bat",
                "Scripts/CreateCommonCliAssemblyVersion.bat",
                "Scripts/CreateCommonVersionHeader.bat",
                "Scripts/RunFunctionalTests.bat",
                "Scripts/RunUnitTests.bat"
            };

            // Verify skip-worktree initial set for all files
            foreach (string file in filesToDelete)
            {
                this.VerifyWorktreeBit(file, LsFilesStatus.SkipWorktree);
            }

            this.fileSystem.DeleteDirectory(this.Enlistment.GetVirtualPathTo(folderToDelete));
            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, folderToDelete + "/");
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, filesToDelete);

            // Verify skip-worktree cleared
            foreach (string file in filesToDelete)
            {
                this.VerifyWorktreeBit(file, LsFilesStatus.Cached);
            }
        }
        public void LockToPreventDelete_SingleFile()
        {
            string testFile1Contents = "TestContentsLockToPreventDelete \r\n";
            string testFile1Name     = "test.txt";
            string testFile1Path     = this.Enlistment.GetVirtualPathTo(Path.Combine(TestParentFolderName, "LockToPreventDelete", testFile1Name));

            testFile1Path.ShouldBeAFile(this.fileSystem).WithContents(testFile1Contents);
            using (SafeFileHandle testFile1Handle = this.CreateFile(testFile1Path, FileShare.Read))
            {
                testFile1Handle.IsInvalid.ShouldEqual(false);

                ProcessResult result = this.InvokeGitAgainstGSDRepo("checkout " + OldCommitId);
                result.Errors.ShouldContain(
                    "GSD was unable to delete the following files. To recover, close all handles to the files and run these commands:",
                    "git clean -f " + TestParentFolderName + "/LockToPreventDelete/" + testFile1Name);

                GitHelpers.CheckGitCommandAgainstGSDRepo(
                    this.Enlistment.RepoRoot,
                    "status -u",
                    "HEAD detached at " + OldCommitId,
                    "Untracked files:",
                    TestParentFolderName + "/LockToPreventDelete/" + testFile1Name);
            }

            this.GitCleanFile(TestParentFolderName + "/LockToPreventDelete/" + testFile1Name);
            this.GitStatusShouldBeClean(OldCommitId);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, TestParentFolderName + "/LockToPreventDelete/" + testFile1Name);
            testFile1Path.ShouldNotExistOnDisk(this.fileSystem);

            this.GitCheckoutCommitId(NewFilesAndChangesCommitId);

            this.GitStatusShouldBeClean(NewFilesAndChangesCommitId);
            testFile1Path.ShouldBeAFile(this.fileSystem).WithContents(testFile1Contents);
        }
        public void MountCanProcessSavedBackgroundQueueTasks()
        {
            string deletedFileEntry = "Test_EPF_WorkingDirectoryTests/1/2/3/4/ReadDeepProjectedFile.cpp";
            string deletedDirEntry  = "Test_EPF_WorkingDirectoryTests/1/2/3/4/";

            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, deletedFileEntry);
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, deletedDirEntry);
            this.Enlistment.UnmountGSD();

            // Prime the background queue with delete messages
            string deleteFilePath               = Path.Combine("Test_EPF_WorkingDirectoryTests", "1", "2", "3", "4", "ReadDeepProjectedFile.cpp");
            string deleteDirPath                = Path.Combine("Test_EPF_WorkingDirectoryTests", "1", "2", "3", "4");
            string persistedDeleteFileTask      = $"A 1\0{this.fileDeletedBackgroundOperationCode}\0{deleteFilePath}\0";
            string persistedDeleteDirectoryTask = $"A 2\0{this.directoryDeletedBackgroundOperationCode}\0{deleteDirPath}\0";

            this.fileSystem.WriteAllText(
                Path.Combine(this.Enlistment.EnlistmentRoot, GSDTestConfig.DotGSDRoot, "databases", "BackgroundGitOperations.dat"),
                $"{persistedDeleteFileTask}\r\n{persistedDeleteDirectoryTask}\r\n");

            // Background queue should process the delete messages and modifiedPaths should show the change
            this.Enlistment.MountGSD();
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, deletedFileEntry);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, deletedDirEntry);
        }
Exemple #4
0
        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 DeletedFileAddedToModifiedPathsFile()
        {
            string fileToDeleteEntry = "GVFlt_DeleteFileTest/GVFlt_DeleteFullFileWithoutFileContext_DeleteOnClose/a.txt";

            this.VerifyWorktreeBit(fileToDeleteEntry, LsFilesStatus.SkipWorktree);

            this.fileSystem.DeleteFile(this.Enlistment.GetVirtualPathTo(fileToDeleteEntry));
            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileToDeleteEntry);

            // Verify skip-worktree cleared
            this.VerifyWorktreeBit(fileToDeleteEntry, LsFilesStatus.Cached);
        }
Exemple #6
0
 private void ValidGitStatusWithRetry(string srcPath)
 {
     this.Enlistment.WaitForBackgroundOperations();
     GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.FileSystem, srcPath);
     try
     {
         this.ValidateGitCommand("status");
     }
     catch (Exception ex)
     {
         Thread.Sleep(1000);
         this.ValidateGitCommand("status");
         Assert.Fail("{0} was succesful on the second try, but failed on first: {1}", nameof(this.ValidateGitCommand), ex.Message);
     }
 }
        public void HardlinkFromInsideRepoToOutside()
        {
            string fileName       = "Readme.md";
            string fileInsideRepo = this.Enlistment.GetVirtualPathTo(fileName);

            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, fileName);

            string fileNameLink        = "InsideRepoToOutside_RepoLink.txt";
            string fileLinkOutsideRepo = Path.Combine(this.Enlistment.EnlistmentRoot, fileNameLink);

            this.fileSystem.CreateHardLink(fileLinkOutsideRepo, fileInsideRepo);
            fileLinkOutsideRepo.ShouldBeAFile(this.fileSystem);
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileName);
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, fileNameLink);
        }
Exemple #8
0
        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 CreateFileInFolderTest()
        {
            string folderName = "folder2";
            string fileName   = "file2.txt";
            string filePath   = Path.Combine(folderName, fileName);

            this.Enlistment.GetVirtualPathTo(filePath).ShouldNotExistOnDisk(this.fileSystem);
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, filePath);

            this.fileSystem.CreateDirectory(this.Enlistment.GetVirtualPathTo(folderName));
            this.fileSystem.CreateEmptyFile(this.Enlistment.GetVirtualPathTo(filePath));
            this.Enlistment.GetVirtualPathTo(filePath).ShouldBeAFile(this.fileSystem);

            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, folderName + "/");
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, folderName + "/" + fileName);
        }
        public void HardlinkExistingFileInRepo()
        {
            string fileName     = "GVFS/GVFS.Mount/Program.cs";
            string fileNameLink = "HardLinkToReadme";

            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, fileName);
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, fileNameLink);

            string fileInsideRepo     = this.Enlistment.GetVirtualPathTo(fileName);
            string fileLinkInsideRepo = this.Enlistment.GetVirtualPathTo(fileNameLink);

            this.fileSystem.CreateHardLink(fileLinkInsideRepo, fileInsideRepo);
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileName);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileNameLink);
            fileInsideRepo.ShouldBeAFile(this.fileSystem);
            fileLinkInsideRepo.ShouldBeAFile(this.fileSystem);
        }
        public void CreateFileTest()
        {
            string fileName = "file1.txt";

            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, fileName);
            this.fileSystem.WriteAllText(this.Enlistment.GetVirtualPathTo(fileName), "Some content here");
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileName);
            this.Enlistment.GetVirtualPathTo(fileName).ShouldBeAFile(this.fileSystem).WithContents("Some content here");

            string emptyFileName = "file1empty.txt";

            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, emptyFileName);
            this.fileSystem.CreateEmptyFile(this.Enlistment.GetVirtualPathTo(emptyFileName));
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, emptyFileName);
            this.Enlistment.GetVirtualPathTo(emptyFileName).ShouldBeAFile(this.fileSystem);
        }
        public void RenamedFileAddedToModifiedPathsFile()
        {
            string fileToRenameEntry       = "Test_EPF_MoveRenameFileTests/ChangeUnhydratedFileName/Program.cs";
            string fileToRenameTargetEntry = "Test_EPF_MoveRenameFileTests/ChangeUnhydratedFileName/Program2.cs";

            this.VerifyWorktreeBit(fileToRenameEntry, LsFilesStatus.SkipWorktree);

            this.fileSystem.MoveFile(
                this.Enlistment.GetVirtualPathTo(fileToRenameEntry),
                this.Enlistment.GetVirtualPathTo(fileToRenameTargetEntry));
            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileToRenameEntry);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileToRenameTargetEntry);

            // Verify skip-worktree cleared
            this.VerifyWorktreeBit(fileToRenameEntry, LsFilesStatus.Cached);
        }
        public void FileMovedFromOutsideRepoToInside()
        {
            string fileName        = "OutsideRepoToInside.txt";
            string fileOutsideRepo = Path.Combine(this.Enlistment.EnlistmentRoot, fileName);

            this.fileSystem.WriteAllText(fileOutsideRepo, "Contents for the new file");
            fileOutsideRepo.ShouldBeAFile(this.fileSystem);
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, fileName);

            string fileMovedInsideRepo = this.Enlistment.GetVirtualPathTo(fileName);

            this.fileSystem.MoveFile(fileOutsideRepo, fileMovedInsideRepo);
            fileMovedInsideRepo.ShouldBeAFile(this.fileSystem);
            fileOutsideRepo.ShouldNotExistOnDisk(this.fileSystem);
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileName);
        }
        public void ModifiedFileWillGetAddedToModifiedPathsFile()
        {
            string gitFileToTest = "GVFS/GVFS.Common/RetryWrapper.cs";
            string fileToCreate  = this.Enlistment.GetVirtualPathTo(gitFileToTest);

            this.VerifyWorktreeBit(gitFileToTest, LsFilesStatus.SkipWorktree);

            ManualResetEventSlim resetEvent = GitHelpers.AcquireGSDLock(this.Enlistment, out _);

            this.fileSystem.WriteAllText(fileToCreate, "Anything can go here");
            this.fileSystem.FileExists(fileToCreate).ShouldEqual(true);
            resetEvent.Set();

            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, gitFileToTest);
            this.VerifyWorktreeBit(gitFileToTest, LsFilesStatus.Cached);
        }
        public void RenameEmptyFolderTest()
        {
            string folderName        = "folder3a";
            string renamedFolderName = "folder3b";

            string[] expectedModifiedEntries =
            {
                renamedFolderName + "/",
            };

            this.Enlistment.GetVirtualPathTo(folderName).ShouldNotExistOnDisk(this.fileSystem);
            this.fileSystem.CreateDirectory(this.Enlistment.GetVirtualPathTo(folderName));
            this.fileSystem.MoveDirectory(this.Enlistment.GetVirtualPathTo(folderName), this.Enlistment.GetVirtualPathTo(renamedFolderName));

            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, expectedModifiedEntries);
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, folderName + "/");
        }
        public void OverwrittenFileAddedToModifiedPathsAndSkipWorktreeBitCleared()
        {
            string fileToOverwriteEntry       = "Test_EPF_WorkingDirectoryTests/1/2/3/4/ReadDeepProjectedFile.cpp";
            string fileToOverwriteVirtualPath = this.Enlistment.GetVirtualPathTo(fileToOverwriteEntry);

            this.VerifyWorktreeBit(fileToOverwriteEntry, LsFilesStatus.SkipWorktree);

            string testContents = $"Test contents for {nameof(this.OverwrittenFileAddedToModifiedPathsAndSkipWorktreeBitCleared)}";

            this.fileSystem.WriteAllText(fileToOverwriteVirtualPath, testContents);
            this.Enlistment.WaitForBackgroundOperations();

            fileToOverwriteVirtualPath.ShouldBeAFile(this.fileSystem).WithContents(testContents);

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileToOverwriteEntry);

            // Verify skip-worktree cleared
            this.VerifyWorktreeBit(fileToOverwriteEntry, LsFilesStatus.Cached);
        }
        public void FileRenamedOutOfRepoAddedToModifiedPathsAndSkipWorktreeBitCleared()
        {
            string fileToRenameEntry       = "GVFlt_MoveFileTest/PartialToOutside/from/lessInFrom.txt";
            string fileToRenameVirtualPath = this.Enlistment.GetVirtualPathTo(fileToRenameEntry);

            this.VerifyWorktreeBit(fileToRenameEntry, LsFilesStatus.SkipWorktree);

            string fileOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, $"{nameof(this.FileRenamedOutOfRepoAddedToModifiedPathsAndSkipWorktreeBitCleared)}.txt");

            this.fileSystem.MoveFile(fileToRenameVirtualPath, fileOutsideRepoPath);
            fileOutsideRepoPath.ShouldBeAFile(this.fileSystem).WithContents("lessData");

            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileToRenameEntry);

            // Verify skip-worktree cleared
            this.VerifyWorktreeBit(fileToRenameEntry, LsFilesStatus.Cached);
        }
        public void HardlinkInsideRepo()
        {
            string fileName       = "InsideRepo_FileForHardlink.txt";
            string fileInsideRepo = this.Enlistment.GetVirtualPathTo(fileName);

            this.fileSystem.WriteAllText(fileInsideRepo, "Contents for the new file");
            fileInsideRepo.ShouldBeAFile(this.fileSystem);
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileName);

            string fileNameLink       = "InsideRepo_RepoLink.txt";
            string fileLinkInsideRepo = this.Enlistment.GetVirtualPathTo(fileNameLink);

            this.fileSystem.CreateHardLink(fileLinkInsideRepo, fileInsideRepo);
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileName);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileNameLink);
            fileLinkInsideRepo.ShouldBeAFile(this.fileSystem);
        }
        public void CreateHardLinkTest()
        {
            string existingFileName = "fileToLinkTo.txt";
            string existingFilePath = this.Enlistment.GetVirtualPathTo(existingFileName);

            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, existingFileName);
            this.fileSystem.WriteAllText(existingFilePath, "Some content here");
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, existingFileName);
            existingFilePath.ShouldBeAFile(this.fileSystem).WithContents("Some content here");

            string newLinkFileName = "newHardLink.txt";
            string newLinkFilePath = this.Enlistment.GetVirtualPathTo(newLinkFileName);

            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, newLinkFileName);
            this.fileSystem.CreateHardLink(newLinkFilePath, existingFilePath);
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, newLinkFileName);
            newLinkFilePath.ShouldBeAFile(this.fileSystem).WithContents("Some content here");
        }
        public void SupersededFileAddedToModifiedPathsAndSkipWorktreeBitCleared()
        {
            string fileToSupersedeEntry = "GVFlt_FileOperationTest/WriteAndVerify.txt";
            string fileToSupersedePath  = this.Enlistment.GetVirtualPathTo("GVFlt_FileOperationTest\\WriteAndVerify.txt");

            this.VerifyWorktreeBit(fileToSupersedeEntry, LsFilesStatus.SkipWorktree);

            string newContent = $"{nameof(this.SupersededFileAddedToModifiedPathsAndSkipWorktreeBitCleared)} test new contents";

            SupersedeFile(fileToSupersedePath, newContent).ShouldEqual(true);
            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileToSupersedeEntry);

            // Verify skip-worktree cleared
            this.VerifyWorktreeBit(fileToSupersedeEntry, LsFilesStatus.Cached);

            // Verify new content written
            fileToSupersedePath.ShouldBeAFile(this.fileSystem).WithContents(newContent);
        }
        public void RenamedFileAndOverwrittenTargetAddedToModifiedPathsFile()
        {
            string fileToRenameEntry       = "Test_EPF_MoveRenameFileTests_2/MoveUnhydratedFileToOverwriteUnhydratedFileAndWrite/RunUnitTests.bat";
            string fileToRenameTargetEntry = "Test_EPF_MoveRenameFileTests_2/MoveUnhydratedFileToOverwriteUnhydratedFileAndWrite/RunFunctionalTests.bat";

            this.VerifyWorktreeBit(fileToRenameEntry, LsFilesStatus.SkipWorktree);
            this.VerifyWorktreeBit(fileToRenameTargetEntry, LsFilesStatus.SkipWorktree);

            this.fileSystem.ReplaceFile(
                this.Enlistment.GetVirtualPathTo(fileToRenameEntry),
                this.Enlistment.GetVirtualPathTo(fileToRenameTargetEntry));
            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileToRenameEntry);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileToRenameTargetEntry);

            // Verify skip-worktree cleared
            this.VerifyWorktreeBit(fileToRenameEntry, LsFilesStatus.Cached);
            this.VerifyWorktreeBit(fileToRenameTargetEntry, LsFilesStatus.Cached);
        }
        public void CaseOnlyRenameOfNewFolderKeepsModifiedPathsEntries()
        {
            if (this.fileSystem is PowerShellRunner)
            {
                Assert.Ignore("Powershell does not support case only renames.");
            }

            this.fileSystem.CreateDirectory(Path.Combine(this.Enlistment.RepoRoot, "Folder"));
            this.fileSystem.CreateEmptyFile(Path.Combine(this.Enlistment.RepoRoot, "Folder", "testfile"));
            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, "Folder/");
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, "Folder/testfile");

            this.fileSystem.RenameDirectory(this.Enlistment.RepoRoot, "Folder", "folder");
            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, "folder/");
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, "folder/testfile");
        }
Exemple #23
0
        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 FileMovedFromInsideRepoToOutside()
        {
            string fileInsideRepoEntry = "GitCommandsTests/RenameFileTests/1/#test";
            string fileNameFullPath    = Path.Combine("GitCommandsTests", "RenameFileTests", "1", "#test");
            string fileInsideRepo      = this.Enlistment.GetVirtualPathTo(fileNameFullPath);

            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, fileInsideRepoEntry);

            string fileNameOutsideRepo  = "FileNameOutSideRepo";
            string fileMovedOutsideRepo = Path.Combine(this.Enlistment.EnlistmentRoot, fileNameOutsideRepo);

            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, fileNameOutsideRepo);

            this.fileSystem.MoveFile(fileInsideRepo, fileMovedOutsideRepo);

            fileInsideRepo.ShouldNotExistOnDisk(this.fileSystem);
            fileMovedOutsideRepo.ShouldBeAFile(this.fileSystem);
            this.fileSystem.ReadAllText(fileMovedOutsideRepo).ShouldContain("test");
            this.Enlistment.WaitForBackgroundOperations();
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, fileInsideRepoEntry);
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, fileNameOutsideRepo);
        }
        public void RenameFolderTest()
        {
            string folderName        = "folder4a";
            string renamedFolderName = "folder4b";

            string[] fileNames = { "a", "b", "c" };
            string[] expectedModifiedEntries =
            {
                renamedFolderName + "/",
            };

            string[] unexpectedModifiedEntries =
            {
                renamedFolderName + "/" + fileNames[0],
                renamedFolderName + "/" + fileNames[1],
                renamedFolderName + "/" + fileNames[2],
                folderName + "/",
                folderName + "/" + fileNames[0],
                folderName + "/" + fileNames[1],
                folderName + "/" + fileNames[2],
            };

            this.Enlistment.GetVirtualPathTo(folderName).ShouldNotExistOnDisk(this.fileSystem);
            this.fileSystem.CreateDirectory(this.Enlistment.GetVirtualPathTo(folderName));
            foreach (string fileName in fileNames)
            {
                string filePath = Path.Combine(folderName, fileName);
                this.fileSystem.CreateEmptyFile(this.Enlistment.GetVirtualPathTo(filePath));
                this.Enlistment.GetVirtualPathTo(filePath).ShouldBeAFile(this.fileSystem);
            }

            this.fileSystem.MoveDirectory(this.Enlistment.GetVirtualPathTo(folderName), this.Enlistment.GetVirtualPathTo(renamedFolderName));

            this.Enlistment.WaitForBackgroundOperations();

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, expectedModifiedEntries);
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.fileSystem, unexpectedModifiedEntries);
        }
        public void LockToPreventUpdate_MultipleFiles()
        {
            string testFile2Contents = "Commit2LockToPreventUpdate2 \r\n";
            string testFile3Contents = "Commit2LockToPreventUpdate3 \r\n";
            string testFile4Contents = "Commit2LockToPreventUpdate4 \r\n";

            string testFile2OldContents = "TestFileLockToPreventUpdate2 \r\n";
            string testFile3OldContents = "TestFileLockToPreventUpdate3 \r\n";
            string testFile4OldContents = "TestFileLockToPreventUpdate4 \r\n";

            string testFile2Name = "test2.txt";
            string testFile3Name = "test3.txt";
            string testFile4Name = "test4.txt";

            string testFile2Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestParentFolderName, "LockToPreventUpdate", testFile2Name));
            string testFile3Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestParentFolderName, "LockToPreventUpdate", testFile3Name));
            string testFile4Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestParentFolderName, "LockToPreventUpdate", testFile4Name));

            testFile2Path.ShouldBeAFile(this.fileSystem).WithContents(testFile2Contents);
            testFile3Path.ShouldBeAFile(this.fileSystem).WithContents(testFile3Contents);
            testFile4Path.ShouldBeAFile(this.fileSystem).WithContents(testFile4Contents);

            using (SafeFileHandle testFile2Handle = this.CreateFile(testFile2Path, FileShare.Read))
                using (SafeFileHandle testFile3Handle = this.CreateFile(testFile3Path, FileShare.Read))
                    using (SafeFileHandle testFile4Handle = this.CreateFile(testFile4Path, FileShare.Read))
                    {
                        testFile2Handle.IsInvalid.ShouldEqual(false);
                        testFile3Handle.IsInvalid.ShouldEqual(false);
                        testFile4Handle.IsInvalid.ShouldEqual(false);

                        ProcessResult result = this.InvokeGitAgainstGSDRepo("checkout " + OldCommitId);
                        result.Errors.ShouldContain(
                            "GSD was unable to update the following files. To recover, close all handles to the files and run these commands:",
                            "git checkout -- " + TestParentFolderName + "/LockToPreventUpdate/" + testFile2Name,
                            "git checkout -- " + TestParentFolderName + "/LockToPreventUpdate/" + testFile3Name,
                            "git checkout -- " + TestParentFolderName + "/LockToPreventUpdate/" + testFile4Name);

                        GitHelpers.CheckGitCommandAgainstGSDRepo(
                            this.Enlistment.RepoRoot,
                            "status",
                            "HEAD detached at " + OldCommitId,
                            "Changes not staged for commit:",
                            TestParentFolderName + "/LockToPreventUpdate/" + testFile2Name,
                            TestParentFolderName + "/LockToPreventUpdate/" + testFile3Name,
                            TestParentFolderName + "/LockToPreventUpdate/" + testFile4Name);
                    }

            this.GitCheckoutToDiscardChanges(TestParentFolderName + "/LockToPreventUpdate/" + testFile2Name);
            this.GitCheckoutToDiscardChanges(TestParentFolderName + "/LockToPreventUpdate/" + testFile3Name);
            this.GitCheckoutToDiscardChanges(TestParentFolderName + "/LockToPreventUpdate/" + testFile4Name);

            this.GitStatusShouldBeClean(OldCommitId);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, TestParentFolderName + "/LockToPreventUpdate/" + testFile2Name);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, TestParentFolderName + "/LockToPreventUpdate/" + testFile3Name);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, TestParentFolderName + "/LockToPreventUpdate/" + testFile4Name);
            testFile2Path.ShouldBeAFile(this.fileSystem).WithContents(testFile2OldContents);
            testFile3Path.ShouldBeAFile(this.fileSystem).WithContents(testFile3OldContents);
            testFile4Path.ShouldBeAFile(this.fileSystem).WithContents(testFile4OldContents);

            this.GitCheckoutCommitId(NewFilesAndChangesCommitId);

            this.GitStatusShouldBeClean(NewFilesAndChangesCommitId);
            testFile2Path.ShouldBeAFile(this.fileSystem).WithContents(testFile2Contents);
            testFile3Path.ShouldBeAFile(this.fileSystem).WithContents(testFile3Contents);
            testFile4Path.ShouldBeAFile(this.fileSystem).WithContents(testFile4Contents);
        }
        public void LockToPreventUpdateAndDelete()
        {
            string testFileUpdate1Contents = "Commit2LockToPreventUpdateAndDelete \r\n";
            string testFileUpdate2Contents = "Commit2LockToPreventUpdateAndDelete2 \r\n";
            string testFileUpdate3Contents = "Commit2LockToPreventUpdateAndDelete3 \r\n";
            string testFileDelete1Contents = "PreventDelete \r\n";
            string testFileDelete2Contents = "PreventDelete2 \r\n";
            string testFileDelete3Contents = "PreventDelete3 \r\n";

            string testFileUpdate1OldContents = "TestFileLockToPreventUpdateAndDelete \r\n";
            string testFileUpdate2OldContents = "TestFileLockToPreventUpdateAndDelete2 \r\n";
            string testFileUpdate3OldContents = "TestFileLockToPreventUpdateAndDelete3 \r\n";

            string testFileUpdate1Name = "test.txt";
            string testFileUpdate2Name = "test2.txt";
            string testFileUpdate3Name = "test3.txt";
            string testFileDelete1Name = "test_delete.txt";
            string testFileDelete2Name = "test_delete2.txt";
            string testFileDelete3Name = "test_delete3.txt";

            string testFileUpdate1Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestParentFolderName, "LockToPreventUpdateAndDelete", testFileUpdate1Name));
            string testFileUpdate2Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestParentFolderName, "LockToPreventUpdateAndDelete", testFileUpdate2Name));
            string testFileUpdate3Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestParentFolderName, "LockToPreventUpdateAndDelete", testFileUpdate3Name));
            string testFileDelete1Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestParentFolderName, "LockToPreventUpdateAndDelete", testFileDelete1Name));
            string testFileDelete2Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestParentFolderName, "LockToPreventUpdateAndDelete", testFileDelete2Name));
            string testFileDelete3Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestParentFolderName, "LockToPreventUpdateAndDelete", testFileDelete3Name));

            testFileUpdate1Path.ShouldBeAFile(this.fileSystem).WithContents(testFileUpdate1Contents);
            testFileUpdate2Path.ShouldBeAFile(this.fileSystem).WithContents(testFileUpdate2Contents);
            testFileUpdate3Path.ShouldBeAFile(this.fileSystem).WithContents(testFileUpdate3Contents);
            testFileDelete1Path.ShouldBeAFile(this.fileSystem).WithContents(testFileDelete1Contents);
            testFileDelete2Path.ShouldBeAFile(this.fileSystem).WithContents(testFileDelete2Contents);
            testFileDelete3Path.ShouldBeAFile(this.fileSystem).WithContents(testFileDelete3Contents);

            using (SafeFileHandle testFileUpdate1Handle = this.CreateFile(testFileUpdate1Path, FileShare.Read))
                using (SafeFileHandle testFileUpdate2Handle = this.CreateFile(testFileUpdate2Path, FileShare.Read))
                    using (SafeFileHandle testFileUpdate3Handle = this.CreateFile(testFileUpdate3Path, FileShare.Read))
                        using (SafeFileHandle testFileDelete1Handle = this.CreateFile(testFileDelete1Path, FileShare.Read))
                            using (SafeFileHandle testFileDelete2Handle = this.CreateFile(testFileDelete2Path, FileShare.Read))
                                using (SafeFileHandle testFileDelete3Handle = this.CreateFile(testFileDelete3Path, FileShare.Read))
                                {
                                    testFileUpdate1Handle.IsInvalid.ShouldEqual(false);
                                    testFileUpdate2Handle.IsInvalid.ShouldEqual(false);
                                    testFileUpdate3Handle.IsInvalid.ShouldEqual(false);
                                    testFileDelete1Handle.IsInvalid.ShouldEqual(false);
                                    testFileDelete2Handle.IsInvalid.ShouldEqual(false);
                                    testFileDelete3Handle.IsInvalid.ShouldEqual(false);

                                    ProcessResult checkoutResult = GitProcess.InvokeProcess(this.Enlistment.RepoRoot, "checkout " + OldCommitId);
                                    checkoutResult.Errors.ShouldContain(
                                        "HEAD is now at " + OldCommitId,
                                        "GSD was unable to delete the following files. To recover, close all handles to the files and run these commands:",
                                        "git clean -f " + TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileDelete1Name,
                                        "git clean -f " + TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileDelete2Name,
                                        "git clean -f " + TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileDelete3Name,
                                        "GSD was unable to update the following files. To recover, close all handles to the files and run these commands:",
                                        "git checkout -- " + TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileUpdate1Name,
                                        "git checkout -- " + TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileUpdate2Name,
                                        "git checkout -- " + TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileUpdate3Name);

                                    GitHelpers.CheckGitCommandAgainstGSDRepo(
                                        this.Enlistment.RepoRoot,
                                        "status",
                                        "HEAD detached at " + OldCommitId,
                                        "modified:   Test_EPF_UpdatePlaceholderTests/LockToPreventUpdateAndDelete/test.txt",
                                        "modified:   Test_EPF_UpdatePlaceholderTests/LockToPreventUpdateAndDelete/test2.txt",
                                        "modified:   Test_EPF_UpdatePlaceholderTests/LockToPreventUpdateAndDelete/test3.txt",
                                        "Untracked files:\n  (use \"git add <file>...\" to include in what will be committed)\n\n\tTest_EPF_UpdatePlaceholderTests/LockToPreventUpdateAndDelete/test_delete.txt\n\tTest_EPF_UpdatePlaceholderTests/LockToPreventUpdateAndDelete/test_delete2.txt\n\tTest_EPF_UpdatePlaceholderTests/LockToPreventUpdateAndDelete/test_delete3.txt",
                                        "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n");
                                }

            this.GitCheckoutToDiscardChanges(TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileUpdate1Name);
            this.GitCheckoutToDiscardChanges(TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileUpdate2Name);
            this.GitCheckoutToDiscardChanges(TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileUpdate3Name);
            this.GitCleanFile(TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileDelete1Name);
            this.GitCleanFile(TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileDelete2Name);
            this.GitCleanFile(TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileDelete3Name);

            this.GitStatusShouldBeClean(OldCommitId);

            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileUpdate1Name);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileUpdate2Name);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileUpdate3Name);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileDelete1Name);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileDelete2Name);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.fileSystem, TestParentFolderName + "/LockToPreventUpdateAndDelete/" + testFileDelete3Name);

            testFileUpdate1Path.ShouldBeAFile(this.fileSystem).WithContents(testFileUpdate1OldContents);
            testFileUpdate2Path.ShouldBeAFile(this.fileSystem).WithContents(testFileUpdate2OldContents);
            testFileUpdate3Path.ShouldBeAFile(this.fileSystem).WithContents(testFileUpdate3OldContents);
            testFileDelete1Path.ShouldNotExistOnDisk(this.fileSystem);
            testFileDelete2Path.ShouldNotExistOnDisk(this.fileSystem);
            testFileDelete3Path.ShouldNotExistOnDisk(this.fileSystem);

            this.GitCheckoutCommitId(NewFilesAndChangesCommitId);

            this.GitStatusShouldBeClean(NewFilesAndChangesCommitId);
            testFileUpdate1Path.ShouldBeAFile(this.fileSystem).WithContents(testFileUpdate1Contents);
            testFileUpdate2Path.ShouldBeAFile(this.fileSystem).WithContents(testFileUpdate2Contents);
            testFileUpdate3Path.ShouldBeAFile(this.fileSystem).WithContents(testFileUpdate3Contents);
            testFileDelete1Path.ShouldBeAFile(this.fileSystem).WithContents(testFileDelete1Contents);
            testFileDelete2Path.ShouldBeAFile(this.fileSystem).WithContents(testFileDelete2Contents);
            testFileDelete3Path.ShouldBeAFile(this.fileSystem).WithContents(testFileDelete3Contents);
        }