]> git.ipfire.org Git - thirdparty/git.git/commitdiff
ref-filter.h: add functions for filter/format & format-only
authorVictoria Dye <vdye@github.com>
Tue, 14 Nov 2023 19:53:52 +0000 (19:53 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Nov 2023 05:02:59 +0000 (14:02 +0900)
Add two new public methods to 'ref-filter.h':

* 'print_formatted_ref_array()' which, given a format specification & array
  of ref items, formats and prints the items to stdout.
* 'filter_and_format_refs()' which combines 'filter_refs()',
  'ref_array_sort()', and 'print_formatted_ref_array()' into a single
  function.

This consolidates much of the code used to filter and format refs in
'builtin/for-each-ref.c', 'builtin/tag.c', and 'builtin/branch.c', reducing
duplication and simplifying the future changes needed to optimize the filter
& format process.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/branch.c
builtin/for-each-ref.c
builtin/tag.c
ref-filter.c
ref-filter.h

index 49198b548e8c469367ab6ac3aff800cd5b7a9b74..40da31e640973a1e009cc4d9db720b3fe8d66b02 100644 (file)
@@ -437,8 +437,6 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
 {
        int i;
        struct ref_array array;
-       struct strbuf out = STRBUF_INIT;
-       struct strbuf err = STRBUF_INIT;
        int maxwidth = 0;
        const char *remote_prefix = "";
        char *to_free = NULL;
@@ -468,24 +466,27 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
        filter_ahead_behind(the_repository, format, &array);
        ref_array_sort(sorting, &array);
 
-       for (i = 0; i < array.nr; i++) {
-               strbuf_reset(&err);
-               strbuf_reset(&out);
-               if (format_ref_array_item(array.items[i], format, &out, &err))
-                       die("%s", err.buf);
-               if (column_active(colopts)) {
-                       assert(!filter->verbose && "--column and --verbose are incompatible");
-                        /* format to a string_list to let print_columns() do its job */
+       if (column_active(colopts)) {
+               struct strbuf out = STRBUF_INIT, err = STRBUF_INIT;
+
+               assert(!filter->verbose && "--column and --verbose are incompatible");
+
+               for (i = 0; i < array.nr; i++) {
+                       strbuf_reset(&err);
+                       strbuf_reset(&out);
+                       if (format_ref_array_item(array.items[i], format, &out, &err))
+                               die("%s", err.buf);
+
+                       /* format to a string_list to let print_columns() do its job */
                        string_list_append(output, out.buf);
-               } else {
-                       fwrite(out.buf, 1, out.len, stdout);
-                       if (out.len || !format->array_opts.omit_empty)
-                               putchar('\n');
                }
+
+               strbuf_release(&err);
+               strbuf_release(&out);
+       } else {
+               print_formatted_ref_array(&array, format);
        }
 
-       strbuf_release(&err);
-       strbuf_release(&out);
        ref_array_clear(&array);
        free(to_free);
 }
index 881c3ee055f2a6e408f831bc6bdef8741169b32d..1c19cd5bd340c3b6eecc1168517735eecf0224c5 100644 (file)
@@ -19,15 +19,11 @@ static char const * const for_each_ref_usage[] = {
 
 int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
 {
-       int i, total;
        struct ref_sorting *sorting;
        struct string_list sorting_options = STRING_LIST_INIT_DUP;
        int icase = 0;
-       struct ref_array array;
        struct ref_filter filter = REF_FILTER_INIT;
        struct ref_format format = REF_FORMAT_INIT;
-       struct strbuf output = STRBUF_INIT;
-       struct strbuf err = STRBUF_INIT;
        int from_stdin = 0;
        struct strvec vec = STRVEC_INIT;
 
@@ -61,8 +57,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
                OPT_END(),
        };
 
-       memset(&array, 0, sizeof(array));
-
        format.format = "%(objectname) %(objecttype)\t%(refname)";
 
        git_config(git_default_config, NULL);
@@ -104,27 +98,8 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
        }
 
        filter.match_as_path = 1;
-       filter_refs(&array, &filter, FILTER_REFS_ALL);
-       filter_ahead_behind(the_repository, &format, &array);
-
-       ref_array_sort(sorting, &array);
-
-       total = format.array_opts.max_count;
-       if (!total || array.nr < total)
-               total = array.nr;
-       for (i = 0; i < total; i++) {
-               strbuf_reset(&err);
-               strbuf_reset(&output);
-               if (format_ref_array_item(array.items[i], &format, &output, &err))
-                       die("%s", err.buf);
-               fwrite(output.buf, 1, output.len, stdout);
-               if (output.len || !format.array_opts.omit_empty)
-                       putchar('\n');
-       }
+       filter_and_format_refs(&filter, FILTER_REFS_ALL, sorting, &format);
 
-       strbuf_release(&err);
-       strbuf_release(&output);
-       ref_array_clear(&array);
        ref_filter_clear(&filter);
        ref_sorting_release(sorting);
        strvec_clear(&vec);
index 2d599245d480b6be8447abbe8772b413c3c99670..2528d499dd81bcf6c63a517d6ddf36099a2cc15b 100644 (file)
@@ -48,13 +48,7 @@ static int config_sign_tag = -1; /* unspecified */
 static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
                     struct ref_format *format)
 {
-       struct ref_array array;
-       struct strbuf output = STRBUF_INIT;
-       struct strbuf err = STRBUF_INIT;
        char *to_free = NULL;
-       int i;
-
-       memset(&array, 0, sizeof(array));
 
        if (filter->lines == -1)
                filter->lines = 0;
@@ -72,23 +66,8 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
        if (verify_ref_format(format))
                die(_("unable to parse format string"));
        filter->with_commit_tag_algo = 1;
-       filter_refs(&array, filter, FILTER_REFS_TAGS);
-       filter_ahead_behind(the_repository, format, &array);
-       ref_array_sort(sorting, &array);
-
-       for (i = 0; i < array.nr; i++) {
-               strbuf_reset(&output);
-               strbuf_reset(&err);
-               if (format_ref_array_item(array.items[i], format, &output, &err))
-                       die("%s", err.buf);
-               fwrite(output.buf, 1, output.len, stdout);
-               if (output.len || !format->array_opts.omit_empty)
-                       putchar('\n');
-       }
+       filter_and_format_refs(filter, FILTER_REFS_TAGS, sorting, format);
 
-       strbuf_release(&err);
-       strbuf_release(&output);
-       ref_array_clear(&array);
        free(to_free);
 
        return 0;
index 3de4cefcf5cab8d6456cc3b5910555a17754dfef..f062bb49385fdb08f6a05627637090f05a682254 100644 (file)
@@ -2939,6 +2939,18 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int
        return ret;
 }
 
+void filter_and_format_refs(struct ref_filter *filter, unsigned int type,
+                           struct ref_sorting *sorting,
+                           struct ref_format *format)
+{
+       struct ref_array array = { 0 };
+       filter_refs(&array, filter, type);
+       filter_ahead_behind(the_repository, format, &array);
+       ref_array_sort(sorting, &array);
+       print_formatted_ref_array(&array, format);
+       ref_array_clear(&array);
+}
+
 static int compare_detached_head(struct ref_array_item *a, struct ref_array_item *b)
 {
        if (!(a->kind ^ b->kind))
@@ -3128,6 +3140,29 @@ int format_ref_array_item(struct ref_array_item *info,
        return 0;
 }
 
+void print_formatted_ref_array(struct ref_array *array, struct ref_format *format)
+{
+       int total;
+       struct strbuf output = STRBUF_INIT, err = STRBUF_INIT;
+
+       total = format->array_opts.max_count;
+       if (!total || array->nr < total)
+               total = array->nr;
+       for (int i = 0; i < total; i++) {
+               strbuf_reset(&err);
+               strbuf_reset(&output);
+               if (format_ref_array_item(array->items[i], format, &output, &err))
+                       die("%s", err.buf);
+               if (output.len || !format->array_opts.omit_empty) {
+                       fwrite(output.buf, 1, output.len, stdout);
+                       putchar('\n');
+               }
+       }
+
+       strbuf_release(&err);
+       strbuf_release(&output);
+}
+
 void pretty_print_ref(const char *name, const struct object_id *oid,
                      struct ref_format *format)
 {
index 0db3ff5288978611bdbb5d0e78ea2347e0067104..0ce5af58ab353cf23d27638440399534154d8ce7 100644 (file)
@@ -137,6 +137,14 @@ struct ref_format {
  * filtered refs in the ref_array structure.
  */
 int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type);
+/*
+ * Filter refs using the given ref_filter and type, sort the contents
+ * according to the given ref_sorting, format the filtered refs with the
+ * given ref_format, and print them to stdout.
+ */
+void filter_and_format_refs(struct ref_filter *filter, unsigned int type,
+                           struct ref_sorting *sorting,
+                           struct ref_format *format);
 /*  Clear all memory allocated to ref_array */
 void ref_array_clear(struct ref_array *array);
 /*  Used to verify if the given format is correct and to parse out the used atoms */
@@ -161,6 +169,12 @@ char *get_head_description(void);
 /*  Set up translated strings in the output. */
 void setup_ref_filter_porcelain_msg(void);
 
+/*
+ * Print up to maxcount ref_array elements to stdout using the given
+ * ref_format.
+ */
+void print_formatted_ref_array(struct ref_array *array, struct ref_format *format);
+
 /*
  * Print a single ref, outside of any ref-filter. Note that the
  * name must be a fully qualified refname.