Re: [PATCH] ref-filter: share bases and is_base_tips between formatting and sorting
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.
The version building on top of v1 would look like this:
---
ref-filter.c | 48 ++++++++++++++++++++++++++++--------------------
1 file changed, 28 insertions(+), 20 deletions(-)
diff --git a/ref-filter.c b/ref-filter.c
index 89f44936f9..caf28466ab 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -235,6 +235,9 @@ static struct used_atom {
enum { S_BARE, S_GRADE, S_SIGNER, S_KEY,
S_FINGERPRINT, S_PRI_KEY_FP, S_TRUST_LEVEL } option;
} signature;
+ struct {
+ struct commit *commit;
+ } base;
struct strvec describe_args;
struct refname_atom refname;
char *head;
@@ -242,9 +245,6 @@ static struct used_atom {
} *used_atom;
static int used_atom_cnt, need_tagged, need_symref;
-/* List of bases for ahead-behind counts. */
-static struct string_list bases = STRING_LIST_INIT_DUP;
-
/* List of bases for is-base indicators. */
static struct string_list is_base_tips = STRING_LIST_INIT_DUP;
@@ -898,17 +898,14 @@ static int rest_atom_parser(struct ref_format *format UNUSED,
}
static int ahead_behind_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: %%(ahead-behind:<committish>)"));
- item = string_list_append(&bases, arg);
- item->util = lookup_commit_reference_by_name(arg);
- if (!item->util)
+ atom->u.base.commit = lookup_commit_reference_by_name(arg);
+ if (!atom->u.base.commit)
die("failed to find '%s'", arg);
return 0;
@@ -3030,7 +3027,6 @@ void ref_array_clear(struct ref_array *array)
}
FREE_AND_NULL(used_atom);
used_atom_cnt = 0;
- string_list_clear(&bases, 0);
string_list_clear(&is_base_tips, 0);
if (ref_to_worktree_map.worktrees) {
@@ -3095,18 +3091,27 @@ void filter_ahead_behind(struct repository *r,
struct ref_array *array)
{
struct commit **commits;
- size_t commits_nr = bases.nr + array->nr;
+ size_t bases_nr, commits_nr;
+
+ if (!array->nr)
+ return;
- if (!bases.nr || !array->nr)
+ for (size_t i = bases_nr = 0; i < used_atom_cnt; i++) {
+ if (used_atom[i].atom_type == ATOM_AHEADBEHIND)
+ bases_nr++;
+ }
+ if (!bases_nr)
return;
- ALLOC_ARRAY(commits, commits_nr);
- for (size_t i = 0; i < bases.nr; i++)
- commits[i] = bases.items[i].util;
+ ALLOC_ARRAY(commits, st_add(bases_nr, array->nr));
+ for (size_t i = 0, j = 0; i < used_atom_cnt; i++) {
+ if (used_atom[i].atom_type == ATOM_AHEADBEHIND)
+ commits[j++] = used_atom[i].u.base.commit;
+ }
- ALLOC_ARRAY(array->counts, st_mult(bases.nr, array->nr));
+ ALLOC_ARRAY(array->counts, st_mult(bases_nr, array->nr));
- commits_nr = bases.nr;
+ commits_nr = bases_nr;
array->counts_nr = 0;
for (size_t i = 0; i < array->nr; i++) {
const char *name = array->items[i]->refname;
@@ -3115,8 +3120,8 @@ void filter_ahead_behind(struct repository *r,
if (!commits[commits_nr])
continue;
- CALLOC_ARRAY(array->items[i]->counts, bases.nr);
- for (size_t j = 0; j < bases.nr; j++) {
+ CALLOC_ARRAY(array->items[i]->counts, bases_nr);
+ for (size_t j = 0; j < bases_nr; j++) {
struct ahead_behind_count *count;
count = &array->counts[array->counts_nr++];
count->tip_index = commits_nr;
@@ -3282,9 +3287,12 @@ static inline int can_do_iterative_format(struct ref_filter *filter,
* - filtering on reachability
* - including ahead-behind information in the formatted output
*/
+ for (size_t i = 0; i < used_atom_cnt; i++) {
+ if (used_atom[i].atom_type == ATOM_AHEADBEHIND)
+ return 0;
+ }
return !(filter->reachable_from ||
filter->unreachable_from ||
- bases.nr ||
is_base_tips.nr);
}
--
2.48.1