builtin/reflog: make functions regarding `reflog_expire_options` public

Make functions that are required to manage `reflog_expire_options` available elsewhere by moving them into "reflog.c" and exposing them in the corresponding header. The functions will be used in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Apr 8, 2025 at 08:22 UTC d20fc193b663cd98364c07195e6cb38618a30c10
3 files changed +128 -111
builtin/reflog.c
+4 -111
@@ -88,113 +88,6 @@ static int collect_reflog(const char *ref, void *cb_data)
88 return 0;
89 }
90
91 -static struct reflog_expire_entry_option *find_cfg_ent(struct reflog_expire_options *opts,
92 - const char *pattern, size_t len)
93 -{
94 - struct reflog_expire_entry_option *ent;
95 -
96 - if (!opts->entries_tail)
97 - opts->entries_tail = &opts->entries;
98 -
99 - for (ent = opts->entries; ent; ent = ent->next)
100 - if (!xstrncmpz(ent->pattern, pattern, len))
101 - return ent;
102 -
103 - FLEX_ALLOC_MEM(ent, pattern, pattern, len);
104 - *opts->entries_tail = ent;
105 - opts->entries_tail = &(ent->next);
106 - return ent;
107 -}
108 -
109 -/* expiry timer slot */
110 -#define EXPIRE_TOTAL 01
111 -#define EXPIRE_UNREACH 02
112 -
113 -static int reflog_expire_config(const char *var, const char *value,
114 - const struct config_context *ctx, void *cb)
115 -{
116 - struct reflog_expire_options *opts = cb;
117 - const char *pattern, *key;
118 - size_t pattern_len;
119 - timestamp_t expire;
120 - int slot;
121 - struct reflog_expire_entry_option *ent;
122 -
123 - if (parse_config_key(var, "gc", &pattern, &pattern_len, &key) < 0)
124 - return git_default_config(var, value, ctx, cb);
125 -
126 - if (!strcmp(key, "reflogexpire")) {
127 - slot = EXPIRE_TOTAL;
128 - if (git_config_expiry_date(&expire, var, value))
129 - return -1;
130 - } else if (!strcmp(key, "reflogexpireunreachable")) {
131 - slot = EXPIRE_UNREACH;
132 - if (git_config_expiry_date(&expire, var, value))
133 - return -1;
134 - } else
135 - return git_default_config(var, value, ctx, cb);
136 -
137 - if (!pattern) {
138 - switch (slot) {
139 - case EXPIRE_TOTAL:
140 - opts->default_expire_total = expire;
141 - break;
142 - case EXPIRE_UNREACH:
143 - opts->default_expire_unreachable = expire;
144 - break;
145 - }
146 - return 0;
147 - }
148 -
149 - ent = find_cfg_ent(opts, pattern, pattern_len);
150 - if (!ent)
151 - return -1;
152 - switch (slot) {
153 - case EXPIRE_TOTAL:
154 - ent->expire_total = expire;
155 - break;
156 - case EXPIRE_UNREACH:
157 - ent->expire_unreachable = expire;
158 - break;
159 - }
160 - return 0;
161 -}
162 -
163 -static void set_reflog_expiry_param(struct reflog_expire_options *cb, const char *ref)
164 -{
165 - struct reflog_expire_entry_option *ent;
166 -
167 - if (cb->explicit_expiry == (EXPIRE_TOTAL|EXPIRE_UNREACH))
168 - return; /* both given explicitly -- nothing to tweak */
169 -
170 - for (ent = cb->entries; ent; ent = ent->next) {
171 - if (!wildmatch(ent->pattern, ref, 0)) {
172 - if (!(cb->explicit_expiry & EXPIRE_TOTAL))
173 - cb->expire_total = ent->expire_total;
174 - if (!(cb->explicit_expiry & EXPIRE_UNREACH))
175 - cb->expire_unreachable = ent->expire_unreachable;
176 - return;
177 - }
178 - }
179 -
180 - /*
181 - * If unconfigured, make stash never expire
182 - */
183 - if (!strcmp(ref, "refs/stash")) {
184 - if (!(cb->explicit_expiry & EXPIRE_TOTAL))
185 - cb->expire_total = 0;
186 - if (!(cb->explicit_expiry & EXPIRE_UNREACH))
187 - cb->expire_unreachable = 0;
188 - return;
189 - }
190 -
191 - /* Nothing matched -- use the default value */
192 - if (!(cb->explicit_expiry & EXPIRE_TOTAL))
193 - cb->expire_total = cb->default_expire_total;
194 - if (!(cb->explicit_expiry & EXPIRE_UNREACH))
195 - cb->expire_unreachable = cb->default_expire_unreachable;
196 -}
197 -
91 static int expire_unreachable_callback(const struct option *opt,
92 const char *arg,
93 int unset)
@@ -207,7 +100,7 @@ static int expire_unreachable_callback(const struct option *opt,
100 die(_("invalid timestamp '%s' given to '--%s'"),
101 arg, opt->long_name);
102
210 - opts->explicit_expiry |= EXPIRE_UNREACH;
103 + opts->explicit_expiry |= REFLOG_EXPIRE_UNREACH;
104 return 0;
105 }
106
@@ -223,7 +116,7 @@ static int expire_total_callback(const struct option *opt,
116 die(_("invalid timestamp '%s' given to '--%s'"),
117 arg, opt->long_name);
118
226 - opts->explicit_expiry |= EXPIRE_TOTAL;
119 + opts->explicit_expiry |= REFLOG_EXPIRE_TOTAL;
120 return 0;
121 }
122
@@ -353,7 +246,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix,
246 .dry_run = !!(flags & EXPIRE_REFLOGS_DRY_RUN),
247 };
248
356 - set_reflog_expiry_param(&cb.opts, item->string);
249 + reflog_expire_options_set_refname(&cb.opts, item->string);
250 status |= refs_reflog_expire(get_main_ref_store(the_repository),
251 item->string, flags,
252 reflog_expiry_prepare,
@@ -372,7 +265,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix,
265 status |= error(_("%s points nowhere!"), argv[i]);
266 continue;
267 }
375 - set_reflog_expiry_param(&cb.opts, ref);
268 + reflog_expire_options_set_refname(&cb.opts, ref);
269 status |= refs_reflog_expire(get_main_ref_store(the_repository),
270 ref, flags,
271 reflog_expiry_prepare,
reflog.c
+107
@@ -2,13 +2,120 @@
2 #define DISABLE_SIGN_COMPARE_WARNINGS
3
4 #include "git-compat-util.h"
5 +#include "config.h"
6 #include "gettext.h"
7 #include "object-store-ll.h"
8 +#include "parse-options.h"
9 #include "reflog.h"
10 #include "refs.h"
11 #include "revision.h"
12 #include "tree.h"
13 #include "tree-walk.h"
14 +#include "wildmatch.h"
15 +
16 +static struct reflog_expire_entry_option *find_cfg_ent(struct reflog_expire_options *opts,
17 + const char *pattern, size_t len)
18 +{
19 + struct reflog_expire_entry_option *ent;
20 +
21 + if (!opts->entries_tail)
22 + opts->entries_tail = &opts->entries;
23 +
24 + for (ent = opts->entries; ent; ent = ent->next)
25 + if (!xstrncmpz(ent->pattern, pattern, len))
26 + return ent;
27 +
28 + FLEX_ALLOC_MEM(ent, pattern, pattern, len);
29 + *opts->entries_tail = ent;
30 + opts->entries_tail = &(ent->next);
31 + return ent;
32 +}
33 +
34 +int reflog_expire_config(const char *var, const char *value,
35 + const struct config_context *ctx, void *cb)
36 +{
37 + struct reflog_expire_options *opts = cb;
38 + const char *pattern, *key;
39 + size_t pattern_len;
40 + timestamp_t expire;
41 + int slot;
42 + struct reflog_expire_entry_option *ent;
43 +
44 + if (parse_config_key(var, "gc", &pattern, &pattern_len, &key) < 0)
45 + return git_default_config(var, value, ctx, cb);
46 +
47 + if (!strcmp(key, "reflogexpire")) {
48 + slot = REFLOG_EXPIRE_TOTAL;
49 + if (git_config_expiry_date(&expire, var, value))
50 + return -1;
51 + } else if (!strcmp(key, "reflogexpireunreachable")) {
52 + slot = REFLOG_EXPIRE_UNREACH;
53 + if (git_config_expiry_date(&expire, var, value))
54 + return -1;
55 + } else
56 + return git_default_config(var, value, ctx, cb);
57 +
58 + if (!pattern) {
59 + switch (slot) {
60 + case REFLOG_EXPIRE_TOTAL:
61 + opts->default_expire_total = expire;
62 + break;
63 + case REFLOG_EXPIRE_UNREACH:
64 + opts->default_expire_unreachable = expire;
65 + break;
66 + }
67 + return 0;
68 + }
69 +
70 + ent = find_cfg_ent(opts, pattern, pattern_len);
71 + if (!ent)
72 + return -1;
73 + switch (slot) {
74 + case REFLOG_EXPIRE_TOTAL:
75 + ent->expire_total = expire;
76 + break;
77 + case REFLOG_EXPIRE_UNREACH:
78 + ent->expire_unreachable = expire;
79 + break;
80 + }
81 + return 0;
82 +}
83 +
84 +void reflog_expire_options_set_refname(struct reflog_expire_options *cb,
85 + const char *ref)
86 +{
87 + struct reflog_expire_entry_option *ent;
88 +
89 + if (cb->explicit_expiry == (REFLOG_EXPIRE_TOTAL|REFLOG_EXPIRE_UNREACH))
90 + return; /* both given explicitly -- nothing to tweak */
91 +
92 + for (ent = cb->entries; ent; ent = ent->next) {
93 + if (!wildmatch(ent->pattern, ref, 0)) {
94 + if (!(cb->explicit_expiry & REFLOG_EXPIRE_TOTAL))
95 + cb->expire_total = ent->expire_total;
96 + if (!(cb->explicit_expiry & REFLOG_EXPIRE_UNREACH))
97 + cb->expire_unreachable = ent->expire_unreachable;
98 + return;
99 + }
100 + }
101 +
102 + /*
103 + * If unconfigured, make stash never expire
104 + */
105 + if (!strcmp(ref, "refs/stash")) {
106 + if (!(cb->explicit_expiry & REFLOG_EXPIRE_TOTAL))
107 + cb->expire_total = 0;
108 + if (!(cb->explicit_expiry & REFLOG_EXPIRE_UNREACH))
109 + cb->expire_unreachable = 0;
110 + return;
111 + }
112 +
113 + /* Nothing matched -- use the default value */
114 + if (!(cb->explicit_expiry & REFLOG_EXPIRE_TOTAL))
115 + cb->expire_total = cb->default_expire_total;
116 + if (!(cb->explicit_expiry & REFLOG_EXPIRE_UNREACH))
117 + cb->expire_unreachable = cb->default_expire_unreachable;
118 +}
119
120 /* Remember to update object flag allocation in object.h */
121 #define INCOMPLETE (1u<<10)
reflog.h
+17
@@ -2,6 +2,9 @@
2 #define REFLOG_H
3 #include "refs.h"
4
5 +#define REFLOG_EXPIRE_TOTAL (1 << 0)
6 +#define REFLOG_EXPIRE_UNREACH (1 << 1)
7 +
8 struct reflog_expire_entry_option {
9 struct reflog_expire_entry_option *next;
10 timestamp_t expire_total;
@@ -24,6 +27,20 @@ struct reflog_expire_options {
27 .default_expire_unreachable = now - 90 * 24 * 3600, \
28 }
29
30 +/*
31 + * Parse the reflog expire configuration. This should be used with
32 + * `repo_config()`.
33 + */
34 +int reflog_expire_config(const char *var, const char *value,
35 + const struct config_context *ctx, void *cb);
36 +
37 +/*
38 + * Adapt the options so that they apply to the given refname. This applies any
39 + * per-reference reflog expiry configuration that may exist to the options.
40 + */
41 +void reflog_expire_options_set_refname(struct reflog_expire_options *cb,
42 + const char *refname);
43 +
44 struct expire_reflog_policy_cb {
45 enum {
46 UE_NORMAL,