@@ -56,15 +56,34 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
5656 // when we already have it persisted from a previous request
5757 ( originalEtag != newEtag || originalSha == null ) &&
5858 parts . Length > 2 &&
59- GitHub . IsInstalled &&
60- GitHub . TryApi ( $ "repos/{ parts [ 0 ] } /{ parts [ 1 ] } /commits?per_page=1&path={ string . Join ( '/' , parts . Skip ( 4 ) ) } ", out var json ) &&
61- json is JArray commits &&
62- commits [ 0 ] is JObject obj &&
63- obj . Property ( "sha" ) is JProperty prop &&
64- prop != null &&
65- prop . Value . Type == JTokenType . String )
59+ // Skip raw|blob|tree part. we need at least 2 remaining items: ref+path
60+ parts [ 3 ..] is { Length : >= 2 } rest &&
61+ GitHub . IsInstalled )
6662 {
67- newSha = prop . Value . ToObject < string > ( ) ;
63+ // branch might have / as a separator
64+ // Try i parts for ref, remaining for path
65+ for ( var i = 1 ; i < rest . Length ; i ++ )
66+ {
67+ var refCandidate = string . Join ( '/' , rest . Take ( i ) ) ;
68+ var pathCandidate = string . Join ( '/' , rest . Skip ( i ) ) ;
69+
70+ // Validate by asking for just 1 commit that touched this path on this ref
71+ var url = $ "repos/{ Uri . EscapeDataString ( parts [ 0 ] ) } /{ Uri . EscapeDataString ( parts [ 1 ] ) } /commits" +
72+ $ "?sha={ Uri . EscapeDataString ( refCandidate ) } " +
73+ $ "&path={ Uri . EscapeDataString ( pathCandidate ) } " +
74+ $ "&per_page=1";
75+
76+ if ( GitHub . TryApi ( url , out var json ) &&
77+ json is JArray commits &&
78+ commits [ 0 ] is JObject obj &&
79+ obj . Property ( "sha" ) is JProperty prop &&
80+ prop != null &&
81+ prop . Value . Type == JTokenType . String )
82+ {
83+ newSha = prop . Value . ToObject < string > ( ) ;
84+ break ;
85+ }
86+ }
6887 }
6988
7089 // Just propagate back what we had initially, as an optimization for HEAD and cases
0 commit comments