From: ZheNing Hu <adlternative@xxxxxxxxx> parse_sorting_atom() currently uses a "dummy" ref_format, because it doesn't care about the details of real ref_format. But in fact, we expect to save some state in ref_format, and we need to check these statuses when executing some functions, e.g. in verify_ref_format() we check format->quote_style and format->need_color_reset_at_eol. And we intentionally want some global options (e.g. need_tagged) to be added to struct ref_format, so we need to care about ref_format details now, but the "dummy" ref_format prevents the truly ref_format to record them correctly. So let parse_sorting_atom() use the real ref_format, this requires us to separate the work of parsing the sort atom from parse_ref_sorting(). Add an "arg" member to struct ref_sorting to record the name of the sort atom, and parse_ref_sorting() only records the atom name, and introduce a parse_ref_sorting_list() to traverse the ref_sorting linked list and parsing each sort atom. This will help us add some global options to struct ref_format later. Mentored-by: Christian Couder <christian.couder@xxxxxxxxx> Mentored-by: Hariom Verma <hariom18599@xxxxxxxxx> Signed-off-by: ZheNing Hu <adlternative@xxxxxxxxx> --- builtin/branch.c | 1 + builtin/for-each-ref.c | 1 + builtin/ls-remote.c | 6 ++++-- builtin/tag.c | 1 + ref-filter.c | 25 ++++++++++++++----------- ref-filter.h | 3 +++ 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 72fafd301c5..3b21c2b54b9 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -751,6 +751,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) */ if (list_empty(&sorting.list)) ref_default_sorting(&sorting); + parse_ref_sorting_list(&sorting, &format); ref_sorting_set_sort_flags_all(&sorting, REF_SORTING_ICASE, icase); ref_sorting_set_sort_flags_all( &sorting, REF_SORTING_DETACHED_HEAD_FIRST, 1); diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 3cd38eacd7c..8948b7bcd32 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -73,6 +73,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) if (list_empty(&sorting.list)) ref_default_sorting(&sorting); + parse_ref_sorting_list(&sorting, &format); ref_sorting_set_sort_flags_all(&sorting, REF_SORTING_ICASE, icase); filter.ignore_case = icase; diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index 717ecde03d1..7fac069a29d 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -49,6 +49,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) TRANSPORT_LS_REFS_OPTIONS_INIT; int i; struct string_list server_options = STRING_LIST_INIT_DUP; + struct ref_format dummy = REF_FORMAT_INIT; struct remote *remote; struct transport *transport; @@ -136,9 +137,10 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) item->symref = xstrdup_or_null(ref->symref); } - if (!list_empty(&sorting.list)) + if (!list_empty(&sorting.list)) { + parse_ref_sorting_list(&sorting, &dummy); ref_array_sort(&sorting, &ref_array); - + } for (i = 0; i < ref_array.nr; i++) { const struct ref_array_item *ref = ref_array.items[i]; if (show_symref_target && ref->symref) diff --git a/builtin/tag.c b/builtin/tag.c index 9d057b214e2..a0d4aa775e3 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -529,6 +529,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) } if (list_empty(&sorting.list)) ref_default_sorting(&sorting); + parse_ref_sorting_list(&sorting, &format); ref_sorting_set_sort_flags_all(&sorting, REF_SORTING_ICASE, icase); filter.ignore_case = icase; if (cmdmode == 'l') { diff --git a/ref-filter.c b/ref-filter.c index e9e3841c326..88a3e06eea9 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2656,30 +2656,33 @@ void pretty_print_ref(const char *name, const struct object_id *oid, free_array_item(ref_item); } -static int parse_sorting_atom(const char *atom) +static int parse_sorting_atom(struct ref_format *format, const char *atom) { - /* - * This parses an atom using a dummy ref_format, since we don't - * actually care about the formatting details. - */ - struct ref_format dummy = REF_FORMAT_INIT; const char *end = atom + strlen(atom); struct strbuf err = STRBUF_INIT; - int res = parse_ref_filter_atom(&dummy, atom, end, &err); + int res = parse_ref_filter_atom(format, atom, end, &err); if (res < 0) die("%s", err.buf); strbuf_release(&err); return res; } +void parse_ref_sorting_list(struct ref_sorting *sorting_list, struct ref_format *format) { + struct list_head *pos; + struct ref_sorting *entry; + + list_for_each(pos, &sorting_list->list) { + entry = list_entry(pos, struct ref_sorting, list); + entry->atom = parse_sorting_atom(format, entry->arg); + } +} + /* If no sorting option is given, use refname to sort as default */ void ref_default_sorting(struct ref_sorting *sorting_list) { - static const char cstr_name[] = "refname"; - struct ref_sorting *sorting = xcalloc(1, sizeof(*sorting)); list_add_tail(&sorting->list, &sorting_list->list); - sorting->atom = parse_sorting_atom(cstr_name); + sorting->arg = "refname"; } void free_ref_sorting_list(struct ref_sorting *sorting_list) { @@ -2707,7 +2710,7 @@ void parse_ref_sorting(struct ref_sorting *sorting_list, const char *arg) if (skip_prefix(arg, "version:", &arg) || skip_prefix(arg, "v:", &arg)) s->sort_flags |= REF_SORTING_VERSION; - s->atom = parse_sorting_atom(arg); + s->arg = arg; } int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset) diff --git a/ref-filter.h b/ref-filter.h index a502c2758e9..8f602583788 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -28,6 +28,7 @@ struct atom_value; struct ref_sorting { struct list_head list; int atom; /* index into used_atom array (internal) */ + const char *arg; enum { REF_SORTING_REVERSE = 1<<0, REF_SORTING_ICASE = 1<<1, @@ -128,6 +129,8 @@ void parse_ref_sorting(struct ref_sorting *sorting_list, const char *arg); int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset); /* Default sort option based on refname */ void ref_default_sorting(struct ref_sorting *sorting_list); +/* Parse every sort atom of ref_sorting list */ +void parse_ref_sorting_list(struct ref_sorting *sorting_list, struct ref_format *format); /* Free all ref_sorting items in sorting list */ void free_ref_sorting_list(struct ref_sorting *sorting_list); /* Function to parse --merged and --no-merged options */ -- gitgitgadget