environment: make `get_git_namespace()` self-contained

The logic to set up and retrieve `git_namespace` is distributed across different functions which communicate with each other via a global environment variable. This is rather pointless though, as the value is always derived from an environment variable, and this environment variable does not change after we have parsed global options. Convert the function to be fully self-contained such that it lazily populates once called. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Sep 12, 2024 at 13:29 UTC c22d183b01417f996307de0c3923811b66a44ae7
1 file changed +29 -28
environment.c
+29 -28
@@ -122,8 +122,6 @@ int core_preload_index = 1;
122 /* This is set by setup_git_dir_gently() and/or git_default_config() */
123 char *git_work_tree_cfg;
124
125 -static char *git_namespace;
126 -
125 /*
126 * Repository-local GIT_* environment variables; see environment.h for details.
127 */
@@ -146,27 +144,6 @@ const char * const local_repo_env[] = {
144 NULL
145 };
146
149 -static char *expand_namespace(const char *raw_namespace)
150 -{
151 - struct strbuf buf = STRBUF_INIT;
152 - struct strbuf **components, **c;
153 -
154 - if (!raw_namespace || !*raw_namespace)
155 - return xstrdup("");
156 -
157 - strbuf_addstr(&buf, raw_namespace);
158 - components = strbuf_split(&buf, '/');
159 - strbuf_reset(&buf);
160 - for (c = components; *c; c++)
161 - if (strcmp((*c)->buf, "/") != 0)
162 - strbuf_addf(&buf, "refs/namespaces/%s", (*c)->buf);
163 - strbuf_list_free(components);
164 - if (check_refname_format(buf.buf, 0))
165 - die(_("bad git namespace path \"%s\""), raw_namespace);
166 - strbuf_addch(&buf, '/');
167 - return strbuf_detach(&buf, NULL);
168 -}
169 -
147 const char *getenv_safe(struct strvec *argv, const char *name)
148 {
149 const char *value = getenv(name);
@@ -205,8 +182,6 @@ void setup_git_env(const char *git_dir)
182 : "refs/replace/");
183 update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base);
184
208 - free(git_namespace);
209 - git_namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT));
185 shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
186 if (shallow_file)
187 set_alternate_shallow_file(the_repository, shallow_file, 0);
@@ -229,9 +204,35 @@ int have_git_dir(void)
204
205 const char *get_git_namespace(void)
206 {
232 - if (!git_namespace)
233 - BUG("git environment hasn't been setup");
234 - return git_namespace;
207 + static const char *namespace;
208 +
209 + struct strbuf buf = STRBUF_INIT;
210 + struct strbuf **components, **c;
211 + const char *raw_namespace;
212 +
213 + if (namespace)
214 + return namespace;
215 +
216 + raw_namespace = getenv(GIT_NAMESPACE_ENVIRONMENT);
217 + if (!raw_namespace || !*raw_namespace) {
218 + namespace = "";
219 + return namespace;
220 + }
221 +
222 + strbuf_addstr(&buf, raw_namespace);
223 + components = strbuf_split(&buf, '/');
224 + strbuf_reset(&buf);
225 + for (c = components; *c; c++)
226 + if (strcmp((*c)->buf, "/") != 0)
227 + strbuf_addf(&buf, "refs/namespaces/%s", (*c)->buf);
228 + strbuf_list_free(components);
229 + if (check_refname_format(buf.buf, 0))
230 + die(_("bad git namespace path \"%s\""), raw_namespace);
231 + strbuf_addch(&buf, '/');
232 +
233 + namespace = strbuf_detach(&buf, NULL);
234 +
235 + return namespace;
236 }
237
238 const char *strip_namespace(const char *namespaced_ref)