Skip to content

Commit

Permalink
Add path to included folders when folder created that is in the index…
Browse files Browse the repository at this point in the history
… but not in the included list
  • Loading branch information
Kevin Willford committed Aug 5, 2019
1 parent b8af57a commit 5ab7bcc
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 47 deletions.
54 changes: 34 additions & 20 deletions GVFS/GVFS.Platform.Windows/WindowsFileSystemVirtualizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1005,29 +1005,16 @@ private void NotifyNewFileCreatedHandler(
GitCommandLineParser gitCommand = new GitCommandLineParser(this.Context.Repository.GVFSLock.GetLockedGitCommand());
if (gitCommand.IsValidGitCommand)
{
string directoryPath = Path.Combine(this.Context.Enlistment.WorkingDirectoryRoot, virtualPath);
HResult hr = this.virtualizationInstance.MarkDirectoryAsPlaceholder(
directoryPath,
FolderContentId,
PlaceholderVersionId);

if (hr == HResult.Ok)
{
this.FileSystemCallbacks.OnPlaceholderFolderCreated(virtualPath, triggeringProcessImageFileName);
}
else
{
EventMetadata metadata = this.CreateEventMetadata(virtualPath);
metadata.Add("isDirectory", isDirectory);
metadata.Add("triggeringProcessId", triggeringProcessId);
metadata.Add("triggeringProcessImageFileName", triggeringProcessImageFileName);
metadata.Add("HResult", hr.ToString());
this.Context.Tracer.RelatedError(metadata, nameof(this.NotifyNewFileCreatedHandler) + "_" + nameof(this.virtualizationInstance.MarkDirectoryAsPlaceholder) + " error");
}
this.MarkDirectoryAsPlaceholder(virtualPath, isDirectory, triggeringProcessId, triggeringProcessImageFileName);
}
else
{
this.FileSystemCallbacks.OnFolderCreated(virtualPath);
if (this.FileSystemCallbacks.OnFolderCreated(virtualPath))
{
// When OnFolderCreated returns true it means the folder was previously excluded from the projection and was
// included so it needs to be marked as a placeholder so that it will start projecting items in the folder
this.MarkDirectoryAsPlaceholder(virtualPath, isDirectory, triggeringProcessId, triggeringProcessImageFileName);
}
}
}
else
Expand All @@ -1046,6 +1033,33 @@ private void NotifyNewFileCreatedHandler(
}
}

private void MarkDirectoryAsPlaceholder(
string virtualPath,
bool isDirectory,
uint triggeringProcessId,
string triggeringProcessImageFileName)
{
string directoryPath = Path.Combine(this.Context.Enlistment.WorkingDirectoryRoot, virtualPath);
HResult hr = this.virtualizationInstance.MarkDirectoryAsPlaceholder(
directoryPath,
FolderContentId,
PlaceholderVersionId);

if (hr == HResult.Ok)
{
this.FileSystemCallbacks.OnPlaceholderFolderCreated(virtualPath, triggeringProcessImageFileName);
}
else
{
EventMetadata metadata = this.CreateEventMetadata(virtualPath);
metadata.Add("isDirectory", true);
metadata.Add("triggeringProcessId", triggeringProcessId);
metadata.Add("triggeringProcessImageFileName", triggeringProcessImageFileName);
metadata.Add("HResult", hr.ToString());
this.Context.Tracer.RelatedError(metadata, nameof(this.NotifyNewFileCreatedHandler) + "_" + nameof(this.virtualizationInstance.MarkDirectoryAsPlaceholder) + " error");
}
}

