11using GVFS . Common . FileSystem ;
2- using GVFS . Common . Git ;
32using GVFS . Common . Tracing ;
43using System ;
54using System . Diagnostics ;
65using System . IO ;
7- using System . Linq ;
86using System . Threading ;
97
108namespace GVFS . Common
@@ -45,6 +43,7 @@ public static EnlistmentHydrationSummary CreateSummary(
4543 GVFSEnlistment enlistment ,
4644 PhysicalFileSystem fileSystem ,
4745 ITracer tracer ,
46+ Func < int > projectedFolderCountProvider ,
4847 CancellationToken cancellationToken = default )
4948 {
5049 Stopwatch totalStopwatch = Stopwatch . StartNew ( ) ;
@@ -57,7 +56,6 @@ public static EnlistmentHydrationSummary CreateSummary(
5756 phaseStopwatch . Restart ( ) ;
5857 int totalFileCount = GetIndexFileCount ( enlistment , fileSystem ) ;
5958 long indexReadMs = phaseStopwatch . ElapsedMilliseconds ;
60-
6159 cancellationToken . ThrowIfCancellationRequested ( ) ;
6260
6361 EnlistmentPathData pathData = new EnlistmentPathData ( ) ;
@@ -66,15 +64,13 @@ public static EnlistmentHydrationSummary CreateSummary(
6664 phaseStopwatch . Restart ( ) ;
6765 pathData . LoadPlaceholdersFromDatabase ( enlistment ) ;
6866 long placeholderLoadMs = phaseStopwatch . ElapsedMilliseconds ;
69-
7067 cancellationToken . ThrowIfCancellationRequested ( ) ;
7168
7269 phaseStopwatch . Restart ( ) ;
7370 pathData . LoadModifiedPaths ( enlistment , tracer ) ;
7471 long modifiedPathsLoadMs = phaseStopwatch . ElapsedMilliseconds ;
72+ cancellationToken . ThrowIfCancellationRequested ( ) ;
7573
76- cancellationToken . ThrowIfCancellationRequested ( ) ;
77-
7874 int hydratedFileCount = pathData . ModifiedFilePaths . Count + pathData . PlaceholderFilePaths . Count ;
7975 int hydratedFolderCount = pathData . ModifiedFolderPaths . Count + pathData . PlaceholderFolderPaths . Count ;
8076
@@ -100,11 +96,12 @@ public static EnlistmentHydrationSummary CreateSummary(
10096 return soFar ;
10197 }
10298
103- /* Getting all the directories is also slow, but not as slow as reading the entire index,
104- * GetTotalPathCount caches the count so this is only slow occasionally,
105- * and the GitStatusCache manager also calls this to ensure it is updated frequently. */
99+ /* Get the total folder count from the caller-provided function.
100+ * In the mount process, this comes from the in-memory projection (essentially free).
101+ * In gvfs health --status fallback, this parses the git index via GitIndexProjection. */
102+ cancellationToken . ThrowIfCancellationRequested ( ) ;
106103 phaseStopwatch . Restart ( ) ;
107- int totalFolderCount = GetHeadTreeCount ( enlistment , fileSystem , tracer ) ;
104+ int totalFolderCount = projectedFolderCountProvider ( ) ;
108105 long treeCountMs = phaseStopwatch . ElapsedMilliseconds ;
109106
110107 EmitDurationTelemetry ( tracer , totalStopwatch . ElapsedMilliseconds , indexReadMs , placeholderLoadMs , modifiedPathsLoadMs , treeCountMs , earlyExit : false ) ;
@@ -169,7 +166,7 @@ private static void EmitDurationTelemetry(
169166 /// </summary>
170167 internal static int GetIndexFileCount ( GVFSEnlistment enlistment , PhysicalFileSystem fileSystem )
171168 {
172- string indexPath = Path . Combine ( enlistment . WorkingDirectoryBackingRoot , GVFSConstants . DotGit . Index ) ;
169+ string indexPath = enlistment . GitIndexPath ;
173170 using ( var indexFile = fileSystem . OpenFileStream ( indexPath , FileMode . Open , FileAccess . Read , FileShare . ReadWrite , callFlushFileBuffers : false ) )
174171 {
175172 if ( indexFile . Length < 12 )
@@ -193,77 +190,5 @@ internal static int GetIndexFileCount(GVFSEnlistment enlistment, PhysicalFileSys
193190 }
194191 }
195192
196- /// <summary>
197- /// Get the total number of trees in the repo at HEAD.
198- /// </summary>
199- /// <remarks>
200- /// This is used as the denominator in displaying percentage of hydrated
201- /// directories as part of git status pre-command hook.
202- /// It can take several seconds to calculate, so we cache it near the git status cache.
203- /// </remarks>
204- /// <returns>
205- /// The number of subtrees at HEAD, which may be 0.
206- /// Will return 0 if unsuccessful.
207- /// </returns>
208- internal static int GetHeadTreeCount ( GVFSEnlistment enlistment , PhysicalFileSystem fileSystem , ITracer tracer )
209- {
210- var gitProcess = enlistment . CreateGitProcess ( ) ;
211- var headResult = gitProcess . GetHeadTreeId ( ) ;
212- if ( headResult . ExitCodeIsFailure )
213- {
214- tracer . RelatedError ( $ "Failed to get HEAD tree ID: \n Output: { headResult . Output } \n \n Error:{ headResult . Errors } ") ;
215- return 0 ;
216- }
217- var headSha = headResult . Output . Trim ( ) ;
218- var cacheFile = Path . Combine (
219- enlistment . DotGVFSRoot ,
220- GVFSConstants . DotGVFS . GitStatusCache . TreeCount ) ;
221-
222- // Load from cache if cache matches current HEAD.
223- if ( fileSystem . FileExists ( cacheFile ) )
224- {
225- try
226- {
227- var lines = fileSystem . ReadLines ( cacheFile ) . ToArray ( ) ;
228- if ( lines . Length == 2
229- && lines [ 0 ] == headSha
230- && int . TryParse ( lines [ 1 ] , out int cachedCount ) )
231- {
232- return cachedCount ;
233- }
234- }
235- catch ( Exception ex )
236- {
237- tracer . RelatedWarning ( $ "Failed to read tree count cache file at { cacheFile } : { ex } ") ;
238- // Ignore errors reading the cache
239- }
240- }
241-
242- int totalPathCount = 0 ;
243- GitProcess . Result folderResult = gitProcess . LsTree (
244- GVFSConstants . DotGit . HeadName ,
245- line => totalPathCount ++ ,
246- recursive : true ,
247- showDirectories : true ) ;
248-
249- if ( GitProcess . Result . SuccessCode != folderResult . ExitCode )
250- {
251- tracer . RelatedError ( $ "Failed to get tree count from HEAD: \n Output: { folderResult . Output } \n \n Error:{ folderResult . Errors } ") ;
252- return 0 ;
253- }
254-
255- try
256- {
257- fileSystem . CreateDirectory ( Path . GetDirectoryName ( cacheFile ) ) ;
258- fileSystem . WriteAllText ( cacheFile , $ "{ headSha } \n { totalPathCount } ") ;
259- }
260- catch ( Exception ex )
261- {
262- // Ignore errors writing the cache
263- tracer . RelatedWarning ( $ "Failed to write tree count cache file at { cacheFile } : { ex } ") ;
264- }
265-
266- return totalPathCount ;
267- }
268193 }
269194}
0 commit comments