Am 18.01.25 um 18:11 schrieb René Scharfe: > I think moving to the right place in one step requires less churn. Let's > compare; v2 coming up. ... and this: --- ref-filter.c | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index caf28466ab..6da8d4c03b 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -236,6 +236,7 @@ static struct used_atom { S_FINGERPRINT, S_PRI_KEY_FP, S_TRUST_LEVEL } option; } signature; struct { + char *name; struct commit *commit; } base; struct strvec describe_args; @@ -245,9 +246,6 @@ static struct used_atom { } *used_atom; static int used_atom_cnt, need_tagged, need_symref; -/* List of bases for is-base indicators. */ -static struct string_list is_base_tips = STRING_LIST_INIT_DUP; - /* * Expand string, append it to strbuf *sb, then return error code ret. * Allow to save few lines of code. @@ -912,17 +910,15 @@ static int ahead_behind_atom_parser(struct ref_format *format UNUSED, } static int is_base_atom_parser(struct ref_format *format UNUSED, - struct used_atom *atom UNUSED, + struct used_atom *atom, const char *arg, struct strbuf *err) { - struct string_list_item *item; - if (!arg) return strbuf_addf_ret(err, -1, _("expected format: %%(is-base:<committish>)")); - item = string_list_append(&is_base_tips, arg); - item->util = lookup_commit_reference_by_name(arg); - if (!item->util) + atom->u.base.name = xstrdup(arg); + atom->u.base.commit = lookup_commit_reference_by_name(arg); + if (!atom->u.base.commit) die("failed to find '%s'", arg); return 0; @@ -3012,6 +3008,8 @@ void ref_array_clear(struct ref_array *array) free(atom->u.head); else if (atom->atom_type == ATOM_DESCRIBE) strvec_clear(&atom->u.describe_args); + else if (atom->atom_type == ATOM_ISBASE) + free(atom->u.base.name); else if (atom->atom_type == ATOM_TRAILERS || (atom->atom_type == ATOM_CONTENTS && atom->u.contents.option == C_TRAILERS)) { @@ -3027,7 +3025,6 @@ void ref_array_clear(struct ref_array *array) } FREE_AND_NULL(used_atom); used_atom_cnt = 0; - string_list_clear(&is_base_tips, 0); if (ref_to_worktree_map.worktrees) { hashmap_clear_and_free(&(ref_to_worktree_map.map), @@ -3140,10 +3137,17 @@ void filter_is_base(struct repository *r, struct ref_array *array) { struct commit **bases; - size_t bases_nr = 0; + size_t bases_nr = 0, is_base_nr; struct ref_array_item **back_index; - if (!is_base_tips.nr || !array->nr) + if (!array->nr) + return; + + for (size_t i = is_base_nr = 0; i < used_atom_cnt; i++) { + if (used_atom[i].atom_type == ATOM_ISBASE) + is_base_nr++; + } + if (!is_base_nr) return; CALLOC_ARRAY(back_index, array->nr); @@ -3153,7 +3157,7 @@ void filter_is_base(struct repository *r, const char *name = array->items[i]->refname; struct commit *c = lookup_commit_reference_by_name_gently(name, 1); - CALLOC_ARRAY(array->items[i]->is_base, is_base_tips.nr); + CALLOC_ARRAY(array->items[i]->is_base, is_base_nr); if (!c) continue; @@ -3163,15 +3167,20 @@ void filter_is_base(struct repository *r, bases_nr++; } - for (size_t i = 0; i < is_base_tips.nr; i++) { - struct commit *tip = is_base_tips.items[i].util; - int base_index = get_branch_base_for_tip(r, tip, bases, bases_nr); + for (size_t i = 0, j = 0; i < used_atom_cnt; i++) { + struct commit *tip; + int base_index; + if (used_atom[i].atom_type != ATOM_ISBASE) + continue; + + tip = used_atom[i].u.base.commit; + base_index = get_branch_base_for_tip(r, tip, bases, bases_nr); if (base_index < 0) continue; /* Store the string for use in output later. */ - back_index[base_index]->is_base[i] = xstrdup(is_base_tips.items[i].string); + back_index[base_index]->is_base[j++] = xstrdup(used_atom[i].u.base.name); } free(back_index); @@ -3290,10 +3299,10 @@ static inline int can_do_iterative_format(struct ref_filter *filter, for (size_t i = 0; i < used_atom_cnt; i++) { if (used_atom[i].atom_type == ATOM_AHEADBEHIND) return 0; + if (used_atom[i].atom_type == ATOM_ISBASE) + return 0; } - return !(filter->reachable_from || - filter->unreachable_from || - is_base_tips.nr); + return !(filter->reachable_from || filter->unreachable_from); } void filter_and_format_refs(struct ref_filter *filter, unsigned int type, -- 2.48.1