@@ -857,6 +857,32 @@ static int match_name_with_pattern(const char *key, const char *name,
857857 return ret ;
858858}
859859
860+ static void query_refspecs_multiple (struct refspec * refs , int ref_count , struct refspec * query , struct string_list * results )
861+ {
862+ int i ;
863+ int find_src = !query -> src ;
864+
865+ if (find_src && !query -> dst )
866+ error ("query_refspecs_multiple: need either src or dst" );
867+
868+ for (i = 0 ; i < ref_count ; i ++ ) {
869+ struct refspec * refspec = & refs [i ];
870+ const char * key = find_src ? refspec -> dst : refspec -> src ;
871+ const char * value = find_src ? refspec -> src : refspec -> dst ;
872+ const char * needle = find_src ? query -> dst : query -> src ;
873+ char * * result = find_src ? & query -> src : & query -> dst ;
874+
875+ if (!refspec -> dst )
876+ continue ;
877+ if (refspec -> pattern ) {
878+ if (match_name_with_pattern (key , needle , value , result ))
879+ string_list_append_nodup (results , * result );
880+ } else if (!strcmp (needle , key )) {
881+ string_list_append (results , value );
882+ }
883+ }
884+ }
885+
860886int query_refspecs (struct refspec * refs , int ref_count , struct refspec * query )
861887{
862888 int i ;
@@ -1997,25 +2023,37 @@ static int get_stale_heads_cb(const char *refname,
19972023 const unsigned char * sha1 , int flags , void * cb_data )
19982024{
19992025 struct stale_heads_info * info = cb_data ;
2026+ struct string_list matches = STRING_LIST_INIT_DUP ;
20002027 struct refspec query ;
2028+ int i , stale = 1 ;
20012029 memset (& query , 0 , sizeof (struct refspec ));
20022030 query .dst = (char * )refname ;
20032031
2004- if (query_refspecs (info -> refs , info -> ref_count , & query ))
2005- return 0 ; /* No matches */
2032+ query_refspecs_multiple (info -> refs , info -> ref_count , & query , & matches );
2033+ if (matches .nr == 0 )
2034+ goto clean_exit ; /* No matches */
20062035
20072036 /*
20082037 * If we did find a suitable refspec and it's not a symref and
20092038 * it's not in the list of refs that currently exist in that
2010- * remote we consider it to be stale.
2039+ * remote, we consider it to be stale. In order to deal with
2040+ * overlapping refspecs, we need to go over all of the
2041+ * matching refs.
20112042 */
2012- if (!((flags & REF_ISSYMREF ) ||
2013- string_list_has_string (info -> ref_names , query .src ))) {
2043+ if (flags & REF_ISSYMREF )
2044+ goto clean_exit ;
2045+
2046+ for (i = 0 ; stale && i < matches .nr ; i ++ )
2047+ if (string_list_has_string (info -> ref_names , matches .items [i ].string ))
2048+ stale = 0 ;
2049+
2050+ if (stale ) {
20142051 struct ref * ref = make_linked_ref (refname , & info -> stale_refs_tail );
20152052 hashcpy (ref -> new_sha1 , sha1 );
20162053 }
20172054
2018- free (query .src );
2055+ clean_exit :
2056+ string_list_clear (& matches , 0 );
20192057 return 0 ;
20202058}
20212059
0 commit comments