1#include "cache.h"
2#include "repository.h"
3#include "config.h"
4#include "submodule-config.h"
56
/* The main repository */
7static struct repository the_repo;
8struct repository *the_repository = &the_repo;
910
static char *git_path_from_env(const char *envvar, const char *git_dir,
11const char *path, int fromenv)
12{
13if (fromenv) {
14const char *value = getenv(envvar);
15if (value)
16return xstrdup(value);
17}
1819
return xstrfmt("%s/%s", git_dir, path);
20}
2122
static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv)
23{
24if (fromenv) {
25const char *value = getenv(GIT_COMMON_DIR_ENVIRONMENT);
26if (value) {
27strbuf_addstr(sb, value);
28return 1;
29}
30}
3132
return get_common_dir_noenv(sb, gitdir);
33}
3435
static void repo_setup_env(struct repository *repo)
36{
37struct strbuf sb = STRBUF_INIT;
3839
repo->different_commondir = find_common_dir(&sb, repo->gitdir,
40!repo->ignore_env);
41repo->commondir = strbuf_detach(&sb, NULL);
42repo->objectdir = git_path_from_env(DB_ENVIRONMENT, repo->commondir,
43"objects", !repo->ignore_env);
44repo->graft_file = git_path_from_env(GRAFT_ENVIRONMENT, repo->commondir,
45"info/grafts", !repo->ignore_env);
46repo->index_file = git_path_from_env(INDEX_ENVIRONMENT, repo->gitdir,
47"index", !repo->ignore_env);
48}
4950
void repo_set_gitdir(struct repository *repo, const char *path)
51{
52const char *gitfile = read_gitfile(path);
5354
/*
55* NEEDSWORK: Eventually we want to be able to free gitdir and the rest
56* of the environment before reinitializing it again, but we have some
57* crazy code paths where we try to set gitdir with the current gitdir
58* and we don't want to free gitdir before copying the passed in value.
59*/
60repo->gitdir = xstrdup(gitfile ? gitfile : path);
6162
repo_setup_env(repo);
63}
6465
/*
66* Attempt to resolve and set the provided 'gitdir' for repository 'repo'.
67* Return 0 upon success and a non-zero value upon failure.
68*/
69static int repo_init_gitdir(struct repository *repo, const char *gitdir)
70{
71int ret = 0;
72int error = 0;
73char *abspath = NULL;
74const char *resolved_gitdir;
7576
abspath = real_pathdup(gitdir, 0);
77if (!abspath) {
78ret = -1;
79goto out;
80}
8182
/* 'gitdir' must reference the gitdir directly */
83resolved_gitdir = resolve_gitdir_gently(abspath, &error);
84if (!resolved_gitdir) {
85ret = -1;
86goto out;
87}
8889
repo_set_gitdir(repo, resolved_gitdir);
9091
out:
92free(abspath);
93return ret;
94}
9596
void repo_set_worktree(struct repository *repo, const char *path)
97{
98repo->worktree = real_pathdup(path, 1);
99}
100101
static int read_and_verify_repository_format(struct repository_format *format,
102const char *commondir)
103{
104int ret = 0;
105struct strbuf sb = STRBUF_INIT;
106107
strbuf_addf(&sb, "%s/config", commondir);
108read_repository_format(format, sb.buf);
109strbuf_reset(&sb);
110111
if (verify_repository_format(format, &sb) < 0) {
112warning("%s", sb.buf);
113ret = -1;
114}
115116
strbuf_release(&sb);
117return ret;
118}
119120
/*
121* Initialize 'repo' based on the provided 'gitdir'.
122* Return 0 upon success and a non-zero value upon failure.
123*/
124int repo_init(struct repository *repo, const char *gitdir, const char *worktree)
125{
126struct repository_format format;
127memset(repo, 0, sizeof(*repo));
128129
repo->ignore_env = 1;
130131
if (repo_init_gitdir(repo, gitdir))
132goto error;
133134
if (read_and_verify_repository_format(&format, repo->commondir))
135goto error;
136137
if (worktree)
138repo_set_worktree(repo, worktree);
139140
return 0;
141142
error:
143repo_clear(repo);
144return -1;
145}
146147
void repo_clear(struct repository *repo)
148{
149free(repo->gitdir);
150repo->gitdir = NULL;
151free(repo->commondir);
152repo->commondir = NULL;
153free(repo->objectdir);
154repo->objectdir = NULL;
155free(repo->graft_file);
156repo->graft_file = NULL;
157free(repo->index_file);
158repo->index_file = NULL;
159free(repo->worktree);
160repo->worktree = NULL;
161162
if (repo->config) {
163git_configset_clear(repo->config);
164free(repo->config);
165repo->config = NULL;
166}
167168
if (repo->submodule_cache) {
169submodule_cache_free(repo->submodule_cache);
170repo->submodule_cache = NULL;
171}
172173
if (repo->index) {
174discard_index(repo->index);
175free(repo->index);
176repo->index = NULL;
177}
178}
179180
int repo_read_index(struct repository *repo)
181{
182if (!repo->index)
183repo->index = xcalloc(1, sizeof(*repo->index));
184else
185discard_index(repo->index);
186187
return read_index_from(repo->index, repo->index_file);
188}