Skip to content

Commit

Permalink
Merge pull request #314 Check modified paths for parent directories b…
Browse files Browse the repository at this point in the history
…efore adding

Check modified paths for parent directories before adding
  • Loading branch information
Kevin Willford authored Oct 2, 2018
2 parents bc5da49 + 558b7e2 commit ff96c28
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 57 deletions.
18 changes: 17 additions & 1 deletion GVFS/GVFS.Common/ModifiedPathsDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public bool TryAdd(string path, bool isFolder, out bool isRetryable)
{
isRetryable = true;
string entry = this.NormalizeEntryString(path, isFolder);
if (!this.modifiedPaths.Contains(entry))
if (!this.modifiedPaths.Contains(entry) && !this.ContainsParentDirectory(entry))
{
try
{
Expand Down Expand Up @@ -183,6 +183,22 @@ private bool TryParseRemoveLine(string line, out string key, out string error)
return true;
}

private bool ContainsParentDirectory(string modifiedPath)
{
string[] pathParts = modifiedPath.Split(new char[] { GVFSConstants.GitPathSeparator }, StringSplitOptions.RemoveEmptyEntries);
string parentFolder = string.Empty;
for (int i = 0; i < pathParts.Length - 1; i++)
{
parentFolder += pathParts[i] + GVFSConstants.GitPathSeparatorString;
if (this.modifiedPaths.Contains(parentFolder))
{
return true;
}
}

return false;
}

private string NormalizeEntryString(string virtualPath, bool isFolder)
{
// TODO(Mac) This can be optimized if needed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,6 @@ public void MountCreatesModifiedPathsDatabase()
{
"A .gitattributes",
"A developer/me/",
"A developer/me/JLANGE9._prerazzle",
"A developer/me/StateSwitch.Save",
"A tools/x86/remote.exe",
"A tools/x86/runelevated.exe",
"A tools/amd64/remote.exe",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public void CreateFileInFolderTest()
this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete.");

GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, folderName + "/");
GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, folderName + "/" + fileName);
GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, folderName + "/" + fileName);
}

[TestCase, Order(4)]
Expand All @@ -98,6 +98,7 @@ public void RenameEmptyFolderTest()
this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete.");

GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, expectedModifiedEntries);
GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, folderName + "/");
}

[TestCase, Order(5)]
Expand All @@ -112,6 +113,17 @@ public void RenameFolderTest()
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)
Expand All @@ -126,6 +138,7 @@ public void RenameFolderTest()
this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete.");

GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, expectedModifiedEntries);
GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, unexpectedModifiedEntries);
}

[TestCase, Order(6)]
Expand All @@ -137,27 +150,17 @@ public void CaseOnlyRenameOfNewFolderKeepsModifiedPathsEntries()
Assert.Ignore("Powershell does not support case only renames.");
}

string[] expectedModifiedPathsEntriesAfterCreate =
{
"A Folder/",
"A Folder/testfile",
};

string[] expectedModifiedPathsEntriesAfterRename =
{
"A folder/",
};

this.fileSystem.CreateDirectory(Path.Combine(this.Enlistment.RepoRoot, "Folder"));
this.fileSystem.CreateEmptyFile(Path.Combine(this.Enlistment.RepoRoot, "Folder", "testfile"));
this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete.");

GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, expectedModifiedPathsEntriesAfterCreate);
GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "Folder/");

this.fileSystem.RenameDirectory(this.Enlistment.RepoRoot, "Folder", "folder");
this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete.");

GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, expectedModifiedPathsEntriesAfterRename);
GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "folder/");
GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "folder/testfile");
}

[TestCase, Order(7)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void DeletedTempFileIsRemovedFromModifiedFiles(FileSystemRunner fileSyste
tempFile.ShouldNotExistOnDisk(fileSystem);

this.Enlistment.UnmountGVFS();
this.ValidateModifiedPathsDoNotContain(fileSystem, "temp.txt");
GVFSHelpers.ModifiedPathsShouldNotContain(fileSystem, this.Enlistment.DotGVFSRoot, "temp.txt");
}

[TestCaseSource(typeof(FileSystemRunner), FileSystemRunner.TestRunners)]
Expand All @@ -64,7 +64,7 @@ public void DeletedTempFolderIsRemovedFromModifiedFiles(FileSystemRunner fileSys
tempFolder.ShouldNotExistOnDisk(fileSystem);

this.Enlistment.UnmountGVFS();
this.ValidateModifiedPathsDoNotContain(fileSystem, "Temp/");
GVFSHelpers.ModifiedPathsShouldNotContain(fileSystem, this.Enlistment.DotGVFSRoot, "Temp/");
}

[TestCaseSource(typeof(FileSystemRunner), FileSystemRunner.TestRunners)]
Expand All @@ -79,7 +79,7 @@ public void DeletedTempFolderDeletesFilesFromModifiedFiles(FileSystemRunner file
tempFile2.ShouldNotExistOnDisk(fileSystem);

this.Enlistment.UnmountGVFS();
this.ValidateModifiedPathsDoNotContain(fileSystem, "Temp/", "Temp/temp1.txt", "Temp/temp2.txt");
GVFSHelpers.ModifiedPathsShouldNotContain(fileSystem, this.Enlistment.DotGVFSRoot, "Temp/", "Temp/temp1.txt", "Temp/temp2.txt");
}

[Category(Categories.MacTODO.M2)]
Expand Down Expand Up @@ -219,11 +219,5 @@ private string CreateFile(FileSystemRunner fileSystem, string relativePath)
tempFile.ShouldBeAFile(fileSystem);
return tempFile;
}

