private string CreateFile(FileSystemRunner fileSystem, string relativePath)
        {
            string tempFile = this.Enlistment.GetVirtualPathTo(relativePath);

            fileSystem.WriteAllText(tempFile, $"Contents for the {relativePath} file");
            tempFile.ShouldBeAFile(fileSystem);
            return(tempFile);
        }
Beispiel #2
0
        public void CaseRenameFoldersAndRemountAndReanmeAgain(FileSystemRunner fileSystem)
        {
            // Projected folder without a physical folder
            string parentFolderName     = "GVFS";
            string oldGVFSSubFolderName = "GVFS";
            string oldGVFSSubFolderPath = Path.Combine(parentFolderName, oldGVFSSubFolderName);
            string newGVFSSubFolderName = "gvfs";
            string newGVFSSubFolderPath = Path.Combine(parentFolderName, newGVFSSubFolderName);

            this.Enlistment.GetVirtualPathTo(oldGVFSSubFolderPath).ShouldBeADirectory(fileSystem).WithCaseMatchingName(oldGVFSSubFolderName);

            // Use NativeMethods rather than the runner as it supports case-only rename
            NativeMethods.MoveFile(this.Enlistment.GetVirtualPathTo(oldGVFSSubFolderPath), this.Enlistment.GetVirtualPathTo(newGVFSSubFolderPath));

            this.Enlistment.GetVirtualPathTo(newGVFSSubFolderPath).ShouldBeADirectory(fileSystem).WithCaseMatchingName(newGVFSSubFolderName);

            // Projected folder with a physical folder
            string oldTestsSubFolderName = "GVFS.FunctionalTests";
            string oldTestsSubFolderPath = Path.Combine(parentFolderName, oldTestsSubFolderName);
            string newTestsSubFolderName = "gvfs.functionaltests";
            string newTestsSubFolderPath = Path.Combine(parentFolderName, newTestsSubFolderName);

            string fileToAdd        = "NewFile.txt";
            string fileToAddContent = "This is new file text.";
            string fileToAddPath    = this.Enlistment.GetVirtualPathTo(Path.Combine(oldTestsSubFolderPath, fileToAdd));

            fileSystem.WriteAllText(fileToAddPath, fileToAddContent);

            this.Enlistment.GetVirtualPathTo(oldTestsSubFolderPath).ShouldBeADirectory(fileSystem).WithCaseMatchingName(oldTestsSubFolderName);

            // Use NativeMethods rather than the runner as it supports case-only rename
            NativeMethods.MoveFile(this.Enlistment.GetVirtualPathTo(oldTestsSubFolderPath), this.Enlistment.GetVirtualPathTo(newTestsSubFolderPath));

            this.Enlistment.GetVirtualPathTo(newTestsSubFolderPath).ShouldBeADirectory(fileSystem).WithCaseMatchingName(newTestsSubFolderName);

            // Remount
            this.Enlistment.UnmountGVFS();
            this.Enlistment.MountGVFS();

            this.Enlistment.GetVirtualPathTo(newGVFSSubFolderPath).ShouldBeADirectory(fileSystem).WithCaseMatchingName(newGVFSSubFolderName);
            this.Enlistment.GetVirtualPathTo(newTestsSubFolderPath).ShouldBeADirectory(fileSystem).WithCaseMatchingName(newTestsSubFolderName);
            this.Enlistment.GetVirtualPathTo(Path.Combine(newTestsSubFolderPath, fileToAdd)).ShouldBeAFile(fileSystem).WithContents().ShouldEqual(fileToAddContent);

            // Rename each folder again
            string finalGVFSSubFolderName = "gvFS";
            string finalGVFSSubFolderPath = Path.Combine(parentFolderName, finalGVFSSubFolderName);

            NativeMethods.MoveFile(this.Enlistment.GetVirtualPathTo(newGVFSSubFolderPath), this.Enlistment.GetVirtualPathTo(finalGVFSSubFolderPath));
            this.Enlistment.GetVirtualPathTo(finalGVFSSubFolderPath).ShouldBeADirectory(fileSystem).WithCaseMatchingName(finalGVFSSubFolderName);

            string finalTestsSubFolderName = "gvfs.FunctionalTESTS";
            string finalTestsSubFolderPath = Path.Combine(parentFolderName, finalTestsSubFolderName);

            NativeMethods.MoveFile(this.Enlistment.GetVirtualPathTo(newTestsSubFolderPath), this.Enlistment.GetVirtualPathTo(finalTestsSubFolderPath));
            this.Enlistment.GetVirtualPathTo(finalTestsSubFolderPath).ShouldBeADirectory(fileSystem).WithCaseMatchingName(finalTestsSubFolderName);
            this.Enlistment.GetVirtualPathTo(Path.Combine(finalTestsSubFolderPath, fileToAdd)).ShouldBeAFile(fileSystem).WithContents().ShouldEqual(fileToAddContent);
        }
        public void ModifiedPathsCorrectAfterHardLinking(FileSystemRunner fileSystem)
        {
            string[] expectedModifiedFilesContentsAfterHardlinks =
            {
                "A .gitattributes",
                "A LinkToReadme.md",
                "A LinkToFileOutsideSrc.txt",
                "A Readme.md",
                "A GVFS/GVFS/Program.cs",
            };

            // Create a link from src\LinkToReadme.md to src\Readme.md
            string existingFileInRepoPath = this.Enlistment.GetVirtualPathTo("Readme.md");
            string contents = existingFileInRepoPath.ShouldBeAFile(fileSystem).WithContents();
            string hardLinkToFileInRepoPath = this.Enlistment.GetVirtualPathTo("LinkToReadme.md");

            hardLinkToFileInRepoPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.CreateHardLink(hardLinkToFileInRepoPath, existingFileInRepoPath);
            hardLinkToFileInRepoPath.ShouldBeAFile(fileSystem).WithContents(contents);

            // Create a link from src\LinkToFileOutsideSrc.txt to FileOutsideRepo.txt
            string fileOutsideOfRepoPath     = Path.Combine(this.Enlistment.EnlistmentRoot, "FileOutsideRepo.txt");
            string fileOutsideOfRepoContents = "File outside of repo";

            fileOutsideOfRepoPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.WriteAllText(fileOutsideOfRepoPath, fileOutsideOfRepoContents);
            string hardLinkToFileOutsideRepoPath = this.Enlistment.GetVirtualPathTo("LinkToFileOutsideSrc.txt");

            hardLinkToFileOutsideRepoPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.CreateHardLink(hardLinkToFileOutsideRepoPath, fileOutsideOfRepoPath);
            hardLinkToFileOutsideRepoPath.ShouldBeAFile(fileSystem).WithContents(fileOutsideOfRepoContents);

            // Create a link from LinkOutsideSrcToInsideSrc.cs to src\GVFS\GVFS\Program.cs
            string secondFileInRepoPath = this.Enlistment.GetVirtualPathTo("GVFS", "GVFS", "Program.cs");

            contents = secondFileInRepoPath.ShouldBeAFile(fileSystem).WithContents();
            string hardLinkOutsideRepoToFileInRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, "LinkOutsideSrcToInsideSrc.cs");

            hardLinkOutsideRepoToFileInRepoPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.CreateHardLink(hardLinkOutsideRepoToFileInRepoPath, secondFileInRepoPath);
            hardLinkOutsideRepoToFileInRepoPath.ShouldBeAFile(fileSystem).WithContents(contents);

            this.Enlistment.WaitForBackgroundOperations();

            string modifiedPathsDatabase = Path.Combine(this.Enlistment.DotGVFSRoot, TestConstants.Databases.ModifiedPaths);

            modifiedPathsDatabase.ShouldBeAFile(fileSystem);
            using (StreamReader reader = new StreamReader(File.Open(modifiedPathsDatabase, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                reader.ReadToEnd().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).OrderBy(x => x)
                .ShouldMatchInOrder(expectedModifiedFilesContentsAfterHardlinks.OrderBy(x => x));
            }
        }
