environment: move `set_git_dir()` and related into setup layer

The functions `set_git_dir()` and friends are used to set up repositories. As such, they are quite clearly part of the setup subsystem, but still live in "environment.c". Move them over, which also helps to get rid of dependencies on `the_repository` in the environment subsystem. 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 a52beae3a319e8133be0fe245e5fb3b9e7d8d9fb
4 files changed +109 -107
environment.c
-105
@@ -22,14 +22,9 @@
22 #include "fmt-merge-msg.h"
23 #include "commit.h"
24 #include "strvec.h"
25 -#include "object-file.h"
25 #include "path.h"
27 -#include "replace-object.h"
28 -#include "tmp-objdir.h"
26 #include "chdir-notify.h"
27 #include "setup.h"
31 -#include "shallow.h"
32 -#include "trace.h"
28 #include "write-or-die.h"
29
30 int trust_executable_bit = 1;
@@ -155,41 +150,6 @@ const char *getenv_safe(struct strvec *argv, const char *name)
150 return argv->v[argv->nr - 1];
151 }
152
158 -void setup_git_env(const char *git_dir)
159 -{
160 - char *git_replace_ref_base;
161 - const char *shallow_file;
162 - const char *replace_ref_base;
163 - struct set_gitdir_args args = { NULL };
164 - struct strvec to_free = STRVEC_INIT;
165 -
166 - args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT);
167 - args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);
168 - args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);
169 - args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);
170 - args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT);
171 - if (getenv(GIT_QUARANTINE_ENVIRONMENT)) {
172 - args.disable_ref_updates = 1;
173 - }
174 -
175 - repo_set_gitdir(the_repository, git_dir, &args);
176 - strvec_clear(&to_free);
177 -
178 - if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
179 - disable_replace_refs();
180 - replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT);
181 - git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base
182 - : "refs/replace/");
183 - update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base);
184 -
185 - shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
186 - if (shallow_file)
187 - set_alternate_shallow_file(the_repository, shallow_file, 0);
188 -
189 - if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0))
190 - fetch_if_missing = 0;
191 -}
192 -
153 int is_bare_repository(void)
154 {
155 /* if core.bare is not 'false', let's see if there is a work tree */
@@ -243,71 +203,6 @@ const char *strip_namespace(const char *namespaced_ref)
203 return NULL;
204 }
205
246 -static int git_work_tree_initialized;
247 -
248 -/*
249 - * Note. This works only before you used a work tree. This was added
250 - * primarily to support git-clone to work in a new repository it just
251 - * created, and is not meant to flip between different work trees.
252 - */
253 -void set_git_work_tree(const char *new_work_tree)
254 -{
255 - if (git_work_tree_initialized) {
256 - struct strbuf realpath = STRBUF_INIT;
257 -
258 - strbuf_realpath(&realpath, new_work_tree, 1);
259 - new_work_tree = realpath.buf;
260 - if (strcmp(new_work_tree, the_repository->worktree))
261 - die("internal error: work tree has already been set\n"
262 - "Current worktree: %s\nNew worktree: %s",
263 - the_repository->worktree, new_work_tree);
264 - strbuf_release(&realpath);
265 - return;
266 - }
267 - git_work_tree_initialized = 1;
268 - repo_set_worktree(the_repository, new_work_tree);
269 -}
270 -
271 -static void set_git_dir_1(const char *path)
272 -{
273 - xsetenv(GIT_DIR_ENVIRONMENT, path, 1);
274 - setup_git_env(path);
275 -}
276 -
277 -static void update_relative_gitdir(const char *name UNUSED,
278 - const char *old_cwd,
279 - const char *new_cwd,
280 - void *data UNUSED)
281 -{
282 - char *path = reparent_relative_path(old_cwd, new_cwd,
283 - repo_get_git_dir(the_repository));
284 - struct tmp_objdir *tmp_objdir = tmp_objdir_unapply_primary_odb();
285 -
286 - trace_printf_key(&trace_setup_key,
287 - "setup: move $GIT_DIR to '%s'",
288 - path);
289 - set_git_dir_1(path);
290 - if (tmp_objdir)
291 - tmp_objdir_reapply_primary_odb(tmp_objdir, old_cwd, new_cwd);
292 - free(path);
293 -}
294 -
295 -void set_git_dir(const char *path, int make_realpath)
296 -{
297 - struct strbuf realpath = STRBUF_INIT;
298 -
299 - if (make_realpath) {
300 - strbuf_realpath(&realpath, path, 1);
301 - path = realpath.buf;
302 - }
303 -
304 - set_git_dir_1(path);
305 - if (!is_absolute_path(path))
306 - chdir_notify_register(NULL, update_relative_gitdir, NULL);
307 -
308 - strbuf_release(&realpath);
309 -}
310 -
206 const char *get_log_output_encoding(void)
207 {
208 return git_log_output_encoding ? git_log_output_encoding
environment.h
-2
@@ -105,10 +105,8 @@ int have_git_dir(void);
105 extern int is_bare_repository_cfg;
106 int is_bare_repository(void);
107 extern char *git_work_tree_cfg;
108 -void set_git_dir(const char *path, int make_realpath);
108 const char *get_git_namespace(void);
109 const char *strip_namespace(const char *namespaced_ref);
111 -void set_git_work_tree(const char *tree);
110
111 #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
112
setup.c
+106
@@ -7,16 +7,22 @@
7 #include "exec-cmd.h"
8 #include "gettext.h"
9 #include "hex.h"
10 +#include "object-file.h"
11 #include "object-name.h"
12 #include "refs.h"
13 +#include "replace-object.h"
14 #include "repository.h"
15 #include "config.h"
16 #include "dir.h"
17 #include "setup.h"
18 +#include "shallow.h"
19 #include "string-list.h"
20 +#include "strvec.h"
21 #include "chdir-notify.h"
22 #include "path.h"
23 #include "quote.h"
24 +#include "tmp-objdir.h"
25 +#include "trace.h"
26 #include "trace2.h"
27 #include "worktree.h"
28 #include "exec-cmd.h"
@@ -1613,6 +1619,106 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
1619 return result;
1620 }
1621
1622 +void setup_git_env(const char *git_dir)
1623 +{
1624 + char *git_replace_ref_base;
1625 + const char *shallow_file;
1626 + const char *replace_ref_base;
1627 + struct set_gitdir_args args = { NULL };
1628 + struct strvec to_free = STRVEC_INIT;
1629 +
1630 + args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT);
1631 + args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);
1632 + args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);
1633 + args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);
1634 + args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT);
1635 + if (getenv(GIT_QUARANTINE_ENVIRONMENT)) {
1636 + args.disable_ref_updates = 1;
1637 + }
1638 +
1639 + repo_set_gitdir(the_repository, git_dir, &args);
1640 + strvec_clear(&to_free);
1641 +
1642 + if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
1643 + disable_replace_refs();
1644 + replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT);
1645 + git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base
1646 + : "refs/replace/");
1647 + update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base);
1648 +
1649 + shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
1650 + if (shallow_file)
1651 + set_alternate_shallow_file(the_repository, shallow_file, 0);
1652 +
1653 + if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0))
1654 + fetch_if_missing = 0;
1655 +}
1656 +
1657 +static void set_git_dir_1(const char *path)
1658 +{
1659 + xsetenv(GIT_DIR_ENVIRONMENT, path, 1);
1660 + setup_git_env(path);
1661 +}
1662 +
1663 +static void update_relative_gitdir(const char *name UNUSED,
1664 + const char *old_cwd,
1665 + const char *new_cwd,
1666 + void *data UNUSED)
1667 +{
1668 + char *path = reparent_relative_path(old_cwd, new_cwd,
1669 + repo_get_git_dir(the_repository));
1670 + struct tmp_objdir *tmp_objdir = tmp_objdir_unapply_primary_odb();
1671 +
1672 + trace_printf_key(&trace_setup_key,
1673 + "setup: move $GIT_DIR to '%s'",
1674 + path);
1675 + set_git_dir_1(path);
1676 + if (tmp_objdir)
1677 + tmp_objdir_reapply_primary_odb(tmp_objdir, old_cwd, new_cwd);
1678 + free(path);
1679 +}
1680 +
1681 +void set_git_dir(const char *path, int make_realpath)
1682 +{
1683 + struct strbuf realpath = STRBUF_INIT;
1684 +
1685 + if (make_realpath) {
1686 + strbuf_realpath(&realpath, path, 1);
1687 + path = realpath.buf;
1688 + }
1689 +
1690 + set_git_dir_1(path);
1691 + if (!is_absolute_path(path))
1692 + chdir_notify_register(NULL, update_relative_gitdir, NULL);
1693 +
1694 + strbuf_release(&realpath);
1695 +}
1696 +
1697 +static int git_work_tree_initialized;
1698 +
1699 +/*
1700 + * Note. This works only before you used a work tree. This was added
1701 + * primarily to support git-clone to work in a new repository it just
1702 + * created, and is not meant to flip between different work trees.
1703 + */
1704 +void set_git_work_tree(const char *new_work_tree)
1705 +{
1706 + if (git_work_tree_initialized) {
1707 + struct strbuf realpath = STRBUF_INIT;
1708 +
1709 + strbuf_realpath(&realpath, new_work_tree, 1);
1710 + new_work_tree = realpath.buf;
1711 + if (strcmp(new_work_tree, the_repository->worktree))
1712 + die("internal error: work tree has already been set\n"
1713 + "Current worktree: %s\nNew worktree: %s",
1714 + the_repository->worktree, new_work_tree);
1715 + strbuf_release(&realpath);
1716 + return;
1717 + }
1718 + git_work_tree_initialized = 1;
1719 + repo_set_worktree(the_repository, new_work_tree);
1720 +}
1721 +
1722 const char *setup_git_directory_gently(int *nongit_ok)
1723 {
1724 static struct strbuf cwd = STRBUF_INIT;
setup.h
+3
@@ -94,6 +94,9 @@ static inline int discover_git_directory(struct strbuf *commondir,
94 return 0;
95 }
96
97 +void set_git_dir(const char *path, int make_realpath);
98 +void set_git_work_tree(const char *tree);
99 +
100 const char *setup_git_directory_gently(int *);
101 const char *setup_git_directory(void);
102 char *prefix_path(const char *prefix, int len, const char *path);