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