Git fork

ref-filter: move is-base tip to used_atom

The string_list "is_base_tips" in struct ref_format stores the
committish part of "is-base:<committish>". It has the same problems
that its sibling string_list "bases" had. Fix them the same way as the
previous commit did for the latter, by replacing the string_list with
fields in "used_atom".

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

René Scharfe and committed by
Junio C Hamano
7ee4fd18 5e58db65

+62 -28
+33 -23
ref-filter.c
··· 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 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 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 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 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 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 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 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 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 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 }
-5
ref-filter.h
··· 99 99 /* Internal state to ref-filter */ 100 100 int need_color_reset_at_eol; 101 101 102 - /* List of bases for is-base indicators. */ 103 - struct string_list is_base_tips; 104 - 105 102 struct { 106 103 int max_count; 107 104 int omit_empty; ··· 114 111 } 115 112 #define REF_FORMAT_INIT { \ 116 113 .use_color = -1, \ 117 - .is_base_tips = STRING_LIST_INIT_DUP, \ 118 114 } 119 115 120 116 /* Macros for checking --merged and --no-merged options */ ··· 210 206 * If this is not called, then any is-base atoms will be blank. 211 207 */ 212 208 void filter_is_base(struct repository *r, 213 - struct ref_format *format, 214 209 struct ref_array *array); 215 210 216 211 void ref_filter_init(struct ref_filter *filter);
+29
t/t6600-test-reach.sh
··· 733 733 --format="%(refname)[%(is-base:commit-2-3)-%(is-base:commit-6-5)]" --stdin 734 734 ' 735 735 736 + test_expect_success 'for-each-ref is-base: --sort' ' 737 + cat >input <<-\EOF && 738 + refs/heads/commit-1-1 739 + refs/heads/commit-4-2 740 + refs/heads/commit-4-4 741 + refs/heads/commit-8-4 742 + EOF 743 + 744 + cat >expect <<-\EOF && 745 + refs/heads/commit-1-1 746 + refs/heads/commit-4-4 747 + refs/heads/commit-8-4 748 + refs/heads/commit-4-2 749 + EOF 750 + run_all_modes git for-each-ref \ 751 + --format="%(refname)" --stdin \ 752 + --sort=refname --sort=is-base:commit-2-3 && 753 + 754 + cat >expect <<-\EOF && 755 + refs/heads/commit-4-2 756 + refs/heads/commit-1-1 757 + refs/heads/commit-4-4 758 + refs/heads/commit-8-4 759 + EOF 760 + run_all_modes git for-each-ref \ 761 + --format="%(refname)" --stdin \ 762 + --sort=refname --sort=-is-base:commit-2-3 763 + ' 764 + 736 765 test_done