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));
            }
        }