@@ -236,6 +236,7 @@ static struct used_atom {
236
236
S_FINGERPRINT , S_PRI_KEY_FP , S_TRUST_LEVEL } option ;
237
237
} signature ;
238
238
struct {
239
+ char * name ;
239
240
struct commit * commit ;
240
241
} base ;
241
242
struct strvec describe_args ;
@@ -908,18 +909,16 @@ static int ahead_behind_atom_parser(struct ref_format *format UNUSED,
908
909
return 0 ;
909
910
}
910
911
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 ,
913
914
const char * arg , struct strbuf * err )
914
915
{
915
- struct string_list_item * item ;
916
-
917
916
if (!arg )
918
917
return strbuf_addf_ret (err , -1 , _ ("expected format: %%(is-base:<committish>)" ));
919
918
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 )
923
922
die ("failed to find '%s'" , arg );
924
923
925
924
return 0 ;
@@ -3009,6 +3008,8 @@ void ref_array_clear(struct ref_array *array)
3009
3008
free (atom -> u .head );
3010
3009
else if (atom -> atom_type == ATOM_DESCRIBE )
3011
3010
strvec_clear (& atom -> u .describe_args );
3011
+ else if (atom -> atom_type == ATOM_ISBASE )
3012
+ free (atom -> u .base .name );
3012
3013
else if (atom -> atom_type == ATOM_TRAILERS ||
3013
3014
(atom -> atom_type == ATOM_CONTENTS &&
3014
3015
atom -> u .contents .option == C_TRAILERS )) {
@@ -3133,14 +3134,20 @@ void filter_ahead_behind(struct repository *r,
3133
3134
}
3134
3135
3135
3136
void filter_is_base (struct repository * r ,
3136
- struct ref_format * format ,
3137
3137
struct ref_array * array )
3138
3138
{
3139
3139
struct commit * * bases ;
3140
- size_t bases_nr = 0 ;
3140
+ size_t bases_nr = 0 , is_base_nr ;
3141
3141
struct ref_array_item * * back_index ;
3142
3142
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 )
3144
3151
return ;
3145
3152
3146
3153
CALLOC_ARRAY (back_index , array -> nr );
@@ -3150,7 +3157,7 @@ void filter_is_base(struct repository *r,
3150
3157
const char * name = array -> items [i ]-> refname ;
3151
3158
struct commit * c = lookup_commit_reference_by_name_gently (name , 1 );
3152
3159
3153
- CALLOC_ARRAY (array -> items [i ]-> is_base , format -> is_base_tips . nr );
3160
+ CALLOC_ARRAY (array -> items [i ]-> is_base , is_base_nr );
3154
3161
3155
3162
if (!c )
3156
3163
continue ;
@@ -3160,15 +3167,20 @@ void filter_is_base(struct repository *r,
3160
3167
bases_nr ++ ;
3161
3168
}
3162
3169
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 ;
3166
3176
3177
+ tip = used_atom [i ].u .base .commit ;
3178
+ base_index = get_branch_base_for_tip (r , tip , bases , bases_nr );
3167
3179
if (base_index < 0 )
3168
3180
continue ;
3169
3181
3170
3182
/* 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 );
3172
3184
}
3173
3185
3174
3186
free (back_index );
@@ -3260,8 +3272,7 @@ struct ref_sorting {
3260
3272
};
3261
3273
3262
3274
static 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 )
3265
3276
{
3266
3277
/*
3267
3278
* Reference backends sort patterns lexicographically by refname, so if
@@ -3288,17 +3299,17 @@ static inline int can_do_iterative_format(struct ref_filter *filter,
3288
3299
for (size_t i = 0 ; i < used_atom_cnt ; i ++ ) {
3289
3300
if (used_atom [i ].atom_type == ATOM_AHEADBEHIND )
3290
3301
return 0 ;
3302
+ if (used_atom [i ].atom_type == ATOM_ISBASE )
3303
+ return 0 ;
3291
3304
}
3292
- return !(filter -> reachable_from ||
3293
- filter -> unreachable_from ||
3294
- format -> is_base_tips .nr );
3305
+ return !(filter -> reachable_from || filter -> unreachable_from );
3295
3306
}
3296
3307
3297
3308
void filter_and_format_refs (struct ref_filter * filter , unsigned int type ,
3298
3309
struct ref_sorting * sorting ,
3299
3310
struct ref_format * format )
3300
3311
{
3301
- if (can_do_iterative_format (filter , sorting , format )) {
3312
+ if (can_do_iterative_format (filter , sorting )) {
3302
3313
int save_commit_buffer_orig ;
3303
3314
struct ref_filter_and_format_cbdata ref_cbdata = {
3304
3315
.filter = filter ,
@@ -3315,7 +3326,7 @@ void filter_and_format_refs(struct ref_filter *filter, unsigned int type,
3315
3326
struct ref_array array = { 0 };
3316
3327
filter_refs (& array , filter , type );
3317
3328
filter_ahead_behind (the_repository , & array );
3318
- filter_is_base (the_repository , format , & array );
3329
+ filter_is_base (the_repository , & array );
3319
3330
ref_array_sort (sorting , & array );
3320
3331
print_formatted_ref_array (& array , format );
3321
3332
ref_array_clear (& array );
@@ -3658,6 +3669,5 @@ void ref_format_init(struct ref_format *format)
3658
3669
3659
3670
void ref_format_clear (struct ref_format * format )
3660
3671
{
3661
- string_list_clear (& format -> is_base_tips , 0 );
3662
3672
ref_format_init (format );
3663
3673
}
0 commit comments