]> git.proxmox.com Git - libgit2.git/blame - src/refdb.c
treebuilder: fix memory leaks in `write_with_buffer`
[libgit2.git] / src / refdb.c
CommitLineData
d00d5464
ET
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 "common.h"
9#include "posix.h"
4dcd8780 10
d00d5464
ET
11#include "git2/object.h"
12#include "git2/refs.h"
13#include "git2/refdb.h"
4dcd8780
RB
14#include "git2/sys/refdb_backend.h"
15
d00d5464
ET
16#include "hash.h"
17#include "refdb.h"
18#include "refs.h"
b976f3c2 19#include "reflog.h"
d00d5464 20
d00d5464
ET
21int git_refdb_new(git_refdb **out, git_repository *repo)
22{
23 git_refdb *db;
24
25 assert(out && repo);
26
27 db = git__calloc(1, sizeof(*db));
28 GITERR_CHECK_ALLOC(db);
29
30 db->repo = repo;
31
32 *out = db;
33 GIT_REFCOUNT_INC(db);
34 return 0;
35}
36
37int git_refdb_open(git_refdb **out, git_repository *repo)
38{
39 git_refdb *db;
40 git_refdb_backend *dir;
41
42 assert(out && repo);
43
44 *out = NULL;
45
46 if (git_refdb_new(&db, repo) < 0)
47 return -1;
48
49 /* Add the default (filesystem) backend */
4e4eab52 50 if (git_refdb_backend_fs(&dir, repo) < 0) {
d00d5464
ET
51 git_refdb_free(db);
52 return -1;
53 }
54
55 db->repo = repo;
56 db->backend = dir;
57
58 *out = db;
59 return 0;
60}
61
21ca0451 62static void refdb_free_backend(git_refdb *db)
d00d5464 63{
d3b29fb9
AS
64 if (db->backend)
65 db->backend->free(db->backend);
21ca0451 66}
d00d5464 67
21ca0451
RB
68int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend)
69{
70 refdb_free_backend(db);
d00d5464
ET
71 db->backend = backend;
72
73 return 0;
74}
75
76int git_refdb_compress(git_refdb *db)
77{
78 assert(db);
4dcd8780 79
21ca0451 80 if (db->backend->compress)
d00d5464 81 return db->backend->compress(db->backend);
4dcd8780 82
d00d5464
ET
83 return 0;
84}
85
979f75d8 86void git_refdb__free(git_refdb *db)
d00d5464 87{
21ca0451 88 refdb_free_backend(db);
6de9b2ee 89 git__memzero(db, sizeof(*db));
d00d5464
ET
90 git__free(db);
91}
92
7ebc249c
ET
93void git_refdb_free(git_refdb *db)
94{
95 if (db == NULL)
96 return;
97
979f75d8 98 GIT_REFCOUNT_DEC(db, git_refdb__free);
7ebc249c
ET
99}
100
d00d5464
ET
101int git_refdb_exists(int *exists, git_refdb *refdb, const char *ref_name)
102{
103 assert(exists && refdb && refdb->backend);
104
105 return refdb->backend->exists(exists, refdb->backend, ref_name);
106}
107
108int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name)
109{
4e4eab52
ET
110 git_reference *ref;
111 int error;
112
21ca0451 113 assert(db && db->backend && out && ref_name);
4e4eab52 114
ec24e542
VM
115 error = db->backend->lookup(&ref, db->backend, ref_name);
116 if (error < 0)
117 return error;
118
119 GIT_REFCOUNT_INC(db);
120 ref->db = db;
4e4eab52 121
ec24e542
VM
122 *out = ref;
123 return 0;
d00d5464
ET
124}
125
ec24e542 126int git_refdb_iterator(git_reference_iterator **out, git_refdb *db, const char *glob)
4def7035 127{
ce5553d4
CMN
128 int error;
129
51fc5e89 130 if (!db->backend || !db->backend->iterator) {
909d5494 131 giterr_set(GITERR_REFERENCE, "this backend doesn't support iterators");
51fc5e89
CMN
132 return -1;
133 }
134
ce5553d4
CMN
135 if ((error = db->backend->iterator(out, db->backend, glob)) < 0)
136 return error;
c58cac12 137
ec24e542
VM
138 GIT_REFCOUNT_INC(db);
139 (*out)->db = db;
140
c58cac12
CMN
141 return 0;
142}
143
ec24e542 144int git_refdb_iterator_next(git_reference **out, git_reference_iterator *iter)
c58cac12 145{
ec24e542 146 int error;
c58cac12 147
ec24e542
VM
148 if ((error = iter->next(out, iter)) < 0)
149 return error;
c58cac12 150
ec24e542
VM
151 GIT_REFCOUNT_INC(iter->db);
152 (*out)->db = iter->db;
4def7035 153
4def7035
CMN
154 return 0;
155}
156
ec24e542 157int git_refdb_iterator_next_name(const char **out, git_reference_iterator *iter)
4def7035 158{
ec24e542 159 return iter->next_name(out, iter);
4def7035
CMN
160}
161
162void git_refdb_iterator_free(git_reference_iterator *iter)
163{
979f75d8 164 GIT_REFCOUNT_DEC(iter->db, git_refdb__free);
ec24e542 165 iter->free(iter);
4def7035
CMN
166}
167
91123661 168int 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)
d00d5464
ET
169{
170 assert(db && db->backend);
4e6e2ff2
VM
171
172 GIT_REFCOUNT_INC(db);
173 ref->db = db;
174
91123661 175 return db->backend->write(db->backend, ref, force, who, message, old_id, old_target);
4e6e2ff2
VM
176}
177
178int git_refdb_rename(
179 git_reference **out,
180 git_refdb *db,
181 const char *old_name,
182 const char *new_name,
110df893 183 int force,
a57dd3b7 184 const git_signature *who,
110df893 185 const char *message)
4e6e2ff2
VM
186{
187 int error;
188
189 assert(db && db->backend);
a57dd3b7 190 error = db->backend->rename(out, db->backend, old_name, new_name, force, who, message);
4e6e2ff2
VM
191 if (error < 0)
192 return error;
193
194 if (out) {
195 GIT_REFCOUNT_INC(db);
196 (*out)->db = db;
197 }
198
199 return 0;
d00d5464
ET
200}
201
7ee8c7e6 202int git_refdb_delete(struct git_refdb *db, const char *ref_name, const git_oid *old_id, const char *old_target)
d00d5464
ET
203{
204 assert(db && db->backend);
7ee8c7e6 205 return db->backend->del(db->backend, ref_name, old_id, old_target);
d00d5464 206}
b976f3c2
CMN
207
208int git_refdb_reflog_read(git_reflog **out, git_refdb *db, const char *name)
209{
210 int error;
211
212 assert(db && db->backend);
213
214 if ((error = db->backend->reflog_read(out, db->backend, name)) < 0)
215 return error;
216
217 GIT_REFCOUNT_INC(db);
218 (*out)->db = db;
219
220 return 0;
221}
8d5ec910 222
f2105129
CMN
223int git_refdb_has_log(git_refdb *db, const char *refname)
224{
225 assert(db && refname);
226
227 return db->backend->has_log(db->backend, refname);
228}
229
8d5ec910
CMN
230int git_refdb_ensure_log(git_refdb *db, const char *refname)
231{
232 assert(db && refname);
233
234 return db->backend->ensure_log(db->backend, refname);
235}
b9f81997 236
bc91347b 237int git_refdb_init_backend(git_refdb_backend *backend, unsigned int version)
b9f81997 238{
bc91347b
RB
239 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
240 backend, version, git_refdb_backend, GIT_REFDB_BACKEND_INIT);
241 return 0;
b9f81997 242}
ab8d9242
CMN
243
244int git_refdb_lock(void **payload, git_refdb *db, const char *refname)
245{
246 assert(payload && db && refname);
247
248 if (!db->backend->lock) {
249 giterr_set(GITERR_REFERENCE, "backend does not support locking");
250 return -1;
251 }
252
253 return db->backend->lock(payload, db->backend, refname);
254}
255
256int git_refdb_unlock(git_refdb *db, void *payload, int success, int update_reflog, const git_reference *ref, const git_signature *sig, const char *message)
257{
258 assert(db);
259
260 return db->backend->unlock(db->backend, payload, success, update_reflog, ref, sig, message);
261}