Blob


1 #include <assert.h>
2 #include <limits.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <sha1.h>
6 #include <string.h>
8 #include "got_path.h"
9 #include "got_error.h"
10 #include "got_refs.h"
11 #include "got_repository.h"
13 #define GOT_GIT_DIR ".git"
15 /* Mandatory files and directories inside the git directory. */
16 #define GOT_OBJECTS_DIR "objects"
17 #define GOT_REFS_DIR "refs"
18 #define GOT_HEAD_FILE "HEAD"
20 static char *
21 get_path_git_dir(struct got_repository *repo)
22 {
23 char *path_git;
25 if (asprintf(&path_git, "%s/%s", repo->path, GOT_GIT_DIR) == -1)
26 return NULL;
28 return path_git;
29 }
31 static char *
32 get_path_git_child(struct got_repository *repo, const char *basename)
33 {
34 char *path_child;
36 if (asprintf(&path_child, "%s/%s/%s", repo->path, GOT_GIT_DIR,
37 basename) == -1)
38 return NULL;
40 return path_child;
41 }
43 static char *
44 get_path_objects(struct got_repository *repo)
45 {
46 return get_path_git_child(repo, GOT_OBJECTS_DIR);
47 }
49 static char *
50 get_path_refs(struct got_repository *repo)
51 {
52 return get_path_git_child(repo, GOT_REFS_DIR);
53 }
55 static char *
56 get_path_head(struct got_repository *repo)
57 {
58 return get_path_git_child(repo, GOT_HEAD_FILE);
59 }
61 static int
62 is_git_repo(struct got_repository *repo)
63 {
64 char *path_git = get_path_git_dir(repo);
65 char *path_objects = get_path_objects(repo);
66 char *path_refs = get_path_refs(repo);
67 char *path_head = get_path_head(repo);
68 int ret;
70 ret = (path_git != NULL) && (path_objects != NULL) &&
71 (path_refs != NULL) && (path_head != NULL);
73 free(path_git);
74 free(path_objects);
75 free(path_refs);
76 free(path_head);
77 return ret;
79 }
81 const struct got_error *
82 got_repo_open(struct got_repository **ret, const char *abspath)
83 {
84 struct got_repository *repo;
86 if (!got_path_is_absolute(abspath))
87 return got_error(GOT_ERR_NOT_ABSPATH);
89 repo = calloc(1, sizeof(*repo));
90 if (repo == NULL)
91 return got_error(GOT_ERR_NO_MEM);
93 repo->path = got_path_normalize(abspath);
94 if (repo->path == NULL)
95 return got_error(GOT_ERR_BAD_PATH);
97 if (!is_git_repo(repo))
98 return got_error(GOT_ERR_NOT_GIT_REPO);
100 *ret = repo;
101 return NULL;
104 void
105 got_repo_close(struct got_repository *repo)
107 free(repo->path);
108 free(repo);
111 const char *
112 got_repo_get_path(struct got_repository *repo)
114 return repo->path;
117 const struct got_error *
118 got_repo_get_reference(struct got_reference **ref,
119 struct got_repository *repo, const char *refname)
121 const struct got_error *err = NULL;
122 char *path_refs;
124 /* Some refs live in the .git directory. */
125 if (strcmp(refname, GOT_REF_HEAD) == 0)
126 path_refs = get_path_git_dir(repo);
127 else
128 path_refs = get_path_refs(repo);
130 err = got_ref_open(ref, path_refs, refname);
131 free(path_refs);
132 return err;