From: Jeff King <peff@peff•net>
To: "René Scharfe" <l.s.r@web•de>
Cc: Ross Goldberg <ross.goldberg@gmail•com>,
git@vger•kernel.org, Derrick Stolee <stolee@gmail•com>,
Junio C Hamano <gitster@pobox•com>
Subject: Re: [PATCH] ref-filter: share bases and is_base_tips between formatting and sorting
Date: Thu, 16 Jan 2025 05:21:54 -0500 [thread overview]
Message-ID: <20250116102154.GA724126@coredump.intra.peff.net> (raw)
In-Reply-To: <20250116100637.GB144555@coredump.intra.peff.net>
On Thu, Jan 16, 2025 at 05:06:37AM -0500, Jeff King wrote:
> On Thu, Jan 16, 2025 at 04:51:28AM -0500, Jeff King wrote:
>
> > Yet another option in the near term might be storing these ahead-behind
> > bits in the individual atoms. Since the point is to do a single
> > traversal, we'd have to marshal them into a unified data structure at
> > some point. But we already do that! In filter_ahead_behind() we convert
> > the string list into an array (and ironically do not even look at the
> > strings, only their "util" fields).
> >
> > So something like this (only lightly tested) seems to work:
>
> I compiled it without DEVELOPER=1, so I missed a few unused parameters.
> We'd want this on top:
And one final thought on this approach: if we do want to do it, perhaps
it would make sense to build on top of the patch you sent. I think yours
fixes the bug in a more direct and obvious way, and then my approach
would merely be internal reorganization on top.
At any rate, here is the is_base conversion for posterity.
diff --git a/ref-filter.c b/ref-filter.c
index 0de51f13e6..28d48ec585 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;
@@ -908,18 +909,16 @@ static int ahead_behind_atom_parser(struct ref_format *format UNUSED,
return 0;
}
-static int is_base_atom_parser(struct ref_format *format,
- struct used_atom *atom UNUSED,
+static int is_base_atom_parser(struct ref_format *format 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(&format->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;
@@ -3137,14 +3136,20 @@ void filter_ahead_behind(struct repository *r,
}
void filter_is_base(struct repository *r,
- struct ref_format *format,
struct ref_array *array)
{
struct commit **bases;
size_t bases_nr = 0;
struct ref_array_item **back_index;
+ size_t atoms_nr;
- if (!format->is_base_tips.nr || !array->nr)
+ atoms_nr = 0;
+ for (size_t i = 0; i < used_atom_cnt; i++) {
+ if (used_atom[i].atom_type == ATOM_ISBASE)
+ atoms_nr++;
+ }
+
+ if (!atoms_nr || !array->nr)
return;
CALLOC_ARRAY(back_index, array->nr);
@@ -3154,7 +3159,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, format->is_base_tips.nr);
+ CALLOC_ARRAY(array->items[i]->is_base, atoms_nr);
if (!c)
continue;
@@ -3164,15 +3169,21 @@ void filter_is_base(struct repository *r,
bases_nr++;
}
- for (size_t i = 0; i < format->is_base_tips.nr; i++) {
- struct commit *tip = format->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(format->is_base_tips.items[i].string);
+ back_index[base_index]->is_base[j++] = xstrdup(used_atom[i].u.base.name);
}
free(back_index);
@@ -3264,8 +3275,7 @@ struct ref_sorting {
};
static inline int can_do_iterative_format(struct ref_filter *filter,
- struct ref_sorting *sorting,
- struct ref_format *format)
+ struct ref_sorting *sorting)
{
/*
* Reference backends sort patterns lexicographically by refname, so if
@@ -3292,17 +3302,18 @@ 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 ||
- format->is_base_tips.nr);
+ filter->unreachable_from);
}
void filter_and_format_refs(struct ref_filter *filter, unsigned int type,
struct ref_sorting *sorting,
struct ref_format *format)
{
- if (can_do_iterative_format(filter, sorting, format)) {
+ if (can_do_iterative_format(filter, sorting)) {
int save_commit_buffer_orig;
struct ref_filter_and_format_cbdata ref_cbdata = {
.filter = filter,
@@ -3319,7 +3330,7 @@ void filter_and_format_refs(struct ref_filter *filter, unsigned int type,
struct ref_array array = { 0 };
filter_refs(&array, filter, type);
filter_ahead_behind(the_repository, &array);
- filter_is_base(the_repository, format, &array);
+ filter_is_base(the_repository, &array);
ref_array_sort(sorting, &array);
print_formatted_ref_array(&array, format);
ref_array_clear(&array);
@@ -3662,6 +3673,5 @@ void ref_format_init(struct ref_format *format)
void ref_format_clear(struct ref_format *format)
{
- string_list_clear(&format->is_base_tips, 0);
ref_format_init(format);
}
diff --git a/ref-filter.h b/ref-filter.h
index 5f3dd6c931..0ba94df651 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -99,9 +99,6 @@ struct ref_format {
/* Internal state to ref-filter */
int need_color_reset_at_eol;
- /* List of bases for is-base indicators. */
- struct string_list is_base_tips;
-
struct {
int max_count;
int omit_empty;
@@ -114,7 +111,6 @@ struct ref_format {
}
#define REF_FORMAT_INIT { \
.use_color = -1, \
- .is_base_tips = STRING_LIST_INIT_DUP, \
}
/* Macros for checking --merged and --no-merged options */
@@ -210,7 +206,6 @@ void filter_ahead_behind(struct repository *r,
* If this is not called, then any is-base atoms will be blank.
*/
void filter_is_base(struct repository *r,
- struct ref_format *format,
struct ref_array *array);
void ref_filter_init(struct ref_filter *filter);
next prev parent reply other threads:[~2025-01-16 10:21 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-05 9:48 Bug sorting git branch output by ahead-behind:HEAD Ross Goldberg
2025-01-12 10:01 ` [PATCH] ref-filter: share bases and is_base_tips between formatting and sorting René Scharfe
2025-01-13 5:17 ` Jeff King
2025-01-13 5:23 ` Jeff King
2025-01-13 17:25 ` Junio C Hamano
2025-01-14 18:55 ` René Scharfe
2025-01-16 9:51 ` Jeff King
2025-01-16 10:06 ` Jeff King
2025-01-16 10:21 ` Jeff King [this message]
2025-01-16 17:31 ` Junio C Hamano
2025-01-18 17:11 ` René Scharfe
2025-01-19 9:11 ` René Scharfe
2025-01-19 9:11 ` René Scharfe
2025-01-19 9:26 ` René Scharfe
2025-01-19 12:40 ` Jeff King
2025-01-18 17:11 ` René Scharfe
2025-01-18 17:11 ` [PATCH v2 1/3] ref-filter: move ahead-behind bases into used_atom René Scharfe
2025-01-18 17:11 ` [PATCH v2 2/3] ref-filter: move is-base tip to used_atom René Scharfe
2025-01-18 17:11 ` [PATCH v2 3/3] ref-filter: remove ref_format_clear() René Scharfe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250116102154.GA724126@coredump.intra.peff.net \
--to=peff@peff$(echo .)net \
--cc=git@vger$(echo .)kernel.org \
--cc=gitster@pobox$(echo .)com \
--cc=l.s.r@web$(echo .)de \
--cc=ross.goldberg@gmail$(echo .)com \
--cc=stolee@gmail$(echo .)com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox