The second batch
[git] / repository.c
1 /*
2  * not really _using_ the compat macros, just make sure the_index
3  * declaration matches the definition in this file.
4  */
5 #define USE_THE_INDEX_COMPATIBILITY_MACROS
6 #include "cache.h"
7 #include "repository.h"
8 #include "object-store.h"
9 #include "config.h"
10 #include "object.h"
11 #include "lockfile.h"
12 #include "submodule-config.h"
13 #include "sparse-index.h"
14
15 /* The main repository */
16 static struct repository the_repo;
17 struct repository *the_repository;
18 struct index_state the_index;
19
20 void initialize_the_repository(void)
21 {
22         the_repository = &the_repo;
23
24         the_repo.index = &the_index;
25         the_repo.objects = raw_object_store_new();
26         the_repo.parsed_objects = parsed_object_pool_new();
27
28         repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
29 }
30
31 static void expand_base_dir(char **out, const char *in,
32                             const char *base_dir, const char *def_in)
33 {
34         free(*out);
35         if (in)
36                 *out = xstrdup(in);
37         else
38                 *out = xstrfmt("%s/%s", base_dir, def_in);
39 }
40
41 static void repo_set_commondir(struct repository *repo,
42                                const char *commondir)
43 {
44         struct strbuf sb = STRBUF_INIT;
45
46         free(repo->commondir);
47
48         if (commondir) {
49                 repo->different_commondir = 1;
50                 repo->commondir = xstrdup(commondir);
51                 return;
52         }
53
54         repo->different_commondir = get_common_dir_noenv(&sb, repo->gitdir);
55         repo->commondir = strbuf_detach(&sb, NULL);
56 }
57
58 void repo_set_gitdir(struct repository *repo,
59                      const char *root,
60                      const struct set_gitdir_args *o)
61 {
62         const char *gitfile = read_gitfile(root);
63         /*
64          * repo->gitdir is saved because the caller could pass "root"
65          * that also points to repo->gitdir. We want to keep it alive
66          * until after xstrdup(root). Then we can free it.
67          */
68         char *old_gitdir = repo->gitdir;
69
70         repo->gitdir = xstrdup(gitfile ? gitfile : root);
71         free(old_gitdir);
72
73         repo_set_commondir(repo, o->commondir);
74
75         if (!repo->objects->odb) {
76                 CALLOC_ARRAY(repo->objects->odb, 1);
77                 repo->objects->odb_tail = &repo->objects->odb->next;
78         }
79         expand_base_dir(&repo->objects->odb->path, o->object_dir,
80                         repo->commondir, "objects");
81
82         free(repo->objects->alternate_db);
83         repo->objects->alternate_db = xstrdup_or_null(o->alternate_db);
84         expand_base_dir(&repo->graft_file, o->graft_file,
85                         repo->commondir, "info/grafts");
86         expand_base_dir(&repo->index_file, o->index_file,
87                         repo->gitdir, "index");
88 }
89
90 void repo_set_hash_algo(struct repository *repo, int hash_algo)
91 {
92         repo->hash_algo = &hash_algos[hash_algo];
93 }
94
95 /*
96  * Attempt to resolve and set the provided 'gitdir' for repository 'repo'.
97  * Return 0 upon success and a non-zero value upon failure.
98  */
99 static int repo_init_gitdir(struct repository *repo, const char *gitdir)
100 {
101         int ret = 0;
102         int error = 0;
103         char *abspath = NULL;
104         const char *resolved_gitdir;
105         struct set_gitdir_args args = { NULL };
106
107         abspath = real_pathdup(gitdir, 0);
108         if (!abspath) {
109                 ret = -1;
110                 goto out;
111         }
112
113         /* 'gitdir' must reference the gitdir directly */
114         resolved_gitdir = resolve_gitdir_gently(abspath, &error);
115         if (!resolved_gitdir) {
116                 ret = -1;
117                 goto out;
118         }
119
120         repo_set_gitdir(repo, resolved_gitdir, &args);
121
122 out:
123         free(abspath);
124         return ret;
125 }
126
127 void repo_set_worktree(struct repository *repo, const char *path)
128 {
129         repo->worktree = real_pathdup(path, 1);
130
131         trace2_def_repo(repo);
132 }
133
134 static int read_and_verify_repository_format(struct repository_format *format,
135                                              const char *commondir)
136 {
137         int ret = 0;
138         struct strbuf sb = STRBUF_INIT;
139
140         strbuf_addf(&sb, "%s/config", commondir);
141         read_repository_format(format, sb.buf);
142         strbuf_reset(&sb);
143
144         if (verify_repository_format(format, &sb) < 0) {
145                 warning("%s", sb.buf);
146                 ret = -1;
147         }
148
149         strbuf_release(&sb);
150         return ret;
151 }
152
153 /*
154  * Initialize 'repo' based on the provided 'gitdir'.
155  * Return 0 upon success and a non-zero value upon failure.
156  */
157 int repo_init(struct repository *repo,
158               const char *gitdir,
159               const char *worktree)
160 {
161         struct repository_format format = REPOSITORY_FORMAT_INIT;
162         memset(repo, 0, sizeof(*repo));
163
164         repo->objects = raw_object_store_new();
165         repo->parsed_objects = parsed_object_pool_new();
166
167         if (repo_init_gitdir(repo, gitdir))
168                 goto error;
169
170         if (read_and_verify_repository_format(&format, repo->commondir))
171                 goto error;
172
173         repo_set_hash_algo(repo, format.hash_algo);
174
175         if (worktree)
176                 repo_set_worktree(repo, worktree);
177
178         clear_repository_format(&format);
179         return 0;
180
181 error:
182         repo_clear(repo);
183         return -1;
184 }
185
186 int repo_submodule_init(struct repository *subrepo,
187                         struct repository *superproject,
188                         const struct submodule *sub)
189 {
190         struct strbuf gitdir = STRBUF_INIT;
191         struct strbuf worktree = STRBUF_INIT;
192         int ret = 0;
193
194         if (!sub) {
195                 ret = -1;
196                 goto out;
197         }
198
199         strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", sub->path);
200         strbuf_repo_worktree_path(&worktree, superproject, "%s", sub->path);
201
202         if (repo_init(subrepo, gitdir.buf, worktree.buf)) {
203                 /*
204                  * If initialization fails then it may be due to the submodule
205                  * not being populated in the superproject's worktree.  Instead
206                  * we can try to initialize the submodule by finding it's gitdir
207                  * in the superproject's 'modules' directory.  In this case the
208                  * submodule would not have a worktree.
209                  */
210                 strbuf_reset(&gitdir);
211                 strbuf_repo_git_path(&gitdir, superproject,
212                                      "modules/%s", sub->name);
213
214                 if (repo_init(subrepo, gitdir.buf, NULL)) {
215                         ret = -1;
216                         goto out;
217                 }
218         }
219
220         subrepo->submodule_prefix = xstrfmt("%s%s/",
221                                             superproject->submodule_prefix ?
222                                             superproject->submodule_prefix :
223                                             "", sub->path);
224
225 out:
226         strbuf_release(&gitdir);
227         strbuf_release(&worktree);
228         return ret;
229 }
230
231 void repo_clear(struct repository *repo)
232 {
233         FREE_AND_NULL(repo->gitdir);
234         FREE_AND_NULL(repo->commondir);
235         FREE_AND_NULL(repo->graft_file);
236         FREE_AND_NULL(repo->index_file);
237         FREE_AND_NULL(repo->worktree);
238         FREE_AND_NULL(repo->submodule_prefix);
239
240         raw_object_store_clear(repo->objects);
241         FREE_AND_NULL(repo->objects);
242
243         parsed_object_pool_clear(repo->parsed_objects);
244         FREE_AND_NULL(repo->parsed_objects);
245
246         if (repo->config) {
247                 git_configset_clear(repo->config);
248                 FREE_AND_NULL(repo->config);
249         }
250
251         if (repo->submodule_cache) {
252                 submodule_cache_free(repo->submodule_cache);
253                 repo->submodule_cache = NULL;
254         }
255
256         if (repo->index) {
257                 discard_index(repo->index);
258                 if (repo->index != &the_index)
259                         FREE_AND_NULL(repo->index);
260         }
261 }
262
263 int repo_read_index(struct repository *repo)
264 {
265         int res;
266
267         if (!repo->index)
268                 CALLOC_ARRAY(repo->index, 1);
269
270         /* Complete the double-reference */
271         if (!repo->index->repo)
272                 repo->index->repo = repo;
273         else if (repo->index->repo != repo)
274                 BUG("repo's index should point back at itself");
275
276         res = read_index_from(repo->index, repo->index_file, repo->gitdir);
277
278         prepare_repo_settings(repo);
279         if (repo->settings.command_requires_full_index)
280                 ensure_full_index(repo->index);
281
282         return res;
283 }
284
285 int repo_hold_locked_index(struct repository *repo,
286                            struct lock_file *lf,
287                            int flags)
288 {
289         if (!repo->index_file)
290                 BUG("the repo hasn't been setup");
291         return hold_lock_file_for_update(lf, repo->index_file, flags);
292 }