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 #ifndef INCLUDE_sys_git_refdb_backend_h__ 8 #define INCLUDE_sys_git_refdb_backend_h__ 9 10 #include "git2/common.h" 11 #include "git2/types.h" 12 #include "git2/oid.h" 13 14 /** 15 * @file git2/refdb_backend.h 16 * @brief Git custom refs backend functions 17 * @defgroup git_refdb_backend Git custom refs backend API 18 * @ingroup Git 19 * @{ 20 */ 21 GIT_BEGIN_DECL 22 23 24 /** 25 * Every backend's iterator must have a pointer to itself as the first 26 * element, so the API can talk to it. You'd define your iterator as 27 * 28 * struct my_iterator { 29 * git_reference_iterator parent; 30 * ... 31 * } 32 * 33 * and assign `iter->parent.backend` to your `git_refdb_backend`. 34 */ 35 struct git_reference_iterator { 36 git_refdb *db; 37 38 /** 39 * Return the current reference and advance the iterator. 40 */ 41 int GIT_CALLBACK(next)( 42 git_reference **ref, 43 git_reference_iterator *iter); 44 45 /** 46 * Return the name of the current reference and advance the iterator 47 */ 48 int GIT_CALLBACK(next_name)( 49 const char **ref_name, 50 git_reference_iterator *iter); 51 52 /** 53 * Free the iterator 54 */ 55 void GIT_CALLBACK(free)( 56 git_reference_iterator *iter); 57 }; 58 59 /** An instance for a custom backend */ 60 struct git_refdb_backend { 61 unsigned int version; /**< The backend API version */ 62 63 /** 64 * Queries the refdb backend for the existence of a reference. 65 * 66 * A refdb implementation must provide this function. 67 * 68 * @arg exists The implementation shall set this to `0` if a ref does 69 * not exist, otherwise to `1`. 70 * @arg ref_name The reference's name that should be checked for 71 * existence. 72 * @return `0` on success, a negative error value code. 73 */ 74 int GIT_CALLBACK(exists)( 75 int *exists, 76 git_refdb_backend *backend, 77 const char *ref_name); 78 79 /** 80 * Queries the refdb backend for a given reference. 81 * 82 * A refdb implementation must provide this function. 83 * 84 * @arg out The implementation shall set this to the allocated 85 * reference, if it could be found, otherwise to `NULL`. 86 * @arg ref_name The reference's name that should be checked for 87 * existence. 88 * @return `0` on success, `GIT_ENOTFOUND` if the reference does 89 * exist, otherwise a negative error code. 90 */ 91 int GIT_CALLBACK(lookup)( 92 git_reference **out, 93 git_refdb_backend *backend, 94 const char *ref_name); 95 96 /** 97 * Allocate an iterator object for the backend. 98 * 99 * A refdb implementation must provide this function. 100 * 101 * @arg out The implementation shall set this to the allocated 102 * reference iterator. A custom structure may be used with an 103 * embedded `git_reference_iterator` structure. Both `next` 104 * and `next_name` functions of `git_reference_iterator` need 105 * to be populated. 106 * @arg glob A pattern to filter references by. If given, the iterator 107 * shall only return references that match the glob when 108 * passed to `wildmatch`. 109 * @return `0` on success, otherwise a negative error code. 110 */ 111 int GIT_CALLBACK(iterator)( 112 git_reference_iterator **iter, 113 struct git_refdb_backend *backend, 114 const char *glob); 115 116 /** 117 * Writes the given reference to the refdb. 118 * 119 * A refdb implementation must provide this function. 120 * 121 * @arg ref The reference to persist. May either be a symbolic or 122 * direct reference. 123 * @arg force Whether to write the reference if a reference with the 124 * same name already exists. 125 * @arg who The person updating the reference. Shall be used to create 126 * a reflog entry. 127 * @arg message The message detailing what kind of reference update is 128 * performed. Shall be used to create a reflog entry. 129 * @arg old If not `NULL` and `force` is not set, then the 130 * implementation needs to ensure that the reference is currently at 131 * the given OID before writing the new value. If both `old` 132 * and `old_target` are `NULL`, then the reference should not 133 * exist at the point of writing. 134 * @arg old_target If not `NULL` and `force` is not set, then the 135 * implementation needs to ensure that the symbolic 136 * reference is currently at the given target before 137 * writing the new value. If both `old` and 138 * `old_target` are `NULL`, then the reference should 139 * not exist at the point of writing. 140 * @return `0` on success, otherwise a negative error code. 141 */ 142 int GIT_CALLBACK(write)(git_refdb_backend *backend, 143 const git_reference *ref, int force, 144 const git_signature *who, const char *message, 145 const git_oid *old, const char *old_target); 146 147 /** 148 * Rename a reference in the refdb. 149 * 150 * A refdb implementation must provide this function. 151 * 152 * @arg out The implementation shall set this to the newly created 153 * reference or `NULL` on error. 154 * @arg old_name The current name of the reference that is to be renamed. 155 * @arg new_name The new name that the old reference shall be renamed to. 156 * @arg force Whether to write the reference if a reference with the 157 * target name already exists. 158 * @arg who The person updating the reference. Shall be used to create 159 * a reflog entry. 160 * @arg message The message detailing what kind of reference update is 161 * performed. Shall be used to create a reflog entry. 162 * @return `0` on success, otherwise a negative error code. 163 */ 164 int GIT_CALLBACK(rename)( 165 git_reference **out, git_refdb_backend *backend, 166 const char *old_name, const char *new_name, int force, 167 const git_signature *who, const char *message); 168 169 /** 170 * Deletes the given reference from the refdb. 171 * 172 * If it exists, its reflog should be deleted as well. 173 * 174 * A refdb implementation must provide this function. 175 * 176 * @arg ref_name The name of the reference name that shall be deleted. 177 * @arg old_id If not `NULL` and `force` is not set, then the 178 * implementation needs to ensure that the reference is currently at 179 * the given OID before writing the new value. 180 * @arg old_target If not `NULL` and `force` is not set, then the 181 * implementation needs to ensure that the symbolic 182 * reference is currently at the given target before 183 * writing the new value. 184 * @return `0` on success, otherwise a negative error code. 185 */ 186 int GIT_CALLBACK(del)(git_refdb_backend *backend, const char *ref_name, const git_oid *old_id, const char *old_target); 187 188 /** 189 * Suggests that the given refdb compress or optimize its references. 190 * 191 * This mechanism is implementation specific. For on-disk reference 192 * databases, this may pack all loose references. 193 * 194 * A refdb implementation may provide this function; if it is not 195 * provided, nothing will be done. 196 * 197 * @return `0` on success a negative error code otherwise 198 */ 199 int GIT_CALLBACK(compress)(git_refdb_backend *backend); 200 201 /** 202 * Query whether a particular reference has a log (may be empty) 203 * 204 * Shall return 1 if it has a reflog, 0 it it doesn't and negative in 205 * case an error occurred. 206 * 207 * A refdb implementation must provide this function. 208 * 209 * @return `0` on success, `1` if the reflog for the given reference 210 * exists, a negative error code otherwise 211 */ 212 int GIT_CALLBACK(has_log)(git_refdb_backend *backend, const char *refname); 213 214 /** 215 * Make sure a particular reference will have a reflog which 216 * will be appended to on writes. 217 * 218 * A refdb implementation must provide this function. 219 * 220 * @return `0` on success, a negative error code otherwise 221 */ 222 int GIT_CALLBACK(ensure_log)(git_refdb_backend *backend, const char *refname); 223 224 /** 225 * Frees any resources held by the refdb (including the `git_refdb_backend` 226 * itself). 227 * 228 * A refdb backend implementation must provide this function. 229 */ 230 void GIT_CALLBACK(free)(git_refdb_backend *backend); 231 232 /** 233 * Read the reflog for the given reference name. 234 * 235 * A refdb implementation must provide this function. 236 * 237 * @return `0` on success, a negative error code otherwise 238 */ 239 int GIT_CALLBACK(reflog_read)(git_reflog **out, git_refdb_backend *backend, const char *name); 240 241 /** 242 * Write a reflog to disk. 243 * 244 * A refdb implementation must provide this function. 245 * 246 * @arg reflog The complete reference log for a given reference. Note 247 * that this may contain entries that have already been 248 * written to disk. 249 * @return `0` on success, a negative error code otherwise 250 */ 251 int GIT_CALLBACK(reflog_write)(git_refdb_backend *backend, git_reflog *reflog); 252 253 /** 254 * Rename a reflog. 255 * 256 * A refdb implementation must provide this function. 257 * 258 * @arg old_name The name of old reference whose reflog shall be renamed from. 259 * @arg new_name The name of new reference whose reflog shall be renamed to. 260 * @return `0` on success, a negative error code otherwise 261 */ 262 int GIT_CALLBACK(reflog_rename)(git_refdb_backend *_backend, const char *old_name, const char *new_name); 263 264 /** 265 * Remove a reflog. 266 * 267 * A refdb implementation must provide this function. 268 * 269 * @arg name The name of the reference whose reflog shall be deleted. 270 * @return `0` on success, a negative error code otherwise 271 */ 272 int GIT_CALLBACK(reflog_delete)(git_refdb_backend *backend, const char *name); 273 274 /** 275 * Lock a reference. 276 * 277 * A refdb implementation may provide this function; if it is not 278 * provided, the transaction API will fail to work. 279 * 280 * @arg payload_out Opaque parameter that will be passed verbosely to 281 * `unlock`. 282 * @arg refname Reference that shall be locked. 283 * @return `0` on success, a negative error code otherwise 284 */ 285 int GIT_CALLBACK(lock)(void **payload_out, git_refdb_backend *backend, const char *refname); 286 287 /** 288 * Unlock a reference. 289 * 290 * Only one of target or symbolic_target will be set. 291 * `success` will be true if the reference should be update, false if 292 * the lock must be discarded. 293 * 294 * A refdb implementation must provide this function if a `lock` 295 * implementation is provided. 296 * 297 * @arg payload The payload returned by `lock`. 298 * @arg success `1` if a reference should be updated, `2` if 299 * a reference should be deleted, `0` if the lock must be 300 * discarded. 301 * @arg update_reflog `1` in case the reflog should be updated, `0` 302 * otherwise. 303 * @arg ref The reference which should be unlocked. 304 * @arg who The person updating the reference. Shall be used to create 305 * a reflog entry in case `update_reflog` is set. 306 * @arg message The message detailing what kind of reference update is 307 * performed. Shall be used to create a reflog entry in 308 * case `update_reflog` is set. 309 * @return `0` on success, a negative error code otherwise 310 */ 311 int GIT_CALLBACK(unlock)(git_refdb_backend *backend, void *payload, int success, int update_reflog, 312 const git_reference *ref, const git_signature *sig, const char *message); 313 }; 314 315 #define GIT_REFDB_BACKEND_VERSION 1 316 #define GIT_REFDB_BACKEND_INIT {GIT_REFDB_BACKEND_VERSION} 317 318 /** 319 * Initializes a `git_refdb_backend` with default values. Equivalent to 320 * creating an instance with GIT_REFDB_BACKEND_INIT. 321 * 322 * @param backend the `git_refdb_backend` struct to initialize 323 * @param version Version of struct; pass `GIT_REFDB_BACKEND_VERSION` 324 * @return Zero on success; -1 on failure. 325 */ 326 GIT_EXTERN(int) git_refdb_init_backend( 327 git_refdb_backend *backend, 328 unsigned int version); 329 330 /** 331 * Constructors for default filesystem-based refdb backend 332 * 333 * Under normal usage, this is called for you when the repository is 334 * opened / created, but you can use this to explicitly construct a 335 * filesystem refdb backend for a repository. 336 * 337 * @param backend_out Output pointer to the git_refdb_backend object 338 * @param repo Git repository to access 339 * @return 0 on success, <0 error code on failure 340 */ 341 GIT_EXTERN(int) git_refdb_backend_fs( 342 git_refdb_backend **backend_out, 343 git_repository *repo); 344 345 /** 346 * Sets the custom backend to an existing reference DB 347 * 348 * The `git_refdb` will take ownership of the `git_refdb_backend` so you 349 * should NOT free it after calling this function. 350 * 351 * @param refdb database to add the backend to 352 * @param backend pointer to a git_refdb_backend instance 353 * @return 0 on success; error code otherwise 354 */ 355 GIT_EXTERN(int) git_refdb_set_backend( 356 git_refdb *refdb, 357 git_refdb_backend *backend); 358 359 GIT_END_DECL 360 361 #endif 362