source src/refdb.c
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 | - | } |