Line Flow Count Block(s) Source
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 -
8 - #include "refdb.h"
9 -
10 - #include "git2/object.h"
11 - #include "git2/refs.h"
12 - #include "git2/refdb.h"
13 - #include "git2/sys/refdb_backend.h"
14 -
15 - #include "hash.h"
16 - #include "refs.h"
17 - #include "reflog.h"
18 - #include "posix.h"
19 -
20 2168 2 int git_refdb_new(git_refdb **out, git_repository *repo)
21 - {
22 - git_refdb *db;
23 -
24 2168 2-4 assert(out && repo);
25 -
26 2168 5 db = git__calloc(1, sizeof(*db));
27 2168 6,7 GIT_ERROR_CHECK_ALLOC(db);
28 -
29 2168 8 db->repo = repo;
30 -
31 2168 8 *out = db;
32 2168 8 GIT_REFCOUNT_INC(db);
33 2168 9 return 0;
34 - }
35 -
36 2167 2 int git_refdb_open(git_refdb **out, git_repository *repo)
37 - {
38 - git_refdb *db;
39 - git_refdb_backend *dir;
40 -
41 2167 2-4 assert(out && repo);
42 -
43 2167 5 *out = NULL;
44 -
45 2167 5,6 if (git_refdb_new(&db, repo) < 0)
46 ##### 7 return -1;
47 -
48 - /* Add the default (filesystem) backend */
49 2167 8,9 if (git_refdb_backend_fs(&dir, repo) < 0) {
50 ##### 10 git_refdb_free(db);
51 ##### 11 return -1;
52 - }
53 -
54 2167 12 db->repo = repo;
55 2167 12 db->backend = dir;
56 -
57 2167 12 *out = db;
58 2167 12 return 0;
59 - }
60 -
61 2168 2 static void refdb_free_backend(git_refdb *db)
62 - {
63 2168 2 if (db->backend)
64 2167 3 db->backend->free(db->backend);
65 2168 4 }
66 -
67 ##### 2 int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend)
68 - {
69 ##### 2-4 GIT_ERROR_CHECK_VERSION(backend, GIT_REFDB_BACKEND_VERSION, "git_refdb_backend");
70 -
71 ##### 5-8 if (!backend->exists || !backend->lookup || !backend->iterator ||
72 ##### 8-11 !backend->write || !backend->rename || !backend->del ||
73 ##### 11-14 !backend->has_log || !backend->ensure_log || !backend->free ||
74 ##### 14-16 !backend->reflog_read || !backend->reflog_write ||
75 ##### 16-18 !backend->reflog_rename || !backend->reflog_delete ||
76 ##### 18,19 (backend->lock && !backend->unlock)) {
77 ##### 20 git_error_set(GIT_ERROR_REFERENCE, "incomplete refdb backend implementation");
78 ##### 21 return GIT_EINVALID;
79 - }
80 -
81 ##### 22 refdb_free_backend(db);
82 ##### 23 db->backend = backend;
83 -
84 ##### 23 return 0;
85 - }
86 -
87 44 2 int git_refdb_compress(git_refdb *db)
88 - {
89 44 2,3 assert(db);
90 -
91 44 4 if (db->backend->compress)
92 44 5 return db->backend->compress(db->backend);
93 -
94 ##### 6 return 0;
95 - }
96 -
97 2168 2 void git_refdb__free(git_refdb *db)
98 - {
99 2168 2 refdb_free_backend(db);
100 2168 3 git__memzero(db, sizeof(*db));
101 2168 4 git__free(db);
102 2168 5 }
103 -
104 2218 2 void git_refdb_free(git_refdb *db)
105 - {
106 2218 2 if (db == NULL)
107 2218 3,8 return;
108 -
109 2218 4-7 GIT_REFCOUNT_DEC(db, git_refdb__free);
110 - }
111 -
112 ##### 2 int git_refdb_exists(int *exists, git_refdb *refdb, const char *ref_name)
113 - {
114 ##### 2-5 assert(exists && refdb && refdb->backend);
115 -
116 ##### 6 return refdb->backend->exists(exists, refdb->backend, ref_name);
117 - }
118 -
119 32654 2 int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name)
120 - {
121 - git_reference *ref;
122 - int error;
123 -
124 32654 2-6 assert(db && db->backend && out && ref_name);
125 -
126 32654 7 error = db->backend->lookup(&ref, db->backend, ref_name);
127 32655 8 if (error < 0)
128 12009 9 return error;
129 -
130 20646 10 GIT_REFCOUNT_INC(db);
131 20646 11 ref->db = db;
132 -
133 20646 11 *out = ref;
134 20646 11 return 0;
135 - }
136 -
137 488 2 int git_refdb_iterator(git_reference_iterator **out, git_refdb *db, const char *glob)
138 - {
139 - int error;
140 -
141 488 2,3 if (!db->backend || !db->backend->iterator) {
142 ##### 4 git_error_set(GIT_ERROR_REFERENCE, "this backend doesn't support iterators");
143 ##### 5 return -1;
144 - }
145 -
146 488 6,7 if ((error = db->backend->iterator(out, db->backend, glob)) < 0)
147 ##### 8 return error;
148 -
149 488 9 GIT_REFCOUNT_INC(db);
150 488 10 (*out)->db = db;
151 -
152 488 10 return 0;
153 - }
154 -
155 3087 2 int git_refdb_iterator_next(git_reference **out, git_reference_iterator *iter)
156 - {
157 - int error;
158 -
159 3087 2,3 if ((error = iter->next(out, iter)) < 0)
160 135 4 return error;
161 -
162 2921 5 GIT_REFCOUNT_INC(iter->db);
163 2972 6 (*out)->db = iter->db;
164 -
165 2972 6 return 0;
166 - }
167 -
168 4400 2 int git_refdb_iterator_next_name(const char **out, git_reference_iterator *iter)
169 - {
170 4400 2 return iter->next_name(out, iter);
171 - }
172 -
173 488 2 void git_refdb_iterator_free(git_reference_iterator *iter)
174 - {
175 488 2-5 GIT_REFCOUNT_DEC(iter->db, git_refdb__free);
176 488 6 iter->free(iter);
177 488 7 }
178 -
179 2226 2 int git_refdb_write(git_refdb *db, git_reference *ref, int force, const git_signature *who, const char *message, const git_oid *old_id, const char *old_target)
180 - {
181 2226 2-4 assert(db && db->backend);
182 -
183 2226 5 GIT_REFCOUNT_INC(db);
184 2226 6 ref->db = db;
185 -
186 2226 6 return db->backend->write(db->backend, ref, force, who, message, old_id, old_target);
187 - }
188 -
189 42 2 int git_refdb_rename(
190 - git_reference **out,
191 - git_refdb *db,
192 - const char *old_name,
193 - const char *new_name,
194 - int force,
195 - const git_signature *who,
196 - const char *message)
197 - {
198 - int error;
199 -
200 42 2-4 assert(db && db->backend);
201 42 5 error = db->backend->rename(out, db->backend, old_name, new_name, force, who, message);
202 42 6 if (error < 0)
203 5 7 return error;
204 -
205 37 8 if (out) {
206 37 9 GIT_REFCOUNT_INC(db);
207 37 10 (*out)->db = db;
208 - }
209 -
210 37 11 return 0;
211 - }
212 -
213 113 2 int git_refdb_delete(struct git_refdb *db, const char *ref_name, const git_oid *old_id, const char *old_target)
214 - {
215 113 2-4 assert(db && db->backend);
216 113 5 return db->backend->del(db->backend, ref_name, old_id, old_target);
217 - }
218 -
219 197 2 int git_refdb_reflog_read(git_reflog **out, git_refdb *db, const char *name)
220 - {
221 - int error;
222 -
223 197 2-4 assert(db && db->backend);
224 -
225 197 5,6 if ((error = db->backend->reflog_read(out, db->backend, name)) < 0)
226 ##### 7 return error;
227 -
228 197 8 GIT_REFCOUNT_INC(db);
229 197 9 (*out)->db = db;
230 -
231 197 9 return 0;
232 - }
233 -
234 8 2 int git_refdb_has_log(git_refdb *db, const char *refname)
235 - {
236 8 2-4 assert(db && refname);
237 -
238 8 5 return db->backend->has_log(db->backend, refname);
239 - }
240 -
241 61 2 int git_refdb_ensure_log(git_refdb *db, const char *refname)
242 - {
243 61 2-4 assert(db && refname);
244 -
245 61 5 return db->backend->ensure_log(db->backend, refname);
246 - }
247 -
248 2168 2 int git_refdb_init_backend(git_refdb_backend *backend, unsigned int version)
249 - {
250 2168 2-4 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
251 - backend, version, git_refdb_backend, GIT_REFDB_BACKEND_INIT);
252 2168 5 return 0;
253 - }
254 -
255 31 2 int git_refdb_lock(void **payload, git_refdb *db, const char *refname)
256 - {
257 31 2-5 assert(payload && db && refname);
258 -
259 31 6 if (!db->backend->lock) {
260 ##### 7 git_error_set(GIT_ERROR_REFERENCE, "backend does not support locking");
261 ##### 8 return -1;
262 - }
263 -
264 31 9 return db->backend->lock(payload, db->backend, refname);
265 - }
266 -
267 30 2 int git_refdb_unlock(git_refdb *db, void *payload, int success, int update_reflog, const git_reference *ref, const git_signature *sig, const char *message)
268 - {
269 30 2,3 assert(db);
270 -
271 30 4 return db->backend->unlock(db->backend, payload, success, update_reflog, ref, sig, message);
272 - }