Beispiel #4
0
        public void ModifiedPathsCorrectAfterHardLinking(FileSystemRunner fileSystem)
        {
            const string ExpectedModifiedFilesContentsAfterHardlinks =
                @"A .gitattributes
A LinkToReadme.md
A LinkToFileOutsideSrc.txt
";

            // Create a link from src\LinkToReadme.md to src\Readme.md
            string existingFileInRepoPath = this.Enlistment.GetVirtualPathTo("Readme.md");
            string contents = existingFileInRepoPath.ShouldBeAFile(fileSystem).WithContents();
            string hardLinkToFileInRepoPath = this.Enlistment.GetVirtualPathTo("LinkToReadme.md");

            hardLinkToFileInRepoPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.CreateHardLink(hardLinkToFileInRepoPath, existingFileInRepoPath);
            hardLinkToFileInRepoPath.ShouldBeAFile(fileSystem).WithContents(contents);

            // Create a link from src\LinkToFileOutsideSrc.txt to FileOutsideRepo.txt
            string fileOutsideOfRepoPath     = Path.Combine(this.Enlistment.EnlistmentRoot, "FileOutsideRepo.txt");
            string fileOutsideOfRepoContents = "File outside of repo";

            fileOutsideOfRepoPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.WriteAllText(fileOutsideOfRepoPath, fileOutsideOfRepoContents);
            string hardLinkToFileOutsideRepoPath = this.Enlistment.GetVirtualPathTo("LinkToFileOutsideSrc.txt");

            hardLinkToFileOutsideRepoPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.CreateHardLink(hardLinkToFileOutsideRepoPath, fileOutsideOfRepoPath);
            hardLinkToFileOutsideRepoPath.ShouldBeAFile(fileSystem).WithContents(fileOutsideOfRepoContents);

            // Create a link from LinkOutsideSrcToInsideSrc.cs to src\GVFS\GVFS\Program.cs
            string secondFileInRepoPath = this.Enlistment.GetVirtualPathTo("GVFS", "GVFS", "Program.cs");

            contents = secondFileInRepoPath.ShouldBeAFile(fileSystem).WithContents();
            string hardLinkOutsideRepoToFileInRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, "LinkOutsideSrcToInsideSrc.cs");

            hardLinkOutsideRepoToFileInRepoPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.CreateHardLink(hardLinkOutsideRepoToFileInRepoPath, secondFileInRepoPath);
            hardLinkOutsideRepoToFileInRepoPath.ShouldBeAFile(fileSystem).WithContents(contents);

            string modifiedPathsDatabase = Path.Combine(this.Enlistment.DotGVFSRoot, TestConstants.Databases.ModifiedPaths);

            modifiedPathsDatabase.ShouldBeAFile(fileSystem);
            using (StreamReader reader = new StreamReader(File.Open(modifiedPathsDatabase, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                reader.ReadToEnd().ShouldEqual(ExpectedModifiedFilesContentsAfterHardlinks);
            }
        }
Beispiel #5
0
        public void ExcludeSparseFileSavedAfterRemount(FileSystemRunner fileSystem)
        {
            string fileToAdd = this.Enlistment.GetVirtualPathTo(FileToAdd);

            fileSystem.WriteAllText(fileToAdd, "Contents for the new file");

            string fileToUpdate = this.Enlistment.GetVirtualPathTo(FileToUpdate);

            fileSystem.AppendAllText(fileToUpdate, "// Testing");

            string fileToDelete = this.Enlistment.GetVirtualPathTo(FileToDelete);

            fileSystem.DeleteFile(fileToDelete);

            string folderToCreate = this.Enlistment.GetVirtualPathTo(FolderToCreate);

            fileSystem.CreateDirectory(folderToCreate);

            // Remount
            this.Enlistment.UnmountGVFS();
            this.Enlistment.MountGVFS();

            string excludeFile         = this.Enlistment.GetVirtualPathTo(ExcludeFilePath);
            string excludeFileContents = excludeFile.ShouldBeAFile(fileSystem).WithContents();

            excludeFileContents.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
            .Where(x => !x.StartsWith("#"))     // Exclude comments
            .OrderBy(x => x)
            .ShouldMatchInOrder(expectedExcludeFileContents.OrderBy(x => x));

            string sparseFile = this.Enlistment.GetVirtualPathTo(SparseCheckoutFilePath);

            sparseFile.ShouldBeAFile(fileSystem).WithContents()
            .Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
            .Where(x => expectedSparseFileContents.Contains(x))     // Exclude extra entries for files hydrated during test
            .OrderBy(x => x)
            .ShouldMatchInOrder(expectedSparseFileContents.OrderBy(x => x));
        }
        public void ModifiedPathsSavedAfterRemount(FileSystemRunner fileSystem)
        {
            string fileToAdd = this.Enlistment.GetVirtualPathTo(FileToAdd);

            fileSystem.WriteAllText(fileToAdd, "Contents for the new file");

            string fileToUpdate = this.Enlistment.GetVirtualPathTo(FileToUpdate);

            fileSystem.AppendAllText(fileToUpdate, "// Testing");

            string fileToDelete = this.Enlistment.GetVirtualPathTo(FileToDelete);

            fileSystem.DeleteFile(fileToDelete);
            fileToDelete.ShouldNotExistOnDisk(fileSystem);

            string fileToRename = this.Enlistment.GetVirtualPathTo(FileToRename);

            fileSystem.MoveFile(fileToRename, this.Enlistment.GetVirtualPathTo(RenameFileTarget));

            string folderToCreate = this.Enlistment.GetVirtualPathTo(FolderToCreate);

            fileSystem.CreateDirectory(folderToCreate);

            string folderToRename = this.Enlistment.GetVirtualPathTo(FolderToRename);

            fileSystem.CreateDirectory(folderToRename);
            string folderToRenameTarget = this.Enlistment.GetVirtualPathTo(RenameFolderTarget);

            fileSystem.MoveDirectory(folderToRename, folderToRenameTarget);

            // Moving the new folder out of the repo will remove it from the modified paths file
            string folderTargetOutsideSrc = Path.Combine(this.Enlistment.EnlistmentRoot, RenameFolderTarget);

            folderTargetOutsideSrc.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveDirectory(folderToRenameTarget, folderTargetOutsideSrc);
            folderTargetOutsideSrc.ShouldBeADirectory(fileSystem);
            folderToRenameTarget.ShouldNotExistOnDisk(fileSystem);

            // Moving a file from the .git folder to the working directory should add the file to the modified paths
            string dotGitfileToAdd = this.Enlistment.GetVirtualPathTo(DotGitFileToCreate);

            fileSystem.WriteAllText(dotGitfileToAdd, "Contents for the new file in dot git");
            fileSystem.MoveFile(dotGitfileToAdd, this.Enlistment.GetVirtualPathTo(RenameNewDotGitFileTarget));

            // Move a file from outside of src into src
            string fileToCreateOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, FileToCreateOutsideRepo);

            fileSystem.WriteAllText(fileToCreateOutsideRepoPath, "Contents for the new file outside of repo");
            string fileToCreateOutsideRepoTargetPath = this.Enlistment.GetVirtualPathTo(FileToCreateOutsideRepo);

            fileToCreateOutsideRepoTargetPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveFile(fileToCreateOutsideRepoPath, fileToCreateOutsideRepoTargetPath);
            fileToCreateOutsideRepoTargetPath.ShouldBeAFile(fileSystem);
            fileToCreateOutsideRepoPath.ShouldNotExistOnDisk(fileSystem);

            // Move a folder from outside of src into src
            string folderToCreateOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, FolderToCreateOutsideRepo);

            fileSystem.CreateDirectory(folderToCreateOutsideRepoPath);
            folderToCreateOutsideRepoPath.ShouldBeADirectory(fileSystem);
            string folderToCreateOutsideRepoTargetPath = this.Enlistment.GetVirtualPathTo(FolderToCreateOutsideRepo);

            folderToCreateOutsideRepoTargetPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveDirectory(folderToCreateOutsideRepoPath, folderToCreateOutsideRepoTargetPath);
            folderToCreateOutsideRepoTargetPath.ShouldBeADirectory(fileSystem);
            folderToCreateOutsideRepoPath.ShouldNotExistOnDisk(fileSystem);

            string folderToDeleteFullPath = this.Enlistment.GetVirtualPathTo(FolderToDelete);

            fileSystem.WriteAllText(Path.Combine(folderToDeleteFullPath, "NewFile.txt"), "Contents for new file");
            string newFileToDelete = Path.Combine(folderToDeleteFullPath, "NewFileToDelete.txt");

            fileSystem.WriteAllText(newFileToDelete, "Contents for new file");
            fileSystem.DeleteFile(newFileToDelete);
            fileSystem.WriteAllText(Path.Combine(folderToDeleteFullPath, "CreateCommonVersionHeader.bat"), "Changing the file contents");
            fileSystem.DeleteFile(Path.Combine(folderToDeleteFullPath, "RunUnitTests.bat"));

            fileSystem.DeleteDirectory(folderToDeleteFullPath);
            folderToDeleteFullPath.ShouldNotExistOnDisk(fileSystem);

            // Remount
            this.Enlistment.UnmountGVFS();
            this.Enlistment.MountGVFS();

            this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete.");

            string modifiedPathsDatabase = Path.Combine(this.Enlistment.DotGVFSRoot, TestConstants.Databases.ModifiedPaths);

            modifiedPathsDatabase.ShouldBeAFile(fileSystem);
            using (StreamReader reader = new StreamReader(File.Open(modifiedPathsDatabase, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                reader.ReadToEnd().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).OrderBy(x => x)
                .ShouldMatchInOrder(ExpectedModifiedFilesContentsAfterRemount.OrderBy(x => x));
            }
        }
        public void ExcludeSparseFileSavedAfterRemount(FileSystemRunner fileSystem)
        {
            string fileToAdd = this.Enlistment.GetVirtualPathTo(FileToAdd);

            fileSystem.WriteAllText(fileToAdd, "Contents for the new file");

            string fileToUpdate = this.Enlistment.GetVirtualPathTo(FileToUpdate);

            fileSystem.AppendAllText(fileToUpdate, "// Testing");

            string fileToDelete = this.Enlistment.GetVirtualPathTo(FileToDelete);

            fileSystem.DeleteFile(fileToDelete);

            string fileToRename = this.Enlistment.GetVirtualPathTo(FileToRename);

            fileSystem.MoveFile(fileToRename, this.Enlistment.GetVirtualPathTo(RenameFileTarget));

            string folderToCreate = this.Enlistment.GetVirtualPathTo(FolderToCreate);

            fileSystem.CreateDirectory(folderToCreate);

            string folderToRename = this.Enlistment.GetVirtualPathTo(FolderToRename);

            fileSystem.CreateDirectory(folderToRename);
            string folderToRenameTarget = this.Enlistment.GetVirtualPathTo(RenameFolderTarget);

            fileSystem.MoveDirectory(folderToRename, folderToRenameTarget);

            // Moving the new folder out of the repo should not change the always exclude file
            string folderTargetOutsideSrc = Path.Combine(this.Enlistment.EnlistmentRoot, RenameFolderTarget);

            folderTargetOutsideSrc.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveDirectory(folderToRenameTarget, folderTargetOutsideSrc);
            folderTargetOutsideSrc.ShouldBeADirectory(fileSystem);

            // Moving a file from the .git folder to the working directory should add the file to the sparse-checkout
            string dotGitfileToAdd = this.Enlistment.GetVirtualPathTo(DotGitFileToCreate);

            fileSystem.WriteAllText(dotGitfileToAdd, "Contents for the new file in dot git");
            fileSystem.MoveFile(dotGitfileToAdd, this.Enlistment.GetVirtualPathTo(RenameNewDotGitFileTarget));

            // Move a file from outside of src into src
            string fileToCreateOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, FileToCreateOutsideRepo);

            fileSystem.WriteAllText(fileToCreateOutsideRepoPath, "Contents for the new file outside of repo");
            string fileToCreateOutsideRepoTargetPath = this.Enlistment.GetVirtualPathTo(FileToCreateOutsideRepo);

            fileToCreateOutsideRepoTargetPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveFile(fileToCreateOutsideRepoPath, fileToCreateOutsideRepoTargetPath);
            fileToCreateOutsideRepoTargetPath.ShouldBeAFile(fileSystem);

            // Move a folder from outside of src into src
            string folderToCreateOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, FolderToCreateOutsideRepo);

            fileSystem.CreateDirectory(folderToCreateOutsideRepoPath);
            folderToCreateOutsideRepoPath.ShouldBeADirectory(fileSystem);
            string folderToCreateOutsideRepoTargetPath = this.Enlistment.GetVirtualPathTo(FolderToCreateOutsideRepo);

            folderToCreateOutsideRepoTargetPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveDirectory(folderToCreateOutsideRepoPath, folderToCreateOutsideRepoTargetPath);
            folderToCreateOutsideRepoTargetPath.ShouldBeADirectory(fileSystem);

            // Remount
            this.Enlistment.UnmountGVFS();
            this.Enlistment.MountGVFS();

            this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete.");

            string alwaysExcludeFile         = this.Enlistment.GetVirtualPathTo(AlwaysExcludeFilePath);
            string alwaysExcludeFileContents = alwaysExcludeFile.ShouldBeAFile(fileSystem).WithContents();

            alwaysExcludeFileContents.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
            .Where(x => !x.StartsWith("#"))     // Exclude comments
            .OrderBy(x => x)
            .ShouldMatchInOrder(expectedAlwaysExcludeFileContents.OrderBy(x => x));

            string sparseFile         = this.Enlistment.GetVirtualPathTo(SparseCheckoutFilePath);
            string sparseFileContents = sparseFile.ShouldBeAFile(fileSystem).WithContents();

            sparseFileContents.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
            .Where(x => expectedSparseFileContents.Contains(x))     // Exclude extra entries for files hydrated during test
            .OrderBy(x => x)
            .ShouldMatchInOrder(expectedSparseFileContents.OrderBy(x => x));
        }
        public void PersistedDirectoryTests(FileSystemRunner fileSystem)
        {
            // Delete File Setup
            string deleteFileName = ".gitattributes";
            string deleteFilepath = this.Enlistment.GetVirtualPathTo(deleteFileName);

            fileSystem.DeleteFile(deleteFilepath);

            // Delete Folder Setup
            string deleteFolderName = "GVFS\\GVFS";
            string deleteFolderPath = this.Enlistment.GetVirtualPathTo(deleteFolderName);

            fileSystem.DeleteDirectory(deleteFolderPath);

            // Add File Setup
            string fileToAdd        = "NewFile.txt";
            string fileToAddContent = "This is new file text.";
            string fileToAddPath    = this.Enlistment.GetVirtualPathTo(fileToAdd);

            fileSystem.WriteAllText(fileToAddPath, fileToAddContent);

            // Add Folder Setup
            string directoryToAdd     = "NewDirectory";
            string directoryToAddPath = this.Enlistment.GetVirtualPathTo(directoryToAdd);

            fileSystem.CreateDirectory(directoryToAddPath);

            // Move File Setup
            string fileToMove        = this.Enlistment.GetVirtualPathTo("FileToMove.txt");
            string fileToMoveNewPath = this.Enlistment.GetVirtualPathTo("MovedFile.txt");
            string fileToMoveContent = "This is new file text.";

            fileSystem.WriteAllText(fileToMove, fileToMoveContent);
            fileSystem.MoveFile(fileToMove, fileToMoveNewPath);

            // Replace File Setup
            string fileToReplace           = this.Enlistment.GetVirtualPathTo("FileToReplace.txt");
            string fileToReplaceNewPath    = this.Enlistment.GetVirtualPathTo("ReplacedFile.txt");
            string fileToReplaceContent    = "This is new file text.";
            string fileToReplaceOldContent = "This is very different file text.";

            fileSystem.WriteAllText(fileToReplace, fileToReplaceContent);
            fileSystem.WriteAllText(fileToReplaceNewPath, fileToReplaceOldContent);
            fileSystem.ReplaceFile(fileToReplace, fileToReplaceNewPath);

            // MoveFolderPersistsOnRemount Setup
            string directoryToMove     = this.Enlistment.GetVirtualPathTo("MoveDirectory");
            string directoryMoveTarget = this.Enlistment.GetVirtualPathTo("MoveDirectoryTarget");
            string newDirectory        = Path.Combine(directoryMoveTarget, "MoveDirectory_renamed");
            string childFile           = Path.Combine(directoryToMove, "MoveFile.txt");
            string movedChildFile      = Path.Combine(newDirectory, "MoveFile.txt");
            string moveFileContents    = "This text file is getting moved";

            fileSystem.CreateDirectory(directoryToMove);
            fileSystem.CreateDirectory(directoryMoveTarget);
            fileSystem.WriteAllText(childFile, moveFileContents);
            fileSystem.MoveDirectory(directoryToMove, newDirectory);

            // NestedLoadAndWriteAfterMount Setup
            // Write a file to GVFS to ensure it has a physical folder
            string childFileToAdd        = "GVFS\\ChildFileToAdd.txt";
            string childFileToAddContent = "This is new child file in the GVFS folder.";
            string childFileToAddPath    = this.Enlistment.GetVirtualPathTo(childFileToAdd);

            fileSystem.WriteAllText(childFileToAddPath, childFileToAddContent);

            // Remount
            this.Enlistment.UnmountGVFS();
            this.Enlistment.MountGVFS();

            // Delete File Validation
            deleteFilepath.ShouldNotExistOnDisk(fileSystem);

            // Delete Folder Validation
            deleteFolderPath.ShouldNotExistOnDisk(fileSystem);

            // Add File Validation
            fileToAddPath.ShouldBeAFile(fileSystem).WithContents().ShouldEqual(fileToAddContent);

            // Add Folder Validation
            directoryToAddPath.ShouldBeADirectory(fileSystem);

            // Move File Validation
            fileToMove.ShouldNotExistOnDisk(fileSystem);
            fileToMoveNewPath.ShouldBeAFile(fileSystem).WithContents().ShouldEqual(fileToMoveContent);

            // Replace File Validation
            fileToReplace.ShouldNotExistOnDisk(fileSystem);
            fileToReplaceNewPath.ShouldBeAFile(fileSystem).WithContents().ShouldEqual(fileToReplaceContent);

            // MoveFolderPersistsOnRemount Validation
            directoryToMove.ShouldNotExistOnDisk(fileSystem);

            directoryMoveTarget.ShouldBeADirectory(fileSystem);
            newDirectory.ShouldBeADirectory(fileSystem);
            movedChildFile.ShouldBeAFile(fileSystem).WithContents().ShouldEqual(moveFileContents);

            // NestedLoadAndWriteAfterMount Validation
            childFileToAddPath.ShouldBeAFile(fileSystem).WithContents().ShouldEqual(childFileToAddContent);
            string childFolder     = "GVFS\\GVFS.FunctionalTests";
            string childFolderPath = this.Enlistment.GetVirtualPathTo(childFolder);

            childFolderPath.ShouldBeADirectory(fileSystem);
            string postMountChildFile        = "PostMountChildFile.txt";
            string postMountChildFileContent = "This is new child file added after the mount";
            string postMountChildFilePath    = this.Enlistment.GetVirtualPathTo(Path.Combine(childFolder, postMountChildFile));

            fileSystem.WriteAllText(postMountChildFilePath, postMountChildFileContent); // Verify we can create files in subfolders of GVFS
            postMountChildFilePath.ShouldBeAFile(fileSystem).WithContents().ShouldEqual(postMountChildFileContent);

            // 663045 - Ensure that folder can be deleted after a new file is added and GVFS is remounted
            fileSystem.DeleteDirectory(childFolderPath);
            childFolderPath.ShouldNotExistOnDisk(fileSystem);
        }
        public void ExcludeSparseFileSavedAfterRemount(FileSystemRunner fileSystem)
        {
            string fileToAdd = this.Enlistment.GetVirtualPathTo(FileToAdd);

            fileSystem.WriteAllText(fileToAdd, "Contents for the new file");

            string fileToUpdate = this.Enlistment.GetVirtualPathTo(FileToUpdate);

            fileSystem.AppendAllText(fileToUpdate, "// Testing");

            string fileToDelete = this.Enlistment.GetVirtualPathTo(FileToDelete);

            fileSystem.DeleteFile(fileToDelete);
            fileToDelete.ShouldNotExistOnDisk(fileSystem);

            string fileToRename = this.Enlistment.GetVirtualPathTo(FileToRename);

            fileSystem.MoveFile(fileToRename, this.Enlistment.GetVirtualPathTo(RenameFileTarget));

            string folderToCreate = this.Enlistment.GetVirtualPathTo(FolderToCreate);

            fileSystem.CreateDirectory(folderToCreate);

            string folderToRename = this.Enlistment.GetVirtualPathTo(FolderToRename);

            fileSystem.CreateDirectory(folderToRename);
            string folderToRenameTarget = this.Enlistment.GetVirtualPathTo(RenameFolderTarget);

            fileSystem.MoveDirectory(folderToRename, folderToRenameTarget);

            // Moving the new folder out of the repo should not change the always_exclude file
            string folderTargetOutsideSrc = Path.Combine(this.Enlistment.EnlistmentRoot, RenameFolderTarget);

            folderTargetOutsideSrc.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveDirectory(folderToRenameTarget, folderTargetOutsideSrc);
            folderTargetOutsideSrc.ShouldBeADirectory(fileSystem);
            folderToRenameTarget.ShouldNotExistOnDisk(fileSystem);

            // Moving a file from the .git folder to the working directory should add the file to the sparse-checkout
            string dotGitfileToAdd = this.Enlistment.GetVirtualPathTo(DotGitFileToCreate);

            fileSystem.WriteAllText(dotGitfileToAdd, "Contents for the new file in dot git");
            fileSystem.MoveFile(dotGitfileToAdd, this.Enlistment.GetVirtualPathTo(RenameNewDotGitFileTarget));

            // Move a file from outside of src into src
            string fileToCreateOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, FileToCreateOutsideRepo);

            fileSystem.WriteAllText(fileToCreateOutsideRepoPath, "Contents for the new file outside of repo");
            string fileToCreateOutsideRepoTargetPath = this.Enlistment.GetVirtualPathTo(FileToCreateOutsideRepo);

            fileToCreateOutsideRepoTargetPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveFile(fileToCreateOutsideRepoPath, fileToCreateOutsideRepoTargetPath);
            fileToCreateOutsideRepoTargetPath.ShouldBeAFile(fileSystem);
            fileToCreateOutsideRepoPath.ShouldNotExistOnDisk(fileSystem);

            // Move a folder from outside of src into src
            string folderToCreateOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, FolderToCreateOutsideRepo);

            fileSystem.CreateDirectory(folderToCreateOutsideRepoPath);
            folderToCreateOutsideRepoPath.ShouldBeADirectory(fileSystem);
            string folderToCreateOutsideRepoTargetPath = this.Enlistment.GetVirtualPathTo(FolderToCreateOutsideRepo);

            folderToCreateOutsideRepoTargetPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveDirectory(folderToCreateOutsideRepoPath, folderToCreateOutsideRepoTargetPath);
            folderToCreateOutsideRepoTargetPath.ShouldBeADirectory(fileSystem);
            folderToCreateOutsideRepoPath.ShouldNotExistOnDisk(fileSystem);

            string folderToDelete = this.Enlistment.GetVirtualPathTo(FolderToDelete);

            fileSystem.DeleteDirectory(folderToDelete);
            folderToDelete.ShouldNotExistOnDisk(fileSystem);

            // Remount
            this.Enlistment.UnmountGVFS();
            this.Enlistment.MountGVFS();

            this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete.");

            string modifiedPathsDatabase = Path.Combine(this.Enlistment.DotGVFSRoot, TestConstants.Databases.ModifiedPaths);

            modifiedPathsDatabase.ShouldBeAFile(fileSystem);
            using (StreamReader reader = new StreamReader(File.Open(modifiedPathsDatabase, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                reader.ReadToEnd().ShouldEqual(ExpectedModifiedFilesContents);
            }
        }
        public void ModifiedPathsFromChangesInsideRepoSavedAfterRemount(FileSystemRunner fileSystem)
        {
            string[] expectedModifiedFilesContentsAfterRemount =
            {
                @"A .gitattributes",
                $"A {GVFSHelpers.ConvertPathToGitFormat(FileToAdd)}",
                $"A {GVFSHelpers.ConvertPathToGitFormat(FileToUpdate)}",
                $"A {FileToDelete}",
                $"A {GVFSHelpers.ConvertPathToGitFormat(FileToRename)}",
                $"A {GVFSHelpers.ConvertPathToGitFormat(RenameFileTarget)}",
                $"A {FolderToCreate}/",
                $"A {RenameNewDotGitFileTarget}",
                $"A {FolderToDelete}/",
            };

            string fileToAdd = this.Enlistment.GetVirtualPathTo(FileToAdd);

            fileSystem.WriteAllText(fileToAdd, "Contents for the new file");

            string fileToUpdate = this.Enlistment.GetVirtualPathTo(FileToUpdate);

            fileSystem.AppendAllText(fileToUpdate, "// Testing");

            string fileToDelete = this.Enlistment.GetVirtualPathTo(FileToDelete);

            fileSystem.DeleteFile(fileToDelete);
            fileToDelete.ShouldNotExistOnDisk(fileSystem);

            string fileToRename = this.Enlistment.GetVirtualPathTo(FileToRename);

            fileSystem.MoveFile(fileToRename, this.Enlistment.GetVirtualPathTo(RenameFileTarget));

            string folderToCreate = this.Enlistment.GetVirtualPathTo(FolderToCreate);

            fileSystem.CreateDirectory(folderToCreate);

            string folderToRename = this.Enlistment.GetVirtualPathTo(FolderToRename);

            fileSystem.CreateDirectory(folderToRename);
            string folderToRenameTarget = this.Enlistment.GetVirtualPathTo(RenameFolderTarget);

            fileSystem.MoveDirectory(folderToRename, folderToRenameTarget);

            // Deleting the new folder will remove it from the modified paths file
            fileSystem.DeleteDirectory(folderToRenameTarget);
            folderToRenameTarget.ShouldNotExistOnDisk(fileSystem);

            // Moving a file from the .git folder to the working directory should add the file to the modified paths
            string dotGitfileToAdd = this.Enlistment.GetVirtualPathTo(DotGitFileToCreate);

            fileSystem.WriteAllText(dotGitfileToAdd, "Contents for the new file in dot git");
            fileSystem.MoveFile(dotGitfileToAdd, this.Enlistment.GetVirtualPathTo(RenameNewDotGitFileTarget));

            string folderToDeleteFullPath = this.Enlistment.GetVirtualPathTo(FolderToDelete);

            fileSystem.WriteAllText(Path.Combine(folderToDeleteFullPath, "NewFile.txt"), "Contents for new file");
            string newFileToDelete = Path.Combine(folderToDeleteFullPath, "NewFileToDelete.txt");

            fileSystem.WriteAllText(newFileToDelete, "Contents for new file");
            fileSystem.DeleteFile(newFileToDelete);
            fileSystem.WriteAllText(Path.Combine(folderToDeleteFullPath, "CreateCommonVersionHeader.bat"), "Changing the file contents");
            fileSystem.DeleteFile(Path.Combine(folderToDeleteFullPath, "RunUnitTests.bat"));

            fileSystem.DeleteDirectory(folderToDeleteFullPath);
            folderToDeleteFullPath.ShouldNotExistOnDisk(fileSystem);

            // Remount
            this.Enlistment.UnmountGVFS();
            this.Enlistment.MountGVFS();

            this.Enlistment.WaitForBackgroundOperations();

            string modifiedPathsDatabase = Path.Combine(this.Enlistment.DotGVFSRoot, TestConstants.Databases.ModifiedPaths);

            modifiedPathsDatabase.ShouldBeAFile(fileSystem);
            using (StreamReader reader = new StreamReader(File.Open(modifiedPathsDatabase, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                reader.ReadToEnd().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).OrderBy(x => x)
                .ShouldMatchInOrder(expectedModifiedFilesContentsAfterRemount.OrderBy(x => x));
            }
        }
        public void ModifiedPathsFromRenamingOutsideRepoSavedAfterRemount(FileSystemRunner fileSystem)
        {
            string[] expectedModifiedFilesContentsAfterRemount =
            {
                @"A .gitattributes",
                $"A {FileToCreateOutsideRepo}",
                $"A {FolderToCreateOutsideRepo}/",
            };

            string folderToRename = this.Enlistment.GetVirtualPathTo(FolderToRename);

            fileSystem.CreateDirectory(folderToRename);
            string folderToRenameTarget = this.Enlistment.GetVirtualPathTo(RenameFolderTarget);

            fileSystem.MoveDirectory(folderToRename, folderToRenameTarget);

            // Moving the new folder out of the repo will remove it from the modified paths file
            string folderTargetOutsideSrc = Path.Combine(this.Enlistment.EnlistmentRoot, RenameFolderTarget);

            folderTargetOutsideSrc.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveDirectory(folderToRenameTarget, folderTargetOutsideSrc);
            folderTargetOutsideSrc.ShouldBeADirectory(fileSystem);
            folderToRenameTarget.ShouldNotExistOnDisk(fileSystem);

            // Move a file from outside of src into src
            string fileToCreateOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, FileToCreateOutsideRepo);

            fileSystem.WriteAllText(fileToCreateOutsideRepoPath, "Contents for the new file outside of repo");
            string fileToCreateOutsideRepoTargetPath = this.Enlistment.GetVirtualPathTo(FileToCreateOutsideRepo);

            fileToCreateOutsideRepoTargetPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveFile(fileToCreateOutsideRepoPath, fileToCreateOutsideRepoTargetPath);
            fileToCreateOutsideRepoTargetPath.ShouldBeAFile(fileSystem);
            fileToCreateOutsideRepoPath.ShouldNotExistOnDisk(fileSystem);

            // Move a folder from outside of src into src
            string folderToCreateOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, FolderToCreateOutsideRepo);

            fileSystem.CreateDirectory(folderToCreateOutsideRepoPath);
            folderToCreateOutsideRepoPath.ShouldBeADirectory(fileSystem);
            string folderToCreateOutsideRepoTargetPath = this.Enlistment.GetVirtualPathTo(FolderToCreateOutsideRepo);

            folderToCreateOutsideRepoTargetPath.ShouldNotExistOnDisk(fileSystem);
            fileSystem.MoveDirectory(folderToCreateOutsideRepoPath, folderToCreateOutsideRepoTargetPath);
            folderToCreateOutsideRepoTargetPath.ShouldBeADirectory(fileSystem);
            folderToCreateOutsideRepoPath.ShouldNotExistOnDisk(fileSystem);

            // Remount
            this.Enlistment.UnmountGVFS();
            this.Enlistment.MountGVFS();

            this.Enlistment.WaitForBackgroundOperations();

            string modifiedPathsDatabase = Path.Combine(this.Enlistment.DotGVFSRoot, TestConstants.Databases.ModifiedPaths);

            modifiedPathsDatabase.ShouldBeAFile(fileSystem);
            using (StreamReader reader = new StreamReader(File.Open(modifiedPathsDatabase, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                reader.ReadToEnd().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).OrderBy(x => x)
                .ShouldMatchInOrder(expectedModifiedFilesContentsAfterRemount.OrderBy(x => x));
            }
        }