Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions GVFS/GVFS.Common/ModifiedPathsDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,31 @@ public static bool TryLoadOrCreate(ITracer tracer, string dataDirectory, Physica
return true;
}

/// <summary>
/// This method will examine the modified paths to check if there is already a parent folder entry in
/// the modified paths. If there is a parent folder the entry does not need to be in the modified paths
/// and will be removed because the parent folder is recursive and covers any children.
/// </summary>
public void RemoveEntriesWithParentFolderEntry(ITracer tracer)
{
int startingCount = this.modifiedPaths.Count;
using (ITracer activity = tracer.StartActivity(nameof(this.RemoveEntriesWithParentFolderEntry), EventLevel.Informational))
{
foreach (string modifiedPath in this.modifiedPaths)
{
if (this.ContainsParentDirectory(modifiedPath))
{
this.modifiedPaths.TryRemove(modifiedPath);
}
}

EventMetadata metadata = new EventMetadata();
metadata.Add(nameof(startingCount), startingCount);
metadata.Add("EndCount", this.modifiedPaths.Count);
activity.Stop(metadata);
}
}

public bool Contains(string path, bool isFolder)
{
string entry = this.NormalizeEntryString(path, isFolder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ public class ModifiedPathsTests : TestsWithEnlistmentPerTestCase
$"A {RenameNewDotGitFileTarget}",
$"A {FileToCreateOutsideRepo}",
$"A {FolderToCreateOutsideRepo}/",
$"A {FolderToDelete}/CreateCommonAssemblyVersion.bat",
$"A {FolderToDelete}/CreateCommonCliAssemblyVersion.bat",
$"A {FolderToDelete}/CreateCommonVersionHeader.bat",
$"A {FolderToDelete}/RunFunctionalTests.bat",
$"A {FolderToDelete}/RunUnitTests.bat",
$"A {FolderToDelete}/",
};

Expand Down Expand Up @@ -138,9 +133,16 @@ public void ModifiedPathsSavedAfterRemount(FileSystemRunner fileSystem)
folderToCreateOutsideRepoTargetPath.ShouldBeADirectory(fileSystem);
folderToCreateOutsideRepoPath.ShouldNotExistOnDisk(fileSystem);

string folderToDelete = this.Enlistment.GetVirtualPathTo(FolderToDelete);
fileSystem.DeleteDirectory(folderToDelete);
folderToDelete.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"));
Comment thread
kewillford marked this conversation as resolved.

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

// Remount
this.Enlistment.UnmountGVFS();
Expand Down
29 changes: 29 additions & 0 deletions GVFS/GVFS.UnitTests/Common/ModifiedPathsDatabaseTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using GVFS.Common;
using GVFS.Tests.Should;
using GVFS.UnitTests.Mock;
using GVFS.UnitTests.Mock.Common;
using GVFS.UnitTests.Mock.FileSystem;
using NUnit.Framework;
using System;
Expand All @@ -17,6 +18,21 @@ public class ModifiedPathsDatabaseTests
private const string ExistingEntries = @"A file.txt
A dir/file2.txt
A dir1/dir2/file3.txt
";
private const string EntriesToCompress = @"A file.txt
Comment thread
kewillford marked this conversation as resolved.
D deleted.txt
A dir/file2.txt
A dir/dir3/dir4/
A dir1/dir2/file3.txt
A dir/
D deleted/
A dir1/dir2/
A dir1/file.txt
A dir1/dir2/dir3/dir4/dir5/
A dir/dir2/file3.txt
A dir/dir4/dir5/
D dir/dir2/deleted.txt
A dir1/dir2
";

[TestCase]
Expand Down Expand Up @@ -119,6 +135,19 @@ public void EntryNotAddedIfParentDirectoryExists()
modifiedPathsDatabase.Contains("dir2/dir", isFolder: true).ShouldBeTrue();
}

[TestCase]
public void RemoveEntriesWithParentFolderEntry()
{
ModifiedPathsDatabase modifiedPathsDatabase = CreateModifiedPathsDatabase(EntriesToCompress);
modifiedPathsDatabase.RemoveEntriesWithParentFolderEntry(new MockTracer());
modifiedPathsDatabase.Count.ShouldEqual(5);
modifiedPathsDatabase.Contains("file.txt", isFolder: false).ShouldBeTrue();
modifiedPathsDatabase.Contains("dir/", isFolder: true).ShouldBeTrue();
modifiedPathsDatabase.Contains("dir1/dir2", isFolder: false).ShouldBeTrue();
modifiedPathsDatabase.Contains("dir1/dir2/", isFolder: true).ShouldBeTrue();
modifiedPathsDatabase.Contains("dir1/file.txt", isFolder: false).ShouldBeTrue();
}

private static void TestAddingPath(string path, bool isFolder = false)
{
TestAddingPath(path, path, isFolder);
Expand Down
3 changes: 3 additions & 0 deletions GVFS/GVFS.Virtualization/FileSystemCallbacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ public static bool IsPathInsideDotGit(string relativePath)

public bool TryStart(out string error)
{
this.modifiedPaths.RemoveEntriesWithParentFolderEntry(this.context.Tracer);
this.modifiedPaths.WriteAllEntriesAndFlush();

if (!this.fileSystemVirtualizer.TryStart(this, out error))
{
return false;
Expand Down