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