diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2013-03-01 15:37:33 -0600 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2013-03-07 11:01:52 -0600 |
commit | d00d54645d931c77a9b401518c0d73e3f640454b (patch) | |
tree | e1932dcc97172a53524e9db1ba4923cf137a4f9c /include | |
parent | 6a9ef012376e8a21dcfd0499ab16048eb6e954c3 (diff) | |
download | libgit2-d00d54645d931c77a9b401518c0d73e3f640454b.tar.gz |
immutable references and a pluggable ref database
Diffstat (limited to 'include')
-rw-r--r-- | include/git2/branch.h | 48 | ||||
-rw-r--r-- | include/git2/refdb.h | 98 | ||||
-rw-r--r-- | include/git2/refdb_backend.h | 109 | ||||
-rw-r--r-- | include/git2/refs.h | 67 | ||||
-rw-r--r-- | include/git2/repository.h | 33 | ||||
-rw-r--r-- | include/git2/types.h | 10 |
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. */ |