11using System ;
22using System . Collections . Generic ;
33using System . Diagnostics ;
4+ using System . Linq ;
45using System . Text ;
56
67namespace GitCredentialManager
@@ -345,7 +346,7 @@ public class GitProcessConfiguration : IGitConfiguration
345346
346347 private readonly ITrace _trace ;
347348 private readonly GitProcess _git ;
348- private readonly ConfigCache _cache ;
349+ private readonly Dictionary < GitConfigurationType , ConfigCache > _cache ;
349350 private readonly bool _useCache ;
350351
351352 internal GitProcessConfiguration ( ITrace trace , GitProcess git ) : this ( trace , git , useCache : true )
@@ -360,15 +361,44 @@ internal GitProcessConfiguration(ITrace trace, GitProcess git, bool useCache)
360361 _trace = trace ;
361362 _git = git ;
362363 _useCache = useCache ;
363- _cache = useCache ? new ConfigCache ( ) : null ;
364+ _cache = useCache ? new Dictionary < GitConfigurationType , ConfigCache > ( ) : null ;
364365 }
365366
366- private void EnsureCacheLoaded ( )
367+ private void EnsureCacheLoaded ( GitConfigurationType type )
367368 {
368- if ( ! _useCache || _cache . IsLoaded )
369+ ConfigCache cache ;
370+ if ( ! _useCache || ( _cache . TryGetValue ( type , out cache ) && cache . IsLoaded ) )
371+ {
369372 return ;
373+ }
374+
375+ if ( cache == null )
376+ {
377+ cache = new ConfigCache ( ) ;
378+ _cache [ type ] = cache ;
379+ }
380+
381+ string typeArg ;
370382
371- using ( ChildProcess git = _git . CreateProcess ( "config list --show-scope --show-origin -z" ) )
383+ switch ( type )
384+ {
385+ case GitConfigurationType . Raw :
386+ typeArg = "--no-type" ;
387+ break ;
388+
389+ case GitConfigurationType . Path :
390+ typeArg = "--type=path" ;
391+ break ;
392+
393+ case GitConfigurationType . Bool :
394+ typeArg = "--type=bool" ;
395+ break ;
396+
397+ default :
398+ return ;
399+ }
400+
401+ using ( ChildProcess git = _git . CreateProcess ( $ "config list --show-scope --show-origin -z { typeArg } ") )
372402 {
373403 git . Start ( Trace2ProcessClass . Git ) ;
374404 // To avoid deadlocks, always read the output stream first and then wait
@@ -378,7 +408,7 @@ private void EnsureCacheLoaded()
378408 switch ( git . ExitCode )
379409 {
380410 case 0 : // OK
381- _cache . Load ( data , _trace ) ;
411+ cache . Load ( data , _trace ) ;
382412 break ;
383413 default :
384414 _trace . WriteLine ( $ "Failed to load config cache (exit={ git . ExitCode } ), will use individual git config commands") ;
@@ -392,18 +422,24 @@ private void InvalidateCache()
392422 {
393423 if ( _useCache )
394424 {
395- _cache . Clear ( ) ;
425+ foreach ( ConfigCache cache in _cache . Values )
426+ {
427+ cache . Clear ( ) ;
428+ }
396429 }
397430 }
398431
399432 public void Enumerate ( GitConfigurationLevel level , GitConfigurationEnumerationCallback cb )
400433 {
401434 if ( _useCache )
402435 {
403- EnsureCacheLoaded ( ) ;
404- if ( _cache . IsLoaded )
436+ EnsureCacheLoaded ( GitConfigurationType . Raw ) ;
437+
438+ ConfigCache cache = _cache [ GitConfigurationType . Raw ] ;
439+
440+ if ( cache . IsLoaded )
405441 {
406- _cache . Enumerate ( level , cb ) ;
442+ cache . Enumerate ( level , cb ) ;
407443 return ;
408444 }
409445 }
@@ -478,10 +514,12 @@ public void Enumerate(GitConfigurationLevel level, GitConfigurationEnumerationCa
478514 public bool TryGet ( GitConfigurationLevel level , GitConfigurationType type , string name , out string value )
479515 {
480516 // Use cache for raw types only - typed queries need Git's canonicalization
481- if ( _useCache && type == GitConfigurationType . Raw )
517+ if ( _useCache )
482518 {
483- EnsureCacheLoaded ( ) ;
484- if ( _cache . IsLoaded && _cache . TryGet ( name , level , out value ) )
519+ EnsureCacheLoaded ( type ) ;
520+
521+ ConfigCache cache = _cache [ type ] ;
522+ if ( cache . IsLoaded && cache . TryGet ( name , level , out value ) )
485523 {
486524 return true ;
487525 }
@@ -593,12 +631,14 @@ public void Unset(GitConfigurationLevel level, string name)
593631 public IEnumerable < string > GetAll ( GitConfigurationLevel level , GitConfigurationType type , string name )
594632 {
595633 // Use cache for raw types only - typed queries need Git's canonicalization
596- if ( _useCache && type == GitConfigurationType . Raw )
634+ if ( _useCache )
597635 {
598- EnsureCacheLoaded ( ) ;
599- if ( _cache . IsLoaded )
636+ EnsureCacheLoaded ( type ) ;
637+
638+ ConfigCache cache = _cache [ type ] ;
639+ if ( cache . IsLoaded )
600640 {
601- var cachedValues = _cache . GetAll ( name , level ) ;
641+ var cachedValues = cache . GetAll ( name , level ) ;
602642 foreach ( var val in cachedValues )
603643 {
604644 yield return val ;
0 commit comments