]> git.proxmox.com Git - libgit2.git/blob - src/repository.c
New upstream version 1.0.1+dfsg.1
[libgit2.git] / src / repository.c
1 /*
2 * Copyright (C) the libgit2 contributors. All rights reserved.
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
7
8 #include "repository.h"
9
10 #include <ctype.h>
11
12 #include "git2/object.h"
13 #include "git2/sys/repository.h"
14
15 #include "common.h"
16 #include "commit.h"
17 #include "tag.h"
18 #include "blob.h"
19 #include "futils.h"
20 #include "sysdir.h"
21 #include "filebuf.h"
22 #include "index.h"
23 #include "config.h"
24 #include "refs.h"
25 #include "filter.h"
26 #include "odb.h"
27 #include "refdb.h"
28 #include "remote.h"
29 #include "merge.h"
30 #include "diff_driver.h"
31 #include "annotated_commit.h"
32 #include "submodule.h"
33 #include "worktree.h"
34
35 #include "strmap.h"
36
37 #ifdef GIT_WIN32
38 # include "win32/w32_util.h"
39 #endif
40
41 bool git_repository__fsync_gitdir = false;
42
43 static const struct {
44 git_repository_item_t parent;
45 git_repository_item_t fallback;
46 const char *name;
47 bool directory;
48 } items[] = {
49 { GIT_REPOSITORY_ITEM_GITDIR, GIT_REPOSITORY_ITEM__LAST, NULL, true },
50 { GIT_REPOSITORY_ITEM_WORKDIR, GIT_REPOSITORY_ITEM__LAST, NULL, true },
51 { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM__LAST, NULL, true },
52 { GIT_REPOSITORY_ITEM_GITDIR, GIT_REPOSITORY_ITEM__LAST, "index", false },
53 { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "objects", true },
54 { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "refs", true },
55 { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "packed-refs", false },
56 { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "remotes", true },
57 { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "config", false },
58 { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "info", true },
59 { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "hooks", true },
60 { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "logs", true },
61 { GIT_REPOSITORY_ITEM_GITDIR, GIT_REPOSITORY_ITEM__LAST, "modules", true },
62 { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "worktrees", true }
63 };
64
65 static int check_repositoryformatversion(git_config *config);
66
67 #define GIT_COMMONDIR_FILE "commondir"
68 #define GIT_GITDIR_FILE "gitdir"
69
70 #define GIT_FILE_CONTENT_PREFIX "gitdir:"
71
72 #define GIT_BRANCH_MASTER "master"
73
74 #define GIT_REPO_VERSION 0
75
76 git_buf git_repository__reserved_names_win32[] = {
77 { DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
78 { GIT_DIR_SHORTNAME, 0, CONST_STRLEN(GIT_DIR_SHORTNAME) }
79 };
80 size_t git_repository__reserved_names_win32_len = 2;
81
82 git_buf git_repository__reserved_names_posix[] = {
83 { DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
84 };
85 size_t git_repository__reserved_names_posix_len = 1;
86
87 static void set_odb(git_repository *repo, git_odb *odb)
88 {
89 if (odb) {
90 GIT_REFCOUNT_OWN(odb, repo);
91 GIT_REFCOUNT_INC(odb);
92 }
93
94 if ((odb = git__swap(repo->_odb, odb)) != NULL) {
95 GIT_REFCOUNT_OWN(odb, NULL);
96 git_odb_free(odb);
97 }
98 }
99
100 static void set_refdb(git_repository *repo, git_refdb *refdb)
101 {
102 if (refdb) {
103 GIT_REFCOUNT_OWN(refdb, repo);
104 GIT_REFCOUNT_INC(refdb);
105 }
106
107 if ((refdb = git__swap(repo->_refdb, refdb)) != NULL) {
108 GIT_REFCOUNT_OWN(refdb, NULL);
109 git_refdb_free(refdb);
110 }
111 }
112
113 static void set_config(git_repository *repo, git_config *config)
114 {
115 if (config) {
116 GIT_REFCOUNT_OWN(config, repo);
117 GIT_REFCOUNT_INC(config);
118 }
119
120 if ((config = git__swap(repo->_config, config)) != NULL) {
121 GIT_REFCOUNT_OWN(config, NULL);
122 git_config_free(config);
123 }
124
125 git_repository__configmap_lookup_cache_clear(repo);
126 }
127
128 static void set_index(git_repository *repo, git_index *index)
129 {
130 if (index) {
131 GIT_REFCOUNT_OWN(index, repo);
132 GIT_REFCOUNT_INC(index);
133 }
134
135 if ((index = git__swap(repo->_index, index)) != NULL) {
136 GIT_REFCOUNT_OWN(index, NULL);
137 git_index_free(index);
138 }
139 }
140
141 int git_repository__cleanup(git_repository *repo)
142 {
143 assert(repo);
144
145 git_repository_submodule_cache_clear(repo);
146 git_cache_clear(&repo->objects);
147 git_attr_cache_flush(repo);
148
149 set_config(repo, NULL);
150 set_index(repo, NULL);
151 set_odb(repo, NULL);
152 set_refdb(repo, NULL);
153
154 return 0;
155 }
156
157 void git_repository_free(git_repository *repo)
158 {
159 size_t i;
160
161 if (repo == NULL)
162 return;
163
164 git_repository__cleanup(repo);
165
166 git_cache_dispose(&repo->objects);
167
168 git_diff_driver_registry_free(repo->diff_drivers);
169 repo->diff_drivers = NULL;
170
171 for (i = 0; i < repo->reserved_names.size; i++)
172 git_buf_dispose(git_array_get(repo->reserved_names, i));
173 git_array_clear(repo->reserved_names);
174
175 git__free(repo->gitlink);
176 git__free(repo->gitdir);
177 git__free(repo->commondir);
178 git__free(repo->workdir);
179 git__free(repo->namespace);
180 git__free(repo->ident_name);
181 git__free(repo->ident_email);
182
183 git__memzero(repo, sizeof(*repo));
184 git__free(repo);
185 }
186
187 /*
188 * Git repository open methods
189 *
190 * Open a repository object from its path
191 */
192 static int is_valid_repository_path(bool *out, git_buf *repository_path, git_buf *common_path)
193 {
194 int error;
195
196 *out = false;
197
198 /* Check if we have a separate commondir (e.g. we have a
199 * worktree) */
200 if (git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) {
201 git_buf common_link = GIT_BUF_INIT;
202
203 if ((error = git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 ||
204 (error = git_futils_readbuffer(&common_link, common_link.ptr)) < 0)
205 return error;
206
207 git_buf_rtrim(&common_link);
208 if (git_path_is_relative(common_link.ptr)) {
209 if ((error = git_buf_joinpath(common_path, repository_path->ptr, common_link.ptr)) < 0)
210 return error;
211 } else {
212 git_buf_swap(common_path, &common_link);
213 }
214
215 git_buf_dispose(&common_link);
216 }
217 else {
218 if ((error = git_buf_set(common_path, repository_path->ptr, repository_path->size)) < 0)
219 return error;
220 }
221
222 /* Make sure the commondir path always has a trailing * slash */
223 if (git_buf_rfind(common_path, '/') != (ssize_t)common_path->size - 1)
224 if ((error = git_buf_putc(common_path, '/')) < 0)
225 return error;
226
227 /* Ensure HEAD file exists */
228 if (git_path_contains_file(repository_path, GIT_HEAD_FILE) == false)
229 return 0;
230 /* Check files in common dir */
231 if (git_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false)
232 return 0;
233 if (git_path_contains_dir(common_path, GIT_REFS_DIR) == false)
234 return 0;
235
236 *out = true;
237 return 0;
238 }
239
240 static git_repository *repository_alloc(void)
241 {
242 git_repository *repo = git__calloc(1, sizeof(git_repository));
243
244 if (repo == NULL ||
245 git_cache_init(&repo->objects) < 0)
246 goto on_error;
247
248 git_array_init_to_size(repo->reserved_names, 4);
249 if (!repo->reserved_names.ptr)
250 goto on_error;
251
252 /* set all the entries in the configmap cache to `unset` */
253 git_repository__configmap_lookup_cache_clear(repo);
254
255 return repo;
256
257 on_error:
258 if (repo)
259 git_cache_dispose(&repo->objects);
260
261 git__free(repo);
262 return NULL;
263 }
264
265 int git_repository_new(git_repository **out)
266 {
267 git_repository *repo;
268
269 *out = repo = repository_alloc();
270 GIT_ERROR_CHECK_ALLOC(repo);
271
272 repo->is_bare = 1;
273 repo->is_worktree = 0;
274
275 return 0;
276 }
277
278 static int load_config_data(git_repository *repo, const git_config *config)
279 {
280 int is_bare;
281
282 int err = git_config_get_bool(&is_bare, config, "core.bare");
283 if (err < 0 && err != GIT_ENOTFOUND)
284 return err;
285
286 /* Try to figure out if it's bare, default to non-bare if it's not set */
287 if (err != GIT_ENOTFOUND)
288 repo->is_bare = is_bare && !repo->is_worktree;
289 else
290 repo->is_bare = 0;
291
292 return 0;
293 }
294
295 static int load_workdir(git_repository *repo, git_config *config, git_buf *parent_path)
296 {
297 int error;
298 git_config_entry *ce;
299 git_buf worktree = GIT_BUF_INIT;
300 git_buf path = GIT_BUF_INIT;
301
302 if (repo->is_bare)
303 return 0;
304
305 if ((error = git_config__lookup_entry(
306 &ce, config, "core.worktree", false)) < 0)
307 return error;
308
309 if (repo->is_worktree) {
310 char *gitlink = git_worktree__read_link(repo->gitdir, GIT_GITDIR_FILE);
311 if (!gitlink) {
312 error = -1;
313 goto cleanup;
314 }
315
316 git_buf_attach(&worktree, gitlink, 0);
317
318 if ((git_path_dirname_r(&worktree, worktree.ptr)) < 0 ||
319 git_path_to_dir(&worktree) < 0) {
320 error = -1;
321 goto cleanup;
322 }
323
324 repo->workdir = git_buf_detach(&worktree);
325 }
326 else if (ce && ce->value) {
327 if ((error = git_path_prettify_dir(
328 &worktree, ce->value, repo->gitdir)) < 0)
329 goto cleanup;
330
331 repo->workdir = git_buf_detach(&worktree);
332 }
333 else if (parent_path && git_path_isdir(parent_path->ptr))
334 repo->workdir = git_buf_detach(parent_path);
335 else {
336 if (git_path_dirname_r(&worktree, repo->gitdir) < 0 ||
337 git_path_to_dir(&worktree) < 0) {
338 error = -1;
339 goto cleanup;
340 }
341
342 repo->workdir = git_buf_detach(&worktree);
343 }
344
345 GIT_ERROR_CHECK_ALLOC(repo->workdir);
346 cleanup:
347 git_buf_dispose(&path);
348 git_config_entry_free(ce);
349 return error;
350 }
351
352 /*
353 * This function returns furthest offset into path where a ceiling dir
354 * is found, so we can stop processing the path at that point.
355 *
356 * Note: converting this to use git_bufs instead of GIT_PATH_MAX buffers on
357 * the stack could remove directories name limits, but at the cost of doing
358 * repeated malloc/frees inside the loop below, so let's not do it now.
359 */
360 static size_t find_ceiling_dir_offset(
361 const char *path,
362 const char *ceiling_directories)
363 {
364 char buf[GIT_PATH_MAX + 1];
365 char buf2[GIT_PATH_MAX + 1];
366 const char *ceil, *sep;
367 size_t len, max_len = 0, min_len;
368
369 assert(path);
370
371 min_len = (size_t)(git_path_root(path) + 1);
372
373 if (ceiling_directories == NULL || min_len == 0)
374 return min_len;
375
376 for (sep = ceil = ceiling_directories; *sep; ceil = sep + 1) {
377 for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
378 len = sep - ceil;
379
380 if (len == 0 || len >= sizeof(buf) || git_path_root(ceil) == -1)
381 continue;
382
383 strncpy(buf, ceil, len);
384 buf[len] = '\0';
385
386 if (p_realpath(buf, buf2) == NULL)
387 continue;
388
389 len = strlen(buf2);
390 if (len > 0 && buf2[len-1] == '/')
391 buf[--len] = '\0';
392
393 if (!strncmp(path, buf2, len) &&
394 (path[len] == '/' || !path[len]) &&
395 len > max_len)
396 {
397 max_len = len;
398 }
399 }
400
401 return (max_len <= min_len ? min_len : max_len);
402 }
403
404 /*
405 * Read the contents of `file_path` and set `path_out` to the repo dir that
406 * it points to. Before calling, set `path_out` to the base directory that
407 * should be used if the contents of `file_path` are a relative path.
408 */
409 static int read_gitfile(git_buf *path_out, const char *file_path)
410 {
411 int error = 0;
412 git_buf file = GIT_BUF_INIT;
413 size_t prefix_len = strlen(GIT_FILE_CONTENT_PREFIX);
414
415 assert(path_out && file_path);
416
417 if (git_futils_readbuffer(&file, file_path) < 0)
418 return -1;
419
420 git_buf_rtrim(&file);
421 /* apparently on Windows, some people use backslashes in paths */
422 git_path_mkposix(file.ptr);
423
424 if (git_buf_len(&file) <= prefix_len ||
425 memcmp(git_buf_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0)
426 {
427 git_error_set(GIT_ERROR_REPOSITORY,
428 "the `.git` file at '%s' is malformed", file_path);
429 error = -1;
430 }
431 else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) {
432 const char *gitlink = git_buf_cstr(&file) + prefix_len;
433 while (*gitlink && git__isspace(*gitlink)) gitlink++;
434
435 error = git_path_prettify_dir(
436 path_out, gitlink, git_buf_cstr(path_out));
437 }
438
439 git_buf_dispose(&file);
440 return error;
441 }
442
443 static int find_repo(
444 git_buf *gitdir_path,
445 git_buf *workdir_path,
446 git_buf *gitlink_path,
447 git_buf *commondir_path,
448 const char *start_path,
449 uint32_t flags,
450 const char *ceiling_dirs)
451 {
452 git_buf path = GIT_BUF_INIT;
453 git_buf repo_link = GIT_BUF_INIT;
454 git_buf common_link = GIT_BUF_INIT;
455 struct stat st;
456 dev_t initial_device = 0;
457 int min_iterations;
458 bool in_dot_git, is_valid;
459 size_t ceiling_offset = 0;
460 int error;
461
462 git_buf_clear(gitdir_path);
463
464 error = git_path_prettify(&path, start_path, NULL);
465 if (error < 0)
466 return error;
467
468 /* in_dot_git toggles each loop:
469 * /a/b/c/.git, /a/b/c, /a/b/.git, /a/b, /a/.git, /a
470 * With GIT_REPOSITORY_OPEN_BARE or GIT_REPOSITORY_OPEN_NO_DOTGIT, we
471 * assume we started with /a/b/c.git and don't append .git the first
472 * time through.
473 * min_iterations indicates the number of iterations left before going
474 * further counts as a search. */
475 if (flags & (GIT_REPOSITORY_OPEN_BARE | GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
476 in_dot_git = true;
477 min_iterations = 1;
478 } else {
479 in_dot_git = false;
480 min_iterations = 2;
481 }
482
483 for (;;) {
484 if (!(flags & GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
485 if (!in_dot_git) {
486 if ((error = git_buf_joinpath(&path, path.ptr, DOT_GIT)) < 0)
487 goto out;
488 }
489 in_dot_git = !in_dot_git;
490 }
491
492 if (p_stat(path.ptr, &st) == 0) {
493 /* check that we have not crossed device boundaries */
494 if (initial_device == 0)
495 initial_device = st.st_dev;
496 else if (st.st_dev != initial_device &&
497 !(flags & GIT_REPOSITORY_OPEN_CROSS_FS))
498 break;
499
500 if (S_ISDIR(st.st_mode)) {
501 if ((error = is_valid_repository_path(&is_valid, &path, &common_link)) < 0)
502 goto out;
503
504 if (is_valid) {
505 if ((error = git_path_to_dir(&path)) < 0 ||
506 (error = git_buf_set(gitdir_path, path.ptr, path.size)) < 0)
507 goto out;
508
509 if (gitlink_path)
510 if ((error = git_buf_attach(gitlink_path, git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0)) < 0)
511 goto out;
512 if (commondir_path)
513 git_buf_swap(&common_link, commondir_path);
514
515 break;
516 }
517 } else if (S_ISREG(st.st_mode) && git__suffixcmp(path.ptr, "/" DOT_GIT) == 0) {
518 if ((error = read_gitfile(&repo_link, path.ptr)) < 0 ||
519 (error = is_valid_repository_path(&is_valid, &repo_link, &common_link)) < 0)
520 goto out;
521
522 if (is_valid) {
523 git_buf_swap(gitdir_path, &repo_link);
524
525 if (gitlink_path)
526 if ((error = git_buf_put(gitlink_path, path.ptr, path.size)) < 0)
527 goto out;
528 if (commondir_path)
529 git_buf_swap(&common_link, commondir_path);
530 }
531 break;
532 }
533 }
534
535 /* Move up one directory. If we're in_dot_git, we'll search the
536 * parent itself next. If we're !in_dot_git, we'll search .git
537 * in the parent directory next (added at the top of the loop). */
538 if ((error = git_path_dirname_r(&path, path.ptr)) < 0)
539 goto out;
540
541 /* Once we've checked the directory (and .git if applicable),
542 * find the ceiling for a search. */
543 if (min_iterations && (--min_iterations == 0))
544 ceiling_offset = find_ceiling_dir_offset(path.ptr, ceiling_dirs);
545
546 /* Check if we should stop searching here. */
547 if (min_iterations == 0 &&
548 (path.ptr[ceiling_offset] == 0 || (flags & GIT_REPOSITORY_OPEN_NO_SEARCH)))
549 break;
550 }
551
552 if (workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
553 if (!git_buf_len(gitdir_path))
554 git_buf_clear(workdir_path);
555 else if ((error = git_path_dirname_r(workdir_path, path.ptr)) < 0 ||
556 (error = git_path_to_dir(workdir_path)) < 0)
557 goto out;
558 }
559
560 /* If we didn't find the repository, and we don't have any other error
561 * to report, report that. */
562 if (!git_buf_len(gitdir_path)) {
563 git_error_set(GIT_ERROR_REPOSITORY, "could not find repository from '%s'", start_path);
564 error = GIT_ENOTFOUND;
565 goto out;
566 }
567
568 out:
569 git_buf_dispose(&path);
570 git_buf_dispose(&repo_link);
571 git_buf_dispose(&common_link);
572 return error;
573 }
574
575 int git_repository_open_bare(
576 git_repository **repo_ptr,
577 const char *bare_path)
578 {
579 git_buf path = GIT_BUF_INIT, common_path = GIT_BUF_INIT;
580 git_repository *repo = NULL;
581 bool is_valid;
582 int error;
583
584 if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0 ||
585 (error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0)
586 return error;
587
588 if (!is_valid) {
589 git_buf_dispose(&path);
590 git_buf_dispose(&common_path);
591 git_error_set(GIT_ERROR_REPOSITORY, "path is not a repository: %s", bare_path);
592 return GIT_ENOTFOUND;
593 }
594
595 repo = repository_alloc();
596 GIT_ERROR_CHECK_ALLOC(repo);
597
598 repo->gitdir = git_buf_detach(&path);
599 GIT_ERROR_CHECK_ALLOC(repo->gitdir);
600 repo->commondir = git_buf_detach(&common_path);
601 GIT_ERROR_CHECK_ALLOC(repo->commondir);
602
603 /* of course we're bare! */
604 repo->is_bare = 1;
605 repo->is_worktree = 0;
606 repo->workdir = NULL;
607
608 *repo_ptr = repo;
609 return 0;
610 }
611
612 static int _git_repository_open_ext_from_env(
613 git_repository **out,
614 const char *start_path)
615 {
616 git_repository *repo = NULL;
617 git_index *index = NULL;
618 git_odb *odb = NULL;
619 git_buf dir_buf = GIT_BUF_INIT;
620 git_buf ceiling_dirs_buf = GIT_BUF_INIT;
621 git_buf across_fs_buf = GIT_BUF_INIT;
622 git_buf index_file_buf = GIT_BUF_INIT;
623 git_buf namespace_buf = GIT_BUF_INIT;
624 git_buf object_dir_buf = GIT_BUF_INIT;
625 git_buf alts_buf = GIT_BUF_INIT;
626 git_buf work_tree_buf = GIT_BUF_INIT;
627 git_buf common_dir_buf = GIT_BUF_INIT;
628 const char *ceiling_dirs = NULL;
629 unsigned flags = 0;
630 int error;
631
632 if (!start_path) {
633 error = git__getenv(&dir_buf, "GIT_DIR");
634 if (error == GIT_ENOTFOUND) {
635 git_error_clear();
636 start_path = ".";
637 } else if (error < 0)
638 goto error;
639 else {
640 start_path = git_buf_cstr(&dir_buf);
641 flags |= GIT_REPOSITORY_OPEN_NO_SEARCH;
642 flags |= GIT_REPOSITORY_OPEN_NO_DOTGIT;
643 }
644 }
645
646 error = git__getenv(&ceiling_dirs_buf, "GIT_CEILING_DIRECTORIES");
647 if (error == GIT_ENOTFOUND)
648 git_error_clear();
649 else if (error < 0)
650 goto error;
651 else
652 ceiling_dirs = git_buf_cstr(&ceiling_dirs_buf);
653
654 error = git__getenv(&across_fs_buf, "GIT_DISCOVERY_ACROSS_FILESYSTEM");
655 if (error == GIT_ENOTFOUND)
656 git_error_clear();
657 else if (error < 0)
658 goto error;
659 else {
660 int across_fs = 0;
661 error = git_config_parse_bool(&across_fs, git_buf_cstr(&across_fs_buf));
662 if (error < 0)
663 goto error;
664 if (across_fs)
665 flags |= GIT_REPOSITORY_OPEN_CROSS_FS;
666 }
667
668 error = git__getenv(&index_file_buf, "GIT_INDEX_FILE");
669 if (error == GIT_ENOTFOUND)
670 git_error_clear();
671 else if (error < 0)
672 goto error;
673 else {
674 error = git_index_open(&index, git_buf_cstr(&index_file_buf));
675 if (error < 0)
676 goto error;
677 }
678
679 error = git__getenv(&namespace_buf, "GIT_NAMESPACE");
680 if (error == GIT_ENOTFOUND)
681 git_error_clear();
682 else if (error < 0)
683 goto error;
684
685 error = git__getenv(&object_dir_buf, "GIT_OBJECT_DIRECTORY");
686 if (error == GIT_ENOTFOUND)
687 git_error_clear();
688 else if (error < 0)
689 goto error;
690 else {
691 error = git_odb_open(&odb, git_buf_cstr(&object_dir_buf));
692 if (error < 0)
693 goto error;
694 }
695
696 error = git__getenv(&work_tree_buf, "GIT_WORK_TREE");
697 if (error == GIT_ENOTFOUND)
698 git_error_clear();
699 else if (error < 0)
700 goto error;
701 else {
702 git_error_set(GIT_ERROR_INVALID, "GIT_WORK_TREE unimplemented");
703 error = GIT_ERROR;
704 goto error;
705 }
706
707 error = git__getenv(&work_tree_buf, "GIT_COMMON_DIR");
708 if (error == GIT_ENOTFOUND)
709 git_error_clear();
710 else if (error < 0)
711 goto error;
712 else {
713 git_error_set(GIT_ERROR_INVALID, "GIT_COMMON_DIR unimplemented");
714 error = GIT_ERROR;
715 goto error;
716 }
717
718 error = git_repository_open_ext(&repo, start_path, flags, ceiling_dirs);
719 if (error < 0)
720 goto error;
721
722 if (odb)
723 git_repository_set_odb(repo, odb);
724
725 error = git__getenv(&alts_buf, "GIT_ALTERNATE_OBJECT_DIRECTORIES");
726 if (error == GIT_ENOTFOUND) {
727 git_error_clear();
728 error = 0;
729 } else if (error < 0)
730 goto error;
731 else {
732 const char *end;
733 char *alt, *sep;
734 if (!odb) {
735 error = git_repository_odb(&odb, repo);
736 if (error < 0)
737 goto error;
738 }
739
740 end = git_buf_cstr(&alts_buf) + git_buf_len(&alts_buf);
741 for (sep = alt = alts_buf.ptr; sep != end; alt = sep+1) {
742 for (sep = alt; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++)
743 ;
744 if (*sep)
745 *sep = '\0';
746 error = git_odb_add_disk_alternate(odb, alt);
747 if (error < 0)
748 goto error;
749 }
750 }
751
752 if (git_buf_len(&namespace_buf)) {
753 error = git_repository_set_namespace(repo, git_buf_cstr(&namespace_buf));
754 if (error < 0)
755 goto error;
756 }
757
758 git_repository_set_index(repo, index);
759
760 if (out) {
761 *out = repo;
762 goto success;
763 }
764 error:
765 git_repository_free(repo);
766 success:
767 git_odb_free(odb);
768 git_index_free(index);
769 git_buf_dispose(&common_dir_buf);
770 git_buf_dispose(&work_tree_buf);
771 git_buf_dispose(&alts_buf);
772 git_buf_dispose(&object_dir_buf);
773 git_buf_dispose(&namespace_buf);
774 git_buf_dispose(&index_file_buf);
775 git_buf_dispose(&across_fs_buf);
776 git_buf_dispose(&ceiling_dirs_buf);
777 git_buf_dispose(&dir_buf);
778 return error;
779 }
780
781 static int repo_is_worktree(unsigned *out, const git_repository *repo)
782 {
783 git_buf gitdir_link = GIT_BUF_INIT;
784 int error;
785
786 /* Worktrees cannot have the same commondir and gitdir */
787 if (repo->commondir && repo->gitdir
788 && !strcmp(repo->commondir, repo->gitdir)) {
789 *out = 0;
790 return 0;
791 }
792
793 if ((error = git_buf_joinpath(&gitdir_link, repo->gitdir, "gitdir")) < 0)
794 return -1;
795
796 /* A 'gitdir' file inside a git directory is currently
797 * only used when the repository is a working tree. */
798 *out = !!git_path_exists(gitdir_link.ptr);
799
800 git_buf_dispose(&gitdir_link);
801 return error;
802 }
803
804 int git_repository_open_ext(
805 git_repository **repo_ptr,
806 const char *start_path,
807 unsigned int flags,
808 const char *ceiling_dirs)
809 {
810 int error;
811 unsigned is_worktree;
812 git_buf gitdir = GIT_BUF_INIT, workdir = GIT_BUF_INIT,
813 gitlink = GIT_BUF_INIT, commondir = GIT_BUF_INIT;
814 git_repository *repo = NULL;
815 git_config *config = NULL;
816
817 if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
818 return _git_repository_open_ext_from_env(repo_ptr, start_path);
819
820 if (repo_ptr)
821 *repo_ptr = NULL;
822
823 error = find_repo(
824 &gitdir, &workdir, &gitlink, &commondir, start_path, flags, ceiling_dirs);
825
826 if (error < 0 || !repo_ptr)
827 goto cleanup;
828
829 repo = repository_alloc();
830 GIT_ERROR_CHECK_ALLOC(repo);
831
832 repo->gitdir = git_buf_detach(&gitdir);
833 GIT_ERROR_CHECK_ALLOC(repo->gitdir);
834
835 if (gitlink.size) {
836 repo->gitlink = git_buf_detach(&gitlink);
837 GIT_ERROR_CHECK_ALLOC(repo->gitlink);
838 }
839 if (commondir.size) {
840 repo->commondir = git_buf_detach(&commondir);
841 GIT_ERROR_CHECK_ALLOC(repo->commondir);
842 }
843
844 if ((error = repo_is_worktree(&is_worktree, repo)) < 0)
845 goto cleanup;
846 repo->is_worktree = is_worktree;
847
848 /*
849 * We'd like to have the config, but git doesn't particularly
850 * care if it's not there, so we need to deal with that.
851 */
852
853 error = git_repository_config_snapshot(&config, repo);
854 if (error < 0 && error != GIT_ENOTFOUND)
855 goto cleanup;
856
857 if (config && (error = check_repositoryformatversion(config)) < 0)
858 goto cleanup;
859
860 if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0)
861 repo->is_bare = 1;
862 else {
863
864 if (config &&
865 ((error = load_config_data(repo, config)) < 0 ||
866 (error = load_workdir(repo, config, &workdir)) < 0))
867 goto cleanup;
868 }
869
870 cleanup:
871 git_buf_dispose(&gitdir);
872 git_buf_dispose(&workdir);
873 git_buf_dispose(&gitlink);
874 git_buf_dispose(&commondir);
875 git_config_free(config);
876
877 if (error < 0)
878 git_repository_free(repo);
879 else if (repo_ptr)
880 *repo_ptr = repo;
881
882 return error;
883 }
884
885 int git_repository_open(git_repository **repo_out, const char *path)
886 {
887 return git_repository_open_ext(
888 repo_out, path, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL);
889 }
890
891 int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *wt)
892 {
893 git_buf path = GIT_BUF_INIT;
894 git_repository *repo = NULL;
895 size_t len;
896 int err;
897
898 assert(repo_out && wt);
899
900 *repo_out = NULL;
901 len = strlen(wt->gitlink_path);
902
903 if (len <= 4 || strcasecmp(wt->gitlink_path + len - 4, ".git")) {
904 err = -1;
905 goto out;
906 }
907
908 if ((err = git_buf_set(&path, wt->gitlink_path, len - 4)) < 0)
909 goto out;
910
911 if ((err = git_repository_open(&repo, path.ptr)) < 0)
912 goto out;
913
914 *repo_out = repo;
915
916 out:
917 git_buf_dispose(&path);
918
919 return err;
920 }
921
922 int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
923 {
924 git_repository *repo;
925
926 repo = repository_alloc();
927 GIT_ERROR_CHECK_ALLOC(repo);
928
929 git_repository_set_odb(repo, odb);
930 *repo_out = repo;
931
932 return 0;
933 }
934
935 int git_repository_discover(
936 git_buf *out,
937 const char *start_path,
938 int across_fs,
939 const char *ceiling_dirs)
940 {
941 uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0;
942
943 assert(start_path);
944
945 git_buf_sanitize(out);
946
947 return find_repo(out, NULL, NULL, NULL, start_path, flags, ceiling_dirs);
948 }
949
950 static int load_config(
951 git_config **out,
952 git_repository *repo,
953 const char *global_config_path,
954 const char *xdg_config_path,
955 const char *system_config_path,
956 const char *programdata_path)
957 {
958 int error;
959 git_buf config_path = GIT_BUF_INIT;
960 git_config *cfg = NULL;
961
962 assert(out);
963
964 if ((error = git_config_new(&cfg)) < 0)
965 return error;
966
967 if (repo) {
968 if ((error = git_repository_item_path(&config_path, repo, GIT_REPOSITORY_ITEM_CONFIG)) == 0)
969 error = git_config_add_file_ondisk(cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, repo, 0);
970
971 if (error && error != GIT_ENOTFOUND)
972 goto on_error;
973
974 git_buf_dispose(&config_path);
975 }
976
977 if (global_config_path != NULL &&
978 (error = git_config_add_file_ondisk(
979 cfg, global_config_path, GIT_CONFIG_LEVEL_GLOBAL, repo, 0)) < 0 &&
980 error != GIT_ENOTFOUND)
981 goto on_error;
982
983 if (xdg_config_path != NULL &&
984 (error = git_config_add_file_ondisk(
985 cfg, xdg_config_path, GIT_CONFIG_LEVEL_XDG, repo, 0)) < 0 &&
986 error != GIT_ENOTFOUND)
987 goto on_error;
988
989 if (system_config_path != NULL &&
990 (error = git_config_add_file_ondisk(
991 cfg, system_config_path, GIT_CONFIG_LEVEL_SYSTEM, repo, 0)) < 0 &&
992 error != GIT_ENOTFOUND)
993 goto on_error;
994
995 if (programdata_path != NULL &&
996 (error = git_config_add_file_ondisk(
997 cfg, programdata_path, GIT_CONFIG_LEVEL_PROGRAMDATA, repo, 0)) < 0 &&
998 error != GIT_ENOTFOUND)
999 goto on_error;
1000
1001 git_error_clear(); /* clear any lingering ENOTFOUND errors */
1002
1003 *out = cfg;
1004 return 0;
1005
1006 on_error:
1007 git_buf_dispose(&config_path);
1008 git_config_free(cfg);
1009 *out = NULL;
1010 return error;
1011 }
1012
1013 static const char *path_unless_empty(git_buf *buf)
1014 {
1015 return git_buf_len(buf) > 0 ? git_buf_cstr(buf) : NULL;
1016 }
1017
1018 int git_repository_config__weakptr(git_config **out, git_repository *repo)
1019 {
1020 int error = 0;
1021
1022 if (repo->_config == NULL) {
1023 git_buf global_buf = GIT_BUF_INIT;
1024 git_buf xdg_buf = GIT_BUF_INIT;
1025 git_buf system_buf = GIT_BUF_INIT;
1026 git_buf programdata_buf = GIT_BUF_INIT;
1027 git_config *config;
1028
1029 git_config_find_global(&global_buf);
1030 git_config_find_xdg(&xdg_buf);
1031 git_config_find_system(&system_buf);
1032 git_config_find_programdata(&programdata_buf);
1033
1034 /* If there is no global file, open a backend for it anyway */
1035 if (git_buf_len(&global_buf) == 0)
1036 git_config__global_location(&global_buf);
1037
1038 error = load_config(
1039 &config, repo,
1040 path_unless_empty(&global_buf),
1041 path_unless_empty(&xdg_buf),
1042 path_unless_empty(&system_buf),
1043 path_unless_empty(&programdata_buf));
1044 if (!error) {
1045 GIT_REFCOUNT_OWN(config, repo);
1046
1047 config = git__compare_and_swap(&repo->_config, NULL, config);
1048 if (config != NULL) {
1049 GIT_REFCOUNT_OWN(config, NULL);
1050 git_config_free(config);
1051 }
1052 }
1053
1054 git_buf_dispose(&global_buf);
1055 git_buf_dispose(&xdg_buf);
1056 git_buf_dispose(&system_buf);
1057 git_buf_dispose(&programdata_buf);
1058 }
1059
1060 *out = repo->_config;
1061 return error;
1062 }
1063
1064 int git_repository_config(git_config **out, git_repository *repo)
1065 {
1066 if (git_repository_config__weakptr(out, repo) < 0)
1067 return -1;
1068
1069 GIT_REFCOUNT_INC(*out);
1070 return 0;
1071 }
1072
1073 int git_repository_config_snapshot(git_config **out, git_repository *repo)
1074 {
1075 int error;
1076 git_config *weak;
1077
1078 if ((error = git_repository_config__weakptr(&weak, repo)) < 0)
1079 return error;
1080
1081 return git_config_snapshot(out, weak);
1082 }
1083
1084 int git_repository_set_config(git_repository *repo, git_config *config)
1085 {
1086 assert(repo && config);
1087 set_config(repo, config);
1088 return 0;
1089 }
1090
1091 int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
1092 {
1093 int error = 0;
1094
1095 assert(repo && out);
1096
1097 if (repo->_odb == NULL) {
1098 git_buf odb_path = GIT_BUF_INIT;
1099 git_odb *odb;
1100
1101 if ((error = git_repository_item_path(&odb_path, repo,
1102 GIT_REPOSITORY_ITEM_OBJECTS)) < 0 ||
1103 (error = git_odb_new(&odb)) < 0)
1104 return error;
1105
1106 GIT_REFCOUNT_OWN(odb, repo);
1107
1108 if ((error = git_odb__set_caps(odb, GIT_ODB_CAP_FROM_OWNER)) < 0 ||
1109 (error = git_odb__add_default_backends(odb, odb_path.ptr, 0, 0)) < 0) {
1110 git_odb_free(odb);
1111 return error;
1112 }
1113
1114 odb = git__compare_and_swap(&repo->_odb, NULL, odb);
1115 if (odb != NULL) {
1116 GIT_REFCOUNT_OWN(odb, NULL);
1117 git_odb_free(odb);
1118 }
1119
1120 git_buf_dispose(&odb_path);
1121 }
1122
1123 *out = repo->_odb;
1124 return error;
1125 }
1126
1127 int git_repository_odb(git_odb **out, git_repository *repo)
1128 {
1129 if (git_repository_odb__weakptr(out, repo) < 0)
1130 return -1;
1131
1132 GIT_REFCOUNT_INC(*out);
1133 return 0;
1134 }
1135
1136 int git_repository_set_odb(git_repository *repo, git_odb *odb)
1137 {
1138 assert(repo && odb);
1139 set_odb(repo, odb);
1140 return 0;
1141 }
1142
1143 int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo)
1144 {
1145 int error = 0;
1146
1147 assert(out && repo);
1148
1149 if (repo->_refdb == NULL) {
1150 git_refdb *refdb;
1151
1152 error = git_refdb_open(&refdb, repo);
1153 if (!error) {
1154 GIT_REFCOUNT_OWN(refdb, repo);
1155
1156 refdb = git__compare_and_swap(&repo->_refdb, NULL, refdb);
1157 if (refdb != NULL) {
1158 GIT_REFCOUNT_OWN(refdb, NULL);
1159 git_refdb_free(refdb);
1160 }
1161 }
1162 }
1163
1164 *out = repo->_refdb;
1165 return error;
1166 }
1167
1168 int git_repository_refdb(git_refdb **out, git_repository *repo)
1169 {
1170 if (git_repository_refdb__weakptr(out, repo) < 0)
1171 return -1;
1172
1173 GIT_REFCOUNT_INC(*out);
1174 return 0;
1175 }
1176
1177 int git_repository_set_refdb(git_repository *repo, git_refdb *refdb)
1178 {
1179 assert(repo && refdb);
1180 set_refdb(repo, refdb);
1181 return 0;
1182 }
1183
1184 int git_repository_index__weakptr(git_index **out, git_repository *repo)
1185 {
1186 int error = 0;
1187
1188 assert(out && repo);
1189
1190 if (repo->_index == NULL) {
1191 git_buf index_path = GIT_BUF_INIT;
1192 git_index *index;
1193
1194 if ((error = git_buf_joinpath(&index_path, repo->gitdir, GIT_INDEX_FILE)) < 0)
1195 return error;
1196
1197 error = git_index_open(&index, index_path.ptr);
1198 if (!error) {
1199 GIT_REFCOUNT_OWN(index, repo);
1200
1201 index = git__compare_and_swap(&repo->_index, NULL, index);
1202 if (index != NULL) {
1203 GIT_REFCOUNT_OWN(index, NULL);
1204 git_index_free(index);
1205 }
1206
1207 error = git_index_set_caps(repo->_index,
1208 GIT_INDEX_CAPABILITY_FROM_OWNER);
1209 }
1210
1211 git_buf_dispose(&index_path);
1212 }
1213
1214 *out = repo->_index;
1215 return error;
1216 }
1217
1218 int git_repository_index(git_index **out, git_repository *repo)
1219 {
1220 if (git_repository_index__weakptr(out, repo) < 0)
1221 return -1;
1222
1223 GIT_REFCOUNT_INC(*out);
1224 return 0;
1225 }
1226
1227 int git_repository_set_index(git_repository *repo, git_index *index)
1228 {
1229 assert(repo);
1230 set_index(repo, index);
1231 return 0;
1232 }
1233
1234 int git_repository_set_namespace(git_repository *repo, const char *namespace)
1235 {
1236 git__free(repo->namespace);
1237
1238 if (namespace == NULL) {
1239 repo->namespace = NULL;
1240 return 0;
1241 }
1242
1243 return (repo->namespace = git__strdup(namespace)) ? 0 : -1;
1244 }
1245
1246 const char *git_repository_get_namespace(git_repository *repo)
1247 {
1248 return repo->namespace;
1249 }
1250
1251 #ifdef GIT_WIN32
1252 static int reserved_names_add8dot3(git_repository *repo, const char *path)
1253 {
1254 char *name = git_win32_path_8dot3_name(path);
1255 const char *def = GIT_DIR_SHORTNAME;
1256 const char *def_dot_git = DOT_GIT;
1257 size_t name_len, def_len = CONST_STRLEN(GIT_DIR_SHORTNAME);
1258 size_t def_dot_git_len = CONST_STRLEN(DOT_GIT);
1259 git_buf *buf;
1260
1261 if (!name)
1262 return 0;
1263
1264 name_len = strlen(name);
1265
1266 if ((name_len == def_len && memcmp(name, def, def_len) == 0) ||
1267 (name_len == def_dot_git_len && memcmp(name, def_dot_git, def_dot_git_len) == 0)) {
1268 git__free(name);
1269 return 0;
1270 }
1271
1272 if ((buf = git_array_alloc(repo->reserved_names)) == NULL)
1273 return -1;
1274
1275 git_buf_attach(buf, name, name_len);
1276 return true;
1277 }
1278
1279 bool git_repository__reserved_names(
1280 git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs)
1281 {
1282 GIT_UNUSED(include_ntfs);
1283
1284 if (repo->reserved_names.size == 0) {
1285 git_buf *buf;
1286 size_t i;
1287
1288 /* Add the static defaults */
1289 for (i = 0; i < git_repository__reserved_names_win32_len; i++) {
1290 if ((buf = git_array_alloc(repo->reserved_names)) == NULL)
1291 goto on_error;
1292
1293 buf->ptr = git_repository__reserved_names_win32[i].ptr;
1294 buf->size = git_repository__reserved_names_win32[i].size;
1295 }
1296
1297 /* Try to add any repo-specific reserved names - the gitlink file
1298 * within a submodule or the repository (if the repository directory
1299 * is beneath the workdir). These are typically `.git`, but should
1300 * be protected in case they are not. Note, repo and workdir paths
1301 * are always prettified to end in `/`, so a prefixcmp is safe.
1302 */
1303 if (!repo->is_bare) {
1304 int (*prefixcmp)(const char *, const char *);
1305 int error, ignorecase;
1306
1307 error = git_repository__configmap_lookup(
1308 &ignorecase, repo, GIT_CONFIGMAP_IGNORECASE);
1309 prefixcmp = (error || ignorecase) ? git__prefixcmp_icase :
1310 git__prefixcmp;
1311
1312 if (repo->gitlink &&
1313 reserved_names_add8dot3(repo, repo->gitlink) < 0)
1314 goto on_error;
1315
1316 if (repo->gitdir &&
1317 prefixcmp(repo->gitdir, repo->workdir) == 0 &&
1318 reserved_names_add8dot3(repo, repo->gitdir) < 0)
1319 goto on_error;
1320 }
1321 }
1322
1323 *out = repo->reserved_names.ptr;
1324 *outlen = repo->reserved_names.size;
1325
1326 return true;
1327
1328 /* Always give good defaults, even on OOM */
1329 on_error:
1330 *out = git_repository__reserved_names_win32;
1331 *outlen = git_repository__reserved_names_win32_len;
1332
1333 return false;
1334 }
1335 #else
1336 bool git_repository__reserved_names(
1337 git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs)
1338 {
1339 GIT_UNUSED(repo);
1340
1341 if (include_ntfs) {
1342 *out = git_repository__reserved_names_win32;
1343 *outlen = git_repository__reserved_names_win32_len;
1344 } else {
1345 *out = git_repository__reserved_names_posix;
1346 *outlen = git_repository__reserved_names_posix_len;
1347 }
1348
1349 return true;
1350 }
1351 #endif
1352
1353 static int check_repositoryformatversion(git_config *config)
1354 {
1355 int version, error;
1356
1357 error = git_config_get_int32(&version, config, "core.repositoryformatversion");
1358 /* git ignores this if the config variable isn't there */
1359 if (error == GIT_ENOTFOUND)
1360 return 0;
1361
1362 if (error < 0)
1363 return -1;
1364
1365 if (GIT_REPO_VERSION < version) {
1366 git_error_set(GIT_ERROR_REPOSITORY,
1367 "unsupported repository version %d. Only versions up to %d are supported.",
1368 version, GIT_REPO_VERSION);
1369 return -1;
1370 }
1371
1372 return 0;
1373 }
1374
1375 int git_repository_create_head(const char *git_dir, const char *ref_name)
1376 {
1377 git_buf ref_path = GIT_BUF_INIT;
1378 git_filebuf ref = GIT_FILEBUF_INIT;
1379 const char *fmt;
1380 int error;
1381
1382 if ((error = git_buf_joinpath(&ref_path, git_dir, GIT_HEAD_FILE)) < 0 ||
1383 (error = git_filebuf_open(&ref, ref_path.ptr, 0, GIT_REFS_FILE_MODE)) < 0)
1384 goto out;
1385
1386 if (!ref_name)
1387 ref_name = GIT_BRANCH_MASTER;
1388
1389 if (git__prefixcmp(ref_name, GIT_REFS_DIR) == 0)
1390 fmt = "ref: %s\n";
1391 else
1392 fmt = "ref: " GIT_REFS_HEADS_DIR "%s\n";
1393
1394 if ((error = git_filebuf_printf(&ref, fmt, ref_name)) < 0 ||
1395 (error = git_filebuf_commit(&ref)) < 0)
1396 goto out;
1397
1398 out:
1399 git_buf_dispose(&ref_path);
1400 git_filebuf_cleanup(&ref);
1401 return error;
1402 }
1403
1404 static bool is_chmod_supported(const char *file_path)
1405 {
1406 struct stat st1, st2;
1407
1408 if (p_stat(file_path, &st1) < 0)
1409 return false;
1410
1411 if (p_chmod(file_path, st1.st_mode ^ S_IXUSR) < 0)
1412 return false;
1413
1414 if (p_stat(file_path, &st2) < 0)
1415 return false;
1416
1417 return (st1.st_mode != st2.st_mode);
1418 }
1419
1420 static bool is_filesystem_case_insensitive(const char *gitdir_path)
1421 {
1422 git_buf path = GIT_BUF_INIT;
1423 int is_insensitive = -1;
1424
1425 if (!git_buf_joinpath(&path, gitdir_path, "CoNfIg"))
1426 is_insensitive = git_path_exists(git_buf_cstr(&path));
1427
1428 git_buf_dispose(&path);
1429 return is_insensitive;
1430 }
1431
1432 static bool are_symlinks_supported(const char *wd_path)
1433 {
1434 git_config *config = NULL;
1435 git_buf global_buf = GIT_BUF_INIT;
1436 git_buf xdg_buf = GIT_BUF_INIT;
1437 git_buf system_buf = GIT_BUF_INIT;
1438 git_buf programdata_buf = GIT_BUF_INIT;
1439 int symlinks = 0;
1440
1441 /*
1442 * To emulate Git for Windows, symlinks on Windows must be explicitly
1443 * opted-in. We examine the system configuration for a core.symlinks
1444 * set to true. If found, we then examine the filesystem to see if
1445 * symlinks are _actually_ supported by the current user. If that is
1446 * _not_ set, then we do not test or enable symlink support.
1447 */
1448 #ifdef GIT_WIN32
1449 git_config_find_global(&global_buf);
1450 git_config_find_xdg(&xdg_buf);
1451 git_config_find_system(&system_buf);
1452 git_config_find_programdata(&programdata_buf);
1453
1454 if (load_config(&config, NULL,
1455 path_unless_empty(&global_buf),
1456 path_unless_empty(&xdg_buf),
1457 path_unless_empty(&system_buf),
1458 path_unless_empty(&programdata_buf)) < 0)
1459 goto done;
1460
1461 if (git_config_get_bool(&symlinks, config, "core.symlinks") < 0 || !symlinks)
1462 goto done;
1463 #endif
1464
1465 if (!(symlinks = git_path_supports_symlinks(wd_path)))
1466 goto done;
1467
1468 done:
1469 git_buf_dispose(&global_buf);
1470 git_buf_dispose(&xdg_buf);
1471 git_buf_dispose(&system_buf);
1472 git_buf_dispose(&programdata_buf);
1473 git_config_free(config);
1474 return symlinks != 0;
1475 }
1476
1477 static int create_empty_file(const char *path, mode_t mode)
1478 {
1479 int fd;
1480
1481 if ((fd = p_creat(path, mode)) < 0) {
1482 git_error_set(GIT_ERROR_OS, "error while creating '%s'", path);
1483 return -1;
1484 }
1485
1486 if (p_close(fd) < 0) {
1487 git_error_set(GIT_ERROR_OS, "error while closing '%s'", path);
1488 return -1;
1489 }
1490
1491 return 0;
1492 }
1493
1494 static int repo_local_config(
1495 git_config **out,
1496 git_buf *config_dir,
1497 git_repository *repo,
1498 const char *repo_dir)
1499 {
1500 int error = 0;
1501 git_config *parent;
1502 const char *cfg_path;
1503
1504 if (git_buf_joinpath(config_dir, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
1505 return -1;
1506 cfg_path = git_buf_cstr(config_dir);
1507
1508 /* make LOCAL config if missing */
1509 if (!git_path_isfile(cfg_path) &&
1510 (error = create_empty_file(cfg_path, GIT_CONFIG_FILE_MODE)) < 0)
1511 return error;
1512
1513 /* if no repo, just open that file directly */
1514 if (!repo)
1515 return git_config_open_ondisk(out, cfg_path);
1516
1517 /* otherwise, open parent config and get that level */
1518 if ((error = git_repository_config__weakptr(&parent, repo)) < 0)
1519 return error;
1520
1521 if (git_config_open_level(out, parent, GIT_CONFIG_LEVEL_LOCAL) < 0) {
1522 git_error_clear();
1523
1524 if (!(error = git_config_add_file_ondisk(
1525 parent, cfg_path, GIT_CONFIG_LEVEL_LOCAL, repo, false)))
1526 error = git_config_open_level(out, parent, GIT_CONFIG_LEVEL_LOCAL);
1527 }
1528
1529 git_config_free(parent);
1530
1531 return error;
1532 }
1533
1534 static int repo_init_fs_configs(
1535 git_config *cfg,
1536 const char *cfg_path,
1537 const char *repo_dir,
1538 const char *work_dir,
1539 bool update_ignorecase)
1540 {
1541 int error = 0;
1542
1543 if (!work_dir)
1544 work_dir = repo_dir;
1545
1546 if ((error = git_config_set_bool(
1547 cfg, "core.filemode", is_chmod_supported(cfg_path))) < 0)
1548 return error;
1549
1550 if (!are_symlinks_supported(work_dir)) {
1551 if ((error = git_config_set_bool(cfg, "core.symlinks", false)) < 0)
1552 return error;
1553 } else if (git_config_delete_entry(cfg, "core.symlinks") < 0)
1554 git_error_clear();
1555
1556 if (update_ignorecase) {
1557 if (is_filesystem_case_insensitive(repo_dir)) {
1558 if ((error = git_config_set_bool(cfg, "core.ignorecase", true)) < 0)
1559 return error;
1560 } else if (git_config_delete_entry(cfg, "core.ignorecase") < 0)
1561 git_error_clear();
1562 }
1563
1564 #ifdef GIT_USE_ICONV
1565 if ((error = git_config_set_bool(
1566 cfg, "core.precomposeunicode",
1567 git_path_does_fs_decompose_unicode(work_dir))) < 0)
1568 return error;
1569 /* on non-iconv platforms, don't even set core.precomposeunicode */
1570 #endif
1571
1572 return 0;
1573 }
1574
1575 static int repo_init_config(
1576 const char *repo_dir,
1577 const char *work_dir,
1578 uint32_t flags,
1579 uint32_t mode)
1580 {
1581 int error = 0;
1582 git_buf cfg_path = GIT_BUF_INIT, worktree_path = GIT_BUF_INIT;
1583 git_config *config = NULL;
1584 bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
1585 bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0);
1586
1587 if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0)
1588 goto cleanup;
1589
1590 if (is_reinit && (error = check_repositoryformatversion(config)) < 0)
1591 goto cleanup;
1592
1593 #define SET_REPO_CONFIG(TYPE, NAME, VAL) do { \
1594 if ((error = git_config_set_##TYPE(config, NAME, VAL)) < 0) \
1595 goto cleanup; } while (0)
1596
1597 SET_REPO_CONFIG(bool, "core.bare", is_bare);
1598 SET_REPO_CONFIG(int32, "core.repositoryformatversion", GIT_REPO_VERSION);
1599
1600 if ((error = repo_init_fs_configs(
1601 config, cfg_path.ptr, repo_dir, work_dir, !is_reinit)) < 0)
1602 goto cleanup;
1603
1604 if (!is_bare) {
1605 SET_REPO_CONFIG(bool, "core.logallrefupdates", true);
1606
1607 if (!(flags & GIT_REPOSITORY_INIT__NATURAL_WD)) {
1608 if ((error = git_buf_sets(&worktree_path, work_dir)) < 0)
1609 goto cleanup;
1610
1611 if ((flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK))
1612 if ((error = git_path_make_relative(&worktree_path, repo_dir)) < 0)
1613 goto cleanup;
1614
1615 SET_REPO_CONFIG(string, "core.worktree", worktree_path.ptr);
1616 } else if (is_reinit) {
1617 if (git_config_delete_entry(config, "core.worktree") < 0)
1618 git_error_clear();
1619 }
1620 }
1621
1622 if (mode == GIT_REPOSITORY_INIT_SHARED_GROUP) {
1623 SET_REPO_CONFIG(int32, "core.sharedrepository", 1);
1624 SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
1625 }
1626 else if (mode == GIT_REPOSITORY_INIT_SHARED_ALL) {
1627 SET_REPO_CONFIG(int32, "core.sharedrepository", 2);
1628 SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
1629 }
1630
1631 cleanup:
1632 git_buf_dispose(&cfg_path);
1633 git_buf_dispose(&worktree_path);
1634 git_config_free(config);
1635
1636 return error;
1637 }
1638
1639 static int repo_reinit_submodule_fs(git_submodule *sm, const char *n, void *p)
1640 {
1641 git_repository *smrepo = NULL;
1642 GIT_UNUSED(n); GIT_UNUSED(p);
1643
1644 if (git_submodule_open(&smrepo, sm) < 0 ||
1645 git_repository_reinit_filesystem(smrepo, true) < 0)
1646 git_error_clear();
1647 git_repository_free(smrepo);
1648
1649 return 0;
1650 }
1651
1652 int git_repository_reinit_filesystem(git_repository *repo, int recurse)
1653 {
1654 int error = 0;
1655 git_buf path = GIT_BUF_INIT;
1656 git_config *config = NULL;
1657 const char *repo_dir = git_repository_path(repo);
1658
1659 if (!(error = repo_local_config(&config, &path, repo, repo_dir)))
1660 error = repo_init_fs_configs(
1661 config, path.ptr, repo_dir, git_repository_workdir(repo), true);
1662
1663 git_config_free(config);
1664 git_buf_dispose(&path);
1665
1666 git_repository__configmap_lookup_cache_clear(repo);
1667
1668 if (!repo->is_bare && recurse)
1669 (void)git_submodule_foreach(repo, repo_reinit_submodule_fs, NULL);
1670
1671 return error;
1672 }
1673
1674 static int repo_write_template(
1675 const char *git_dir,
1676 bool allow_overwrite,
1677 const char *file,
1678 mode_t mode,
1679 bool hidden,
1680 const char *content)
1681 {
1682 git_buf path = GIT_BUF_INIT;
1683 int fd, error = 0, flags;
1684
1685 if (git_buf_joinpath(&path, git_dir, file) < 0)
1686 return -1;
1687
1688 if (allow_overwrite)
1689 flags = O_WRONLY | O_CREAT | O_TRUNC;
1690 else
1691 flags = O_WRONLY | O_CREAT | O_EXCL;
1692
1693 fd = p_open(git_buf_cstr(&path), flags, mode);
1694
1695 if (fd >= 0) {
1696 error = p_write(fd, content, strlen(content));
1697
1698 p_close(fd);
1699 }
1700 else if (errno != EEXIST)
1701 error = fd;
1702
1703 #ifdef GIT_WIN32
1704 if (!error && hidden) {
1705 if (git_win32__set_hidden(path.ptr, true) < 0)
1706 error = -1;
1707 }
1708 #else
1709 GIT_UNUSED(hidden);
1710 #endif
1711
1712 git_buf_dispose(&path);
1713
1714 if (error)
1715 git_error_set(GIT_ERROR_OS,
1716 "failed to initialize repository with template '%s'", file);
1717
1718 return error;
1719 }
1720
1721 static int repo_write_gitlink(
1722 const char *in_dir, const char *to_repo, bool use_relative_path)
1723 {
1724 int error;
1725 git_buf buf = GIT_BUF_INIT;
1726 git_buf path_to_repo = GIT_BUF_INIT;
1727 struct stat st;
1728
1729 git_path_dirname_r(&buf, to_repo);
1730 git_path_to_dir(&buf);
1731 if (git_buf_oom(&buf))
1732 return -1;
1733
1734 /* don't write gitlink to natural workdir */
1735 if (git__suffixcmp(to_repo, "/" DOT_GIT "/") == 0 &&
1736 strcmp(in_dir, buf.ptr) == 0)
1737 {
1738 error = GIT_PASSTHROUGH;
1739 goto cleanup;
1740 }
1741
1742 if ((error = git_buf_joinpath(&buf, in_dir, DOT_GIT)) < 0)
1743 goto cleanup;
1744
1745 if (!p_stat(buf.ptr, &st) && !S_ISREG(st.st_mode)) {
1746 git_error_set(GIT_ERROR_REPOSITORY,
1747 "cannot overwrite gitlink file into path '%s'", in_dir);
1748 error = GIT_EEXISTS;
1749 goto cleanup;
1750 }
1751
1752 git_buf_clear(&buf);
1753
1754 error = git_buf_sets(&path_to_repo, to_repo);
1755
1756 if (!error && use_relative_path)
1757 error = git_path_make_relative(&path_to_repo, in_dir);
1758
1759 if (!error)
1760 error = git_buf_join(&buf, ' ', GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr);
1761
1762 if (!error)
1763 error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr);
1764
1765 cleanup:
1766 git_buf_dispose(&buf);
1767 git_buf_dispose(&path_to_repo);
1768 return error;
1769 }
1770
1771 static mode_t pick_dir_mode(git_repository_init_options *opts)
1772 {
1773 if (opts->mode == GIT_REPOSITORY_INIT_SHARED_UMASK)
1774 return 0777;
1775 if (opts->mode == GIT_REPOSITORY_INIT_SHARED_GROUP)
1776 return (0775 | S_ISGID);
1777 if (opts->mode == GIT_REPOSITORY_INIT_SHARED_ALL)
1778 return (0777 | S_ISGID);
1779 return opts->mode;
1780 }
1781
1782 #include "repo_template.h"
1783
1784 static int repo_init_structure(
1785 const char *repo_dir,
1786 const char *work_dir,
1787 git_repository_init_options *opts)
1788 {
1789 int error = 0;
1790 repo_template_item *tpl;
1791 bool external_tpl =
1792 ((opts->flags & GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE) != 0);
1793 mode_t dmode = pick_dir_mode(opts);
1794 bool chmod = opts->mode != GIT_REPOSITORY_INIT_SHARED_UMASK;
1795
1796 /* Hide the ".git" directory */
1797 #ifdef GIT_WIN32
1798 if ((opts->flags & GIT_REPOSITORY_INIT__HAS_DOTGIT) != 0) {
1799 if (git_win32__set_hidden(repo_dir, true) < 0) {
1800 git_error_set(GIT_ERROR_OS,
1801 "failed to mark Git repository folder as hidden");
1802 return -1;
1803 }
1804 }
1805 #endif
1806
1807 /* Create the .git gitlink if appropriate */
1808 if ((opts->flags & GIT_REPOSITORY_INIT_BARE) == 0 &&
1809 (opts->flags & GIT_REPOSITORY_INIT__NATURAL_WD) == 0)
1810 {
1811 if (repo_write_gitlink(work_dir, repo_dir, opts->flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK) < 0)
1812 return -1;
1813 }
1814
1815 /* Copy external template if requested */
1816 if (external_tpl) {
1817 git_config *cfg = NULL;
1818 const char *tdir = NULL;
1819 bool default_template = false;
1820 git_buf template_buf = GIT_BUF_INIT;
1821
1822 if (opts->template_path)
1823 tdir = opts->template_path;
1824 else if ((error = git_config_open_default(&cfg)) >= 0) {
1825 if (!git_config_get_path(&template_buf, cfg, "init.templatedir"))
1826 tdir = template_buf.ptr;
1827 git_error_clear();
1828 }
1829
1830 if (!tdir) {
1831 if (!(error = git_sysdir_find_template_dir(&template_buf)))
1832 tdir = template_buf.ptr;
1833 default_template = true;
1834 }
1835
1836 /*
1837 * If tdir was the empty string, treat it like tdir was a path to an
1838 * empty directory (so, don't do any copying). This is the behavior
1839 * that git(1) exhibits, although it doesn't seem to be officially
1840 * documented.
1841 */
1842 if (tdir && git__strcmp(tdir, "") != 0) {
1843 uint32_t cpflags = GIT_CPDIR_COPY_SYMLINKS |
1844 GIT_CPDIR_SIMPLE_TO_MODE |
1845 GIT_CPDIR_COPY_DOTFILES;
1846 if (opts->mode != GIT_REPOSITORY_INIT_SHARED_UMASK)
1847 cpflags |= GIT_CPDIR_CHMOD_DIRS;
1848 error = git_futils_cp_r(tdir, repo_dir, cpflags, dmode);
1849 }
1850
1851 git_buf_dispose(&template_buf);
1852 git_config_free(cfg);
1853
1854 if (error < 0) {
1855 if (!default_template)
1856 return error;
1857
1858 /* if template was default, ignore error and use internal */
1859 git_error_clear();
1860 external_tpl = false;
1861 error = 0;
1862 }
1863 }
1864
1865 /* Copy internal template
1866 * - always ensure existence of dirs
1867 * - only create files if no external template was specified
1868 */
1869 for (tpl = repo_template; !error && tpl->path; ++tpl) {
1870 if (!tpl->content) {
1871 uint32_t mkdir_flags = GIT_MKDIR_PATH;
1872 if (chmod)
1873 mkdir_flags |= GIT_MKDIR_CHMOD;
1874
1875 error = git_futils_mkdir_relative(
1876 tpl->path, repo_dir, dmode, mkdir_flags, NULL);
1877 }
1878 else if (!external_tpl) {
1879 const char *content = tpl->content;
1880
1881 if (opts->description && strcmp(tpl->path, GIT_DESC_FILE) == 0)
1882 content = opts->description;
1883
1884 error = repo_write_template(
1885 repo_dir, false, tpl->path, tpl->mode, false, content);
1886 }
1887 }
1888
1889 return error;
1890 }
1891
1892 static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2)
1893 {
1894 /* When making parent directories during repository initialization
1895 * don't try to set gid or grant world write access
1896 */
1897 return git_futils_mkdir(
1898 buf->ptr, mode & ~(S_ISGID | 0002),
1899 GIT_MKDIR_PATH | GIT_MKDIR_VERIFY_DIR |
1900 (skip2 ? GIT_MKDIR_SKIP_LAST2 : GIT_MKDIR_SKIP_LAST));
1901 }
1902
1903 static int repo_init_directories(
1904 git_buf *repo_path,
1905 git_buf *wd_path,
1906 const char *given_repo,
1907 git_repository_init_options *opts)
1908 {
1909 int error = 0;
1910 bool is_bare, add_dotgit, has_dotgit, natural_wd;
1911 mode_t dirmode;
1912
1913 /* There are three possible rules for what we are allowed to create:
1914 * - MKPATH means anything we need
1915 * - MKDIR means just the .git directory and its parent and the workdir
1916 * - Neither means only the .git directory can be created
1917 *
1918 * There are 5 "segments" of path that we might need to deal with:
1919 * 1. The .git directory
1920 * 2. The parent of the .git directory
1921 * 3. Everything above the parent of the .git directory
1922 * 4. The working directory (often the same as #2)
1923 * 5. Everything above the working directory (often the same as #3)
1924 *
1925 * For all directories created, we start with the init_mode value for
1926 * permissions and then strip off bits in some cases:
1927 *
1928 * For MKPATH, we create #3 (and #5) paths without S_ISGID or S_IWOTH
1929 * For MKPATH and MKDIR, we create #2 (and #4) without S_ISGID
1930 * For all rules, we create #1 using the untouched init_mode
1931 */
1932
1933 /* set up repo path */
1934
1935 is_bare = ((opts->flags & GIT_REPOSITORY_INIT_BARE) != 0);
1936
1937 add_dotgit =
1938 (opts->flags & GIT_REPOSITORY_INIT_NO_DOTGIT_DIR) == 0 &&
1939 !is_bare &&
1940 git__suffixcmp(given_repo, "/" DOT_GIT) != 0 &&
1941 git__suffixcmp(given_repo, "/" GIT_DIR) != 0;
1942
1943 if (git_buf_joinpath(repo_path, given_repo, add_dotgit ? GIT_DIR : "") < 0)
1944 return -1;
1945
1946 has_dotgit = (git__suffixcmp(repo_path->ptr, "/" GIT_DIR) == 0);
1947 if (has_dotgit)
1948 opts->flags |= GIT_REPOSITORY_INIT__HAS_DOTGIT;
1949
1950 /* set up workdir path */
1951
1952 if (!is_bare) {
1953 if (opts->workdir_path) {
1954 if (git_path_join_unrooted(
1955 wd_path, opts->workdir_path, repo_path->ptr, NULL) < 0)
1956 return -1;
1957 } else if (has_dotgit) {
1958 if (git_path_dirname_r(wd_path, repo_path->ptr) < 0)
1959 return -1;
1960 } else {
1961 git_error_set(GIT_ERROR_REPOSITORY, "cannot pick working directory"
1962 " for non-bare repository that isn't a '.git' directory");
1963 return -1;
1964 }
1965
1966 if (git_path_to_dir(wd_path) < 0)
1967 return -1;
1968 } else {
1969 git_buf_clear(wd_path);
1970 }
1971
1972 natural_wd =
1973 has_dotgit &&
1974 wd_path->size > 0 &&
1975 wd_path->size + strlen(GIT_DIR) == repo_path->size &&
1976 memcmp(repo_path->ptr, wd_path->ptr, wd_path->size) == 0;
1977 if (natural_wd)
1978 opts->flags |= GIT_REPOSITORY_INIT__NATURAL_WD;
1979
1980 /* create directories as needed / requested */
1981
1982 dirmode = pick_dir_mode(opts);
1983
1984 if ((opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0) {
1985 /* create path #5 */
1986 if (wd_path->size > 0 &&
1987 (error = mkdir_parent(wd_path, dirmode, false)) < 0)
1988 return error;
1989
1990 /* create path #3 (if not the same as #5) */
1991 if (!natural_wd &&
1992 (error = mkdir_parent(repo_path, dirmode, has_dotgit)) < 0)
1993 return error;
1994 }
1995
1996 if ((opts->flags & GIT_REPOSITORY_INIT_MKDIR) != 0 ||
1997 (opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0)
1998 {
1999 /* create path #4 */
2000 if (wd_path->size > 0 &&
2001 (error = git_futils_mkdir(
2002 wd_path->ptr, dirmode & ~S_ISGID,
2003 GIT_MKDIR_VERIFY_DIR)) < 0)
2004 return error;
2005
2006 /* create path #2 (if not the same as #4) */
2007 if (!natural_wd &&
2008 (error = git_futils_mkdir(
2009 repo_path->ptr, dirmode & ~S_ISGID,
2010 GIT_MKDIR_VERIFY_DIR | GIT_MKDIR_SKIP_LAST)) < 0)
2011 return error;
2012 }
2013
2014 if ((opts->flags & GIT_REPOSITORY_INIT_MKDIR) != 0 ||
2015 (opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0 ||
2016 has_dotgit)
2017 {
2018 /* create path #1 */
2019 error = git_futils_mkdir(repo_path->ptr, dirmode,
2020 GIT_MKDIR_VERIFY_DIR | ((dirmode & S_ISGID) ? GIT_MKDIR_CHMOD : 0));
2021 }
2022
2023 /* prettify both directories now that they are created */
2024
2025 if (!error) {
2026 error = git_path_prettify_dir(repo_path, repo_path->ptr, NULL);
2027
2028 if (!error && wd_path->size > 0)
2029 error = git_path_prettify_dir(wd_path, wd_path->ptr, NULL);
2030 }
2031
2032 return error;
2033 }
2034
2035 static int repo_init_create_origin(git_repository *repo, const char *url)
2036 {
2037 int error;
2038 git_remote *remote;
2039
2040 if (!(error = git_remote_create(&remote, repo, GIT_REMOTE_ORIGIN, url))) {
2041 git_remote_free(remote);
2042 }
2043
2044 return error;
2045 }
2046
2047 int git_repository_init(
2048 git_repository **repo_out, const char *path, unsigned is_bare)
2049 {
2050 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
2051
2052 opts.flags = GIT_REPOSITORY_INIT_MKPATH; /* don't love this default */
2053 if (is_bare)
2054 opts.flags |= GIT_REPOSITORY_INIT_BARE;
2055
2056 return git_repository_init_ext(repo_out, path, &opts);
2057 }
2058
2059 int git_repository_init_ext(
2060 git_repository **out,
2061 const char *given_repo,
2062 git_repository_init_options *opts)
2063 {
2064 git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT,
2065 common_path = GIT_BUF_INIT, head_path = GIT_BUF_INIT;
2066 const char *wd;
2067 bool is_valid;
2068 int error;
2069
2070 assert(out && given_repo && opts);
2071
2072 GIT_ERROR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options");
2073
2074 if ((error = repo_init_directories(&repo_path, &wd_path, given_repo, opts)) < 0)
2075 goto out;
2076
2077 wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_buf_cstr(&wd_path);
2078
2079 if ((error = is_valid_repository_path(&is_valid, &repo_path, &common_path)) < 0)
2080 goto out;
2081
2082 if (is_valid) {
2083 if ((opts->flags & GIT_REPOSITORY_INIT_NO_REINIT) != 0) {
2084 git_error_set(GIT_ERROR_REPOSITORY,
2085 "attempt to reinitialize '%s'", given_repo);
2086 error = GIT_EEXISTS;
2087 goto out;
2088 }
2089
2090 opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT;
2091
2092 if ((error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode)) < 0)
2093 goto out;
2094
2095 /* TODO: reinitialize the templates */
2096 } else {
2097 if ((error = repo_init_structure(repo_path.ptr, wd, opts)) < 0 ||
2098 (error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode)) < 0 ||
2099 (error = git_buf_joinpath(&head_path, repo_path.ptr, GIT_HEAD_FILE)) < 0)
2100 goto out;
2101
2102 /*
2103 * Only set the new HEAD if the file does not exist already via
2104 * a template or if the caller has explicitly supplied an
2105 * initial HEAD value.
2106 */
2107 if ((!git_path_exists(head_path.ptr) || opts->initial_head) &&
2108 (error = git_repository_create_head(repo_path.ptr, opts->initial_head)) < 0)
2109 goto out;
2110 }
2111
2112 if ((error = git_repository_open(out, repo_path.ptr)) < 0)
2113 goto out;
2114
2115 if (opts->origin_url &&
2116 (error = repo_init_create_origin(*out, opts->origin_url)) < 0)
2117 goto out;
2118
2119 out:
2120 git_buf_dispose(&head_path);
2121 git_buf_dispose(&common_path);
2122 git_buf_dispose(&repo_path);
2123 git_buf_dispose(&wd_path);
2124
2125 return error;
2126 }
2127
2128 int git_repository_head_detached(git_repository *repo)
2129 {
2130 git_reference *ref;
2131 git_odb *odb = NULL;
2132 int exists;
2133
2134 if (git_repository_odb__weakptr(&odb, repo) < 0)
2135 return -1;
2136
2137 if (git_reference_lookup(&ref, repo, GIT_HEAD_FILE) < 0)
2138 return -1;
2139
2140 if (git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC) {
2141 git_reference_free(ref);
2142 return 0;
2143 }
2144
2145 exists = git_odb_exists(odb, git_reference_target(ref));
2146
2147 git_reference_free(ref);
2148 return exists;
2149 }
2150
2151 static int get_worktree_file_path(git_buf *out, git_repository *repo, const char *worktree, const char *file)
2152 {
2153 git_buf_clear(out);
2154 return git_buf_printf(out, "%s/worktrees/%s/%s", repo->commondir, worktree, file);
2155 }
2156
2157 int git_repository_head_detached_for_worktree(git_repository *repo, const char *name)
2158 {
2159 git_reference *ref = NULL;
2160 int error;
2161
2162 assert(repo && name);
2163
2164 if ((error = git_repository_head_for_worktree(&ref, repo, name)) < 0)
2165 goto out;
2166
2167 error = (git_reference_type(ref) != GIT_REFERENCE_SYMBOLIC);
2168 out:
2169 git_reference_free(ref);
2170
2171 return error;
2172 }
2173
2174 int git_repository_head(git_reference **head_out, git_repository *repo)
2175 {
2176 git_reference *head;
2177 int error;
2178
2179 assert(head_out);
2180
2181 if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0)
2182 return error;
2183
2184 if (git_reference_type(head) == GIT_REFERENCE_DIRECT) {
2185 *head_out = head;
2186 return 0;
2187 }
2188
2189 error = git_reference_lookup_resolved(head_out, repo, git_reference_symbolic_target(head), -1);
2190 git_reference_free(head);
2191
2192 return error == GIT_ENOTFOUND ? GIT_EUNBORNBRANCH : error;
2193 }
2194
2195 int git_repository_head_for_worktree(git_reference **out, git_repository *repo, const char *name)
2196 {
2197 git_buf path = GIT_BUF_INIT;
2198 git_reference *head = NULL;
2199 int error;
2200
2201 assert(out && repo && name);
2202
2203 *out = NULL;
2204
2205 if ((error = get_worktree_file_path(&path, repo, name, GIT_HEAD_FILE)) < 0 ||
2206 (error = git_reference__read_head(&head, repo, path.ptr)) < 0)
2207 goto out;
2208
2209 if (git_reference_type(head) != GIT_REFERENCE_DIRECT) {
2210 git_reference *resolved;
2211
2212 error = git_reference_lookup_resolved(&resolved, repo, git_reference_symbolic_target(head), -1);
2213 git_reference_free(head);
2214 head = resolved;
2215 }
2216
2217 *out = head;
2218
2219 out:
2220 if (error)
2221 git_reference_free(head);
2222
2223 git_buf_dispose(&path);
2224
2225 return error;
2226 }
2227
2228 int git_repository_foreach_head(git_repository *repo,
2229 git_repository_foreach_head_cb cb,
2230 int flags, void *payload)
2231 {
2232 git_strarray worktrees = GIT_VECTOR_INIT;
2233 git_buf path = GIT_BUF_INIT;
2234 int error = 0;
2235 size_t i;
2236
2237
2238 if (!(flags & GIT_REPOSITORY_FOREACH_HEAD_SKIP_REPO)) {
2239 /* Gather HEAD of main repository */
2240 if ((error = git_buf_joinpath(&path, repo->commondir, GIT_HEAD_FILE)) < 0 ||
2241 (error = cb(repo, path.ptr, payload) != 0))
2242 goto out;
2243 }
2244
2245 if (!(flags & GIT_REPOSITORY_FOREACH_HEAD_SKIP_WORKTREES)) {
2246 if ((error = git_worktree_list(&worktrees, repo)) < 0) {
2247 error = 0;
2248 goto out;
2249 }
2250
2251 /* Gather HEADs of all worktrees */
2252 for (i = 0; i < worktrees.count; i++) {
2253 if (get_worktree_file_path(&path, repo, worktrees.strings[i], GIT_HEAD_FILE) < 0)
2254 continue;
2255
2256 if ((error = cb(repo, path.ptr, payload)) != 0)
2257 goto out;
2258 }
2259 }
2260
2261 out:
2262 git_buf_dispose(&path);
2263 git_strarray_free(&worktrees);
2264 return error;
2265 }
2266
2267 int git_repository_head_unborn(git_repository *repo)
2268 {
2269 git_reference *ref = NULL;
2270 int error;
2271
2272 error = git_repository_head(&ref, repo);
2273 git_reference_free(ref);
2274
2275 if (error == GIT_EUNBORNBRANCH) {
2276 git_error_clear();
2277 return 1;
2278 }
2279
2280 if (error < 0)
2281 return -1;
2282
2283 return 0;
2284 }
2285
2286 static int at_least_one_cb(const char *refname, void *payload)
2287 {
2288 GIT_UNUSED(refname);
2289 GIT_UNUSED(payload);
2290 return GIT_PASSTHROUGH;
2291 }
2292
2293 static int repo_contains_no_reference(git_repository *repo)
2294 {
2295 int error = git_reference_foreach_name(repo, &at_least_one_cb, NULL);
2296
2297 if (error == GIT_PASSTHROUGH)
2298 return 0;
2299
2300 if (!error)
2301 return 1;
2302
2303 return error;
2304 }
2305
2306 int git_repository_is_empty(git_repository *repo)
2307 {
2308 git_reference *head = NULL;
2309 int is_empty = 0;
2310
2311 if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
2312 return -1;
2313
2314 if (git_reference_type(head) == GIT_REFERENCE_SYMBOLIC)
2315 is_empty =
2316 (strcmp(git_reference_symbolic_target(head),
2317 GIT_REFS_HEADS_DIR "master") == 0) &&
2318 repo_contains_no_reference(repo);
2319
2320 git_reference_free(head);
2321
2322 return is_empty;
2323 }
2324
2325 static const char *resolved_parent_path(const git_repository *repo, git_repository_item_t item, git_repository_item_t fallback)
2326 {
2327 const char *parent;
2328
2329 switch (item) {
2330 case GIT_REPOSITORY_ITEM_GITDIR:
2331 parent = git_repository_path(repo);
2332 break;
2333 case GIT_REPOSITORY_ITEM_WORKDIR:
2334 parent = git_repository_workdir(repo);
2335 break;
2336 case GIT_REPOSITORY_ITEM_COMMONDIR:
2337 parent = git_repository_commondir(repo);
2338 break;
2339 default:
2340 git_error_set(GIT_ERROR_INVALID, "invalid item directory");
2341 return NULL;
2342 }
2343 if (!parent && fallback != GIT_REPOSITORY_ITEM__LAST)
2344 return resolved_parent_path(repo, fallback, GIT_REPOSITORY_ITEM__LAST);
2345
2346 return parent;
2347 }
2348
2349 int git_repository_item_path(git_buf *out, const git_repository *repo, git_repository_item_t item)
2350 {
2351 const char *parent = resolved_parent_path(repo, items[item].parent, items[item].fallback);
2352 if (parent == NULL) {
2353 git_error_set(GIT_ERROR_INVALID, "path cannot exist in repository");
2354 return GIT_ENOTFOUND;
2355 }
2356
2357 if (git_buf_sets(out, parent) < 0)
2358 return -1;
2359
2360 if (items[item].name) {
2361 if (git_buf_joinpath(out, parent, items[item].name) < 0)
2362 return -1;
2363 }
2364
2365 if (items[item].directory) {
2366 if (git_path_to_dir(out) < 0)
2367 return -1;
2368 }
2369
2370 return 0;
2371 }
2372
2373 const char *git_repository_path(const git_repository *repo)
2374 {
2375 assert(repo);
2376 return repo->gitdir;
2377 }
2378
2379 const char *git_repository_workdir(const git_repository *repo)
2380 {
2381 assert(repo);
2382
2383 if (repo->is_bare)
2384 return NULL;
2385
2386 return repo->workdir;
2387 }
2388
2389 const char *git_repository_commondir(const git_repository *repo)
2390 {
2391 assert(repo);
2392 return repo->commondir;
2393 }
2394
2395 int git_repository_set_workdir(
2396 git_repository *repo, const char *workdir, int update_gitlink)
2397 {
2398 int error = 0;
2399 git_buf path = GIT_BUF_INIT;
2400
2401 assert(repo && workdir);
2402
2403 if (git_path_prettify_dir(&path, workdir, NULL) < 0)
2404 return -1;
2405
2406 if (repo->workdir && strcmp(repo->workdir, path.ptr) == 0)
2407 return 0;
2408
2409 if (update_gitlink) {
2410 git_config *config;
2411
2412 if (git_repository_config__weakptr(&config, repo) < 0)
2413 return -1;
2414
2415 error = repo_write_gitlink(path.ptr, git_repository_path(repo), false);
2416
2417 /* passthrough error means gitlink is unnecessary */
2418 if (error == GIT_PASSTHROUGH)
2419 error = git_config_delete_entry(config, "core.worktree");
2420 else if (!error)
2421 error = git_config_set_string(config, "core.worktree", path.ptr);
2422
2423 if (!error)
2424 error = git_config_set_bool(config, "core.bare", false);
2425 }
2426
2427 if (!error) {
2428 char *old_workdir = repo->workdir;
2429
2430 repo->workdir = git_buf_detach(&path);
2431 repo->is_bare = 0;
2432
2433 git__free(old_workdir);
2434 }
2435
2436 return error;
2437 }
2438
2439 int git_repository_is_bare(const git_repository *repo)
2440 {
2441 assert(repo);
2442 return repo->is_bare;
2443 }
2444
2445 int git_repository_is_worktree(const git_repository *repo)
2446 {
2447 assert(repo);
2448 return repo->is_worktree;
2449 }
2450
2451 int git_repository_set_bare(git_repository *repo)
2452 {
2453 int error;
2454 git_config *config;
2455
2456 assert(repo);
2457
2458 if (repo->is_bare)
2459 return 0;
2460
2461 if ((error = git_repository_config__weakptr(&config, repo)) < 0)
2462 return error;
2463
2464 if ((error = git_config_set_bool(config, "core.bare", true)) < 0)
2465 return error;
2466
2467 if ((error = git_config__update_entry(config, "core.worktree", NULL, true, true)) < 0)
2468 return error;
2469
2470 git__free(repo->workdir);
2471 repo->workdir = NULL;
2472 repo->is_bare = 1;
2473
2474 return 0;
2475 }
2476
2477 int git_repository_head_tree(git_tree **tree, git_repository *repo)
2478 {
2479 git_reference *head;
2480 git_object *obj;
2481 int error;
2482
2483 if ((error = git_repository_head(&head, repo)) < 0)
2484 return error;
2485
2486 if ((error = git_reference_peel(&obj, head, GIT_OBJECT_TREE)) < 0)
2487 goto cleanup;
2488
2489 *tree = (git_tree *)obj;
2490
2491 cleanup:
2492 git_reference_free(head);
2493 return error;
2494 }
2495
2496 int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head)
2497 {
2498 git_filebuf file = GIT_FILEBUF_INIT;
2499 git_buf file_path = GIT_BUF_INIT;
2500 char orig_head_str[GIT_OID_HEXSZ];
2501 int error = 0;
2502
2503 git_oid_fmt(orig_head_str, orig_head);
2504
2505 if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 &&
2506 (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) == 0 &&
2507 (error = git_filebuf_printf(&file, "%.*s\n", GIT_OID_HEXSZ, orig_head_str)) == 0)
2508 error = git_filebuf_commit(&file);
2509
2510 if (error < 0)
2511 git_filebuf_cleanup(&file);
2512
2513 git_buf_dispose(&file_path);
2514
2515 return error;
2516 }
2517
2518 int git_repository_message(git_buf *out, git_repository *repo)
2519 {
2520 git_buf path = GIT_BUF_INIT;
2521 struct stat st;
2522 int error;
2523
2524 git_buf_sanitize(out);
2525
2526 if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
2527 return -1;
2528
2529 if ((error = p_stat(git_buf_cstr(&path), &st)) < 0) {
2530 if (errno == ENOENT)
2531 error = GIT_ENOTFOUND;
2532 git_error_set(GIT_ERROR_OS, "could not access message file");
2533 } else {
2534 error = git_futils_readbuffer(out, git_buf_cstr(&path));
2535 }
2536
2537 git_buf_dispose(&path);
2538
2539 return error;
2540 }
2541
2542 int git_repository_message_remove(git_repository *repo)
2543 {
2544 git_buf path = GIT_BUF_INIT;
2545 int error;
2546
2547 if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
2548 return -1;
2549
2550 error = p_unlink(git_buf_cstr(&path));
2551 git_buf_dispose(&path);
2552
2553 return error;
2554 }
2555
2556 int git_repository_hashfile(
2557 git_oid *out,
2558 git_repository *repo,
2559 const char *path,
2560 git_object_t type,
2561 const char *as_path)
2562 {
2563 int error;
2564 git_filter_list *fl = NULL;
2565 git_file fd = -1;
2566 uint64_t len;
2567 git_buf full_path = GIT_BUF_INIT;
2568
2569 assert(out && path && repo); /* as_path can be NULL */
2570
2571 /* At some point, it would be nice if repo could be NULL to just
2572 * apply filter rules defined in system and global files, but for
2573 * now that is not possible because git_filters_load() needs it.
2574 */
2575
2576 error = git_path_join_unrooted(
2577 &full_path, path, git_repository_workdir(repo), NULL);
2578 if (error < 0)
2579 return error;
2580
2581 if (!as_path)
2582 as_path = path;
2583
2584 /* passing empty string for "as_path" indicated --no-filters */
2585 if (strlen(as_path) > 0) {
2586 error = git_filter_list_load(
2587 &fl, repo, NULL, as_path,
2588 GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT);
2589 if (error < 0)
2590 return error;
2591 } else {
2592 error = 0;
2593 }
2594
2595 /* at this point, error is a count of the number of loaded filters */
2596
2597 fd = git_futils_open_ro(full_path.ptr);
2598 if (fd < 0) {
2599 error = fd;
2600 goto cleanup;
2601 }
2602
2603 if ((error = git_futils_filesize(&len, fd)) < 0)
2604 goto cleanup;
2605
2606 if (!git__is_sizet(len)) {
2607 git_error_set(GIT_ERROR_OS, "file size overflow for 32-bit systems");
2608 error = -1;
2609 goto cleanup;
2610 }
2611
2612 error = git_odb__hashfd_filtered(out, fd, (size_t)len, type, fl);
2613
2614 cleanup:
2615 if (fd >= 0)
2616 p_close(fd);
2617 git_filter_list_free(fl);
2618 git_buf_dispose(&full_path);
2619
2620 return error;
2621 }
2622
2623 static int checkout_message(git_buf *out, git_reference *old, const char *new)
2624 {
2625 git_buf_puts(out, "checkout: moving from ");
2626
2627 if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC)
2628 git_buf_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
2629 else
2630 git_buf_puts(out, git_oid_tostr_s(git_reference_target(old)));
2631
2632 git_buf_puts(out, " to ");
2633
2634 if (git_reference__is_branch(new) ||
2635 git_reference__is_tag(new) ||
2636 git_reference__is_remote(new))
2637 git_buf_puts(out, git_reference__shorthand(new));
2638 else
2639 git_buf_puts(out, new);
2640
2641 if (git_buf_oom(out))
2642 return -1;
2643
2644 return 0;
2645 }
2646
2647 static int detach(git_repository *repo, const git_oid *id, const char *new)
2648 {
2649 int error;
2650 git_buf log_message = GIT_BUF_INIT;
2651 git_object *object = NULL, *peeled = NULL;
2652 git_reference *new_head = NULL, *current = NULL;
2653
2654 assert(repo && id);
2655
2656 if ((error = git_reference_lookup(&current, repo, GIT_HEAD_FILE)) < 0)
2657 return error;
2658
2659 if ((error = git_object_lookup(&object, repo, id, GIT_OBJECT_ANY)) < 0)
2660 goto cleanup;
2661
2662 if ((error = git_object_peel(&peeled, object, GIT_OBJECT_COMMIT)) < 0)
2663 goto cleanup;
2664
2665 if (new == NULL)
2666 new = git_oid_tostr_s(git_object_id(peeled));
2667
2668 if ((error = checkout_message(&log_message, current, new)) < 0)
2669 goto cleanup;
2670
2671 error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_buf_cstr(&log_message));
2672
2673 cleanup:
2674 git_buf_dispose(&log_message);
2675 git_object_free(object);
2676 git_object_free(peeled);
2677 git_reference_free(current);
2678 git_reference_free(new_head);
2679 return error;
2680 }
2681
2682 int git_repository_set_head(
2683 git_repository* repo,
2684 const char* refname)
2685 {
2686 git_reference *ref = NULL, *current = NULL, *new_head = NULL;
2687 git_buf log_message = GIT_BUF_INIT;
2688 int error;
2689
2690 assert(repo && refname);
2691
2692 if ((error = git_reference_lookup(&current, repo, GIT_HEAD_FILE)) < 0)
2693 return error;
2694
2695 if ((error = checkout_message(&log_message, current, refname)) < 0)
2696 goto cleanup;
2697
2698 error = git_reference_lookup(&ref, repo, refname);
2699 if (error < 0 && error != GIT_ENOTFOUND)
2700 goto cleanup;
2701
2702 if (ref && current->type == GIT_REFERENCE_SYMBOLIC && git__strcmp(current->target.symbolic, ref->name) &&
2703 git_reference_is_branch(ref) && git_branch_is_checked_out(ref)) {
2704 git_error_set(GIT_ERROR_REPOSITORY, "cannot set HEAD to reference '%s' as it is the current HEAD "
2705 "of a linked repository.", git_reference_name(ref));
2706 error = -1;
2707 goto cleanup;
2708 }
2709
2710 if (!error) {
2711 if (git_reference_is_branch(ref)) {
2712 error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE,
2713 git_reference_name(ref), true, git_buf_cstr(&log_message));
2714 } else {
2715 error = detach(repo, git_reference_target(ref),
2716 git_reference_is_tag(ref) || git_reference_is_remote(ref) ? refname : NULL);
2717 }
2718 } else if (git_reference__is_branch(refname)) {
2719 error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname,
2720 true, git_buf_cstr(&log_message));
2721 }
2722
2723 cleanup:
2724 git_buf_dispose(&log_message);
2725 git_reference_free(current);
2726 git_reference_free(ref);
2727 git_reference_free(new_head);
2728 return error;
2729 }
2730
2731 int git_repository_set_head_detached(
2732 git_repository* repo,
2733 const git_oid* commitish)
2734 {
2735 return detach(repo, commitish, NULL);
2736 }
2737
2738 int git_repository_set_head_detached_from_annotated(
2739 git_repository *repo,
2740 const git_annotated_commit *commitish)
2741 {
2742 assert(repo && commitish);
2743
2744 return detach(repo, git_annotated_commit_id(commitish), commitish->description);
2745 }
2746
2747 int git_repository_detach_head(git_repository* repo)
2748 {
2749 git_reference *old_head = NULL, *new_head = NULL, *current = NULL;
2750 git_object *object = NULL;
2751 git_buf log_message = GIT_BUF_INIT;
2752 int error;
2753
2754 assert(repo);
2755
2756 if ((error = git_reference_lookup(&current, repo, GIT_HEAD_FILE)) < 0)
2757 return error;
2758
2759 if ((error = git_repository_head(&old_head, repo)) < 0)
2760 goto cleanup;
2761
2762 if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJECT_COMMIT)) < 0)
2763 goto cleanup;
2764
2765 if ((error = checkout_message(&log_message, current, git_oid_tostr_s(git_object_id(object)))) < 0)
2766 goto cleanup;
2767
2768 error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head),
2769 1, git_buf_cstr(&log_message));
2770
2771 cleanup:
2772 git_buf_dispose(&log_message);
2773 git_object_free(object);
2774 git_reference_free(old_head);
2775 git_reference_free(new_head);
2776 git_reference_free(current);
2777 return error;
2778 }
2779
2780 /**
2781 * Loosely ported from git.git
2782 * https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh#L198-289
2783 */
2784 int git_repository_state(git_repository *repo)
2785 {
2786 git_buf repo_path = GIT_BUF_INIT;
2787 int state = GIT_REPOSITORY_STATE_NONE;
2788
2789 assert(repo);
2790
2791 if (git_buf_puts(&repo_path, repo->gitdir) < 0)
2792 return -1;
2793
2794 if (git_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE))
2795 state = GIT_REPOSITORY_STATE_REBASE_INTERACTIVE;
2796 else if (git_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR))
2797 state = GIT_REPOSITORY_STATE_REBASE_MERGE;
2798 else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE))
2799 state = GIT_REPOSITORY_STATE_REBASE;
2800 else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE))
2801 state = GIT_REPOSITORY_STATE_APPLY_MAILBOX;
2802 else if (git_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR))
2803 state = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE;
2804 else if (git_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE))
2805 state = GIT_REPOSITORY_STATE_MERGE;
2806 else if (git_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE)) {
2807 state = GIT_REPOSITORY_STATE_REVERT;
2808 if (git_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) {
2809 state = GIT_REPOSITORY_STATE_REVERT_SEQUENCE;
2810 }
2811 } else if (git_path_contains_file(&repo_path, GIT_CHERRYPICK_HEAD_FILE)) {
2812 state = GIT_REPOSITORY_STATE_CHERRYPICK;
2813 if (git_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) {
2814 state = GIT_REPOSITORY_STATE_CHERRYPICK_SEQUENCE;
2815 }
2816 } else if (git_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE))
2817 state = GIT_REPOSITORY_STATE_BISECT;
2818
2819 git_buf_dispose(&repo_path);
2820 return state;
2821 }
2822
2823 int git_repository__cleanup_files(
2824 git_repository *repo, const char *files[], size_t files_len)
2825 {
2826 git_buf buf = GIT_BUF_INIT;
2827 size_t i;
2828 int error;
2829
2830 for (error = 0, i = 0; !error && i < files_len; ++i) {
2831 const char *path;
2832
2833 if (git_buf_joinpath(&buf, repo->gitdir, files[i]) < 0)
2834 return -1;
2835
2836 path = git_buf_cstr(&buf);
2837
2838 if (git_path_isfile(path)) {
2839 error = p_unlink(path);
2840 } else if (git_path_isdir(path)) {
2841 error = git_futils_rmdir_r(path, NULL,
2842 GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS);
2843 }
2844
2845 git_buf_clear(&buf);
2846 }
2847
2848 git_buf_dispose(&buf);
2849 return error;
2850 }
2851
2852 static const char *state_files[] = {
2853 GIT_MERGE_HEAD_FILE,
2854 GIT_MERGE_MODE_FILE,
2855 GIT_MERGE_MSG_FILE,
2856 GIT_REVERT_HEAD_FILE,
2857 GIT_CHERRYPICK_HEAD_FILE,
2858 GIT_BISECT_LOG_FILE,
2859 GIT_REBASE_MERGE_DIR,
2860 GIT_REBASE_APPLY_DIR,
2861 GIT_SEQUENCER_DIR,
2862 };
2863
2864 int git_repository_state_cleanup(git_repository *repo)
2865 {
2866 assert(repo);
2867
2868 return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
2869 }
2870
2871 int git_repository_is_shallow(git_repository *repo)
2872 {
2873 git_buf path = GIT_BUF_INIT;
2874 struct stat st;
2875 int error;
2876
2877 if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0)
2878 return error;
2879
2880 error = git_path_lstat(path.ptr, &st);
2881 git_buf_dispose(&path);
2882
2883 if (error == GIT_ENOTFOUND) {
2884 git_error_clear();
2885 return 0;
2886 }
2887
2888 if (error < 0)
2889 return error;
2890 return st.st_size == 0 ? 0 : 1;
2891 }
2892
2893 int git_repository_init_options_init(
2894 git_repository_init_options *opts, unsigned int version)
2895 {
2896 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
2897 opts, version, git_repository_init_options,
2898 GIT_REPOSITORY_INIT_OPTIONS_INIT);
2899 return 0;
2900 }
2901
2902 int git_repository_init_init_options(
2903 git_repository_init_options *opts, unsigned int version)
2904 {
2905 return git_repository_init_options_init(opts, version);
2906 }
2907
2908 int git_repository_ident(const char **name, const char **email, const git_repository *repo)
2909 {
2910 *name = repo->ident_name;
2911 *email = repo->ident_email;
2912
2913 return 0;
2914 }
2915
2916 int git_repository_set_ident(git_repository *repo, const char *name, const char *email)
2917 {
2918 char *tmp_name = NULL, *tmp_email = NULL;
2919
2920 if (name) {
2921 tmp_name = git__strdup(name);
2922 GIT_ERROR_CHECK_ALLOC(tmp_name);
2923 }
2924
2925 if (email) {
2926 tmp_email = git__strdup(email);
2927 GIT_ERROR_CHECK_ALLOC(tmp_email);
2928 }
2929
2930 tmp_name = git__swap(repo->ident_name, tmp_name);
2931 tmp_email = git__swap(repo->ident_email, tmp_email);
2932
2933 git__free(tmp_name);
2934 git__free(tmp_email);
2935
2936 return 0;
2937 }
2938
2939 int git_repository_submodule_cache_all(git_repository *repo)
2940 {
2941 int error;
2942
2943 assert(repo);
2944
2945 if ((error = git_strmap_new(&repo->submodule_cache)))
2946 return error;
2947
2948 error = git_submodule__map(repo, repo->submodule_cache);
2949 return error;
2950 }
2951
2952 int git_repository_submodule_cache_clear(git_repository *repo)
2953 {
2954 git_submodule *sm;
2955 assert(repo);
2956 if (repo->submodule_cache == NULL) {
2957 return 0;
2958 }
2959 git_strmap_foreach_value(repo->submodule_cache, sm, {
2960 git_submodule_free(sm);
2961 });
2962 git_strmap_free(repo->submodule_cache);
2963 repo->submodule_cache = 0;
2964 return 0;
2965 }