@@ -799,7 +799,39 @@ public async Task GetSourceAsync(
799
799
string args = ComposeGitArgs ( executionContext , gitCommandManager , configKey , username , password , useBearerAuthType ) ;
800
800
additionalFetchArgs . Add ( args ) ;
801
801
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 )
803
835
{
804
836
additionalCheckoutArgs . Add ( args ) ;
805
837
}
@@ -1530,6 +1562,41 @@ private IEnumerable<string> ParseFetchFilterOptions(AgentTaskPluginExecutionCont
1530
1562
return filters ;
1531
1563
}
1532
1564
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
+
1533
1600
private async Task RunGitStatusIfSystemDebug ( AgentTaskPluginExecutionContext executionContext , GitCliManager gitCommandManager , string targetPath )
1534
1601
{
1535
1602
if ( executionContext . IsSystemDebugTrue ( ) )
0 commit comments