@@ -235,6 +235,10 @@ static struct used_atom {
235
235
enum { S_BARE , S_GRADE , S_SIGNER , S_KEY ,
236
236
S_FINGERPRINT , S_PRI_KEY_FP , S_TRUST_LEVEL } option ;
237
237
} signature ;
238
+ struct {
239
+ char * name ;
240
+ struct commit * commit ;
241
+ } base ;
238
242
struct strvec describe_args ;
239
243
struct refname_atom refname ;
240
244
char * head ;
@@ -891,35 +895,30 @@ static int rest_atom_parser(struct ref_format *format UNUSED,
891
895
return 0 ;
892
896
}
893
897
894
- static int ahead_behind_atom_parser (struct ref_format * format ,
895
- struct used_atom * atom UNUSED ,
898
+ static int ahead_behind_atom_parser (struct ref_format * format UNUSED ,
899
+ struct used_atom * atom ,
896
900
const char * arg , struct strbuf * err )
897
901
{
898
- struct string_list_item * item ;
899
-
900
902
if (!arg )
901
903
return strbuf_addf_ret (err , -1 , _ ("expected format: %%(ahead-behind:<committish>)" ));
902
904
903
- item = string_list_append (& format -> bases , arg );
904
- item -> util = lookup_commit_reference_by_name (arg );
905
- if (!item -> util )
905
+ atom -> u .base .commit = lookup_commit_reference_by_name (arg );
906
+ if (!atom -> u .base .commit )
906
907
die ("failed to find '%s'" , arg );
907
908
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 )) {
@@ -3084,22 +3085,30 @@ static void reach_filter(struct ref_array *array,
3084
3085
}
3085
3086
3086
3087
void filter_ahead_behind (struct repository * r ,
3087
- struct ref_format * format ,
3088
3088
struct ref_array * array )
3089
3089
{
3090
3090
struct commit * * commits ;
3091
- size_t commits_nr = format -> bases .nr + array -> nr ;
3091
+ size_t bases_nr , commits_nr ;
3092
+
3093
+ if (!array -> nr )
3094
+ return ;
3092
3095
3093
- if (!format -> bases .nr || !array -> nr )
3096
+ for (size_t i = bases_nr = 0 ; i < used_atom_cnt ; i ++ ) {
3097
+ if (used_atom [i ].atom_type == ATOM_AHEADBEHIND )
3098
+ bases_nr ++ ;
3099
+ }
3100
+ if (!bases_nr )
3094
3101
return ;
3095
3102
3096
- ALLOC_ARRAY (commits , commits_nr );
3097
- for (size_t i = 0 ; i < format -> bases .nr ; i ++ )
3098
- commits [i ] = format -> bases .items [i ].util ;
3103
+ ALLOC_ARRAY (commits , st_add (bases_nr , array -> nr ));
3104
+ for (size_t i = 0 , j = 0 ; i < used_atom_cnt ; i ++ ) {
3105
+ if (used_atom [i ].atom_type == ATOM_AHEADBEHIND )
3106
+ commits [j ++ ] = used_atom [i ].u .base .commit ;
3107
+ }
3099
3108
3100
- ALLOC_ARRAY (array -> counts , st_mult (format -> bases . nr , array -> nr ));
3109
+ ALLOC_ARRAY (array -> counts , st_mult (bases_nr , array -> nr ));
3101
3110
3102
- commits_nr = format -> bases . nr ;
3111
+ commits_nr = bases_nr ;
3103
3112
array -> counts_nr = 0 ;
3104
3113
for (size_t i = 0 ; i < array -> nr ; i ++ ) {
3105
3114
const char * name = array -> items [i ]-> refname ;
@@ -3108,8 +3117,8 @@ void filter_ahead_behind(struct repository *r,
3108
3117
if (!commits [commits_nr ])
3109
3118
continue ;
3110
3119
3111
- CALLOC_ARRAY (array -> items [i ]-> counts , format -> bases . nr );
3112
- for (size_t j = 0 ; j < format -> bases . nr ; j ++ ) {
3120
+ CALLOC_ARRAY (array -> items [i ]-> counts , bases_nr );
3121
+ for (size_t j = 0 ; j < bases_nr ; j ++ ) {
3113
3122
struct ahead_behind_count * count ;
3114
3123
count = & array -> counts [array -> counts_nr ++ ];
3115
3124
count -> tip_index = commits_nr ;
@@ -3125,14 +3134,20 @@ void filter_ahead_behind(struct repository *r,
3125
3134
}
3126
3135
3127
3136
void filter_is_base (struct repository * r ,
3128
- struct ref_format * format ,
3129
3137
struct ref_array * array )
3130
3138
{
3131
3139
struct commit * * bases ;
3132
- size_t bases_nr = 0 ;
3140
+ size_t bases_nr = 0 , is_base_nr ;
3133
3141
struct ref_array_item * * back_index ;
3134
3142
3135
- 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 )
3136
3151
return ;
3137
3152
3138
3153
CALLOC_ARRAY (back_index , array -> nr );
@@ -3142,7 +3157,7 @@ void filter_is_base(struct repository *r,
3142
3157
const char * name = array -> items [i ]-> refname ;
3143
3158
struct commit * c = lookup_commit_reference_by_name_gently (name , 1 );
3144
3159
3145
- CALLOC_ARRAY (array -> items [i ]-> is_base , format -> is_base_tips . nr );
3160
+ CALLOC_ARRAY (array -> items [i ]-> is_base , is_base_nr );
3146
3161
3147
3162
if (!c )
3148
3163
continue ;
@@ -3152,15 +3167,20 @@ void filter_is_base(struct repository *r,
3152
3167
bases_nr ++ ;
3153
3168
}
3154
3169
3155
- for (size_t i = 0 ; i < format -> is_base_tips .nr ; i ++ ) {
3156
- struct commit * tip = format -> is_base_tips .items [i ].util ;
3157
- 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 ;
3158
3176
3177
+ tip = used_atom [i ].u .base .commit ;
3178
+ base_index = get_branch_base_for_tip (r , tip , bases , bases_nr );
3159
3179
if (base_index < 0 )
3160
3180
continue ;
3161
3181
3162
3182
/* Store the string for use in output later. */
3163
- 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 );
3164
3184
}
3165
3185
3166
3186
free (back_index );
@@ -3252,8 +3272,7 @@ struct ref_sorting {
3252
3272
};
3253
3273
3254
3274
static inline int can_do_iterative_format (struct ref_filter * filter ,
3255
- struct ref_sorting * sorting ,
3256
- struct ref_format * format )
3275
+ struct ref_sorting * sorting )
3257
3276
{
3258
3277
/*
3259
3278
* Reference backends sort patterns lexicographically by refname, so if
@@ -3277,17 +3296,20 @@ static inline int can_do_iterative_format(struct ref_filter *filter,
3277
3296
* - filtering on reachability
3278
3297
* - including ahead-behind information in the formatted output
3279
3298
*/
3280
- return !(filter -> reachable_from ||
3281
- filter -> unreachable_from ||
3282
- format -> bases .nr ||
3283
- format -> is_base_tips .nr );
3299
+ for (size_t i = 0 ; i < used_atom_cnt ; i ++ ) {
3300
+ if (used_atom [i ].atom_type == ATOM_AHEADBEHIND )
3301
+ return 0 ;
3302
+ if (used_atom [i ].atom_type == ATOM_ISBASE )
3303
+ return 0 ;
3304
+ }
3305
+ return !(filter -> reachable_from || filter -> unreachable_from );
3284
3306
}
3285
3307
3286
3308
void filter_and_format_refs (struct ref_filter * filter , unsigned int type ,
3287
3309
struct ref_sorting * sorting ,
3288
3310
struct ref_format * format )
3289
3311
{
3290
- if (can_do_iterative_format (filter , sorting , format )) {
3312
+ if (can_do_iterative_format (filter , sorting )) {
3291
3313
int save_commit_buffer_orig ;
3292
3314
struct ref_filter_and_format_cbdata ref_cbdata = {
3293
3315
.filter = filter ,
@@ -3303,8 +3325,8 @@ void filter_and_format_refs(struct ref_filter *filter, unsigned int type,
3303
3325
} else {
3304
3326
struct ref_array array = { 0 };
3305
3327
filter_refs (& array , filter , type );
3306
- filter_ahead_behind (the_repository , format , & array );
3307
- filter_is_base (the_repository , format , & array );
3328
+ filter_ahead_behind (the_repository , & array );
3329
+ filter_is_base (the_repository , & array );
3308
3330
ref_array_sort (sorting , & array );
3309
3331
print_formatted_ref_array (& array , format );
3310
3332
ref_array_clear (& array );
@@ -3638,16 +3660,3 @@ void ref_filter_clear(struct ref_filter *filter)
3638
3660
free_commit_list (filter -> unreachable_from );
3639
3661
ref_filter_init (filter );
3640
3662
}
3641
-
3642
- void ref_format_init (struct ref_format * format )
3643
- {
3644
- struct ref_format blank = REF_FORMAT_INIT ;
3645
- memcpy (format , & blank , sizeof (blank ));
3646
- }
3647
-
3648
- void ref_format_clear (struct ref_format * format )
3649
- {
3650
- string_list_clear (& format -> bases , 0 );
3651
- string_list_clear (& format -> is_base_tips , 0 );
3652
- ref_format_init (format );
3653
- }
0 commit comments