@@ -210,6 +210,76 @@ public bool TryInitialize(ITracer tracer, Enlistment enlistment, out string erro
210210 return true ;
211211 }
212212
213+ /// <summary>
214+ /// Combines authentication initialization with the GVFS config query,
215+ /// eliminating the redundant anonymous probe HTTP request. Instead of:
216+ /// 1. Anonymous probe → /gvfs/config → 401 (TryInitialize)
217+ /// 2. Credential fetch (TryInitialize)
218+ /// 3. Config query → /gvfs/config → 200 (QueryGVFSConfig)
219+ /// This method does:
220+ /// 1. Config query → /gvfs/config → 401 or 200
221+ /// 2. If 401: credential fetch, then retry → 200
222+ /// Saving one HTTP round-trip and reusing the same TCP/TLS connection.
223+ /// </summary>
224+ public bool TryInitializeAndQueryGVFSConfig (
225+ ITracer tracer ,
226+ Enlistment enlistment ,
227+ RetryConfig retryConfig ,
228+ out ServerGVFSConfig serverGVFSConfig ,
229+ out string errorMessage )
230+ {
231+ if ( this . isInitialized )
232+ {
233+ throw new InvalidOperationException ( "Already initialized" ) ;
234+ }
235+
236+ serverGVFSConfig = null ;
237+ errorMessage = null ;
238+
239+ using ( ConfigHttpRequestor configRequestor = new ConfigHttpRequestor ( tracer , enlistment , retryConfig ) )
240+ {
241+ HttpStatusCode ? httpStatus ;
242+
243+ // First attempt without credentials. If anonymous access works,
244+ // we get the config in a single request.
245+ if ( configRequestor . TryQueryGVFSConfig ( false , out serverGVFSConfig , out httpStatus , out _ ) )
246+ {
247+ this . IsAnonymous = true ;
248+ this . isInitialized = true ;
249+ tracer . RelatedInfo ( "{0}: Anonymous access succeeded, config obtained in one request" , nameof ( this . TryInitializeAndQueryGVFSConfig ) ) ;
250+ return true ;
251+ }
252+
253+ if ( httpStatus != HttpStatusCode . Unauthorized )
254+ {
255+ errorMessage = "Unable to query /gvfs/config" ;
256+ tracer . RelatedWarning ( "{0}: Config query failed with status {1}" , nameof ( this . TryInitializeAndQueryGVFSConfig ) , httpStatus ? . ToString ( ) ?? "None" ) ;
257+ return false ;
258+ }
259+
260+ // Server requires authentication — fetch credentials
261+ this . IsAnonymous = false ;
262+
263+ if ( ! this . TryCallGitCredential ( tracer , out errorMessage ) )
264+ {
265+ tracer . RelatedWarning ( "{0}: Credential fetch failed: {1}" , nameof ( this . TryInitializeAndQueryGVFSConfig ) , errorMessage ) ;
266+ return false ;
267+ }
268+
269+ this . isInitialized = true ;
270+
271+ // Retry with credentials using the same ConfigHttpRequestor (reuses HttpClient/connection)
272+ if ( configRequestor . TryQueryGVFSConfig ( true , out serverGVFSConfig , out _ , out errorMessage ) )
273+ {
274+ tracer . RelatedInfo ( "{0}: Config obtained with credentials" , nameof ( this . TryInitializeAndQueryGVFSConfig ) ) ;
275+ return true ;
276+ }
277+
278+ tracer . RelatedWarning ( "{0}: Config query failed with credentials: {1}" , nameof ( this . TryInitializeAndQueryGVFSConfig ) , errorMessage ) ;
279+ return false ;
280+ }
281+ }
282+
213283 public bool TryInitializeAndRequireAuth ( ITracer tracer , out string errorMessage )
214284 {
215285 if ( this . isInitialized )
0 commit comments