in GVFS/GVFS.Virtualization/Projection/GitIndexProjection.cs [1540:1634]
private void ReExpandFolder(
string relativeFolderPath,
HashSet<string> existingPlaceholders)
{
bool foundFolder = this.TryGetOrAddFolderDataFromCache(relativeFolderPath, out FolderData folderData);
if (!foundFolder)
{
// Folder is no longer in the projection
existingPlaceholders.Remove(relativeFolderPath);
this.placeholderDatabase.Remove(relativeFolderPath);
return;
}
if (GVFSPlatform.Instance.KernelDriver.EmptyPlaceholdersRequireFileSize)
{
using (BlobSizes.BlobSizesConnection blobSizesConnection = this.blobSizes.CreateConnection())
{
folderData.PopulateSizes(
this.context.Tracer,
this.gitObjects,
blobSizesConnection,
availableSizes: null,
cancellationToken: CancellationToken.None);
}
}
for (int i = 0; i < folderData.ChildEntries.Count; i++)
{
FolderEntryData childEntry = folderData.ChildEntries[i];
if (!childEntry.IsFolder || ((FolderData)childEntry).IsIncluded)
{
string childRelativePath;
if (relativeFolderPath.Length == 0)
{
childRelativePath = childEntry.Name.GetString();
}
else
{
childRelativePath = relativeFolderPath + Path.DirectorySeparatorChar + childEntry.Name.GetString();
}
if (!existingPlaceholders.Contains(childRelativePath))
{
FileSystemResult result;
if (childEntry.IsFolder)
{
result = this.fileSystemVirtualizer.WritePlaceholderDirectory(childRelativePath);
if (result.Result == FSResult.Ok)
{
this.placeholderDatabase.AddPartialFolder(childRelativePath, sha: null);
}
else if (result.Result == FSResult.IOError)
{
// When running in sparse mode there could be directories that were left on disk but are not in the
// modified paths or in the placeholder list because they were not part of the projection
// At this point they need to be re-expanded because they are on disk and part of the projection
if (this.context.FileSystem.DirectoryExists(Path.Combine(this.context.Enlistment.WorkingDirectoryRoot, childRelativePath)))
{
this.ReExpandFolder(childRelativePath, existingPlaceholders);
this.placeholderDatabase.AddExpandedFolder(childRelativePath);
}
}
}
else
{
FileData childFileData = childEntry as FileData;
string fileSha = childFileData.Sha.ToString();
result = this.fileSystemVirtualizer.WritePlaceholderFile(childRelativePath, childFileData.Size, fileSha);
if (result.Result == FSResult.Ok)
{
this.placeholderDatabase.AddFile(childRelativePath, fileSha);
}
}
switch (result.Result)
{
case FSResult.Ok:
break;
case FSResult.FileOrPathNotFound:
// Git command must have removed the folder being re-expanded (relativeFolderPath)
// Remove the folder from existingFolderPlaceholders so that its parent will create
// it again (when it's re-expanded)
existingPlaceholders.Remove(relativeFolderPath);
this.placeholderDatabase.Remove(relativeFolderPath);
return;
default:
// TODO(#245): Handle failures of WritePlaceholderDirectory and WritePlaceholderFile
break;
}
}
}
}
}