summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2013-03-01 15:37:33 -0600
committerEdward Thomson <ethomson@edwardthomson.com>2013-03-07 11:01:52 -0600
commitd00d54645d931c77a9b401518c0d73e3f640454b (patch)
treee1932dcc97172a53524e9db1ba4923cf137a4f9c /include
parent6a9ef012376e8a21dcfd0499ab16048eb6e954c3 (diff)
downloadlibgit2-d00d54645d931c77a9b401518c0d73e3f640454b.tar.gz
immutable references and a pluggable ref database
Diffstat (limited to 'include')
-rw-r--r--include/git2/branch.h48
-rw-r--r--include/git2/refdb.h98
-rw-r--r--include/git2/refdb_backend.h109
-rw-r--r--include/git2/refs.h67
-rw-r--r--include/git2/repository.h33
-rw-r--r--include/git2/types.h10
6 files changed, 300 insertions, 65 deletions
diff --git a/include/git2/branch.h b/include/git2/branch.h
index d372c2c92..4d24e2d82 100644
--- a/include/git2/branch.h
+++ b/include/git2/branch.h
@@ -50,11 +50,11 @@ GIT_BEGIN_DECL
* pointing to the provided target commit.
*/
GIT_EXTERN(int) git_branch_create(
- git_reference **out,
- git_repository *repo,
- const char *branch_name,
- const git_commit *target,
- int force);
+ git_reference **out,
+ git_repository *repo,
+ const char *branch_name,
+ const git_commit *target,
+ int force);
/**
* Delete an existing branch reference.
@@ -67,6 +67,11 @@ GIT_EXTERN(int) git_branch_create(
*/
GIT_EXTERN(int) git_branch_delete(git_reference *branch);
+typedef int (*git_branch_foreach_cb)(
+ const char *branch_name,
+ git_branch_t branch_type,
+ void *payload);
+
/**
* Loop over all the branches and issue a callback for each one.
*
@@ -85,14 +90,10 @@ GIT_EXTERN(int) git_branch_delete(git_reference *branch);
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_branch_foreach(
- git_repository *repo,
- unsigned int list_flags,
- int (*branch_cb)(
- const char *branch_name,
- git_branch_t branch_type,
- void *payload),
- void *payload
-);
+ git_repository *repo,
+ unsigned int list_flags,
+ git_branch_foreach_cb branch_cb,
+ void *payload);
/**
* Move/rename an existing local branch reference.
@@ -110,9 +111,10 @@ GIT_EXTERN(int) git_branch_foreach(
* @return 0 on success, GIT_EINVALIDSPEC or an error code.
*/
GIT_EXTERN(int) git_branch_move(
- git_reference *branch,
- const char *new_branch_name,
- int force);
+ git_reference **out,
+ git_reference *branch,
+ const char *new_branch_name,
+ int force);
/**
* Lookup a branch by its name in a repository.
@@ -136,10 +138,10 @@ GIT_EXTERN(int) git_branch_move(
* exists, GIT_EINVALIDSPEC, otherwise an error code.
*/
GIT_EXTERN(int) git_branch_lookup(
- git_reference **out,
- git_repository *repo,
- const char *branch_name,
- git_branch_t branch_type);
+ git_reference **out,
+ git_repository *repo,
+ const char *branch_name,
+ git_branch_t branch_type);
/**
* Return the name of the given local or remote branch.
@@ -172,8 +174,8 @@ GIT_EXTERN(int) git_branch_name(const char **out,
* reference exists, otherwise an error code.
*/
GIT_EXTERN(int) git_branch_tracking(
- git_reference **out,
- git_reference *branch);
+ git_reference **out,
+ git_reference *branch);
/**
* Return the name of the reference supporting the remote tracking branch,
@@ -208,7 +210,7 @@ GIT_EXTERN(int) git_branch_tracking_name(
* error code otherwise.
*/
GIT_EXTERN(int) git_branch_is_head(
- git_reference *branch);
+ git_reference *branch);
/**
* Return the name of remote that the remote tracking branch belongs to.
diff --git a/include/git2/refdb.h b/include/git2/refdb.h
new file mode 100644
index 000000000..8d5be8e47
--- /dev/null
+++ b/include/git2/refdb.h
@@ -0,0 +1,98 @@
+/*
+ * 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_git_refdb_h__
+#define INCLUDE_git_refdb_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "refs.h"
+
+/**
+ * @file git2/refdb.h
+ * @brief Git custom refs backend functions
+ * @defgroup git_refdb Git custom refs backend API
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new reference. Either an oid or a symbolic target must be
+ * specified.
+ *
+ * @param refdb the reference database to associate with this reference
+ * @param name the reference name
+ * @param oid the object id for a direct reference
+ * @param symbolic the target for a symbolic reference
+ * @return the created git_reference or NULL on error
+ */
+git_reference *git_reference__alloc(
+ git_refdb *refdb,
+ const char *name,
+ const git_oid *oid,
+ const char *symbolic);
+
+/**
+ * Create a new reference database with no backends.
+ *
+ * Before the Ref DB can be used for read/writing, a custom database
+ * backend must be manually set using `git_refdb_set_backend()`
+ *
+ * @param out location to store the database pointer, if opened.
+ * Set to NULL if the open failed.
+ * @param repo the repository
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_refdb_new(git_refdb **out, git_repository *repo);
+
+/**
+ * Create a new reference database and automatically add
+ * the default backends:
+ *
+ * - git_refdb_dir: read and write loose and packed refs
+ * from disk, assuming the repository dir as the folder
+ *
+ * @param out location to store the database pointer, if opened.
+ * Set to NULL if the open failed.
+ * @param repo the repository
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_refdb_open(git_refdb **out, git_repository *repo);
+
+/**
+ * Suggests that the given refdb compress or optimize its references.
+ * This mechanism is implementation specific. For on-disk reference
+ * databases, for example, this may pack all loose references.
+ */
+GIT_EXTERN(int) git_refdb_compress(git_refdb *refdb);
+
+/**
+ * Close an open reference database.
+ *
+ * @param refdb reference database pointer or NULL
+ */
+GIT_EXTERN(void) git_refdb_free(git_refdb *refdb);
+
+/**
+ * Sets the custom backend to an existing reference DB
+ *
+ * Read <refdb_backends.h> for more information.
+ *
+ * @param refdb database to add the backend to
+ * @param backend pointer to a git_refdb_backend instance
+ * @param priority Value for ordering the backends queue
+ * @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
diff --git a/include/git2/refdb_backend.h b/include/git2/refdb_backend.h
new file mode 100644
index 000000000..bf33817d6
--- /dev/null
+++ b/include/git2/refdb_backend.h
@@ -0,0 +1,109 @@
+/*
+ * 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_git_refdb_backend_h__
+#define INCLUDE_git_refdb_backend_h__
+
+#include "common.h"
+#include "types.h"
+#include "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
+
+/** An instance for a custom backend */
+struct git_refdb_backend {
+ unsigned int version;
+
+ /**
+ * Queries the refdb backend to determine if the given ref_name
+ * exists. A refdb implementation must provide this function.
+ */
+ int (*exists)(
+ int *exists,
+ struct git_refdb_backend *backend,
+ const char *ref_name);
+
+ /**
+ * Queries the refdb backend for a given reference. A refdb
+ * implementation must provide this function.
+ */
+ int (*lookup)(
+ git_reference **out,
+ struct git_refdb_backend *backend,
+ const char *ref_name);
+
+ /**
+ * Enumerates each reference in the refdb. A refdb implementation must
+ * provide this function.
+ */
+ int (*foreach)(
+ struct git_refdb_backend *backend,
+ unsigned int list_flags,
+ git_reference_foreach_cb callback,
+ void *payload);
+
+ /**
+ * Enumerates each reference in the refdb that matches the given
+ * glob string. A refdb implementation may provide this function;
+ * if it is not provided, foreach will be used and the results filtered
+ * against the glob.
+ */
+ int (*foreach_glob)(
+ struct git_refdb_backend *backend,
+ const char *glob,
+ unsigned int list_flags,
+ git_reference_foreach_cb callback,
+ void *payload);
+
+ /**
+ * Writes the given reference to the refdb. A refdb implementation
+ * must provide this function.
+ */
+ int (*write)(struct git_refdb_backend *backend, const git_reference *ref);
+
+ /**
+ * Deletes the given reference from the refdb. A refdb implementation
+ * must provide this function.
+ */
+ int (*delete)(struct git_refdb_backend *backend, const git_reference *ref);
+
+ /**
+ * 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.
+ */
+ int (*compress)(struct git_refdb_backend *backend);
+
+ /**
+ * Frees any resources held by the refdb. A refdb implementation may
+ * provide this function; if it is not provided, nothing will be done.
+ */
+ void (*free)(struct git_refdb_backend *backend);
+};
+
+#define GIT_ODB_BACKEND_VERSION 1
+#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
+
+/**
+ * Constructors for default refdb backends.
+ */
+GIT_EXTERN(int) git_refdb_backend_fs(
+ struct git_refdb_backend **backend_out,
+ git_repository *repo,
+ git_refdb *refdb);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/refs.h b/include/git2/refs.h
index d586917c2..2373bee77 100644
--- a/include/git2/refs.h
+++ b/include/git2/refs.h
@@ -189,33 +189,41 @@ GIT_EXTERN(int) git_reference_resolve(git_reference **out, const git_reference *
GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref);
/**
- * Set the symbolic target of a reference.
+ * Create a new reference with the same name as the given reference but a
+ * different symbolic target. The reference must be a symbolic reference,
+ * otherwise this will fail.
*
- * The reference must be a symbolic reference, otherwise this will fail.
- *
- * The reference will be automatically updated in memory and on disk.
+ * The new reference will be written to disk, overwriting the given reference.
*
* The target name will be checked for validity.
* See `git_reference_create_symbolic()` for rules about valid names.
*
+ * @param out Pointer to the newly created reference
* @param ref The reference
* @param target The new target for the reference
* @return 0 on success, EINVALIDSPEC or an error code
*/
-GIT_EXTERN(int) git_reference_symbolic_set_target(git_reference *ref, const char *target);
+GIT_EXTERN(int) git_reference_symbolic_set_target(
+ git_reference **out,
+ git_reference *ref,
+ const char *target);
/**
- * Set the OID target of a reference.
+ * Create a new reference with the same name as the given reference but a
+ * different OID target. The reference must be a direct reference, otherwise
+ * this will fail.
*
- * The reference must be a direct reference, otherwise this will fail.
- *
- * The reference will be automatically updated in memory and on disk.
+ * The new reference will be written to disk, overwriting the given reference.
*
+ * @param out Pointer to the newly created reference
* @param ref The reference
* @param id The new target OID for the reference
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const git_oid *id);
+GIT_EXTERN(int) git_reference_set_target(
+ git_reference **out,
+ git_reference *ref,
+ const git_oid *id);
/**
* Rename an existing reference.
@@ -225,7 +233,8 @@ GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const git_oid *id);
* The new name will be checked for validity.
* See `git_reference_create_symbolic()` for rules about valid names.
*
- * The given git_reference will be updated in place.
+ * On success, the given git_reference will be deleted from disk and a
+ * new `git_reference` will be returned.
*
* The reference will be immediately renamed in-memory and on disk.
*
@@ -243,15 +252,18 @@ GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const git_oid *id);
* @return 0 on success, EINVALIDSPEC, EEXISTS or an error code
*
*/
-GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *name, int force);
+GIT_EXTERN(int) git_reference_rename(
+ git_reference **out,
+ git_reference *ref,
+ const char *new_name,
+ int force);
/**
* Delete an existing reference.
*
- * This method works for both direct and symbolic references.
- *
- * The reference will be immediately removed on disk and from memory
- * (i.e. freed). The given reference pointer will no longer be valid.
+ * This method works for both direct and symbolic references. The reference
+ * will be immediately removed on disk but the memory will not be freed.
+ * Callers must call `git_reference_free`.
*
* @param ref The reference to remove
* @return 0 or an error code
@@ -259,21 +271,6 @@ GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *name, int f
GIT_EXTERN(int) git_reference_delete(git_reference *ref);
/**
- * Pack all the loose references in the repository.
- *
- * This method will load into the cache all the loose
- * references on the repository and update the
- * `packed-refs` file with them.
- *
- * Once the `packed-refs` file has been written properly,
- * the loose references will be removed from disk.
- *
- * @param repo Repository where the loose refs will be packed
- * @return 0 or an error code
- */
-GIT_EXTERN(int) git_reference_packall(git_repository *repo);
-
-/**
* Fill a list with all the references that can be found in a repository.
*
* Using the `list_flags` parameter, the listed references may be filtered
@@ -323,14 +320,6 @@ GIT_EXTERN(int) git_reference_foreach(
void *payload);
/**
- * Check if a reference has been loaded from a packfile.
- *
- * @param ref A git reference
- * @return 0 in case it's not packed; 1 otherwise
- */
-GIT_EXTERN(int) git_reference_is_packed(git_reference *ref);
-
-/**
* Reload a reference from disk.
*
* Reference pointers can become outdated if the Git repository is
diff --git a/include/git2/repository.h b/include/git2/repository.h
index e207e5bb5..e75c8b136 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -434,6 +434,39 @@ GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo);
GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb);
/**
+ * Get the Reference Database Backend for this repository.
+ *
+ * If a custom refsdb has not been set, the default database for
+ * the repository will be returned (the one that manipulates loose
+ * and packed references in the `.git` directory).
+ *
+ * The refdb must be freed once it's no longer being used by
+ * the user.
+ *
+ * @param out Pointer to store the loaded refdb
+ * @param repo A repository object
+ * @return 0, or an error code
+ */
+GIT_EXTERN(int) git_repository_refdb(git_refdb **out, git_repository *repo);
+
+/**
+ * Set the Reference Database Backend for this repository
+ *
+ * The refdb will be used for all reference related operations
+ * involving this repository.
+ *
+ * The repository will keep a reference to the refdb; the user
+ * must still free the refdb object after setting it to the
+ * repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param refdb An refdb object
+ */
+GIT_EXTERN(void) git_repository_set_refdb(
+ git_repository *repo,
+ git_refdb *refdb);
+
+/**
* Get the Index file for this repository.
*
* If a custom index has not been set, the default
diff --git a/include/git2/types.h b/include/git2/types.h
index c16bb8872..bc15050ce 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -92,6 +92,12 @@ typedef struct git_odb_stream git_odb_stream;
/** A stream to write a packfile to the ODB */
typedef struct git_odb_writepack git_odb_writepack;
+/** An open refs database handle. */
+typedef struct git_refdb git_refdb;
+
+/** A custom backend for refs */
+typedef struct git_refdb_backend git_refdb_backend;
+
/**
* Representation of an existing git repository,
* including all its object contents
@@ -164,9 +170,7 @@ typedef enum {
GIT_REF_INVALID = 0, /** Invalid reference */
GIT_REF_OID = 1, /** A reference which points at an object id */
GIT_REF_SYMBOLIC = 2, /** A reference which points at another reference */
- GIT_REF_PACKED = 4,
- GIT_REF_HAS_PEEL = 8,
- GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC|GIT_REF_PACKED,
+ GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC,
} git_ref_t;
/** Basic type of any Git branch. */