private void NotifyFileOverwrittenHandler(
string virtualPath,
bool isDirectory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ public void TestFileSystemOperationsInvalidateStatusCache()
this.ValidateActionInvalidatesStatusCache(backgroundTaskRunner, gitStatusCache, fileSystemCallbacks.OnFileDeleted, "OnFileDeleted.txt", FileSystemTask.OperationType.OnFileDeleted);
this.ValidateActionInvalidatesStatusCache(backgroundTaskRunner, gitStatusCache, fileSystemCallbacks.OnFileOverwritten, "OnFileDeleted.txt", FileSystemTask.OperationType.OnFileOverwritten);
this.ValidateActionInvalidatesStatusCache(backgroundTaskRunner, gitStatusCache, fileSystemCallbacks.OnFileSuperseded, "OnFileSuperseded.txt", FileSystemTask.OperationType.OnFileSuperseded);
this.ValidateActionInvalidatesStatusCache(backgroundTaskRunner, gitStatusCache, fileSystemCallbacks.OnFolderCreated, "OnFileSuperseded.txt", FileSystemTask.OperationType.OnFolderCreated);
this.ValidateActionInvalidatesStatusCache(backgroundTaskRunner, gitStatusCache, x => fileSystemCallbacks.OnFolderCreated(x), "OnFileSuperseded.txt", FileSystemTask.OperationType.OnFolderCreated);
this.ValidateActionInvalidatesStatusCache(backgroundTaskRunner, gitStatusCache, fileSystemCallbacks.OnFolderDeleted, "OnFileSuperseded.txt", FileSystemTask.OperationType.OnFolderDeleted);
this.ValidateActionInvalidatesStatusCache(backgroundTaskRunner, gitStatusCache, fileSystemCallbacks.OnFileConvertedToFull, "OnFileConvertedToFull.txt", FileSystemTask.OperationType.OnFileConvertedToFull);
}
Expand Down
22 changes: 19 additions & 3 deletions GVFS/GVFS.Virtualization/FileSystemCallbacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,17 @@ public void OnFilePreDelete(string relativePath)
this.backgroundFileSystemTaskRunner.Enqueue(FileSystemTask.OnFilePreDelete(relativePath));
}

public void OnFolderCreated(string relativePath)
public bool OnFolderCreated(string relativePath)
{
this.AddToNewlyCreatedList(relativePath, isFolder: true);
bool pathExcluded = this.GitIndexProjection.IsPathExcluded(relativePath);
if (!pathExcluded)
{
this.AddToNewlyCreatedList(relativePath, isFolder: true);
}

this.backgroundFileSystemTaskRunner.Enqueue(FileSystemTask.OnFolderCreated(relativePath));

return pathExcluded;
}

