summaryrefslogtreecommitdiffstats
path: root/include/git2/sys/refdb_backend.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/git2/sys/refdb_backend.h')
-rw-r--r--include/git2/sys/refdb_backend.h361
1 files changed, 361 insertions, 0 deletions
diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h
new file mode 100644
index 0000000..c31e26d
--- /dev/null
+++ b/include/git2/sys/refdb_backend.h
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_refdb_backend_h__
+#define INCLUDE_sys_git_refdb_backend_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+/**
+ * @file git2/refdb_backend.h
+ * @brief Git custom refs backend functions
+ * @defgroup git_refdb_backend Git custom refs backend API
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+
+/**
+ * Every backend's iterator must have a pointer to itself as the first
+ * element, so the API can talk to it. You'd define your iterator as
+ *
+ * struct my_iterator {
+ * git_reference_iterator parent;
+ * ...
+ * }
+ *
+ * and assign `iter->parent.backend` to your `git_refdb_backend`.
+ */
+struct git_reference_iterator {
+ git_refdb *db;
+
+ /**
+ * Return the current reference and advance the iterator.
+ */
+ int GIT_CALLBACK(next)(
+ git_reference **ref,
+ git_reference_iterator *iter);
+
+ /**
+ * Return the name of the current reference and advance the iterator
+ */
+ int GIT_CALLBACK(next_name)(
+ const char **ref_name,
+ git_reference_iterator *iter);
+
+ /**
+ * Free the iterator
+ */
+ void GIT_CALLBACK(free)(
+ git_reference_iterator *iter);
+};
+
+/** An instance for a custom backend */
+struct git_refdb_backend {
+ unsigned int version; /**< The backend API version */
+
+ /**
+ * Queries the refdb backend for the existence of a reference.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg exists The implementation shall set this to `0` if a ref does
+ * not exist, otherwise to `1`.
+ * @arg ref_name The reference's name that should be checked for
+ * existence.
+ * @return `0` on success, a negative error value code.
+ */
+ int GIT_CALLBACK(exists)(
+ int *exists,
+ git_refdb_backend *backend,
+ const char *ref_name);
+
+ /**
+ * Queries the refdb backend for a given reference.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg out The implementation shall set this to the allocated
+ * reference, if it could be found, otherwise to `NULL`.
+ * @arg ref_name The reference's name that should be checked for
+ * existence.
+ * @return `0` on success, `GIT_ENOTFOUND` if the reference does
+ * exist, otherwise a negative error code.
+ */
+ int GIT_CALLBACK(lookup)(
+ git_reference **out,
+ git_refdb_backend *backend,
+ const char *ref_name);
+
+ /**
+ * Allocate an iterator object for the backend.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg out The implementation shall set this to the allocated
+ * reference iterator. A custom structure may be used with an
+ * embedded `git_reference_iterator` structure. Both `next`
+ * and `next_name` functions of `git_reference_iterator` need
+ * to be populated.
+ * @arg glob A pattern to filter references by. If given, the iterator
+ * shall only return references that match the glob when
+ * passed to `wildmatch`.
+ * @return `0` on success, otherwise a negative error code.
+ */
+ int GIT_CALLBACK(iterator)(
+ git_reference_iterator **iter,
+ struct git_refdb_backend *backend,
+ const char *glob);
+
+ /**
+ * Writes the given reference to the refdb.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg ref The reference to persist. May either be a symbolic or
+ * direct reference.
+ * @arg force Whether to write the reference if a reference with the
+ * same name already exists.
+ * @arg who The person updating the reference. Shall be used to create
+ * a reflog entry.
+ * @arg message The message detailing what kind of reference update is
+ * performed. Shall be used to create a reflog entry.
+ * @arg old If not `NULL` and `force` is not set, then the
+ * implementation needs to ensure that the reference is currently at
+ * the given OID before writing the new value. If both `old`
+ * and `old_target` are `NULL`, then the reference should not
+ * exist at the point of writing.
+ * @arg old_target If not `NULL` and `force` is not set, then the
+ * implementation needs to ensure that the symbolic
+ * reference is currently at the given target before
+ * writing the new value. If both `old` and
+ * `old_target` are `NULL`, then the reference should
+ * not exist at the point of writing.
+ * @return `0` on success, otherwise a negative error code.
+ */
+ int GIT_CALLBACK(write)(git_refdb_backend *backend,
+ const git_reference *ref, int force,
+ const git_signature *who, const char *message,
+ const git_oid *old, const char *old_target);
+
+ /**
+ * Rename a reference in the refdb.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg out The implementation shall set this to the newly created
+ * reference or `NULL` on error.
+ * @arg old_name The current name of the reference that is to be renamed.
+ * @arg new_name The new name that the old reference shall be renamed to.
+ * @arg force Whether to write the reference if a reference with the
+ * target name already exists.
+ * @arg who The person updating the reference. Shall be used to create
+ * a reflog entry.
+ * @arg message The message detailing what kind of reference update is
+ * performed. Shall be used to create a reflog entry.
+ * @return `0` on success, otherwise a negative error code.
+ */
+ int GIT_CALLBACK(rename)(
+ git_reference **out, git_refdb_backend *backend,
+ const char *old_name, const char *new_name, int force,
+ const git_signature *who, const char *message);
+
+ /**
+ * Deletes the given reference from the refdb.
+ *
+ * If it exists, its reflog should be deleted as well.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg ref_name The name of the reference name that shall be deleted.
+ * @arg old_id If not `NULL` and `force` is not set, then the
+ * implementation needs to ensure that the reference is currently at
+ * the given OID before writing the new value.
+ * @arg old_target If not `NULL` and `force` is not set, then the
+ * implementation needs to ensure that the symbolic
+ * reference is currently at the given target before
+ * writing the new value.
+ * @return `0` on success, otherwise a negative error code.
+ */
+ int GIT_CALLBACK(del)(git_refdb_backend *backend, const char *ref_name, const git_oid *old_id, const char *old_target);
+
+ /**
+ * Suggests that the given refdb compress or optimize its references.
+ *
+ * This mechanism is implementation specific. For on-disk reference
+ * databases, this may pack all loose references.
+ *
+ * A refdb implementation may provide this function; if it is not
+ * provided, nothing will be done.
+ *
+ * @return `0` on success a negative error code otherwise
+ */
+ int GIT_CALLBACK(compress)(git_refdb_backend *backend);
+
+ /**
+ * Query whether a particular reference has a log (may be empty)
+ *
+ * Shall return 1 if it has a reflog, 0 it it doesn't and negative in
+ * case an error occurred.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @return `0` on success, `1` if the reflog for the given reference
+ * exists, a negative error code otherwise
+ */
+ int GIT_CALLBACK(has_log)(git_refdb_backend *backend, const char *refname);
+
+ /**
+ * Make sure a particular reference will have a reflog which
+ * will be appended to on writes.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(ensure_log)(git_refdb_backend *backend, const char *refname);
+
+ /**
+ * Frees any resources held by the refdb (including the `git_refdb_backend`
+ * itself).
+ *
+ * A refdb backend implementation must provide this function.
+ */
+ void GIT_CALLBACK(free)(git_refdb_backend *backend);
+
+ /**
+ * Read the reflog for the given reference name.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(reflog_read)(git_reflog **out, git_refdb_backend *backend, const char *name);
+
+ /**
+ * Write a reflog to disk.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg reflog The complete reference log for a given reference. Note
+ * that this may contain entries that have already been
+ * written to disk.
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(reflog_write)(git_refdb_backend *backend, git_reflog *reflog);
+
+ /**
+ * Rename a reflog.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg old_name The name of old reference whose reflog shall be renamed from.
+ * @arg new_name The name of new reference whose reflog shall be renamed to.
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(reflog_rename)(git_refdb_backend *_backend, const char *old_name, const char *new_name);
+
+ /**
+ * Remove a reflog.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg name The name of the reference whose reflog shall be deleted.
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(reflog_delete)(git_refdb_backend *backend, const char *name);
+
+ /**
+ * Lock a reference.
+ *
+ * A refdb implementation may provide this function; if it is not
+ * provided, the transaction API will fail to work.
+ *
+ * @arg payload_out Opaque parameter that will be passed verbosely to
+ * `unlock`.
+ * @arg refname Reference that shall be locked.
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(lock)(void **payload_out, git_refdb_backend *backend, const char *refname);
+
+ /**
+ * Unlock a reference.
+ *
+ * Only one of target or symbolic_target will be set.
+ * `success` will be true if the reference should be update, false if
+ * the lock must be discarded.
+ *
+ * A refdb implementation must provide this function if a `lock`
+ * implementation is provided.
+ *
+ * @arg payload The payload returned by `lock`.
+ * @arg success `1` if a reference should be updated, `2` if
+ * a reference should be deleted, `0` if the lock must be
+ * discarded.
+ * @arg update_reflog `1` in case the reflog should be updated, `0`
+ * otherwise.
+ * @arg ref The reference which should be unlocked.
+ * @arg who The person updating the reference. Shall be used to create
+ * a reflog entry in case `update_reflog` is set.
+ * @arg message The message detailing what kind of reference update is
+ * performed. Shall be used to create a reflog entry in
+ * case `update_reflog` is set.
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(unlock)(git_refdb_backend *backend, void *payload, int success, int update_reflog,
+ const git_reference *ref, const git_signature *sig, const char *message);
+};
+
+#define GIT_REFDB_BACKEND_VERSION 1
+#define GIT_REFDB_BACKEND_INIT {GIT_REFDB_BACKEND_VERSION}
+
+/**
+ * Initializes a `git_refdb_backend` with default values. Equivalent to
+ * creating an instance with GIT_REFDB_BACKEND_INIT.
+ *
+ * @param backend the `git_refdb_backend` struct to initialize
+ * @param version Version of struct; pass `GIT_REFDB_BACKEND_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_refdb_init_backend(
+ git_refdb_backend *backend,
+ unsigned int version);
+
+/**
+ * Constructors for default filesystem-based refdb backend
+ *
+ * Under normal usage, this is called for you when the repository is
+ * opened / created, but you can use this to explicitly construct a
+ * filesystem refdb backend for a repository.
+ *
+ * @param backend_out Output pointer to the git_refdb_backend object
+ * @param repo Git repository to access
+ * @return 0 on success, <0 error code on failure
+ */
+GIT_EXTERN(int) git_refdb_backend_fs(
+ git_refdb_backend **backend_out,
+ git_repository *repo);
+
+/**
+ * Sets the custom backend to an existing reference DB
+ *
+ * The `git_refdb` will take ownership of the `git_refdb_backend` so you
+ * should NOT free it after calling this function.
+ *
+ * @param refdb database to add the backend to
+ * @param backend pointer to a git_refdb_backend instance
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_refdb_set_backend(
+ git_refdb *refdb,
+ git_refdb_backend *backend);
+
+GIT_END_DECL
+
+#endif