]> git.proxmox.com Git - libgit2.git/blob - src/repository.c
No such thing as an orphan branch
[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 <stdarg.h>
8 #include <ctype.h>
9
10 #include "git2/object.h"
11 #include "git2/refdb.h"
12 #include "git2/sys/repository.h"
13
14 #include "common.h"
15 #include "repository.h"
16 #include "commit.h"
17 #include "tag.h"
18 #include "blob.h"
19 #include "fileops.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
30 #define GIT_FILE_CONTENT_PREFIX "gitdir:"
31
32 #define GIT_BRANCH_MASTER "master"
33
34 #define GIT_REPO_VERSION 0
35
36 #define GIT_TEMPLATE_DIR "/usr/share/git-core/templates"
37
38 static void set_odb(git_repository *repo, git_odb *odb)
39 {
40 if (odb) {
41 GIT_REFCOUNT_OWN(odb, repo);
42 GIT_REFCOUNT_INC(odb);
43 }
44
45 if ((odb = git__swap(repo->_odb, odb)) != NULL) {
46 GIT_REFCOUNT_OWN(odb, NULL);
47 git_odb_free(odb);
48 }
49 }
50
51 static void set_refdb(git_repository *repo, git_refdb *refdb)
52 {
53 if (refdb) {
54 GIT_REFCOUNT_OWN(refdb, repo);
55 GIT_REFCOUNT_INC(refdb);
56 }
57
58 if ((refdb = git__swap(repo->_refdb, refdb)) != NULL) {
59 GIT_REFCOUNT_OWN(refdb, NULL);
60 git_refdb_free(refdb);
61 }
62 }
63
64 static void set_config(git_repository *repo, git_config *config)
65 {
66 if (config) {
67 GIT_REFCOUNT_OWN(config, repo);
68 GIT_REFCOUNT_INC(config);
69 }
70
71 if ((config = git__swap(repo->_config, config)) != NULL) {
72 GIT_REFCOUNT_OWN(config, NULL);
73 git_config_free(config);
74 }
75
76 git_repository__cvar_cache_clear(repo);
77 }
78
79 static void set_index(git_repository *repo, git_index *index)
80 {
81 if (index) {
82 GIT_REFCOUNT_OWN(index, repo);
83 GIT_REFCOUNT_INC(index);
84 }
85
86 if ((index = git__swap(repo->_index, index)) != NULL) {
87 GIT_REFCOUNT_OWN(index, NULL);
88 git_index_free(index);
89 }
90 }
91
92 void git_repository__cleanup(git_repository *repo)
93 {
94 assert(repo);
95
96 git_cache_clear(&repo->objects);
97 git_attr_cache_flush(repo);
98
99 set_config(repo, NULL);
100 set_index(repo, NULL);
101 set_odb(repo, NULL);
102 set_refdb(repo, NULL);
103 }
104
105 void git_repository_free(git_repository *repo)
106 {
107 if (repo == NULL)
108 return;
109
110 git_repository__cleanup(repo);
111
112 git_cache_free(&repo->objects);
113 git_submodule_config_free(repo);
114
115 git_diff_driver_registry_free(repo->diff_drivers);
116 repo->diff_drivers = NULL;
117
118 git__free(repo->path_repository);
119 git__free(repo->workdir);
120 git__free(repo->namespace);
121
122 git__memzero(repo, sizeof(*repo));
123 git__free(repo);
124 }
125
126 /*
127 * Git repository open methods
128 *
129 * Open a repository object from its path
130 */
131 static bool valid_repository_path(git_buf *repository_path)
132 {
133 /* Check OBJECTS_DIR first, since it will generate the longest path name */
134 if (git_path_contains_dir(repository_path, GIT_OBJECTS_DIR) == false)
135 return false;
136
137 /* Ensure HEAD file exists */
138 if (git_path_contains_file(repository_path, GIT_HEAD_FILE) == false)
139 return false;
140
141 if (git_path_contains_dir(repository_path, GIT_REFS_DIR) == false)
142 return false;
143
144 return true;
145 }
146
147 static git_repository *repository_alloc(void)
148 {
149 git_repository *repo = git__calloc(1, sizeof(git_repository));
150 if (!repo)
151 return NULL;
152
153 if (git_cache_init(&repo->objects) < 0) {
154 git__free(repo);
155 return NULL;
156 }
157
158 /* set all the entries in the cvar cache to `unset` */
159 git_repository__cvar_cache_clear(repo);
160
161 return repo;
162 }
163
164 int git_repository_new(git_repository **out)
165 {
166 *out = repository_alloc();
167 return 0;
168 }
169
170 static int load_config_data(git_repository *repo)
171 {
172 int is_bare;
173 git_config *config;
174
175 if (git_repository_config__weakptr(&config, repo) < 0)
176 return -1;
177
178 /* Try to figure out if it's bare, default to non-bare if it's not set */
179 if (git_config_get_bool(&is_bare, config, "core.bare") < 0)
180 repo->is_bare = 0;
181 else
182 repo->is_bare = is_bare;
183
184 return 0;
185 }
186
187 static int load_workdir(git_repository *repo, git_buf *parent_path)
188 {
189 int error;
190 git_config *config;
191 const char *worktree;
192 git_buf worktree_buf = GIT_BUF_INIT;
193
194 if (repo->is_bare)
195 return 0;
196
197 if (git_repository_config__weakptr(&config, repo) < 0)
198 return -1;
199
200 error = git_config_get_string(&worktree, config, "core.worktree");
201 if (!error && worktree != NULL) {
202 error = git_path_prettify_dir(
203 &worktree_buf, worktree, repo->path_repository);
204 if (error < 0)
205 return error;
206 repo->workdir = git_buf_detach(&worktree_buf);
207 }
208 else if (error != GIT_ENOTFOUND)
209 return error;
210 else {
211 giterr_clear();
212
213 if (parent_path && git_path_isdir(parent_path->ptr))
214 repo->workdir = git_buf_detach(parent_path);
215 else {
216 git_path_dirname_r(&worktree_buf, repo->path_repository);
217 git_path_to_dir(&worktree_buf);
218 repo->workdir = git_buf_detach(&worktree_buf);
219 }
220 }
221
222 GITERR_CHECK_ALLOC(repo->workdir);
223
224 return 0;
225 }
226
227 /*
228 * This function returns furthest offset into path where a ceiling dir
229 * is found, so we can stop processing the path at that point.
230 *
231 * Note: converting this to use git_bufs instead of GIT_PATH_MAX buffers on
232 * the stack could remove directories name limits, but at the cost of doing
233 * repeated malloc/frees inside the loop below, so let's not do it now.
234 */
235 static int find_ceiling_dir_offset(
236 const char *path,
237 const char *ceiling_directories)
238 {
239 char buf[GIT_PATH_MAX + 1];
240 char buf2[GIT_PATH_MAX + 1];
241 const char *ceil, *sep;
242 size_t len, max_len = 0, min_len;
243
244 assert(path);
245
246 min_len = (size_t)(git_path_root(path) + 1);
247
248 if (ceiling_directories == NULL || min_len == 0)
249 return (int)min_len;
250
251 for (sep = ceil = ceiling_directories; *sep; ceil = sep + 1) {
252 for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
253 len = sep - ceil;
254
255 if (len == 0 || len >= sizeof(buf) || git_path_root(ceil) == -1)
256 continue;
257
258 strncpy(buf, ceil, len);
259 buf[len] = '\0';
260
261 if (p_realpath(buf, buf2) == NULL)
262 continue;
263
264 len = strlen(buf2);
265 if (len > 0 && buf2[len-1] == '/')
266 buf[--len] = '\0';
267
268 if (!strncmp(path, buf2, len) &&
269 (path[len] == '/' || !path[len]) &&
270 len > max_len)
271 {
272 max_len = len;
273 }
274 }
275
276 return (int)(max_len <= min_len ? min_len : max_len);
277 }
278
279 /*
280 * Read the contents of `file_path` and set `path_out` to the repo dir that
281 * it points to. Before calling, set `path_out` to the base directory that
282 * should be used if the contents of `file_path` are a relative path.
283 */
284 static int read_gitfile(git_buf *path_out, const char *file_path)
285 {
286 int error = 0;
287 git_buf file = GIT_BUF_INIT;
288 size_t prefix_len = strlen(GIT_FILE_CONTENT_PREFIX);
289
290 assert(path_out && file_path);
291
292 if (git_futils_readbuffer(&file, file_path) < 0)
293 return -1;
294
295 git_buf_rtrim(&file);
296
297 if (git_buf_len(&file) <= prefix_len ||
298 memcmp(git_buf_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0)
299 {
300 giterr_set(GITERR_REPOSITORY, "The `.git` file at '%s' is malformed", file_path);
301 error = -1;
302 }
303 else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) {
304 const char *gitlink = git_buf_cstr(&file) + prefix_len;
305 while (*gitlink && git__isspace(*gitlink)) gitlink++;
306 error = git_path_prettify_dir(
307 path_out, gitlink, git_buf_cstr(path_out));
308 }
309
310 git_buf_free(&file);
311 return error;
312 }
313
314 static int find_repo(
315 git_buf *repo_path,
316 git_buf *parent_path,
317 const char *start_path,
318 uint32_t flags,
319 const char *ceiling_dirs)
320 {
321 int error;
322 git_buf path = GIT_BUF_INIT;
323 struct stat st;
324 dev_t initial_device = 0;
325 bool try_with_dot_git = ((flags & GIT_REPOSITORY_OPEN_BARE) != 0);
326 int ceiling_offset;
327
328 git_buf_free(repo_path);
329
330 if ((error = git_path_prettify(&path, start_path, NULL)) < 0)
331 return error;
332
333 ceiling_offset = find_ceiling_dir_offset(path.ptr, ceiling_dirs);
334
335 if (!try_with_dot_git &&
336 (error = git_buf_joinpath(&path, path.ptr, DOT_GIT)) < 0)
337 return error;
338
339 while (!error && !git_buf_len(repo_path)) {
340 if (p_stat(path.ptr, &st) == 0) {
341 /* check that we have not crossed device boundaries */
342 if (initial_device == 0)
343 initial_device = st.st_dev;
344 else if (st.st_dev != initial_device &&
345 (flags & GIT_REPOSITORY_OPEN_CROSS_FS) == 0)
346 break;
347
348 if (S_ISDIR(st.st_mode)) {
349 if (valid_repository_path(&path)) {
350 git_path_to_dir(&path);
351 git_buf_set(repo_path, path.ptr, path.size);
352 break;
353 }
354 }
355 else if (S_ISREG(st.st_mode)) {
356 git_buf repo_link = GIT_BUF_INIT;
357
358 if (!(error = read_gitfile(&repo_link, path.ptr))) {
359 if (valid_repository_path(&repo_link))
360 git_buf_swap(repo_path, &repo_link);
361
362 git_buf_free(&repo_link);
363 break;
364 }
365 git_buf_free(&repo_link);
366 }
367 }
368
369 /* move up one directory level */
370 if (git_path_dirname_r(&path, path.ptr) < 0) {
371 error = -1;
372 break;
373 }
374
375 if (try_with_dot_git) {
376 /* if we tried original dir with and without .git AND either hit
377 * directory ceiling or NO_SEARCH was requested, then be done.
378 */
379 if (path.ptr[ceiling_offset] == '\0' ||
380 (flags & GIT_REPOSITORY_OPEN_NO_SEARCH) != 0)
381 break;
382 /* otherwise look first for .git item */
383 error = git_buf_joinpath(&path, path.ptr, DOT_GIT);
384 }
385 try_with_dot_git = !try_with_dot_git;
386 }
387
388 if (!error && parent_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
389 if (!git_buf_len(repo_path))
390 git_buf_clear(parent_path);
391 else {
392 git_path_dirname_r(parent_path, path.ptr);
393 git_path_to_dir(parent_path);
394 }
395 if (git_buf_oom(parent_path))
396 return -1;
397 }
398
399 git_buf_free(&path);
400
401 if (!git_buf_len(repo_path) && !error) {
402 giterr_set(GITERR_REPOSITORY,
403 "Could not find repository from '%s'", start_path);
404 error = GIT_ENOTFOUND;
405 }
406
407 return error;
408 }
409
410 int git_repository_open_bare(
411 git_repository **repo_ptr,
412 const char *bare_path)
413 {
414 int error;
415 git_buf path = GIT_BUF_INIT;
416 git_repository *repo = NULL;
417
418 if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0)
419 return error;
420
421 if (!valid_repository_path(&path)) {
422 git_buf_free(&path);
423 giterr_set(GITERR_REPOSITORY, "Path is not a repository: %s", bare_path);
424 return GIT_ENOTFOUND;
425 }
426
427 repo = repository_alloc();
428 GITERR_CHECK_ALLOC(repo);
429
430 repo->path_repository = git_buf_detach(&path);
431 GITERR_CHECK_ALLOC(repo->path_repository);
432
433 /* of course we're bare! */
434 repo->is_bare = 1;
435 repo->workdir = NULL;
436
437 *repo_ptr = repo;
438 return 0;
439 }
440
441 int git_repository_open_ext(
442 git_repository **repo_ptr,
443 const char *start_path,
444 unsigned int flags,
445 const char *ceiling_dirs)
446 {
447 int error;
448 git_buf path = GIT_BUF_INIT, parent = GIT_BUF_INIT;
449 git_repository *repo;
450
451 if (repo_ptr)
452 *repo_ptr = NULL;
453
454 error = find_repo(&path, &parent, start_path, flags, ceiling_dirs);
455 if (error < 0 || !repo_ptr)
456 return error;
457
458 repo = repository_alloc();
459 GITERR_CHECK_ALLOC(repo);
460
461 repo->path_repository = git_buf_detach(&path);
462 GITERR_CHECK_ALLOC(repo->path_repository);
463
464 if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0)
465 repo->is_bare = 1;
466 else if ((error = load_config_data(repo)) < 0 ||
467 (error = load_workdir(repo, &parent)) < 0)
468 {
469 git_repository_free(repo);
470 return error;
471 }
472
473 git_buf_free(&parent);
474 *repo_ptr = repo;
475 return 0;
476 }
477
478 int git_repository_open(git_repository **repo_out, const char *path)
479 {
480 return git_repository_open_ext(
481 repo_out, path, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL);
482 }
483
484 int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
485 {
486 git_repository *repo;
487
488 repo = repository_alloc();
489 GITERR_CHECK_ALLOC(repo);
490
491 git_repository_set_odb(repo, odb);
492 *repo_out = repo;
493
494 return 0;
495 }
496
497 int git_repository_discover(
498 char *repository_path,
499 size_t size,
500 const char *start_path,
501 int across_fs,
502 const char *ceiling_dirs)
503 {
504 git_buf path = GIT_BUF_INIT;
505 uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0;
506 int error;
507
508 assert(start_path && repository_path && size > 0);
509
510 *repository_path = '\0';
511
512 if ((error = find_repo(&path, NULL, start_path, flags, ceiling_dirs)) < 0)
513 return error != GIT_ENOTFOUND ? -1 : error;
514
515 if (size < (size_t)(path.size + 1)) {
516 giterr_set(GITERR_REPOSITORY,
517 "The given buffer is too small to store the discovered path");
518 git_buf_free(&path);
519 return -1;
520 }
521
522 /* success: we discovered a repository */
523 git_buf_copy_cstr(repository_path, size, &path);
524 git_buf_free(&path);
525 return 0;
526 }
527
528 static int load_config(
529 git_config **out,
530 git_repository *repo,
531 const char *global_config_path,
532 const char *xdg_config_path,
533 const char *system_config_path)
534 {
535 int error;
536 git_buf config_path = GIT_BUF_INIT;
537 git_config *cfg = NULL;
538
539 assert(repo && out);
540
541 if ((error = git_config_new(&cfg)) < 0)
542 return error;
543
544 error = git_buf_joinpath(
545 &config_path, repo->path_repository, GIT_CONFIG_FILENAME_INREPO);
546 if (error < 0)
547 goto on_error;
548
549 if ((error = git_config_add_file_ondisk(
550 cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0 &&
551 error != GIT_ENOTFOUND)
552 goto on_error;
553
554 git_buf_free(&config_path);
555
556 if (global_config_path != NULL &&
557 (error = git_config_add_file_ondisk(
558 cfg, global_config_path, GIT_CONFIG_LEVEL_GLOBAL, 0)) < 0 &&
559 error != GIT_ENOTFOUND)
560 goto on_error;
561
562 if (xdg_config_path != NULL &&
563 (error = git_config_add_file_ondisk(
564 cfg, xdg_config_path, GIT_CONFIG_LEVEL_XDG, 0)) < 0 &&
565 error != GIT_ENOTFOUND)
566 goto on_error;
567
568 if (system_config_path != NULL &&
569 (error = git_config_add_file_ondisk(
570 cfg, system_config_path, GIT_CONFIG_LEVEL_SYSTEM, 0)) < 0 &&
571 error != GIT_ENOTFOUND)
572 goto on_error;
573
574 giterr_clear(); /* clear any lingering ENOTFOUND errors */
575
576 *out = cfg;
577 return 0;
578
579 on_error:
580 git_buf_free(&config_path);
581 git_config_free(cfg);
582 *out = NULL;
583 return error;
584 }
585
586 static const char *path_unless_empty(git_buf *buf)
587 {
588 return git_buf_len(buf) > 0 ? git_buf_cstr(buf) : NULL;
589 }
590
591 int git_repository_config__weakptr(git_config **out, git_repository *repo)
592 {
593 int error = 0;
594
595 if (repo->_config == NULL) {
596 git_buf global_buf = GIT_BUF_INIT;
597 git_buf xdg_buf = GIT_BUF_INIT;
598 git_buf system_buf = GIT_BUF_INIT;
599 git_config *config;
600
601 git_config_find_global_r(&global_buf);
602 git_config_find_xdg_r(&xdg_buf);
603 git_config_find_system_r(&system_buf);
604
605 /* If there is no global file, open a backend for it anyway */
606 if (git_buf_len(&global_buf) == 0)
607 git_config__global_location(&global_buf);
608
609 error = load_config(
610 &config, repo,
611 path_unless_empty(&global_buf),
612 path_unless_empty(&xdg_buf),
613 path_unless_empty(&system_buf));
614 if (!error) {
615 GIT_REFCOUNT_OWN(config, repo);
616
617 config = git__compare_and_swap(&repo->_config, NULL, config);
618 if (config != NULL) {
619 GIT_REFCOUNT_OWN(config, NULL);
620 git_config_free(config);
621 }
622 }
623
624 git_buf_free(&global_buf);
625 git_buf_free(&xdg_buf);
626 git_buf_free(&system_buf);
627 }
628
629 *out = repo->_config;
630 return error;
631 }
632
633 int git_repository_config(git_config **out, git_repository *repo)
634 {
635 if (git_repository_config__weakptr(out, repo) < 0)
636 return -1;
637
638 GIT_REFCOUNT_INC(*out);
639 return 0;
640 }
641
642 void git_repository_set_config(git_repository *repo, git_config *config)
643 {
644 assert(repo && config);
645 set_config(repo, config);
646 }
647
648 int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
649 {
650 int error = 0;
651
652 assert(repo && out);
653
654 if (repo->_odb == NULL) {
655 git_buf odb_path = GIT_BUF_INIT;
656 git_odb *odb;
657
658 git_buf_joinpath(&odb_path, repo->path_repository, GIT_OBJECTS_DIR);
659
660 error = git_odb_open(&odb, odb_path.ptr);
661 if (!error) {
662 GIT_REFCOUNT_OWN(odb, repo);
663
664 odb = git__compare_and_swap(&repo->_odb, NULL, odb);
665 if (odb != NULL) {
666 GIT_REFCOUNT_OWN(odb, NULL);
667 git_odb_free(odb);
668 }
669 }
670
671 git_buf_free(&odb_path);
672 }
673
674 *out = repo->_odb;
675 return error;
676 }
677
678 int git_repository_odb(git_odb **out, git_repository *repo)
679 {
680 if (git_repository_odb__weakptr(out, repo) < 0)
681 return -1;
682
683 GIT_REFCOUNT_INC(*out);
684 return 0;
685 }
686
687 void git_repository_set_odb(git_repository *repo, git_odb *odb)
688 {
689 assert(repo && odb);
690 set_odb(repo, odb);
691 }
692
693 int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo)
694 {
695 int error = 0;
696
697 assert(out && repo);
698
699 if (repo->_refdb == NULL) {
700 git_refdb *refdb;
701
702 error = git_refdb_open(&refdb, repo);
703 if (!error) {
704 GIT_REFCOUNT_OWN(refdb, repo);
705
706 refdb = git__compare_and_swap(&repo->_refdb, NULL, refdb);
707 if (refdb != NULL) {
708 GIT_REFCOUNT_OWN(refdb, NULL);
709 git_refdb_free(refdb);
710 }
711 }
712 }
713
714 *out = repo->_refdb;
715 return error;
716 }
717
718 int git_repository_refdb(git_refdb **out, git_repository *repo)
719 {
720 if (git_repository_refdb__weakptr(out, repo) < 0)
721 return -1;
722
723 GIT_REFCOUNT_INC(*out);
724 return 0;
725 }
726
727 void git_repository_set_refdb(git_repository *repo, git_refdb *refdb)
728 {
729 assert(repo && refdb);
730 set_refdb(repo, refdb);
731 }
732
733 int git_repository_index__weakptr(git_index **out, git_repository *repo)
734 {
735 int error = 0;
736
737 assert(out && repo);
738
739 if (repo->_index == NULL) {
740 git_buf index_path = GIT_BUF_INIT;
741 git_index *index;
742
743 git_buf_joinpath(&index_path, repo->path_repository, GIT_INDEX_FILE);
744
745 error = git_index_open(&index, index_path.ptr);
746 if (!error) {
747 GIT_REFCOUNT_OWN(index, repo);
748
749 index = git__compare_and_swap(&repo->_index, NULL, index);
750 if (index != NULL) {
751 GIT_REFCOUNT_OWN(index, NULL);
752 git_index_free(index);
753 }
754
755 error = git_index_set_caps(repo->_index, GIT_INDEXCAP_FROM_OWNER);
756 }
757
758 git_buf_free(&index_path);
759 }
760
761 *out = repo->_index;
762 return error;
763 }
764
765 int git_repository_index(git_index **out, git_repository *repo)
766 {
767 if (git_repository_index__weakptr(out, repo) < 0)
768 return -1;
769
770 GIT_REFCOUNT_INC(*out);
771 return 0;
772 }
773
774 void git_repository_set_index(git_repository *repo, git_index *index)
775 {
776 assert(repo && index);
777 set_index(repo, index);
778 }
779
780 int git_repository_set_namespace(git_repository *repo, const char *namespace)
781 {
782 git__free(repo->namespace);
783
784 if (namespace == NULL) {
785 repo->namespace = NULL;
786 return 0;
787 }
788
789 return (repo->namespace = git__strdup(namespace)) ? 0 : -1;
790 }
791
792 const char *git_repository_get_namespace(git_repository *repo)
793 {
794 return repo->namespace;
795 }
796
797 static int check_repositoryformatversion(git_config *config)
798 {
799 int version;
800
801 if (git_config_get_int32(&version, config, "core.repositoryformatversion") < 0)
802 return -1;
803
804 if (GIT_REPO_VERSION < version) {
805 giterr_set(GITERR_REPOSITORY,
806 "Unsupported repository version %d. Only versions up to %d are supported.",
807 version, GIT_REPO_VERSION);
808 return -1;
809 }
810
811 return 0;
812 }
813
814 static int repo_init_create_head(const char *git_dir, const char *ref_name)
815 {
816 git_buf ref_path = GIT_BUF_INIT;
817 git_filebuf ref = GIT_FILEBUF_INIT;
818 const char *fmt;
819
820 if (git_buf_joinpath(&ref_path, git_dir, GIT_HEAD_FILE) < 0 ||
821 git_filebuf_open(&ref, ref_path.ptr, 0) < 0)
822 goto fail;
823
824 if (!ref_name)
825 ref_name = GIT_BRANCH_MASTER;
826
827 if (git__prefixcmp(ref_name, GIT_REFS_DIR) == 0)
828 fmt = "ref: %s\n";
829 else
830 fmt = "ref: " GIT_REFS_HEADS_DIR "%s\n";
831
832 if (git_filebuf_printf(&ref, fmt, ref_name) < 0 ||
833 git_filebuf_commit(&ref, GIT_REFS_FILE_MODE) < 0)
834 goto fail;
835
836 git_buf_free(&ref_path);
837 return 0;
838
839 fail:
840 git_buf_free(&ref_path);
841 git_filebuf_cleanup(&ref);
842 return -1;
843 }
844
845 static bool is_chmod_supported(const char *file_path)
846 {
847 struct stat st1, st2;
848 static int _is_supported = -1;
849
850 if (_is_supported > -1)
851 return _is_supported;
852
853 if (p_stat(file_path, &st1) < 0)
854 return false;
855
856 if (p_chmod(file_path, st1.st_mode ^ S_IXUSR) < 0)
857 return false;
858
859 if (p_stat(file_path, &st2) < 0)
860 return false;
861
862 _is_supported = (st1.st_mode != st2.st_mode);
863
864 return _is_supported;
865 }
866
867 static bool is_filesystem_case_insensitive(const char *gitdir_path)
868 {
869 git_buf path = GIT_BUF_INIT;
870 static int _is_insensitive = -1;
871
872 if (_is_insensitive > -1)
873 return _is_insensitive;
874
875 if (git_buf_joinpath(&path, gitdir_path, "CoNfIg") < 0)
876 goto cleanup;
877
878 _is_insensitive = git_path_exists(git_buf_cstr(&path));
879
880 cleanup:
881 git_buf_free(&path);
882 return _is_insensitive;
883 }
884
885 static bool are_symlinks_supported(const char *wd_path)
886 {
887 git_buf path = GIT_BUF_INIT;
888 int fd;
889 struct stat st;
890 static int _symlinks_supported = -1;
891
892 if (_symlinks_supported > -1)
893 return _symlinks_supported;
894
895 if ((fd = git_futils_mktmp(&path, wd_path)) < 0 ||
896 p_close(fd) < 0 ||
897 p_unlink(path.ptr) < 0 ||
898 p_symlink("testing", path.ptr) < 0 ||
899 p_lstat(path.ptr, &st) < 0)
900 _symlinks_supported = false;
901 else
902 _symlinks_supported = (S_ISLNK(st.st_mode) != 0);
903
904 (void)p_unlink(path.ptr);
905 git_buf_free(&path);
906
907 return _symlinks_supported;
908 }
909
910 static int create_empty_file(const char *path, mode_t mode)
911 {
912 int fd;
913
914 if ((fd = p_creat(path, mode)) < 0) {
915 giterr_set(GITERR_OS, "Error while creating '%s'", path);
916 return -1;
917 }
918
919 if (p_close(fd) < 0) {
920 giterr_set(GITERR_OS, "Error while closing '%s'", path);
921 return -1;
922 }
923
924 return 0;
925 }
926
927 static int repo_init_config(
928 const char *repo_dir,
929 const char *work_dir,
930 git_repository_init_options *opts)
931 {
932 int error = 0;
933 git_buf cfg_path = GIT_BUF_INIT;
934 git_config *config = NULL;
935
936 #define SET_REPO_CONFIG(TYPE, NAME, VAL) do {\
937 if ((error = git_config_set_##TYPE(config, NAME, VAL)) < 0) \
938 goto cleanup; } while (0)
939
940 if (git_buf_joinpath(&cfg_path, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
941 return -1;
942
943 if (!git_path_isfile(git_buf_cstr(&cfg_path)) &&
944 create_empty_file(git_buf_cstr(&cfg_path), GIT_CONFIG_FILE_MODE) < 0) {
945 git_buf_free(&cfg_path);
946 return -1;
947 }
948
949 if (git_config_open_ondisk(&config, git_buf_cstr(&cfg_path)) < 0) {
950 git_buf_free(&cfg_path);
951 return -1;
952 }
953
954 if ((opts->flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0 &&
955 (error = check_repositoryformatversion(config)) < 0)
956 goto cleanup;
957
958 SET_REPO_CONFIG(
959 bool, "core.bare", (opts->flags & GIT_REPOSITORY_INIT_BARE) != 0);
960 SET_REPO_CONFIG(
961 int32, "core.repositoryformatversion", GIT_REPO_VERSION);
962 SET_REPO_CONFIG(
963 bool, "core.filemode", is_chmod_supported(git_buf_cstr(&cfg_path)));
964
965 if (!(opts->flags & GIT_REPOSITORY_INIT_BARE)) {
966 SET_REPO_CONFIG(bool, "core.logallrefupdates", true);
967
968 if (!are_symlinks_supported(work_dir))
969 SET_REPO_CONFIG(bool, "core.symlinks", false);
970
971 if (!(opts->flags & GIT_REPOSITORY_INIT__NATURAL_WD)) {
972 SET_REPO_CONFIG(string, "core.worktree", work_dir);
973 }
974 else if ((opts->flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0) {
975 if (git_config_delete_entry(config, "core.worktree") < 0)
976 giterr_clear();
977 }
978 } else {
979 if (!are_symlinks_supported(repo_dir))
980 SET_REPO_CONFIG(bool, "core.symlinks", false);
981 }
982
983 if (!(opts->flags & GIT_REPOSITORY_INIT__IS_REINIT) &&
984 is_filesystem_case_insensitive(repo_dir))
985 SET_REPO_CONFIG(bool, "core.ignorecase", true);
986
987 if (opts->mode == GIT_REPOSITORY_INIT_SHARED_GROUP) {
988 SET_REPO_CONFIG(int32, "core.sharedrepository", 1);
989 SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
990 }
991 else if (opts->mode == GIT_REPOSITORY_INIT_SHARED_ALL) {
992 SET_REPO_CONFIG(int32, "core.sharedrepository", 2);
993 SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
994 }
995
996 cleanup:
997 git_buf_free(&cfg_path);
998 git_config_free(config);
999
1000 return error;
1001 }
1002
1003 static int repo_write_template(
1004 const char *git_dir,
1005 bool allow_overwrite,
1006 const char *file,
1007 mode_t mode,
1008 bool hidden,
1009 const char *content)
1010 {
1011 git_buf path = GIT_BUF_INIT;
1012 int fd, error = 0, flags;
1013
1014 if (git_buf_joinpath(&path, git_dir, file) < 0)
1015 return -1;
1016
1017 if (allow_overwrite)
1018 flags = O_WRONLY | O_CREAT | O_TRUNC;
1019 else
1020 flags = O_WRONLY | O_CREAT | O_EXCL;
1021
1022 fd = p_open(git_buf_cstr(&path), flags, mode);
1023
1024 if (fd >= 0) {
1025 error = p_write(fd, content, strlen(content));
1026
1027 p_close(fd);
1028 }
1029 else if (errno != EEXIST)
1030 error = fd;
1031
1032 #ifdef GIT_WIN32
1033 if (!error && hidden) {
1034 if (p_hide_directory__w32(path.ptr) < 0)
1035 error = -1;
1036 }
1037 #else
1038 GIT_UNUSED(hidden);
1039 #endif
1040
1041 git_buf_free(&path);
1042
1043 if (error)
1044 giterr_set(GITERR_OS,
1045 "Failed to initialize repository with template '%s'", file);
1046
1047 return error;
1048 }
1049
1050 static int repo_write_gitlink(
1051 const char *in_dir, const char *to_repo)
1052 {
1053 int error;
1054 git_buf buf = GIT_BUF_INIT;
1055 struct stat st;
1056
1057 git_path_dirname_r(&buf, to_repo);
1058 git_path_to_dir(&buf);
1059 if (git_buf_oom(&buf))
1060 return -1;
1061
1062 /* don't write gitlink to natural workdir */
1063 if (git__suffixcmp(to_repo, "/" DOT_GIT "/") == 0 &&
1064 strcmp(in_dir, buf.ptr) == 0)
1065 {
1066 error = GIT_PASSTHROUGH;
1067 goto cleanup;
1068 }
1069
1070 if ((error = git_buf_joinpath(&buf, in_dir, DOT_GIT)) < 0)
1071 goto cleanup;
1072
1073 if (!p_stat(buf.ptr, &st) && !S_ISREG(st.st_mode)) {
1074 giterr_set(GITERR_REPOSITORY,
1075 "Cannot overwrite gitlink file into path '%s'", in_dir);
1076 error = GIT_EEXISTS;
1077 goto cleanup;
1078 }
1079
1080 git_buf_clear(&buf);
1081
1082 error = git_buf_printf(&buf, "%s %s", GIT_FILE_CONTENT_PREFIX, to_repo);
1083
1084 if (!error)
1085 error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr);
1086
1087 cleanup:
1088 git_buf_free(&buf);
1089 return error;
1090 }
1091
1092 static mode_t pick_dir_mode(git_repository_init_options *opts)
1093 {
1094 if (opts->mode == GIT_REPOSITORY_INIT_SHARED_UMASK)
1095 return 0777;
1096 if (opts->mode == GIT_REPOSITORY_INIT_SHARED_GROUP)
1097 return (0775 | S_ISGID);
1098 if (opts->mode == GIT_REPOSITORY_INIT_SHARED_ALL)
1099 return (0777 | S_ISGID);
1100 return opts->mode;
1101 }
1102
1103 #include "repo_template.h"
1104
1105 static int repo_init_structure(
1106 const char *repo_dir,
1107 const char *work_dir,
1108 git_repository_init_options *opts)
1109 {
1110 int error = 0;
1111 repo_template_item *tpl;
1112 bool external_tpl =
1113 ((opts->flags & GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE) != 0);
1114 mode_t dmode = pick_dir_mode(opts);
1115
1116 /* Hide the ".git" directory */
1117 #ifdef GIT_WIN32
1118 if ((opts->flags & GIT_REPOSITORY_INIT__HAS_DOTGIT) != 0) {
1119 if (p_hide_directory__w32(repo_dir) < 0) {
1120 giterr_set(GITERR_REPOSITORY,
1121 "Failed to mark Git repository folder as hidden");
1122 return -1;
1123 }
1124 }
1125 #endif
1126
1127 /* Create the .git gitlink if appropriate */
1128 if ((opts->flags & GIT_REPOSITORY_INIT_BARE) == 0 &&
1129 (opts->flags & GIT_REPOSITORY_INIT__NATURAL_WD) == 0)
1130 {
1131 if (repo_write_gitlink(work_dir, repo_dir) < 0)
1132 return -1;
1133 }
1134
1135 /* Copy external template if requested */
1136 if (external_tpl) {
1137 git_config *cfg;
1138 const char *tdir;
1139
1140 if (opts->template_path)
1141 tdir = opts->template_path;
1142 else if ((error = git_config_open_default(&cfg)) < 0)
1143 return error;
1144 else {
1145 error = git_config_get_string(&tdir, cfg, "init.templatedir");
1146
1147 git_config_free(cfg);
1148
1149 if (error && error != GIT_ENOTFOUND)
1150 return error;
1151
1152 giterr_clear();
1153 tdir = GIT_TEMPLATE_DIR;
1154 }
1155
1156 error = git_futils_cp_r(tdir, repo_dir,
1157 GIT_CPDIR_COPY_SYMLINKS | GIT_CPDIR_CHMOD_DIRS |
1158 GIT_CPDIR_SIMPLE_TO_MODE, dmode);
1159
1160 if (error < 0) {
1161 if (strcmp(tdir, GIT_TEMPLATE_DIR) != 0)
1162 return error;
1163
1164 /* if template was default, ignore error and use internal */
1165 giterr_clear();
1166 external_tpl = false;
1167 error = 0;
1168 }
1169 }
1170
1171 /* Copy internal template
1172 * - always ensure existence of dirs
1173 * - only create files if no external template was specified
1174 */
1175 for (tpl = repo_template; !error && tpl->path; ++tpl) {
1176 if (!tpl->content)
1177 error = git_futils_mkdir(
1178 tpl->path, repo_dir, dmode, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD);
1179 else if (!external_tpl) {
1180 const char *content = tpl->content;
1181
1182 if (opts->description && strcmp(tpl->path, GIT_DESC_FILE) == 0)
1183 content = opts->description;
1184
1185 error = repo_write_template(
1186 repo_dir, false, tpl->path, tpl->mode, false, content);
1187 }
1188 }
1189
1190 return error;
1191 }
1192
1193 static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2)
1194 {
1195 /* When making parent directories during repository initialization
1196 * don't try to set gid or grant world write access
1197 */
1198 return git_futils_mkdir(
1199 buf->ptr, NULL, mode & ~(S_ISGID | 0002),
1200 GIT_MKDIR_PATH | GIT_MKDIR_VERIFY_DIR |
1201 (skip2 ? GIT_MKDIR_SKIP_LAST2 : GIT_MKDIR_SKIP_LAST));
1202 }
1203
1204 static int repo_init_directories(
1205 git_buf *repo_path,
1206 git_buf *wd_path,
1207 const char *given_repo,
1208 git_repository_init_options *opts)
1209 {
1210 int error = 0;
1211 bool is_bare, add_dotgit, has_dotgit, natural_wd;
1212 mode_t dirmode;
1213
1214 /* There are three possible rules for what we are allowed to create:
1215 * - MKPATH means anything we need
1216 * - MKDIR means just the .git directory and its parent and the workdir
1217 * - Neither means only the .git directory can be created
1218 *
1219 * There are 5 "segments" of path that we might need to deal with:
1220 * 1. The .git directory
1221 * 2. The parent of the .git directory
1222 * 3. Everything above the parent of the .git directory
1223 * 4. The working directory (often the same as #2)
1224 * 5. Everything above the working directory (often the same as #3)
1225 *
1226 * For all directories created, we start with the init_mode value for
1227 * permissions and then strip off bits in some cases:
1228 *
1229 * For MKPATH, we create #3 (and #5) paths without S_ISGID or S_IWOTH
1230 * For MKPATH and MKDIR, we create #2 (and #4) without S_ISGID
1231 * For all rules, we create #1 using the untouched init_mode
1232 */
1233
1234 /* set up repo path */
1235
1236 is_bare = ((opts->flags & GIT_REPOSITORY_INIT_BARE) != 0);
1237
1238 add_dotgit =
1239 (opts->flags & GIT_REPOSITORY_INIT_NO_DOTGIT_DIR) == 0 &&
1240 !is_bare &&
1241 git__suffixcmp(given_repo, "/" DOT_GIT) != 0 &&
1242 git__suffixcmp(given_repo, "/" GIT_DIR) != 0;
1243
1244 if (git_buf_joinpath(repo_path, given_repo, add_dotgit ? GIT_DIR : "") < 0)
1245 return -1;
1246
1247 has_dotgit = (git__suffixcmp(repo_path->ptr, "/" GIT_DIR) == 0);
1248 if (has_dotgit)
1249 opts->flags |= GIT_REPOSITORY_INIT__HAS_DOTGIT;
1250
1251 /* set up workdir path */
1252
1253 if (!is_bare) {
1254 if (opts->workdir_path) {
1255 if (git_path_join_unrooted(
1256 wd_path, opts->workdir_path, repo_path->ptr, NULL) < 0)
1257 return -1;
1258 } else if (has_dotgit) {
1259 if (git_path_dirname_r(wd_path, repo_path->ptr) < 0)
1260 return -1;
1261 } else {
1262 giterr_set(GITERR_REPOSITORY, "Cannot pick working directory"
1263 " for non-bare repository that isn't a '.git' directory");
1264 return -1;
1265 }
1266
1267 if (git_path_to_dir(wd_path) < 0)
1268 return -1;
1269 } else {
1270 git_buf_clear(wd_path);
1271 }
1272
1273 natural_wd =
1274 has_dotgit &&
1275 wd_path->size > 0 &&
1276 wd_path->size + strlen(GIT_DIR) == repo_path->size &&
1277 memcmp(repo_path->ptr, wd_path->ptr, wd_path->size) == 0;
1278 if (natural_wd)
1279 opts->flags |= GIT_REPOSITORY_INIT__NATURAL_WD;
1280
1281 /* create directories as needed / requested */
1282
1283 dirmode = pick_dir_mode(opts);
1284
1285 if ((opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0) {
1286 /* create path #5 */
1287 if (wd_path->size > 0 &&
1288 (error = mkdir_parent(wd_path, dirmode, false)) < 0)
1289 return error;
1290
1291 /* create path #3 (if not the same as #5) */
1292 if (!natural_wd &&
1293 (error = mkdir_parent(repo_path, dirmode, has_dotgit)) < 0)
1294 return error;
1295 }
1296
1297 if ((opts->flags & GIT_REPOSITORY_INIT_MKDIR) != 0 ||
1298 (opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0)
1299 {
1300 /* create path #4 */
1301 if (wd_path->size > 0 &&
1302 (error = git_futils_mkdir(
1303 wd_path->ptr, NULL, dirmode & ~S_ISGID,
1304 GIT_MKDIR_VERIFY_DIR)) < 0)
1305 return error;
1306
1307 /* create path #2 (if not the same as #4) */
1308 if (!natural_wd &&
1309 (error = git_futils_mkdir(
1310 repo_path->ptr, NULL, dirmode & ~S_ISGID,
1311 GIT_MKDIR_VERIFY_DIR | GIT_MKDIR_SKIP_LAST)) < 0)
1312 return error;
1313 }
1314
1315 if ((opts->flags & GIT_REPOSITORY_INIT_MKDIR) != 0 ||
1316 (opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0 ||
1317 has_dotgit)
1318 {
1319 /* create path #1 */
1320 error = git_futils_mkdir(repo_path->ptr, NULL, dirmode,
1321 GIT_MKDIR_VERIFY_DIR | ((dirmode & S_ISGID) ? GIT_MKDIR_CHMOD : 0));
1322 }
1323
1324 /* prettify both directories now that they are created */
1325
1326 if (!error) {
1327 error = git_path_prettify_dir(repo_path, repo_path->ptr, NULL);
1328
1329 if (!error && wd_path->size > 0)
1330 error = git_path_prettify_dir(wd_path, wd_path->ptr, NULL);
1331 }
1332
1333 return error;
1334 }
1335
1336 static int repo_init_create_origin(git_repository *repo, const char *url)
1337 {
1338 int error;
1339 git_remote *remote;
1340
1341 if (!(error = git_remote_create(&remote, repo, GIT_REMOTE_ORIGIN, url))) {
1342 git_remote_free(remote);
1343 }
1344
1345 return error;
1346 }
1347
1348 int git_repository_init(
1349 git_repository **repo_out, const char *path, unsigned is_bare)
1350 {
1351 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
1352
1353 opts.flags = GIT_REPOSITORY_INIT_MKPATH; /* don't love this default */
1354 if (is_bare)
1355 opts.flags |= GIT_REPOSITORY_INIT_BARE;
1356
1357 return git_repository_init_ext(repo_out, path, &opts);
1358 }
1359
1360 int git_repository_init_ext(
1361 git_repository **out,
1362 const char *given_repo,
1363 git_repository_init_options *opts)
1364 {
1365 int error;
1366 git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT;
1367
1368 assert(out && given_repo && opts);
1369
1370 GITERR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options");
1371
1372 error = repo_init_directories(&repo_path, &wd_path, given_repo, opts);
1373 if (error < 0)
1374 goto cleanup;
1375
1376 if (valid_repository_path(&repo_path)) {
1377
1378 if ((opts->flags & GIT_REPOSITORY_INIT_NO_REINIT) != 0) {
1379 giterr_set(GITERR_REPOSITORY,
1380 "Attempt to reinitialize '%s'", given_repo);
1381 error = GIT_EEXISTS;
1382 goto cleanup;
1383 }
1384
1385 opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT;
1386
1387 error = repo_init_config(
1388 git_buf_cstr(&repo_path), git_buf_cstr(&wd_path), opts);
1389
1390 /* TODO: reinitialize the templates */
1391 }
1392 else {
1393 if (!(error = repo_init_structure(
1394 git_buf_cstr(&repo_path), git_buf_cstr(&wd_path), opts)) &&
1395 !(error = repo_init_config(
1396 git_buf_cstr(&repo_path), git_buf_cstr(&wd_path), opts)))
1397 error = repo_init_create_head(
1398 git_buf_cstr(&repo_path), opts->initial_head);
1399 }
1400 if (error < 0)
1401 goto cleanup;
1402
1403 error = git_repository_open(out, git_buf_cstr(&repo_path));
1404
1405 if (!error && opts->origin_url)
1406 error = repo_init_create_origin(*out, opts->origin_url);
1407
1408 cleanup:
1409 git_buf_free(&repo_path);
1410 git_buf_free(&wd_path);
1411
1412 return error;
1413 }
1414
1415 int git_repository_head_detached(git_repository *repo)
1416 {
1417 git_reference *ref;
1418 git_odb *odb = NULL;
1419 int exists;
1420
1421 if (git_repository_odb__weakptr(&odb, repo) < 0)
1422 return -1;
1423
1424 if (git_reference_lookup(&ref, repo, GIT_HEAD_FILE) < 0)
1425 return -1;
1426
1427 if (git_reference_type(ref) == GIT_REF_SYMBOLIC) {
1428 git_reference_free(ref);
1429 return 0;
1430 }
1431
1432 exists = git_odb_exists(odb, git_reference_target(ref));
1433
1434 git_reference_free(ref);
1435 return exists;
1436 }
1437
1438 int git_repository_head(git_reference **head_out, git_repository *repo)
1439 {
1440 git_reference *head;
1441 int error;
1442
1443 if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0)
1444 return error;
1445
1446 if (git_reference_type(head) == GIT_REF_OID) {
1447 *head_out = head;
1448 return 0;
1449 }
1450
1451 error = git_reference_lookup_resolved(head_out, repo, git_reference_symbolic_target(head), -1);
1452 git_reference_free(head);
1453
1454 return error == GIT_ENOTFOUND ? GIT_EUNBORNBRANCH : error;
1455 }
1456
1457 int git_repository_head_unborn(git_repository *repo)
1458 {
1459 git_reference *ref = NULL;
1460 int error;
1461
1462 error = git_repository_head(&ref, repo);
1463 git_reference_free(ref);
1464
1465 if (error == GIT_EUNBORNBRANCH)
1466 return 1;
1467
1468 if (error < 0)
1469 return -1;
1470
1471 return 0;
1472 }
1473
1474 static int at_least_one_cb(const char *refname, void *payload)
1475 {
1476 GIT_UNUSED(refname);
1477 GIT_UNUSED(payload);
1478
1479 return GIT_EUSER;
1480 }
1481
1482 static int repo_contains_no_reference(git_repository *repo)
1483 {
1484 int error = git_reference_foreach_name(repo, &at_least_one_cb, NULL);
1485
1486 if (error == GIT_EUSER)
1487 return 0;
1488
1489 if (!error)
1490 return 1;
1491
1492 return error;
1493 }
1494
1495 int git_repository_is_empty(git_repository *repo)
1496 {
1497 git_reference *head = NULL;
1498 int is_empty = 0;
1499
1500 if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
1501 return -1;
1502
1503 if (git_reference_type(head) == GIT_REF_SYMBOLIC)
1504 is_empty =
1505 (strcmp(git_reference_symbolic_target(head),
1506 GIT_REFS_HEADS_DIR "master") == 0) &&
1507 repo_contains_no_reference(repo);
1508
1509 git_reference_free(head);
1510
1511 return is_empty;
1512 }
1513
1514 const char *git_repository_path(git_repository *repo)
1515 {
1516 assert(repo);
1517 return repo->path_repository;
1518 }
1519
1520 const char *git_repository_workdir(git_repository *repo)
1521 {
1522 assert(repo);
1523
1524 if (repo->is_bare)
1525 return NULL;
1526
1527 return repo->workdir;
1528 }
1529
1530 int git_repository_set_workdir(
1531 git_repository *repo, const char *workdir, int update_gitlink)
1532 {
1533 int error = 0;
1534 git_buf path = GIT_BUF_INIT;
1535
1536 assert(repo && workdir);
1537
1538 if (git_path_prettify_dir(&path, workdir, NULL) < 0)
1539 return -1;
1540
1541 if (repo->workdir && strcmp(repo->workdir, path.ptr) == 0)
1542 return 0;
1543
1544 if (update_gitlink) {
1545 git_config *config;
1546
1547 if (git_repository_config__weakptr(&config, repo) < 0)
1548 return -1;
1549
1550 error = repo_write_gitlink(path.ptr, git_repository_path(repo));
1551
1552 /* passthrough error means gitlink is unnecessary */
1553 if (error == GIT_PASSTHROUGH)
1554 error = git_config_delete_entry(config, "core.worktree");
1555 else if (!error)
1556 error = git_config_set_string(config, "core.worktree", path.ptr);
1557
1558 if (!error)
1559 error = git_config_set_bool(config, "core.bare", false);
1560 }
1561
1562 if (!error) {
1563 char *old_workdir = repo->workdir;
1564
1565 repo->workdir = git_buf_detach(&path);
1566 repo->is_bare = 0;
1567
1568 git__free(old_workdir);
1569 }
1570
1571 return error;
1572 }
1573
1574 int git_repository_is_bare(git_repository *repo)
1575 {
1576 assert(repo);
1577 return repo->is_bare;
1578 }
1579
1580 int git_repository_head_tree(git_tree **tree, git_repository *repo)
1581 {
1582 git_reference *head;
1583 git_object *obj;
1584 int error;
1585
1586 if ((error = git_repository_head(&head, repo)) < 0)
1587 return error;
1588
1589 if ((error = git_reference_peel(&obj, head, GIT_OBJ_TREE)) < 0)
1590 goto cleanup;
1591
1592 *tree = (git_tree *)obj;
1593
1594 cleanup:
1595 git_reference_free(head);
1596 return error;
1597 }
1598
1599 int git_repository_message(char *buffer, size_t len, git_repository *repo)
1600 {
1601 git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
1602 struct stat st;
1603 int error;
1604
1605 if (buffer != NULL)
1606 *buffer = '\0';
1607
1608 if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0)
1609 return -1;
1610
1611 if ((error = p_stat(git_buf_cstr(&path), &st)) < 0) {
1612 if (errno == ENOENT)
1613 error = GIT_ENOTFOUND;
1614 giterr_set(GITERR_OS, "Could not access message file");
1615 }
1616 else if (buffer != NULL) {
1617 error = git_futils_readbuffer(&buf, git_buf_cstr(&path));
1618 git_buf_copy_cstr(buffer, len, &buf);
1619 }
1620
1621 git_buf_free(&path);
1622 git_buf_free(&buf);
1623
1624 if (!error)
1625 error = (int)st.st_size + 1; /* add 1 for NUL byte */
1626
1627 return error;
1628 }
1629
1630 int git_repository_message_remove(git_repository *repo)
1631 {
1632 git_buf path = GIT_BUF_INIT;
1633 int error;
1634
1635 if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0)
1636 return -1;
1637
1638 error = p_unlink(git_buf_cstr(&path));
1639 git_buf_free(&path);
1640
1641 return error;
1642 }
1643
1644 int git_repository_hashfile(
1645 git_oid *out,
1646 git_repository *repo,
1647 const char *path,
1648 git_otype type,
1649 const char *as_path)
1650 {
1651 int error;
1652 git_vector filters = GIT_VECTOR_INIT;
1653 git_file fd = -1;
1654 git_off_t len;
1655 git_buf full_path = GIT_BUF_INIT;
1656
1657 assert(out && path && repo); /* as_path can be NULL */
1658
1659 /* At some point, it would be nice if repo could be NULL to just
1660 * apply filter rules defined in system and global files, but for
1661 * now that is not possible because git_filters_load() needs it.
1662 */
1663
1664 error = git_path_join_unrooted(
1665 &full_path, path, repo ? git_repository_workdir(repo) : NULL, NULL);
1666 if (error < 0)
1667 return error;
1668
1669 if (!as_path)
1670 as_path = path;
1671
1672 /* passing empty string for "as_path" indicated --no-filters */
1673 if (strlen(as_path) > 0) {
1674 error = git_filters_load(&filters, repo, as_path, GIT_FILTER_TO_ODB);
1675 if (error < 0)
1676 return error;
1677 } else {
1678 error = 0;
1679 }
1680
1681 /* at this point, error is a count of the number of loaded filters */
1682
1683 fd = git_futils_open_ro(full_path.ptr);
1684 if (fd < 0) {
1685 error = fd;
1686 goto cleanup;
1687 }
1688
1689 len = git_futils_filesize(fd);
1690 if (len < 0) {
1691 error = (int)len;
1692 goto cleanup;
1693 }
1694
1695 if (!git__is_sizet(len)) {
1696 giterr_set(GITERR_OS, "File size overflow for 32-bit systems");
1697 error = -1;
1698 goto cleanup;
1699 }
1700
1701 error = git_odb__hashfd_filtered(out, fd, (size_t)len, type, &filters);
1702
1703 cleanup:
1704 if (fd >= 0)
1705 p_close(fd);
1706 git_filters_free(&filters);
1707 git_buf_free(&full_path);
1708
1709 return error;
1710 }
1711
1712 static bool looks_like_a_branch(const char *refname)
1713 {
1714 return git__prefixcmp(refname, GIT_REFS_HEADS_DIR) == 0;
1715 }
1716
1717 int git_repository_set_head(
1718 git_repository* repo,
1719 const char* refname)
1720 {
1721 git_reference *ref,
1722 *new_head = NULL;
1723 int error;
1724
1725 assert(repo && refname);
1726
1727 error = git_reference_lookup(&ref, repo, refname);
1728 if (error < 0 && error != GIT_ENOTFOUND)
1729 return error;
1730
1731 if (!error) {
1732 if (git_reference_is_branch(ref))
1733 error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, git_reference_name(ref), 1);
1734 else
1735 error = git_repository_set_head_detached(repo, git_reference_target(ref));
1736 } else if (looks_like_a_branch(refname))
1737 error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname, 1);
1738
1739 git_reference_free(ref);
1740 git_reference_free(new_head);
1741 return error;
1742 }
1743
1744 int git_repository_set_head_detached(
1745 git_repository* repo,
1746 const git_oid* commitish)
1747 {
1748 int error;
1749 git_object *object,
1750 *peeled = NULL;
1751 git_reference *new_head = NULL;
1752
1753 assert(repo && commitish);
1754
1755 if ((error = git_object_lookup(&object, repo, commitish, GIT_OBJ_ANY)) < 0)
1756 return error;
1757
1758 if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0)
1759 goto cleanup;
1760
1761 error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), 1);
1762
1763 cleanup:
1764 git_object_free(object);
1765 git_object_free(peeled);
1766 git_reference_free(new_head);
1767 return error;
1768 }
1769
1770 int git_repository_detach_head(
1771 git_repository* repo)
1772 {
1773 git_reference *old_head = NULL,
1774 *new_head = NULL;
1775 git_object *object = NULL;
1776 int error;
1777
1778 assert(repo);
1779
1780 if ((error = git_repository_head(&old_head, repo)) < 0)
1781 return error;
1782
1783 if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJ_COMMIT)) < 0)
1784 goto cleanup;
1785
1786 error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head), 1);
1787
1788 cleanup:
1789 git_object_free(object);
1790 git_reference_free(old_head);
1791 git_reference_free(new_head);
1792 return error;
1793 }
1794
1795 /**
1796 * Loosely ported from git.git
1797 * https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh#L198-289
1798 */
1799 int git_repository_state(git_repository *repo)
1800 {
1801 git_buf repo_path = GIT_BUF_INIT;
1802 int state = GIT_REPOSITORY_STATE_NONE;
1803
1804 assert(repo);
1805
1806 if (git_buf_puts(&repo_path, repo->path_repository) < 0)
1807 return -1;
1808
1809 if (git_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE))
1810 state = GIT_REPOSITORY_STATE_REBASE_INTERACTIVE;
1811 else if (git_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR))
1812 state = GIT_REPOSITORY_STATE_REBASE_MERGE;
1813 else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE))
1814 state = GIT_REPOSITORY_STATE_REBASE;
1815 else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE))
1816 state = GIT_REPOSITORY_STATE_APPLY_MAILBOX;
1817 else if (git_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR))
1818 state = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE;
1819 else if (git_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE))
1820 state = GIT_REPOSITORY_STATE_MERGE;
1821 else if(git_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE))
1822 state = GIT_REPOSITORY_STATE_REVERT;
1823 else if(git_path_contains_file(&repo_path, GIT_CHERRY_PICK_HEAD_FILE))
1824 state = GIT_REPOSITORY_STATE_CHERRY_PICK;
1825 else if(git_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE))
1826 state = GIT_REPOSITORY_STATE_BISECT;
1827
1828 git_buf_free(&repo_path);
1829 return state;
1830 }
1831
1832 int git_repository_is_shallow(git_repository *repo)
1833 {
1834 git_buf path = GIT_BUF_INIT;
1835 struct stat st;
1836 int error;
1837
1838 git_buf_joinpath(&path, repo->path_repository, "shallow");
1839 error = git_path_lstat(path.ptr, &st);
1840 git_buf_free(&path);
1841
1842 if (error == GIT_ENOTFOUND)
1843 return 0;
1844 if (error < 0)
1845 return -1;
1846 return st.st_size == 0 ? 0 : 1;
1847 }