Git fork

builtin/for-each-ref: factor out core logic into a helper

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@pks.im>
Mentored-by: shejialuo <shejialuo@gmail.com>
Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Meet Soni <meetsoni3017@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Meet Soni and committed by
Junio C Hamano
6eeb1c07 69c207dc

+45 -22
+19 -22
builtin/for-each-ref.c
··· 2 2 #include "commit.h" 3 3 #include "config.h" 4 4 #include "environment.h" 5 + #include "for-each-ref.h" 5 6 #include "gettext.h" 6 7 #include "object.h" 7 8 #include "parse-options.h" ··· 9 10 #include "strbuf.h" 10 11 #include "strvec.h" 11 12 12 - #define COMMON_USAGE_FOR_EACH_REF \ 13 - "[--count=<count>] [--shell|--perl|--python|--tcl]\n" \ 14 - " [(--sort=<key>)...] [--format=<format>]\n" \ 15 - " [--include-root-refs] [--points-at=<object>]\n" \ 16 - " [--merged[=<object>]] [--no-merged[=<object>]]\n" \ 17 - " [--contains[=<object>]] [--no-contains[=<object>]]\n" \ 18 - " [(--exclude=<pattern>)...] [--start-after=<marker>]\n" \ 19 - " [ --stdin | <pattern>... ]" 20 - 21 - static char const * const for_each_ref_usage[] = { 22 - "git for-each-ref " COMMON_USAGE_FOR_EACH_REF, 23 - NULL 24 - }; 25 - 26 - int cmd_for_each_ref(int argc, 27 - const char **argv, 28 - const char *prefix, 29 - struct repository *repo) 13 + int for_each_ref_core(int argc, const char **argv, const char *prefix, struct repository *repo, const char *const *usage) 30 14 { 31 15 struct ref_sorting *sorting; 32 16 struct string_list sorting_options = STRING_LIST_INIT_DUP; ··· 75 59 /* Set default (refname) sorting */ 76 60 string_list_append(&sorting_options, "refname"); 77 61 78 - parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0); 62 + parse_options(argc, argv, prefix, opts, usage, 0); 79 63 if (format.array_opts.max_count < 0) { 80 64 error("invalid --count argument: `%d'", format.array_opts.max_count); 81 - usage_with_options(for_each_ref_usage, opts); 65 + usage_with_options(usage, opts); 82 66 } 83 67 if (HAS_MULTI_BITS(format.quote_style)) { 84 68 error("more than one quoting style?"); 85 - usage_with_options(for_each_ref_usage, opts); 69 + usage_with_options(usage, opts); 86 70 } 87 71 if (verify_ref_format(&format)) 88 - usage_with_options(for_each_ref_usage, opts); 72 + usage_with_options(usage, opts); 89 73 90 74 if (filter.start_after && sorting_options.nr > 1) 91 75 die(_("cannot use --start-after with custom sort options")); ··· 125 109 strvec_clear(&vec); 126 110 return 0; 127 111 } 112 + 113 + int cmd_for_each_ref(int argc, 114 + const char **argv, 115 + const char *prefix, 116 + struct repository *repo) 117 + { 118 + static char const * const for_each_ref_usage[] = { 119 + N_("git for-each-ref " COMMON_USAGE_FOR_EACH_REF), 120 + NULL 121 + }; 122 + 123 + return for_each_ref_core(argc, argv, prefix, repo, for_each_ref_usage); 124 + }
+26
for-each-ref.h
··· 1 + #ifndef FOR_EACH_REF_H 2 + #define FOR_EACH_REF_H 3 + 4 + struct repository; 5 + 6 + /* 7 + * Shared usage string for options common to git-for-each-ref(1) 8 + * and git-refs-list(1). The command-specific part (e.g., "git refs list ") 9 + * must be prepended by the caller. 10 + */ 11 + #define COMMON_USAGE_FOR_EACH_REF \ 12 + "[--count=<count>] [--shell|--perl|--python|--tcl]\n" \ 13 + " [(--sort=<key>)...] [--format=<format>]\n" \ 14 + " [--include-root-refs] [--points-at=<object>]\n" \ 15 + " [--merged[=<object>]] [--no-merged[=<object>]]\n" \ 16 + " [--contains[=<object>]] [--no-contains[=<object>]]\n" \ 17 + " [(--exclude=<pattern>)...] [--start-after=<marker>]\n" \ 18 + " [ --stdin | <pattern>... ]" 19 + 20 + /* 21 + * The core logic for for-each-ref and its clones. 22 + */ 23 + int for_each_ref_core(int argc, const char **argv, const char *prefix, 24 + struct repository *repo, const char *const *usage); 25 + 26 + #endif /* FOR_EACH_REF_H */