]> git.proxmox.com Git - libgit2.git/blob - src/repository.c
Merge pull request #444 from carlosmn/fetch-fixes
[libgit2.git] / src / repository.c
1 /*
2 * Copyright (C) 2009-2011 the libgit2 contributors
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
9 #include "git2/object.h"
10
11 #include "common.h"
12 #include "repository.h"
13 #include "commit.h"
14 #include "tag.h"
15 #include "blob.h"
16 #include "fileops.h"
17 #include "config.h"
18 #include "refs.h"
19
20 #define GIT_OBJECTS_INFO_DIR GIT_OBJECTS_DIR "info/"
21 #define GIT_OBJECTS_PACK_DIR GIT_OBJECTS_DIR "pack/"
22
23 #define GIT_FILE_CONTENT_PREFIX "gitdir: "
24
25 #define GIT_BRANCH_MASTER "master"
26
27 /*
28 * Git repository open methods
29 *
30 * Open a repository object from its path
31 */
32 static int assign_repository_dirs(
33 git_repository *repo,
34 const char *git_dir,
35 const char *git_object_directory,
36 const char *git_index_file,
37 const char *git_work_tree)
38 {
39 char path_aux[GIT_PATH_MAX];
40 int error = GIT_SUCCESS;
41
42 assert(repo);
43
44 if (git_dir == NULL)
45 return git__throw(GIT_ENOTFOUND, "Failed to open repository. Git dir not found");
46
47 error = git_path_prettify_dir(path_aux, git_dir, NULL);
48 if (error < GIT_SUCCESS)
49 return git__rethrow(error, "Failed to open repository");
50
51 /* store GIT_DIR */
52 repo->path_repository = git__strdup(path_aux);
53 if (repo->path_repository == NULL)
54 return GIT_ENOMEM;
55
56 /* path to GIT_OBJECT_DIRECTORY */
57 if (git_object_directory == NULL)
58 git_path_join(path_aux, repo->path_repository, GIT_OBJECTS_DIR);
59 else {
60 error = git_path_prettify_dir(path_aux, git_object_directory, NULL);
61 if (error < GIT_SUCCESS)
62 return git__rethrow(error, "Failed to open repository");
63 }
64
65 /* Store GIT_OBJECT_DIRECTORY */
66 repo->path_odb = git__strdup(path_aux);
67 if (repo->path_odb == NULL)
68 return GIT_ENOMEM;
69
70 /* path to GIT_WORK_TREE */
71 if (git_work_tree == NULL)
72 repo->is_bare = 1;
73 else {
74 error = git_path_prettify_dir(path_aux, git_work_tree, NULL);
75 if (error < GIT_SUCCESS)
76 return git__rethrow(error, "Failed to open repository");
77
78 /* Store GIT_WORK_TREE */
79 repo->path_workdir = git__strdup(path_aux);
80 if (repo->path_workdir == NULL)
81 return GIT_ENOMEM;
82
83 /* Path to GIT_INDEX_FILE */
84 if (git_index_file == NULL)
85 git_path_join(path_aux, repo->path_repository, GIT_INDEX_FILE);
86 else {
87 error = git_path_prettify(path_aux, git_index_file, NULL);
88 if (error < GIT_SUCCESS)
89 return git__rethrow(error, "Failed to open repository");
90 }
91
92 /* store GIT_INDEX_FILE */
93 repo->path_index = git__strdup(path_aux);
94 if (repo->path_index == NULL)
95 return GIT_ENOMEM;
96 }
97
98 return GIT_SUCCESS;
99 }
100
101 static int check_repository_dirs(git_repository *repo)
102 {
103 char path_aux[GIT_PATH_MAX];
104
105 if (git_futils_isdir(repo->path_repository) < GIT_SUCCESS)
106 return git__throw(GIT_ENOTAREPO, "`%s` is not a folder", repo->path_repository);
107
108 /* Ensure GIT_OBJECT_DIRECTORY exists */
109 if (git_futils_isdir(repo->path_odb) < GIT_SUCCESS)
110 return git__throw(GIT_ENOTAREPO, "`%s` does not exist", repo->path_odb);
111
112 /* Ensure HEAD file exists */
113 git_path_join(path_aux, repo->path_repository, GIT_HEAD_FILE);
114 if (git_futils_isfile(path_aux) < 0)
115 return git__throw(GIT_ENOTAREPO, "HEAD file is missing");
116
117 return GIT_SUCCESS;
118 }
119
120 static int guess_repository_dirs(git_repository *repo, const char *repository_path)
121 {
122 char buffer[GIT_PATH_MAX];
123 const char *path_work_tree = NULL;
124
125 /* Git directory name */
126 if (git_path_basename_r(buffer, sizeof(buffer), repository_path) < 0)
127 return git__throw(GIT_EINVALIDPATH, "Unable to parse folder name from `%s`", repository_path);
128
129 if (strcmp(buffer, DOT_GIT) == 0) {
130 /* Path to working dir */
131 if (git_path_dirname_r(buffer, sizeof(buffer), repository_path) < 0)
132 return git__throw(GIT_EINVALIDPATH, "Unable to parse parent folder name from `%s`", repository_path);
133 path_work_tree = buffer;
134 }
135
136 return assign_repository_dirs(repo, repository_path, NULL, NULL, path_work_tree);
137 }
138
139 static int quickcheck_repository_dir(const char *repository_path)
140 {
141 char path_aux[GIT_PATH_MAX];
142
143 /* Ensure HEAD file exists */
144 git_path_join(path_aux, repository_path, GIT_HEAD_FILE);
145 if (git_futils_isfile(path_aux) < 0)
146 return GIT_ERROR;
147
148 git_path_join(path_aux, repository_path, GIT_OBJECTS_DIR);
149 if (git_futils_isdir(path_aux) < 0)
150 return GIT_ERROR;
151
152 git_path_join(path_aux, repository_path, GIT_REFS_DIR);
153 if (git_futils_isdir(path_aux) < 0)
154 return GIT_ERROR;
155
156 return GIT_SUCCESS;
157 }
158
159 static git_repository *repository_alloc(void)
160 {
161 int error;
162
163 git_repository *repo = git__malloc(sizeof(git_repository));
164 if (!repo)
165 return NULL;
166
167 memset(repo, 0x0, sizeof(git_repository));
168
169 error = git_cache_init(&repo->objects, GIT_DEFAULT_CACHE_SIZE, &git_object__free);
170 if (error < GIT_SUCCESS) {
171 free(repo);
172 return NULL;
173 }
174
175 if (git_repository__refcache_init(&repo->references) < GIT_SUCCESS) {
176 free(repo);
177 return NULL;
178 }
179
180 return repo;
181 }
182
183 static int init_odb(git_repository *repo)
184 {
185 return git_odb_open(&repo->db, repo->path_odb);
186 }
187
188 int git_repository_open3(git_repository **repo_out,
189 const char *git_dir,
190 git_odb *object_database,
191 const char *git_index_file,
192 const char *git_work_tree)
193 {
194 git_repository *repo;
195 int error = GIT_SUCCESS;
196
197 assert(repo_out);
198
199 if (object_database == NULL)
200 return git__throw(GIT_EINVALIDARGS, "Failed to open repository. `object_database` can't be null");
201
202 repo = repository_alloc();
203 if (repo == NULL)
204 return GIT_ENOMEM;
205
206 error = assign_repository_dirs(repo,
207 git_dir,
208 NULL,
209 git_index_file,
210 git_work_tree);
211
212 if (error < GIT_SUCCESS)
213 goto cleanup;
214
215 error = check_repository_dirs(repo);
216 if (error < GIT_SUCCESS)
217 goto cleanup;
218
219 repo->db = object_database;
220
221 *repo_out = repo;
222 return GIT_SUCCESS;
223
224 cleanup:
225 git_repository_free(repo);
226 return git__rethrow(error, "Failed to open repository");
227 }
228
229
230 int git_repository_open2(git_repository **repo_out,
231 const char *git_dir,
232 const char *git_object_directory,
233 const char *git_index_file,
234 const char *git_work_tree)
235 {
236 git_repository *repo;
237 int error = GIT_SUCCESS;
238
239 assert(repo_out);
240
241 repo = repository_alloc();
242 if (repo == NULL)
243 return GIT_ENOMEM;
244
245 error = assign_repository_dirs(repo,
246 git_dir,
247 git_object_directory,
248 git_index_file,
249 git_work_tree);
250
251 if (error < GIT_SUCCESS)
252 goto cleanup;
253
254 error = check_repository_dirs(repo);
255 if (error < GIT_SUCCESS)
256 goto cleanup;
257
258 error = init_odb(repo);
259 if (error < GIT_SUCCESS)
260 goto cleanup;
261
262 *repo_out = repo;
263 return GIT_SUCCESS;
264
265 cleanup:
266 git_repository_free(repo);
267 return git__rethrow(error, "Failed to open repository");
268 }
269
270 int git_repository_config(
271 git_config **out,
272 git_repository *repo,
273 const char *global_config_path,
274 const char *system_config_path)
275 {
276 char config_path[GIT_PATH_MAX];
277 int error;
278
279 assert(out && repo);
280
281 error = git_config_new(out);
282 if (error < GIT_SUCCESS)
283 return error;
284
285 git_path_join(config_path, repo->path_repository, GIT_CONFIG_FILENAME_INREPO);
286 error = git_config_add_file_ondisk(*out, config_path, 3);
287 if (error < GIT_SUCCESS)
288 goto cleanup;
289
290 if (global_config_path != NULL) {
291 error = git_config_add_file_ondisk(*out, global_config_path, 2);
292 if (error < GIT_SUCCESS)
293 goto cleanup;
294 }
295
296 if (system_config_path != NULL) {
297 error = git_config_add_file_ondisk(*out, system_config_path, 1);
298 if (error < GIT_SUCCESS)
299 goto cleanup;
300 }
301
302 (*out)->repo = repo;
303 return GIT_SUCCESS;
304
305 cleanup:
306 git_config_free(*out);
307 return error;
308 }
309
310 int git_repository_config_autoload(
311 git_config **out,
312 git_repository *repo)
313 {
314 char global[GIT_PATH_MAX], system[GIT_PATH_MAX];
315 char *global_path, *system_path;
316 int error;
317
318
319 error = git_config_find_global(global);
320 global_path = error < GIT_SUCCESS ? NULL : global;
321
322 error = git_config_find_system(system);
323 system_path = error < GIT_SUCCESS ? NULL : system;
324
325 return git_repository_config(out, repo, global_path, system_path);
326 }
327
328 static int discover_repository_dirs(git_repository *repo, const char *path)
329 {
330 int error;
331
332 error = guess_repository_dirs(repo, path);
333 if (error < GIT_SUCCESS)
334 return error;
335
336 error = check_repository_dirs(repo);
337 if (error < GIT_SUCCESS)
338 return error;
339
340 return GIT_SUCCESS;
341 }
342
343 int git_repository_open(git_repository **repo_out, const char *path)
344 {
345 git_repository *repo;
346 int error = GIT_SUCCESS;
347
348 assert(repo_out && path);
349
350 repo = repository_alloc();
351 if (repo == NULL)
352 return GIT_ENOMEM;
353
354 error = discover_repository_dirs(repo, path);
355 if (error < GIT_SUCCESS)
356 goto cleanup;
357
358 error = init_odb(repo);
359 if (error < GIT_SUCCESS)
360 goto cleanup;
361
362 *repo_out = repo;
363 return GIT_SUCCESS;
364
365 cleanup:
366 git_repository_free(repo);
367 return git__rethrow(error, "Failed to open repository");
368 }
369
370 static int retrieve_device(dev_t *device_out, const char *path)
371 {
372 struct stat path_info;
373
374 assert(device_out);
375
376 if (p_lstat(path, &path_info))
377 return git__throw(GIT_EOSERR, "Failed to get file informations: %s", path);
378
379 *device_out = path_info.st_dev;
380
381 return GIT_SUCCESS;
382 }
383
384 static int retrieve_ceiling_directories_offset(const char *path, const char *ceiling_directories)
385 {
386 char buf[GIT_PATH_MAX + 1];
387 char buf2[GIT_PATH_MAX + 1];
388 const char *ceil, *sep;
389 int len, max_len = -1;
390 int min_len;
391
392 assert(path);
393
394 min_len = git_path_root(path) + 1;
395
396 if (ceiling_directories == NULL || min_len == 0)
397 return min_len;
398
399 for (sep = ceil = ceiling_directories; *sep; ceil = sep + 1) {
400 for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
401 len = sep - ceil;
402
403 if (len == 0 || len > GIT_PATH_MAX || git_path_root(ceil) == -1)
404 continue;
405
406 strncpy(buf, ceil, len);
407 buf[len] = '\0';
408
409 if (p_realpath(buf, buf2) == NULL)
410 continue;
411
412 len = strlen(buf2);
413 if (len > 0 && buf2[len-1] == '/')
414 buf[--len] = '\0';
415
416 if (!strncmp(path, buf2, len) &&
417 path[len] == '/' &&
418 len > max_len)
419 {
420 max_len = len;
421 }
422 }
423
424 return max_len <= min_len ? min_len : max_len;
425 }
426
427 static int read_gitfile(char *path_out, const char *file_path, const char *base_path)
428 {
429 git_fbuffer file;
430 int error;
431 size_t end_offset;
432 char *data;
433
434 assert(path_out && file_path && base_path);
435
436 error = git_futils_readbuffer(&file, file_path);
437
438 if (error < GIT_SUCCESS)
439 return error;
440
441 data = (char*)(file.data);
442
443 if (git__prefixcmp(data, GIT_FILE_CONTENT_PREFIX)) {
444 git_futils_freebuffer(&file);
445 return git__throw(GIT_ENOTFOUND, "Invalid gitfile format `%s`", file_path);
446 }
447
448 end_offset = strlen(data) - 1;
449
450 for (;data[end_offset] == '\r' || data[end_offset] == '\n'; --end_offset);
451 data[end_offset + 1] = '\0';
452
453 if (strlen(GIT_FILE_CONTENT_PREFIX) == end_offset + 1) {
454 git_futils_freebuffer(&file);
455 return git__throw(GIT_ENOTFOUND, "No path in git file `%s`", file_path);
456 }
457
458 data = data + strlen(GIT_FILE_CONTENT_PREFIX);
459 error = git_path_prettify_dir(path_out, data, base_path);
460 git_futils_freebuffer(&file);
461
462 if (error == 0 && git_futils_exists(path_out) == 0)
463 return GIT_SUCCESS;
464
465 return git__throw(GIT_EOBJCORRUPTED, "The `.git` file points to an inexisting path");
466 }
467
468 static void git_repository__free_dirs(git_repository *repo)
469 {
470 free(repo->path_workdir);
471 repo->path_workdir = NULL;
472 free(repo->path_index);
473 repo->path_index = NULL;
474 free(repo->path_repository);
475 repo->path_repository = NULL;
476 free(repo->path_odb);
477 repo->path_odb = NULL;
478 }
479
480 void git_repository_free(git_repository *repo)
481 {
482 if (repo == NULL)
483 return;
484
485 git_cache_free(&repo->objects);
486 git_repository__refcache_free(&repo->references);
487 git_repository__free_dirs(repo);
488
489 if (repo->db != NULL)
490 git_odb_close(repo->db);
491
492 free(repo);
493 }
494
495 int git_repository_discover(char *repository_path, size_t size, const char *start_path, int across_fs, const char *ceiling_dirs)
496 {
497 int error, ceiling_offset;
498 char bare_path[GIT_PATH_MAX];
499 char normal_path[GIT_PATH_MAX];
500 char *found_path;
501 dev_t current_device = 0;
502
503 assert(start_path && repository_path);
504
505 error = git_path_prettify_dir(bare_path, start_path, NULL);
506 if (error < GIT_SUCCESS)
507 return error;
508
509 if (!across_fs) {
510 error = retrieve_device(&current_device, bare_path);
511 if (error < GIT_SUCCESS)
512 return error;
513 }
514
515 ceiling_offset = retrieve_ceiling_directories_offset(bare_path, ceiling_dirs);
516 git_path_join(normal_path, bare_path, DOT_GIT);
517
518 while(1) {
519 /**
520 * If the `.git` file is regular instead of
521 * a directory, it should contain the path of the actual git repository
522 */
523 if (git_futils_isfile(normal_path) == GIT_SUCCESS) {
524 error = read_gitfile(repository_path, normal_path, bare_path);
525
526 if (error < GIT_SUCCESS)
527 return git__rethrow(error, "Unable to read git file `%s`", normal_path);
528
529 error = quickcheck_repository_dir(repository_path);
530 if (error < GIT_SUCCESS)
531 return git__throw(GIT_ENOTFOUND, "The `.git` file found at '%s' points"
532 "to an inexisting Git folder", normal_path);
533
534 return GIT_SUCCESS;
535 }
536
537 /**
538 * If the `.git` file is a folder, we check inside of it
539 */
540 if (git_futils_isdir(normal_path) == GIT_SUCCESS) {
541 error = quickcheck_repository_dir(normal_path);
542 if (error == GIT_SUCCESS) {
543 found_path = normal_path;
544 break;
545 }
546 }
547
548 /**
549 * Otherwise, the repository may be bare, let's check
550 * the root anyway
551 */
552 error = quickcheck_repository_dir(bare_path);
553 if (error == GIT_SUCCESS) {
554 found_path = bare_path;
555 break;
556 }
557
558 if (git_path_dirname_r(normal_path, sizeof(normal_path), bare_path) < GIT_SUCCESS)
559 return git__throw(GIT_EOSERR, "Failed to dirname '%s'", bare_path);
560
561 if (!across_fs) {
562 dev_t new_device;
563 error = retrieve_device(&new_device, normal_path);
564
565 if (error < GIT_SUCCESS || current_device != new_device) {
566 return git__throw(GIT_ENOTAREPO,"Not a git repository (or any parent up to mount parent %s)\n"
567 "Stopping at filesystem boundary.", bare_path);
568 }
569 current_device = new_device;
570 }
571
572 strcpy(bare_path, normal_path);
573 git_path_join(normal_path, bare_path, DOT_GIT);
574
575 // nothing has been found, lets try the parent directory
576 if (bare_path[ceiling_offset] == '\0') {
577 return git__throw(GIT_ENOTAREPO,"Not a git repository (or any of the parent directories): %s", start_path);
578 }
579 }
580
581 if (size < strlen(found_path) + 2) {
582 return git__throw(GIT_ESHORTBUFFER, "The repository buffer is not long enough to handle the repository path `%s`", found_path);
583 }
584
585 git_path_join(repository_path, found_path, "");
586 return GIT_SUCCESS;
587 }
588
589 git_odb *git_repository_database(git_repository *repo)
590 {
591 assert(repo);
592 return repo->db;
593 }
594
595 static int repo_init_reinit(const char *repository_path, int is_bare)
596 {
597 /* TODO: reinit the repository */
598 return git__throw(GIT_ENOTIMPLEMENTED,
599 "Failed to reinitialize the %srepository at '%s'. "
600 "This feature is not yet implemented",
601 is_bare ? "bare" : "", repository_path);
602 }
603
604 static int repo_init_createhead(git_repository *repo)
605 {
606 git_reference *head_reference;
607 return git_reference_create_symbolic(&head_reference, repo, GIT_HEAD_FILE, GIT_REFS_HEADS_MASTER_FILE, 0);
608 }
609
610 static int repo_init_structure(const char *git_dir, int is_bare)
611 {
612 const int mode = 0755; /* or 0777 ? */
613 int error;
614
615 char temp_path[GIT_PATH_MAX];
616
617 if (git_futils_mkdir_r(git_dir, mode))
618 return git__throw(GIT_ERROR, "Failed to initialize repository structure. Could not mkdir");
619
620 /* Hides the ".git" directory */
621 if (!is_bare) {
622 #ifdef GIT_WIN32
623 error = p_hide_directory__w32(git_dir);
624 if (error < GIT_SUCCESS)
625 return git__rethrow(error, "Failed to initialize repository structure");
626 #endif
627 }
628
629 /* Creates the '/objects/info/' directory */
630 git_path_join(temp_path, git_dir, GIT_OBJECTS_INFO_DIR);
631 error = git_futils_mkdir_r(temp_path, mode);
632 if (error < GIT_SUCCESS)
633 return git__rethrow(error, "Failed to initialize repository structure");
634
635 /* Creates the '/objects/pack/' directory */
636 git_path_join(temp_path, git_dir, GIT_OBJECTS_PACK_DIR);
637 error = p_mkdir(temp_path, mode);
638 if (error < GIT_SUCCESS)
639 return git__throw(error, "Unable to create `%s` folder", temp_path);
640
641 /* Creates the '/refs/heads/' directory */
642 git_path_join(temp_path, git_dir, GIT_REFS_HEADS_DIR);
643 error = git_futils_mkdir_r(temp_path, mode);
644 if (error < GIT_SUCCESS)
645 return git__rethrow(error, "Failed to initialize repository structure");
646
647 /* Creates the '/refs/tags/' directory */
648 git_path_join(temp_path, git_dir, GIT_REFS_TAGS_DIR);
649 error = p_mkdir(temp_path, mode);
650 if (error < GIT_SUCCESS)
651 return git__throw(error, "Unable to create `%s` folder", temp_path);
652
653 /* TODO: what's left? templates? */
654
655 return GIT_SUCCESS;
656 }
657
658 int git_repository_init(git_repository **repo_out, const char *path, unsigned is_bare)
659 {
660 int error = GIT_SUCCESS;
661 git_repository *repo = NULL;
662 char repository_path[GIT_PATH_MAX];
663
664 assert(repo_out && path);
665
666 git_path_join(repository_path, path, is_bare ? "" : GIT_DIR);
667
668 if (git_futils_isdir(repository_path)) {
669 if (quickcheck_repository_dir(repository_path) == GIT_SUCCESS)
670 return repo_init_reinit(repository_path, is_bare);
671 }
672
673 error = repo_init_structure(repository_path, is_bare);
674 if (error < GIT_SUCCESS)
675 goto cleanup;
676
677 repo = repository_alloc();
678 if (repo == NULL) {
679 error = GIT_ENOMEM;
680 goto cleanup;
681 }
682
683 error = guess_repository_dirs(repo, repository_path);
684 if (error < GIT_SUCCESS)
685 goto cleanup;
686
687 assert(repo->is_bare == is_bare);
688
689 error = init_odb(repo);
690 if (error < GIT_SUCCESS)
691 goto cleanup;
692
693 error = repo_init_createhead(repo);
694 if (error < GIT_SUCCESS)
695 goto cleanup;
696
697 /* should never fail */
698 assert(check_repository_dirs(repo) == GIT_SUCCESS);
699
700 *repo_out = repo;
701 return GIT_SUCCESS;
702
703 cleanup:
704 git_repository_free(repo);
705 return git__rethrow(error, "Failed to (re)init the repository `%s`", path);
706 }
707
708 int git_repository_head_detached(git_repository *repo)
709 {
710 git_reference *ref;
711 int error;
712 size_t GIT_UNUSED(_size);
713 git_otype type;
714
715 error = git_reference_lookup(&ref, repo, GIT_HEAD_FILE);
716 if (error < GIT_SUCCESS)
717 return error;
718
719 if (git_reference_type(ref) == GIT_REF_SYMBOLIC)
720 return 0;
721
722 error = git_odb_read_header(&_size, &type, repo->db, git_reference_oid(ref));
723 if (error < GIT_SUCCESS)
724 return error;
725
726 if (type != GIT_OBJ_COMMIT)
727 return git__throw(GIT_EOBJCORRUPTED, "HEAD is not a commit");
728
729 return 1;
730 }
731
732 int git_repository_head(git_reference **head_out, git_repository *repo)
733 {
734 git_reference *ref;
735 int error;
736
737 *head_out = NULL;
738
739 error = git_reference_lookup(&ref, repo, GIT_HEAD_FILE);
740 if (error < GIT_SUCCESS)
741 return git__rethrow(GIT_ENOTAREPO, "Failed to locate the HEAD");
742
743 error = git_reference_resolve(&ref, ref);
744 if (error < GIT_SUCCESS)
745 return git__rethrow(error, "Failed to resolve the HEAD");
746
747 *head_out = ref;
748 return GIT_SUCCESS;
749 }
750
751 int git_repository_head_orphan(git_repository *repo)
752 {
753 git_reference *ref;
754 int error;
755
756 error = git_repository_head(&ref, repo);
757
758 return error == GIT_ENOTFOUND ? 1 : error;
759 }
760
761 int git_repository_is_empty(git_repository *repo)
762 {
763 git_reference *head, *branch;
764 int error;
765
766 error = git_reference_lookup(&head, repo, "HEAD");
767 if (error < GIT_SUCCESS)
768 return git__throw(error, "Corrupted repository. HEAD does not exist");
769
770 if (git_reference_type(head) != GIT_REF_SYMBOLIC)
771 return 0;
772
773 if (strcmp(git_reference_target(head), "refs/heads/master") != 0)
774 return 0;
775
776 error = git_reference_resolve(&branch, head);
777 return error == GIT_ENOTFOUND ? 1 : error;
778 }
779
780 const char *git_repository_path(git_repository *repo, git_repository_pathid id)
781 {
782 assert(repo);
783
784 switch (id) {
785 case GIT_REPO_PATH:
786 return repo->path_repository;
787
788 case GIT_REPO_PATH_INDEX:
789 return repo->path_index;
790
791 case GIT_REPO_PATH_ODB:
792 return repo->path_odb;
793
794 case GIT_REPO_PATH_WORKDIR:
795 return repo->path_workdir;
796
797 default:
798 return NULL;
799 }
800 }
801
802 int git_repository_is_bare(git_repository *repo)
803 {
804 assert(repo);
805 return repo->is_bare;
806 }