private static IEnumerable <string> GetFolderPlaceholdersFromDisk(ITracer tracer, PhysicalFileSystem fileSystem, string path)
        {
            if (!fileSystem.IsSymLink(path))
            {
                foreach (string directory in fileSystem.EnumerateDirectories(path))
                {
                    if (!directory.EndsWith(Path.DirectorySeparatorChar + GVFSConstants.DotGit.Root))
                    {
                        OnDiskFileState fileState = OnDiskFileState.Full;
                        if (Utils.TryGetOnDiskFileState(directory, out fileState))
                        {
                            if (IsPlaceholder(fileState))
                            {
                                yield return(directory);
                            }

                            // Recurse into placeholders and full folders skipping the tombstones
                            if (!IsTombstone(fileState))
                            {
                                foreach (string placeholderPath in GetFolderPlaceholdersFromDisk(tracer, fileSystem, directory))
                                {
                                    yield return(placeholderPath);
                                }
                            }
                        }
                        else
                        {
                            // May cause valid folder placeholders not to be written
                            // to the placeholder database so we want to error out.
                            throw new InvalidDataException($"Error getting on disk file state for {directory}");
                        }
                    }
                }
            }
        }
        private static IEnumerable <string> GetFolderPlaceholdersFromDisk(ITracer tracer, PhysicalFileSystem fileSystem, string path)
        {
            foreach (string directory in fileSystem.EnumerateDirectories(path))
            {
                if (!directory.EndsWith(GVFSConstants.PathSeparatorString + GVFSConstants.DotGit.Root))
                {
                    OnDiskFileState fileState = OnDiskFileState.Full;
                    HResult         result    = Utils.GetOnDiskFileState(directory, ref fileState);
                    if (result == HResult.Ok)
                    {
                        if (IsPlaceholder(fileState))
                        {
                            yield return(directory);
                        }

                        // Recurse into placeholders and full folders skipping the tombstones
                        if (!IsTombstone(fileState))
                        {
                            foreach (string placeholderPath in GetFolderPlaceholdersFromDisk(tracer, fileSystem, directory))
                            {
                                yield return(placeholderPath);
                            }
                        }
                    }
                    else if (result != HResult.FileNotFound)
                    {
                        // FileNotFound is returned for tombstones when the filter is attached to the volume so we want to
                        // just skip those folders.  Any other HResults may cause valid folder placeholders not to be written
                        // to the placeholder database so we want to error out on those.
                        throw new InvalidDataException($"Error getting on disk file state. HResult = {result} for {directory}");
                    }
                }
            }
        }
 private static bool IsPlaceholder(OnDiskFileState fileState)
 {
     return((fileState & (OnDiskFileState.DirtyPlaceholder | OnDiskFileState.HydratedPlaceholder | OnDiskFileState.Placeholder)) != 0);
 }
 private static bool IsTombstone(OnDiskFileState fileState)
 {
     return((fileState & OnDiskFileState.Tombstone) != 0);
 }