@@ -803,59 +803,56 @@ static int match_name_with_pattern(const char *key, const char *name,
803803 return ret ;
804804}
805805
806- char * apply_refspecs (struct refspec * refspecs , int nr_refspec ,
807- const char * name )
806+ static int query_refspecs (struct refspec * refs , int ref_count , struct refspec * query )
808807{
809808 int i ;
810- char * ret = NULL ;
811- for (i = 0 ; i < nr_refspec ; i ++ ) {
812- struct refspec * refspec = refspecs + i ;
813- if (refspec -> pattern ) {
814- if (match_name_with_pattern (refspec -> src , name ,
815- refspec -> dst , & ret ))
816- return ret ;
817- } else if (!strcmp (refspec -> src , name ))
818- return xstrdup (refspec -> dst );
819- }
820- return NULL ;
821- }
809+ int find_src = !query -> src ;
822810
823- int remote_find_tracking (struct remote * remote , struct refspec * refspec )
824- {
825- int find_src = refspec -> src == NULL ;
826- char * needle , * * result ;
827- int i ;
811+ if (find_src && !query -> dst )
812+ return error ("query_refspecs: need either src or dst" );
828813
829- if (find_src ) {
830- if (!refspec -> dst )
831- return error ("find_tracking: need either src or dst" );
832- needle = refspec -> dst ;
833- result = & refspec -> src ;
834- } else {
835- needle = refspec -> src ;
836- result = & refspec -> dst ;
837- }
814+ for (i = 0 ; i < ref_count ; i ++ ) {
815+ struct refspec * refspec = & refs [i ];
816+ const char * key = find_src ? refspec -> dst : refspec -> src ;
817+ const char * value = find_src ? refspec -> src : refspec -> dst ;
818+ const char * needle = find_src ? query -> dst : query -> src ;
819+ char * * result = find_src ? & query -> src : & query -> dst ;
838820
839- for (i = 0 ; i < remote -> fetch_refspec_nr ; i ++ ) {
840- struct refspec * fetch = & remote -> fetch [i ];
841- const char * key = find_src ? fetch -> dst : fetch -> src ;
842- const char * value = find_src ? fetch -> src : fetch -> dst ;
843- if (!fetch -> dst )
821+ if (!refspec -> dst )
844822 continue ;
845- if (fetch -> pattern ) {
823+ if (refspec -> pattern ) {
846824 if (match_name_with_pattern (key , needle , value , result )) {
847- refspec -> force = fetch -> force ;
825+ query -> force = refspec -> force ;
848826 return 0 ;
849827 }
850828 } else if (!strcmp (needle , key )) {
851829 * result = xstrdup (value );
852- refspec -> force = fetch -> force ;
830+ query -> force = refspec -> force ;
853831 return 0 ;
854832 }
855833 }
856834 return -1 ;
857835}
858836
837+ char * apply_refspecs (struct refspec * refspecs , int nr_refspec ,
838+ const char * name )
839+ {
840+ struct refspec query ;
841+
842+ memset (& query , 0 , sizeof (struct refspec ));
843+ query .src = (char * )name ;
844+
845+ if (query_refspecs (refspecs , nr_refspec , & query ))
846+ return NULL ;
847+
848+ return query .dst ;
849+ }
850+
851+ int remote_find_tracking (struct remote * remote , struct refspec * refspec )
852+ {
853+ return query_refspecs (remote -> fetch , remote -> fetch_refspec_nr , refspec );
854+ }
855+
859856static struct ref * alloc_ref_with_prefix (const char * prefix , size_t prefixlen ,
860857 const char * name )
861858{
@@ -1659,36 +1656,47 @@ struct ref *guess_remote_head(const struct ref *head,
16591656}
16601657
16611658struct stale_heads_info {
1662- struct remote * remote ;
16631659 struct string_list * ref_names ;
16641660 struct ref * * stale_refs_tail ;
1661+ struct refspec * refs ;
1662+ int ref_count ;
16651663};
16661664
16671665static int get_stale_heads_cb (const char * refname ,
16681666 const unsigned char * sha1 , int flags , void * cb_data )
16691667{
16701668 struct stale_heads_info * info = cb_data ;
1671- struct refspec refspec ;
1672- memset (& refspec , 0 , sizeof (refspec ));
1673- refspec .dst = (char * )refname ;
1674- if (!remote_find_tracking (info -> remote , & refspec )) {
1675- if (!((flags & REF_ISSYMREF ) ||
1676- string_list_has_string (info -> ref_names , refspec .src ))) {
1677- struct ref * ref = make_linked_ref (refname , & info -> stale_refs_tail );
1678- hashcpy (ref -> new_sha1 , sha1 );
1679- }
1669+ struct refspec query ;
1670+ memset (& query , 0 , sizeof (struct refspec ));
1671+ query .dst = (char * )refname ;
1672+
1673+ if (query_refspecs (info -> refs , info -> ref_count , & query ))
1674+ return 0 ; /* No matches */
1675+
1676+ /*
1677+ * If we did find a suitable refspec and it's not a symref and
1678+ * it's not in the list of refs that currently exist in that
1679+ * remote we consider it to be stale.
1680+ */
1681+ if (!((flags & REF_ISSYMREF ) ||
1682+ string_list_has_string (info -> ref_names , query .src ))) {
1683+ struct ref * ref = make_linked_ref (refname , & info -> stale_refs_tail );
1684+ hashcpy (ref -> new_sha1 , sha1 );
16801685 }
1686+
1687+ free (query .src );
16811688 return 0 ;
16821689}
16831690
1684- struct ref * get_stale_heads (struct remote * remote , struct ref * fetch_map )
1691+ struct ref * get_stale_heads (struct refspec * refs , int ref_count , struct ref * fetch_map )
16851692{
16861693 struct ref * ref , * stale_refs = NULL ;
16871694 struct string_list ref_names = STRING_LIST_INIT_NODUP ;
16881695 struct stale_heads_info info ;
1689- info .remote = remote ;
16901696 info .ref_names = & ref_names ;
16911697 info .stale_refs_tail = & stale_refs ;
1698+ info .refs = refs ;
1699+ info .ref_count = ref_count ;
16921700 for (ref = fetch_map ; ref ; ref = ref -> next )
16931701 string_list_append (& ref_names , ref -> name );
16941702 sort_string_list (& ref_names );
0 commit comments