repository.c: move env-related setup code back to environment.c
It does not make sense that generic repository code contains handling of environment variables, which are specific for the main repository only. Refactor repo_set_gitdir() function to take $GIT_DIR and optionally _all_ other customizable paths. These optional paths can be NULL and will be calculated according to the default directory layout. Note that some dead functions are left behind to reduce diff noise. They will be deleted in the next patch. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Mar 3, 2018 at 18:35 UTC
357a03ebe9e04329705a46ff36d526c5ab0c3ebc
5 files changed
+79
-25
cache.h
+1
-1
@@ -484,7 +484,7 @@ static inline enum object_type object_type(unsigned int mode)
484
*/
485
extern const char * const local_repo_env[];
486
487
-extern void setup_git_env(void);
487
+extern void setup_git_env(const char *git_dir);
488
489
/*
490
* Returns true iff we have a configured git repository (either via
environment.c
+27
-3
@@ -13,6 +13,7 @@
13
#include "refs.h"
14
#include "fmt-merge-msg.h"
15
#include "commit.h"
16
+#include "argv-array.h"
17
18
int trust_executable_bit = 1;
19
int trust_ctime = 1;
@@ -147,10 +148,34 @@ static char *expand_namespace(const char *raw_namespace)
148
return strbuf_detach(&buf, NULL);
149
}
150
150
-void setup_git_env(void)
151
+/*
152
+ * Wrapper of getenv() that returns a strdup value. This value is kept
153
+ * in argv to be freed later.
154
+ */
155
+static const char *getenv_safe(struct argv_array *argv, const char *name)
156
+{
157
+ const char *value = getenv(name);
158
+
159
+ if (!value)
160
+ return NULL;
161
+
162
+ argv_array_push(argv, value);
163
+ return argv->argv[argv->argc - 1];
164
+}
165
+
166
+void setup_git_env(const char *git_dir)
167
{
168
const char *shallow_file;
169
const char *replace_ref_base;
170
+ struct set_gitdir_args args = { NULL };
171
+ struct argv_array to_free = ARGV_ARRAY_INIT;
172
+
173
+ args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT);
174
+ args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);
175
+ args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);
176
+ args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);
177
+ repo_set_gitdir(the_repository, git_dir, &args);
178
+ argv_array_clear(&to_free);
179
180
if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
181
check_replace_refs = 0;
@@ -300,8 +325,7 @@ int set_git_dir(const char *path)
325
{
326
if (setenv(GIT_DIR_ENVIRONMENT, path, 1))
327
return error("Could not set GIT_DIR to '%s'", path);
303
- repo_set_gitdir(the_repository, path);
304
- setup_git_env();
328
+ setup_git_env(path);
329
return 0;
330
}
331
repository.c
+40
-18
@@ -40,34 +40,55 @@ static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv)
40
return get_common_dir_noenv(sb, gitdir);
41
}
42
43
-static void repo_setup_env(struct repository *repo)
43
+static void expand_base_dir(char **out, const char *in,
44
+ const char *base_dir, const char *def_in)
45
+{
46
+ free(*out);
47
+ if (in)
48
+ *out = xstrdup(in);
49
+ else
50
+ *out = xstrfmt("%s/%s", base_dir, def_in);
51
+}
52
+
53
+static void repo_set_commondir(struct repository *repo,
54
+ const char *commondir)
55
{
56
struct strbuf sb = STRBUF_INIT;
57
47
- repo->different_commondir = find_common_dir(&sb, repo->gitdir,
48
- !repo->ignore_env);
58
free(repo->commondir);
59
+
60
+ if (commondir) {
61
+ repo->different_commondir = 1;
62
+ repo->commondir = xstrdup(commondir);
63
+ return;
64
+ }
65
+
66
+ repo->different_commondir = get_common_dir_noenv(&sb, repo->gitdir);
67
repo->commondir = strbuf_detach(&sb, NULL);
51
- free(repo->objectdir);
52
- repo->objectdir = git_path_from_env(DB_ENVIRONMENT, repo->commondir,
53
- "objects", !repo->ignore_env);
54
- free(repo->graft_file);
55
- repo->graft_file = git_path_from_env(GRAFT_ENVIRONMENT, repo->commondir,
56
- "info/grafts", !repo->ignore_env);
57
- free(repo->index_file);
58
- repo->index_file = git_path_from_env(INDEX_ENVIRONMENT, repo->gitdir,
59
- "index", !repo->ignore_env);
68
}
69
62
-void repo_set_gitdir(struct repository *repo, const char *path)
70
+void repo_set_gitdir(struct repository *repo,
71
+ const char *root,
72
+ const struct set_gitdir_args *o)
73
{
64
- const char *gitfile = read_gitfile(path);
74
+ const char *gitfile = read_gitfile(root);
75
+ /*
76
+ * repo->gitdir is saved because the caller could pass "root"
77
+ * that also points to repo->gitdir. We want to keep it alive
78
+ * until after xstrdup(root). Then we can free it.
79
+ */
80
char *old_gitdir = repo->gitdir;
81
67
- repo->gitdir = xstrdup(gitfile ? gitfile : path);
68
- repo_setup_env(repo);
69
-
82
+ repo->gitdir = xstrdup(gitfile ? gitfile : root);
83
free(old_gitdir);
84
+
85
+ repo_set_commondir(repo, o->commondir);
86
+ expand_base_dir(&repo->objectdir, o->object_dir,
87
+ repo->commondir, "objects");
88
+ expand_base_dir(&repo->graft_file, o->graft_file,
89
+ repo->commondir, "info/grafts");
90
+ expand_base_dir(&repo->index_file, o->index_file,
91
+ repo->gitdir, "index");
92
}
93
94
void repo_set_hash_algo(struct repository *repo, int hash_algo)
@@ -85,6 +106,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)
106
int error = 0;
107
char *abspath = NULL;
108
const char *resolved_gitdir;
109
+ struct set_gitdir_args args = { NULL };
110
111
abspath = real_pathdup(gitdir, 0);
112
if (!abspath) {
@@ -99,7 +121,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)
121
goto out;
122
}
123
102
- repo_set_gitdir(repo, resolved_gitdir);
124
+ repo_set_gitdir(repo, resolved_gitdir, &args);
125
126
out:
127
free(abspath);
repository.h
+10
-1
@@ -88,7 +88,16 @@ struct repository {
88
89
extern struct repository *the_repository;
90
91
-extern void repo_set_gitdir(struct repository *repo, const char *path);
91
+struct set_gitdir_args {
92
+ const char *commondir;
93
+ const char *object_dir;
94
+ const char *graft_file;
95
+ const char *index_file;
96
+};
97
+
98
+extern void repo_set_gitdir(struct repository *repo,
99
+ const char *root,
100
+ const struct set_gitdir_args *optional);
101
extern void repo_set_worktree(struct repository *repo, const char *path);
102
extern void repo_set_hash_algo(struct repository *repo, int algo);
103
extern void initialize_the_repository(void);
setup.c
+1
-2
@@ -1116,8 +1116,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
1116
const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
1117
if (!gitdir)
1118
gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
1119
- repo_set_gitdir(the_repository, gitdir);
1120
- setup_git_env();
1119
+ setup_git_env(gitdir);
1120
}
1121
if (startup_info->have_repository)
1122
repo_set_hash_algo(the_repository, repo_fmt.hash_algo);