File Coverage

deps/libgit2/src/refdb.c
Criterion Covered Total %
statement 91 126 72.2
branch 43 128 33.5
condition n/a
subroutine n/a
pod n/a
total 134 254 52.7


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