@@ -799,7 +799,39 @@ public async Task GetSourceAsync(
799799 string args = ComposeGitArgs ( executionContext , gitCommandManager , configKey , username , password , useBearerAuthType ) ;
800800 additionalFetchArgs . Add ( args ) ;
801801
802- if ( additionalFetchFilterOptions . Any ( ) && AgentKnobs . AddForceCredentialsToGitCheckout . GetValue ( executionContext ) . AsBoolean ( ) )
802+ // Partial Clone Credential Handling:
803+ // Two feature flags control when credentials are added to git checkout for partial clones:
804+ // 1. AddForceCredentialsToGitCheckout (legacy): Only checks explicit fetch filters
805+ // 2. AddForceCredentialsToGitCheckoutEnhanced (new): Checks both explicit filters AND inherited partial clone config
806+ // The enhanced flag takes precedence when both are enabled.
807+ bool hasExplicitFetchFilter = additionalFetchFilterOptions . Any ( ) ;
808+ bool forceCredentialsLegacyEnabled = AgentKnobs . AddForceCredentialsToGitCheckout . GetValue ( executionContext ) . AsBoolean ( ) ;
809+ bool forceCredentialsEnhancedEnabled = AgentKnobs . AddForceCredentialsToGitCheckoutEnhanced . GetValue ( executionContext ) . AsBoolean ( ) ;
810+
811+ bool shouldAddCredentials = false ;
812+
813+ // Enhanced behavior takes precedence - checks both explicit filters and promisor remote configuration
814+ if ( forceCredentialsEnhancedEnabled )
815+ {
816+ // Enhanced detection: check for inherited partial clone configuration via git config
817+ bool hasInheritedPartialCloneConfig = await IsPartialCloneRepository ( executionContext , gitCommandManager , targetPath ) ;
818+ executionContext . Debug ( $ "Enhanced partial clone detection - ExplicitFilter: { hasExplicitFetchFilter } , InheritedConfig: { hasInheritedPartialCloneConfig } , ForceCredentialsEnhanced: { forceCredentialsEnhancedEnabled } ") ;
819+ if ( hasExplicitFetchFilter || hasInheritedPartialCloneConfig )
820+ {
821+ executionContext . Debug ( "Adding credentials to checkout due to enhanced partial clone detection" ) ;
822+ shouldAddCredentials = true ;
823+ }
824+ }
825+ else if ( forceCredentialsLegacyEnabled && hasExplicitFetchFilter )
826+ {
827+ // Legacy behavior: only check explicit fetch filter, used when enhanced flag is disabled
828+ executionContext . Debug ( $ "Legacy partial clone detection - ExplicitFilter: { hasExplicitFetchFilter } , ForceCredentials: { forceCredentialsLegacyEnabled } ") ;
829+ executionContext . Debug ( "Adding credentials to checkout due to explicit fetch filter and legacy force credentials knob" ) ;
830+ shouldAddCredentials = true ;
831+ }
832+
833+ // Apply credentials to checkout if either feature flag condition was satisfied
834+ if ( shouldAddCredentials )
803835 {
804836 additionalCheckoutArgs . Add ( args ) ;
805837 }
@@ -1530,6 +1562,41 @@ private IEnumerable<string> ParseFetchFilterOptions(AgentTaskPluginExecutionCont
15301562 return filters ;
15311563 }
15321564
1565+ private async Task < bool > IsPartialCloneRepository ( AgentTaskPluginExecutionContext executionContext , GitCliManager gitCommandManager , string targetPath )
1566+ {
1567+ try
1568+ {
1569+ // Skip check if .git directory doesn't exist (not a Git repository)
1570+ string gitDir = Path . Combine ( targetPath , ".git" ) ;
1571+ if ( ! Directory . Exists ( gitDir ) )
1572+ {
1573+ executionContext . Debug ( "Not a Git repository: .git directory does not exist" ) ;
1574+ return false ;
1575+ }
1576+
1577+ // Check for promisor remote configuration (primary indicator)
1578+ if ( await gitCommandManager . GitConfigExist ( executionContext , targetPath , "remote.origin.promisor" ) )
1579+ {
1580+ executionContext . Debug ( "Detected partial clone: remote.origin.promisor exists" ) ;
1581+ return true ;
1582+ }
1583+
1584+ // Check for partial clone filter configuration (secondary indicator)
1585+ if ( await gitCommandManager . GitConfigExist ( executionContext , targetPath , "remote.origin.partialclonefilter" ) )
1586+ {
1587+ executionContext . Debug ( "Detected partial clone: remote.origin.partialclonefilter exists" ) ;
1588+ return true ;
1589+ }
1590+ return false ;
1591+ }
1592+ catch ( Exception ex )
1593+ {
1594+ // Default to false on detection failure to avoid breaking builds
1595+ executionContext . Debug ( $ "Failed to detect partial clone state: { ex . Message } ") ;
1596+ return false ;
1597+ }
1598+ }
1599+
15331600 private async Task RunGitStatusIfSystemDebug ( AgentTaskPluginExecutionContext executionContext , GitCliManager gitCommandManager , string targetPath )
15341601 {
15351602 if ( executionContext . IsSystemDebugTrue ( ) )
0 commit comments