@@ -236,6 +236,7 @@ static struct used_atom {
236236 S_FINGERPRINT , S_PRI_KEY_FP , S_TRUST_LEVEL } option ;
237237 } signature ;
238238 struct {
239+ char * name ;
239240 struct commit * commit ;
240241 } base ;
241242 struct strvec describe_args ;
@@ -908,18 +909,16 @@ static int ahead_behind_atom_parser(struct ref_format *format UNUSED,
908909 return 0 ;
909910}
910911
911- static int is_base_atom_parser (struct ref_format * format ,
912- struct used_atom * atom UNUSED ,
912+ static int is_base_atom_parser (struct ref_format * format UNUSED ,
913+ struct used_atom * atom ,
913914 const char * arg , struct strbuf * err )
914915{
915- struct string_list_item * item ;
916-
917916 if (!arg )
918917 return strbuf_addf_ret (err , -1 , _ ("expected format: %%(is-base:<committish>)" ));
919918
920- item = string_list_append ( & format -> is_base_tips , arg );
921- item -> util = lookup_commit_reference_by_name (arg );
922- if (!item -> util )
919+ atom -> u . base . name = xstrdup ( arg );
920+ atom -> u . base . commit = lookup_commit_reference_by_name (arg );
921+ if (!atom -> u . base . commit )
923922 die ("failed to find '%s'" , arg );
924923
925924 return 0 ;
@@ -3009,6 +3008,8 @@ void ref_array_clear(struct ref_array *array)
30093008 free (atom -> u .head );
30103009 else if (atom -> atom_type == ATOM_DESCRIBE )
30113010 strvec_clear (& atom -> u .describe_args );
3011+ else if (atom -> atom_type == ATOM_ISBASE )
3012+ free (atom -> u .base .name );
30123013 else if (atom -> atom_type == ATOM_TRAILERS ||
30133014 (atom -> atom_type == ATOM_CONTENTS &&
30143015 atom -> u .contents .option == C_TRAILERS )) {
@@ -3133,14 +3134,20 @@ void filter_ahead_behind(struct repository *r,
31333134}
31343135
31353136void filter_is_base (struct repository * r ,
3136- struct ref_format * format ,
31373137 struct ref_array * array )
31383138{
31393139 struct commit * * bases ;
3140- size_t bases_nr = 0 ;
3140+ size_t bases_nr = 0 , is_base_nr ;
31413141 struct ref_array_item * * back_index ;
31423142
3143- if (!format -> is_base_tips .nr || !array -> nr )
3143+ if (!array -> nr )
3144+ return ;
3145+
3146+ for (size_t i = is_base_nr = 0 ; i < used_atom_cnt ; i ++ ) {
3147+ if (used_atom [i ].atom_type == ATOM_ISBASE )
3148+ is_base_nr ++ ;
3149+ }
3150+ if (!is_base_nr )
31443151 return ;
31453152
31463153 CALLOC_ARRAY (back_index , array -> nr );
@@ -3150,7 +3157,7 @@ void filter_is_base(struct repository *r,
31503157 const char * name = array -> items [i ]-> refname ;
31513158 struct commit * c = lookup_commit_reference_by_name_gently (name , 1 );
31523159
3153- CALLOC_ARRAY (array -> items [i ]-> is_base , format -> is_base_tips . nr );
3160+ CALLOC_ARRAY (array -> items [i ]-> is_base , is_base_nr );
31543161
31553162 if (!c )
31563163 continue ;
@@ -3160,15 +3167,20 @@ void filter_is_base(struct repository *r,
31603167 bases_nr ++ ;
31613168 }
31623169
3163- for (size_t i = 0 ; i < format -> is_base_tips .nr ; i ++ ) {
3164- struct commit * tip = format -> is_base_tips .items [i ].util ;
3165- int base_index = get_branch_base_for_tip (r , tip , bases , bases_nr );
3170+ for (size_t i = 0 , j = 0 ; i < used_atom_cnt ; i ++ ) {
3171+ struct commit * tip ;
3172+ int base_index ;
3173+
3174+ if (used_atom [i ].atom_type != ATOM_ISBASE )
3175+ continue ;
31663176
3177+ tip = used_atom [i ].u .base .commit ;
3178+ base_index = get_branch_base_for_tip (r , tip , bases , bases_nr );
31673179 if (base_index < 0 )
31683180 continue ;
31693181
31703182 /* Store the string for use in output later. */
3171- back_index [base_index ]-> is_base [i ] = xstrdup (format -> is_base_tips . items [i ].string );
3183+ back_index [base_index ]-> is_base [j ++ ] = xstrdup (used_atom [i ].u . base . name );
31723184 }
31733185
31743186 free (back_index );
@@ -3260,8 +3272,7 @@ struct ref_sorting {
32603272};
32613273
32623274static inline int can_do_iterative_format (struct ref_filter * filter ,
3263- struct ref_sorting * sorting ,
3264- struct ref_format * format )
3275+ struct ref_sorting * sorting )
32653276{
32663277 /*
32673278 * Reference backends sort patterns lexicographically by refname, so if
@@ -3288,17 +3299,17 @@ static inline int can_do_iterative_format(struct ref_filter *filter,
32883299 for (size_t i = 0 ; i < used_atom_cnt ; i ++ ) {
32893300 if (used_atom [i ].atom_type == ATOM_AHEADBEHIND )
32903301 return 0 ;
3302+ if (used_atom [i ].atom_type == ATOM_ISBASE )
3303+ return 0 ;
32913304 }
3292- return !(filter -> reachable_from ||
3293- filter -> unreachable_from ||
3294- format -> is_base_tips .nr );
3305+ return !(filter -> reachable_from || filter -> unreachable_from );
32953306}
32963307
32973308void filter_and_format_refs (struct ref_filter * filter , unsigned int type ,
32983309 struct ref_sorting * sorting ,
32993310 struct ref_format * format )
33003311{
3301- if (can_do_iterative_format (filter , sorting , format )) {
3312+ if (can_do_iterative_format (filter , sorting )) {
33023313 int save_commit_buffer_orig ;
33033314 struct ref_filter_and_format_cbdata ref_cbdata = {
33043315 .filter = filter ,
@@ -3315,7 +3326,7 @@ void filter_and_format_refs(struct ref_filter *filter, unsigned int type,
33153326 struct ref_array array = { 0 };
33163327 filter_refs (& array , filter , type );
33173328 filter_ahead_behind (the_repository , & array );
3318- filter_is_base (the_repository , format , & array );
3329+ filter_is_base (the_repository , & array );
33193330 ref_array_sort (sorting , & array );
33203331 print_formatted_ref_array (& array , format );
33213332 ref_array_clear (& array );
@@ -3658,6 +3669,5 @@ void ref_format_init(struct ref_format *format)
36583669
36593670void ref_format_clear (struct ref_format * format )
36603671{
3661- string_list_clear (& format -> is_base_tips , 0 );
36623672 ref_format_init (format );
36633673}
0 commit comments