private void ValidateModifiedPathsDoNotContain(FileSystemRunner fileSystem, params string[] paths)
{
GVFSHelpers.ModifiedPathsShouldNotContain(fileSystem, this.Enlistment.DotGVFSRoot, paths.Select(x => $"A {x}" + Environment.NewLine).ToArray());
GVFSHelpers.ModifiedPathsShouldNotContain(fileSystem, this.Enlistment.DotGVFSRoot, paths.Select(x => $"D {x}" + Environment.NewLine).ToArray());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -980,15 +980,17 @@ public void EditFileNeedingUtf8Encoding()
{
this.ValidateGitCommand("checkout -b tests/functional/EditFileNeedingUtf8Encoding");
this.ValidateGitCommand("status");

string virtualFile = Path.Combine(this.Enlistment.RepoRoot, EncodingFileFolder, EncodingFilename);
string controlFile = Path.Combine(this.ControlGitRepo.RootPath, EncodingFileFolder, EncodingFilename);
string relativeGitPath = EncodingFileFolder + "/" + EncodingFilename;

string contents = virtualFile.ShouldBeAFile(this.FileSystem).WithContents();
string expectedContents = controlFile.ShouldBeAFile(this.FileSystem).WithContents();
contents.ShouldEqual(expectedContents);

// Confirm that the entry is not in the the modified paths database
GVFSHelpers.ModifiedPathsShouldNotContain(this.FileSystem, this.Enlistment.DotGVFSRoot, EncodingFilename);
GVFSHelpers.ModifiedPathsShouldNotContain(this.FileSystem, this.Enlistment.DotGVFSRoot, relativeGitPath);
this.ValidateGitCommand("status");

this.AppendAllText(ContentWhenEditingFile, virtualFile);
Expand All @@ -997,7 +999,7 @@ public void EditFileNeedingUtf8Encoding()
this.ValidateGitCommand("status");

// Confirm that the entry was added to the modified paths database
GVFSHelpers.ModifiedPathsShouldContain(this.FileSystem, this.Enlistment.DotGVFSRoot, EncodingFilename);
GVFSHelpers.ModifiedPathsShouldContain(this.FileSystem, this.Enlistment.DotGVFSRoot, relativeGitPath);
}

[TestCase]
Expand Down
25 changes: 21 additions & 4 deletions GVFS/GVFS.FunctionalTests/Tools/GVFSHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
using Microsoft.Data.Sqlite;
using Newtonsoft.Json;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

namespace GVFS.FunctionalTests.Tools
{
Expand All @@ -19,6 +19,9 @@ public static class GVFSHelpers
public static readonly string PlaceholderListFile = Path.Combine("databases", "PlaceholderList.dat");
public static readonly string RepoMetadataName = Path.Combine("databases", "RepoMetadata.dat");

private const string ModifedPathsLineAddPrefix = "A ";
private const string ModifedPathsLineDeletePrefix = "D ";

private const string DiskLayoutMajorVersionKey = "DiskLayoutVersion";
private const string DiskLayoutMinorVersionKey = "DiskLayoutMinorVersion";
private const string LocalCacheRootKey = "LocalCacheRoot";
Expand Down Expand Up @@ -111,15 +114,29 @@ public static void ModifiedPathsShouldContain(FileSystemRunner fileSystem, strin
{
string modifiedPathsDatabase = Path.Combine(dotGVFSRoot, TestConstants.Databases.ModifiedPaths);
modifiedPathsDatabase.ShouldBeAFile(fileSystem);
GVFSHelpers.ReadAllTextFromWriteLockedFile(modifiedPathsDatabase).ShouldContain(
gitPaths.Select(path => path + ModifiedPathsNewLine).ToArray());
string modifedPathsContents = GVFSHelpers.ReadAllTextFromWriteLockedFile(modifiedPathsDatabase);
string[] modifedPathLines = modifedPathsContents.Split(new[] { ModifiedPathsNewLine }, StringSplitOptions.None);
foreach (string gitPath in gitPaths)
{
modifedPathLines.ShouldContain(path => path.Equals(ModifedPathsLineAddPrefix + gitPath));
}
}

public static void ModifiedPathsShouldNotContain(FileSystemRunner fileSystem, string dotGVFSRoot, params string[] gitPaths)
{
string modifiedPathsDatabase = Path.Combine(dotGVFSRoot, TestConstants.Databases.ModifiedPaths);
modifiedPathsDatabase.ShouldBeAFile(fileSystem);
GVFSHelpers.ReadAllTextFromWriteLockedFile(modifiedPathsDatabase).ShouldNotContain(ignoreCase: true, unexpectedSubstrings: gitPaths);
string modifedPathsContents = GVFSHelpers.ReadAllTextFromWriteLockedFile(modifiedPathsDatabase);
string[] modifedPathLines = modifedPathsContents.Split(new[] { ModifiedPathsNewLine }, StringSplitOptions.None);
foreach (string gitPath in gitPaths)
{
modifedPathLines.ShouldNotContain(
path =>
{
return path.Equals(ModifedPathsLineAddPrefix + gitPath, StringComparison.OrdinalIgnoreCase) ||
path.Equals(ModifedPathsLineDeletePrefix + gitPath, StringComparison.OrdinalIgnoreCase);
});
}
}

private static byte[] StringToShaBytes(string sha)
Expand Down
Loading

0 comments on commit ff96c28

Please sign in to comment.