public virtual void OnFolderRenamed(string oldRelativePath, string newRelativePath)
Expand Down Expand Up @@ -701,7 +708,16 @@ private FileSystemTaskResult ExecuteBackgroundOperation(FileSystemTask gitUpdate

case FileSystemTask.OperationType.OnFolderCreated:
metadata.Add("virtualPath", gitUpdate.VirtualPath);
result = this.TryAddModifiedPath(gitUpdate.VirtualPath, isFolder: true);
if (this.GitIndexProjection.IsPathExcluded(gitUpdate.VirtualPath))
{
bool added = this.GitIndexProjection.TryAddIncludedFolder(gitUpdate.VirtualPath);
result = added ? FileSystemTaskResult.Success : FileSystemTaskResult.RetryableError;
}
else
{
result = this.TryAddModifiedPath(gitUpdate.VirtualPath, isFolder: true);
}

break;

case FileSystemTask.OperationType.OnFolderRenamed:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public void ResetData(LazyUTF8String name)
{
this.Name = name;
this.ChildrenHaveSizes = false;
this.IsIncluded = true;
if (this.ChildEntries == null)
{
this.ChildEntries = new SortedFolderEntries();
Expand All @@ -39,6 +40,15 @@ public FileData AddChildFile(LazyUTF8String name, byte[] shaBytes)
return this.ChildEntries.AddFile(name, shaBytes);
}

public override void Include()
{
base.Include();
for (int i = 0; i < this.ChildEntries.Count; i++)
{
this.ChildEntries[i].Include();
}
}

public void PopulateSizes(
ITracer tracer,
GVFSGitObjects gitObjects,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ internal abstract class FolderEntryData
{
public LazyUTF8String Name { get; protected set; }
public abstract bool IsFolder { get; }
public bool IsIncluded { get; set; } = true;

public virtual void Include()
{
this.IsIncluded = true;
}

protected static EventMetadata CreateEventMetadata(Exception e = null)
{
Expand Down
77 changes: 54 additions & 23 deletions GVFS/GVFS.Virtualization/Projection/GitIndexProjection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,41 @@ public virtual List<ProjectedFileInfo> GetProjectedItems(
}
}

public bool IsPathExcluded(string virtualPath)
{
this.GetChildNameAndParentKey(virtualPath, out string fileName, out string parentKey);
FolderEntryData data = this.GetProjectedFolderEntryData(
blobSizesConnection: null,
childName: fileName,
parentKey: parentKey);

return !(data != null && data.IsIncluded);
}

public bool TryAddIncludedFolder(string virtualPath)
{
try
{
this.GetChildNameAndParentKey(virtualPath, out string fileName, out string parentKey);
FolderEntryData data = this.GetProjectedFolderEntryData(
blobSizesConnection: null,
childName: fileName,
parentKey: parentKey);

if (data != null && !data.IsIncluded)
{
data.Include();
this.includedFolderCollection.Add(virtualPath);
}

return true;
}
catch (GVFSDatabaseException)
{
return false;
}
}

public virtual bool IsPathProjected(string virtualPath, out string fileName, out bool isFolder)
{
isFolder = false;
Expand All @@ -442,7 +477,7 @@ public virtual bool IsPathProjected(string virtualPath, out string fileName, out
childName: fileName,
parentKey: parentKey);

if (data != null)
if (data != null && data.IsIncluded)
{
isFolder = data.IsFolder;
return true;
Expand Down Expand Up @@ -470,7 +505,7 @@ public virtual ProjectedFileInfo GetProjectedFileInfo(
parentKey: parentKey,
gitCasedChildName: out gitCasedChildName);

if (data != null)
if (data != null && data.IsIncluded)
{
if (data.IsFolder)
{
Expand Down Expand Up @@ -643,18 +678,22 @@ private static EventMetadata CreateEventMetadata(Exception e = null)
private static List<ProjectedFileInfo> ConvertToProjectedFileInfos(SortedFolderEntries sortedFolderEntries)
{
List<ProjectedFileInfo> childItems = new List<ProjectedFileInfo>(sortedFolderEntries.Count);
FolderEntryData childEntry;
for (int i = 0; i < sortedFolderEntries.Count; i++)
{
FolderEntryData childEntry = sortedFolderEntries[i];
childEntry = sortedFolderEntries[i];

if (childEntry.IsFolder)
{
childItems.Add(new ProjectedFileInfo(childEntry.Name.GetString(), size: 0, isFolder: true, sha: Sha1Id.None));
}
else
if (childEntry.IsIncluded)
{
FileData fileData = (FileData)childEntry;
childItems.Add(new ProjectedFileInfo(fileData.Name.GetString(), fileData.Size, isFolder: false, sha: fileData.Sha));
if (childEntry.IsFolder)
{
childItems.Add(new ProjectedFileInfo(childEntry.Name.GetString(), size: 0, isFolder: true, sha: Sha1Id.None));
}
else
{
FileData fileData = (FileData)childEntry;
childItems.Add(new ProjectedFileInfo(fileData.Name.GetString(), fileData.Size, isFolder: false, sha: fileData.Sha));
}
}
}

Expand All @@ -665,12 +704,7 @@ private void AddItemFromIndexEntry(GitIndexEntry indexEntry)
{
if (indexEntry.BuildingProjection_HasSameParentAsLastEntry)
{
if (this.rootIncludedFolder.Children.Count == 0 ||
indexEntry.BuildingProjection_ShouldInclude ||
indexEntry.BuildingProjection_ShouldIncludeRecursive)
{
indexEntry.BuildingProjection_LastParent.AddChildFile(indexEntry.BuildingProjection_GetChildName(), indexEntry.Sha);
}
indexEntry.BuildingProjection_LastParent.AddChildFile(indexEntry.BuildingProjection_GetChildName(), indexEntry.Sha);
}
else
{
Expand Down Expand Up @@ -843,6 +877,8 @@ private FolderData AddFileToTree(GitIndexEntry indexEntry)
throw new InvalidDataException("Found a file (" + parentFolderName + ") where a folder was expected: " + gitPath);
}

parentFolder = parentFolder.ChildEntries.GetOrAddFolder(indexEntry.BuildingProjection_PathParts[pathIndex]);

if (this.rootIncludedFolder.Children.Count > 0)
{
if (indexEntry.BuildingProjection_LastEntryIncludedFolder == null)
Expand All @@ -865,15 +901,10 @@ private FolderData AddFileToTree(GitIndexEntry indexEntry)
indexEntry.BuildingProjection_ShouldIncludeRecursive = false;
indexEntry.BuildingProjection_LastEntryIncludedFolder = null;
}

if (!indexEntry.BuildingProjection_ShouldInclude)
{
return parentFolder;
}
}
}

parentFolder = parentFolder.ChildEntries.GetOrAddFolder(indexEntry.BuildingProjection_PathParts[pathIndex]);
parentFolder.IsIncluded = indexEntry.BuildingProjection_ShouldInclude || indexEntry.BuildingProjection_ShouldIncludeRecursive;
}
}

parentFolder.AddChildFile(indexEntry.BuildingProjection_PathParts[indexEntry.BuildingProjection_NumParts - 1], indexEntry.Sha);
Expand Down

0 comments on commit 5ab7bcc

Please sign in to comment.