The implementation of `git for-each-ref` is monolithic within `cmd_for_each_ref()`, making it impossible to share its logic with other commands. To enable code reuse for the upcoming `git refs list` subcommand, refactor the core logic into a shared helper function. Introduce a new `for-each-ref.h` header to define the public interface for this shared logic. It contains the declaration for a new helper function, `for_each_ref_core()`, and a macro for the common usage options. Move the option parsing, filtering, and formatting logic from `cmd_for_each_ref()` into a new helper function named `for_each_ref_core()`. This helper is made generic by accepting the command's usage string as a parameter. The original `cmd_for_each_ref()` is simplified to a thin wrapper that is only responsible for defining its specific usage array and calling the shared helper. Mentored-by: Patrick Steinhardt <ps@xxxxxx> Mentored-by: shejialuo <shejialuo@xxxxxxxxx> Mentored-by: Karthik Nayak <karthik.188@xxxxxxxxx> Signed-off-by: Meet Soni <meetsoni3017@xxxxxxxxx> --- builtin/for-each-ref.c | 35 +++++++++++++++++++---------------- for-each-ref.h | 24 ++++++++++++++++++++++++ t/t0450/adoc-help-mismatches | 1 - 3 files changed, 43 insertions(+), 17 deletions(-) create mode 100644 for-each-ref.h diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 3d2207ec77..bbc0e5ad1c 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -7,19 +7,9 @@ #include "ref-filter.h" #include "strbuf.h" #include "strvec.h" +#include "for-each-ref.h" -static char const * const for_each_ref_usage[] = { - N_("git for-each-ref [<options>] [<pattern>]"), - N_("git for-each-ref [--points-at <object>]"), - N_("git for-each-ref [--merged [<commit>]] [--no-merged [<commit>]]"), - N_("git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]"), - NULL -}; - -int cmd_for_each_ref(int argc, - const char **argv, - const char *prefix, - struct repository *repo) +int for_each_ref_core(int argc, const char **argv, const char *prefix, struct repository *repo, const char *const *usage) { struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; @@ -67,17 +57,17 @@ int cmd_for_each_ref(int argc, /* Set default (refname) sorting */ string_list_append(&sorting_options, "refname"); - parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0); + parse_options(argc, argv, prefix, opts, usage, 0); if (format.array_opts.max_count < 0) { error("invalid --count argument: `%d'", format.array_opts.max_count); - usage_with_options(for_each_ref_usage, opts); + usage_with_options(usage, opts); } if (HAS_MULTI_BITS(format.quote_style)) { error("more than one quoting style?"); - usage_with_options(for_each_ref_usage, opts); + usage_with_options(usage, opts); } if (verify_ref_format(&format)) - usage_with_options(for_each_ref_usage, opts); + usage_with_options(usage, opts); sorting = ref_sorting_options(&sorting_options); ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase); @@ -111,3 +101,16 @@ int cmd_for_each_ref(int argc, strvec_clear(&vec); return 0; } + +int cmd_for_each_ref(int argc, + const char **argv, + const char *prefix, + struct repository *repo) +{ + static char const * const for_each_ref_usage[] = { + N_("git for-each-ref " COMMON_USAGE_FOR_EACH_REF), + NULL + }; + + return for_each_ref_core(argc, argv, prefix, repo, for_each_ref_usage); +} diff --git a/for-each-ref.h b/for-each-ref.h new file mode 100644 index 0000000000..06d5b123b3 --- /dev/null +++ b/for-each-ref.h @@ -0,0 +1,24 @@ +#ifndef FOR_EACH_REF_H +#define FOR_EACH_REF_H + +/* + * Shared usage string for options common to git-for-each-ref(1) + * and git-refs-list(1). The command-specific part (e.g., "git refs list ") + * must be prepended by the caller. + */ +#define COMMON_USAGE_FOR_EACH_REF \ + "[--count=<count>] [--shell|--perl|--python|--tcl]\n" \ + " [(--sort=<key>)...] [--format=<format>]\n" \ + " [--include-root-refs] [ --stdin | <pattern>... ]\n" \ + " [--points-at=<object>]\n" \ + " [--merged[=<object>]] [--no-merged[=<object>]]\n" \ + " [--contains[=<object>]] [--no-contains[=<object>]]\n" \ + " [--exclude=<pattern> ...]" + +/* + * The core logic for for-each-ref and its clones. + */ +int for_each_ref_core(int argc, const char **argv, const char *prefix, + struct repository *repo, const char *const *usage); + +#endif /* FOR_EACH_REF_H */ diff --git a/t/t0450/adoc-help-mismatches b/t/t0450/adoc-help-mismatches index 06b469bdee..2c6ecd5fc8 100644 --- a/t/t0450/adoc-help-mismatches +++ b/t/t0450/adoc-help-mismatches @@ -17,7 +17,6 @@ fast-export fast-import fetch-pack fmt-merge-msg -for-each-ref format-patch fsck-objects fsmonitor--daemon -- 2.34.1