From 83041c711cd7d9fccb7a1327e642ce33f0705370 Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Fri, 19 Apr 2013 11:52:04 -0700 Subject: [PATCH 1/8] Move git_config_backend to include/git2/sys Moving backend implementor objects into include/git2/sys so the APIs can be isolated from the ones that normal libgit2 users would be likely to use. --- include/git2/config.h | 52 ++------------------------- include/git2/sys/config.h | 70 +++++++++++++++++++++++++++++++++++++ src/config.c | 1 + src/config_file.c | 1 + src/submodule.c | 1 + tests-clar/config/backend.c | 1 + 6 files changed, 76 insertions(+), 50 deletions(-) create mode 100644 include/git2/sys/config.h diff --git a/include/git2/config.h b/include/git2/config.h index 19d4cb78d..5a2f956fd 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -43,29 +43,6 @@ typedef struct { typedef int (*git_config_foreach_cb)(const git_config_entry *, void *); - -/** - * Generic backend that implements the interface to - * access a configuration file - */ -struct git_config_backend { - unsigned int version; - struct git_config *cfg; - - /* Open means open the file/database and parse if necessary */ - int (*open)(struct git_config_backend *, unsigned int level); - int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry); - int (*get_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload); - int (*set)(struct git_config_backend *, const char *key, const char *value); - int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value); - int (*del)(struct git_config_backend *, const char *key); - int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload); - int (*refresh)(struct git_config_backend *); - void (*free)(struct git_config_backend *); -}; -#define GIT_CONFIG_BACKEND_VERSION 1 -#define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION} - typedef enum { GIT_CVAR_FALSE = 0, GIT_CVAR_TRUE = 1, @@ -153,30 +130,6 @@ GIT_EXTERN(int) git_config_open_default(git_config **out); */ GIT_EXTERN(int) git_config_new(git_config **out); -/** - * Add a generic config file instance to an existing config - * - * Note that the configuration object will free the file - * automatically. - * - * Further queries on this config object will access each - * of the config file instances in order (instances with - * a higher priority level will be accessed first). - * - * @param cfg the configuration to add the file to - * @param file the configuration file (backend) to add - * @param level the priority level of the backend - * @param force if a config file already exists for the given - * priority level, replace it - * @return 0 on success, GIT_EEXISTS when adding more than one file - * for a given priority level (and force_replace set to 0), or error code - */ -GIT_EXTERN(int) git_config_add_backend( - git_config *cfg, - git_config_backend *file, - unsigned int level, - int force); - /** * Add an on-disk config file instance to an existing config * @@ -192,10 +145,9 @@ GIT_EXTERN(int) git_config_add_backend( * a higher priority level will be accessed first). * * @param cfg the configuration to add the file to - * @param path path to the configuration file (backend) to add + * @param path path to the configuration file to add * @param level the priority level of the backend - * @param force if a config file already exists for the given - * priority level, replace it + * @param force replace config file at the given priority level * @return 0 on success, GIT_EEXISTS when adding more than one file * for a given priority level (and force_replace set to 0), * GIT_ENOTFOUND when the file doesn't exist or error code diff --git a/include/git2/sys/config.h b/include/git2/sys/config.h new file mode 100644 index 000000000..c9039e96e --- /dev/null +++ b/include/git2/sys/config.h @@ -0,0 +1,70 @@ +/* + * 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_sys_config_h__ +#define INCLUDE_git_sys_config_h__ + +#include "git2/common.h" +#include "git2/types.h" +#include "git2/config.h" + +/** + * @file git2/sys/config.h + * @brief Git config backend routines + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Generic backend that implements the interface to + * access a configuration file + */ +struct git_config_backend { + unsigned int version; + struct git_config *cfg; + + /* Open means open the file/database and parse if necessary */ + int (*open)(struct git_config_backend *, unsigned int level); + int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry); + int (*get_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload); + int (*set)(struct git_config_backend *, const char *key, const char *value); + int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value); + int (*del)(struct git_config_backend *, const char *key); + int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload); + int (*refresh)(struct git_config_backend *); + void (*free)(struct git_config_backend *); +}; +#define GIT_CONFIG_BACKEND_VERSION 1 +#define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION} + +/** + * Add a generic config file instance to an existing config + * + * Note that the configuration object will free the file + * automatically. + * + * Further queries on this config object will access each + * of the config file instances in order (instances with + * a higher priority level will be accessed first). + * + * @param cfg the configuration to add the file to + * @param file the configuration file (backend) to add + * @param level the priority level of the backend + * @param force if a config file already exists for the given + * priority level, replace it + * @return 0 on success, GIT_EEXISTS when adding more than one file + * for a given priority level (and force_replace set to 0), or error code + */ +GIT_EXTERN(int) git_config_add_backend( + git_config *cfg, + git_config_backend *file, + unsigned int level, + int force); + +/** @} */ +GIT_END_DECL +#endif diff --git a/src/config.c b/src/config.c index 5379b0ec5..1283522ca 100644 --- a/src/config.c +++ b/src/config.c @@ -9,6 +9,7 @@ #include "fileops.h" #include "config.h" #include "git2/config.h" +#include "git2/sys/config.h" #include "vector.h" #include "buf_text.h" #include "config_file.h" diff --git a/src/config_file.c b/src/config_file.c index 8b51ab21b..a4ff8bb94 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -12,6 +12,7 @@ #include "buffer.h" #include "buf_text.h" #include "git2/config.h" +#include "git2/sys/config.h" #include "git2/types.h" #include "strmap.h" diff --git a/src/submodule.c b/src/submodule.c index 2fdaf2f77..0a22e3b13 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -7,6 +7,7 @@ #include "common.h" #include "git2/config.h" +#include "git2/sys/config.h" #include "git2/types.h" #include "git2/repository.h" #include "git2/index.h" diff --git a/tests-clar/config/backend.c b/tests-clar/config/backend.c index 28502a8ba..3fd6eb114 100644 --- a/tests-clar/config/backend.c +++ b/tests-clar/config/backend.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" +#include "git2/sys/config.h" void test_config_backend__checks_version(void) { From 83cc70d9fec5f81d07f9fc4133c9515527efb9af Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Fri, 19 Apr 2013 12:48:33 -0700 Subject: [PATCH 2/8] Move odb_backend implementors stuff into git2/sys This moves some of the odb_backend stuff that is related to the internals of an odb_backend implementation into include/git2/sys. Some of the stuff related to streaming I left in include/git2 because it seemed like it would be reasonably needed by a normal user who wanted to stream objects into and out of the ODB. Also, I added APIs for traversing the list of backends so that some of the tests would not need to access ODB internals. --- include/git2/indexer.h | 22 +----- include/git2/odb.h | 97 +++++++++++++++---------- include/git2/odb_backend.h | 123 +++++--------------------------- include/git2/sys/config.h | 5 +- include/git2/sys/odb_backend.h | 86 ++++++++++++++++++++++ include/git2/types.h | 20 ++++++ src/blob.c | 1 + src/odb.c | 22 ++++++ src/odb_loose.c | 2 +- src/odb_pack.c | 3 +- src/tag.c | 1 + src/transports/smart_protocol.c | 1 + tests-clar/object/raw/write.c | 3 +- tests-clar/odb/packed_one.c | 3 +- tests-clar/odb/sorting.c | 18 +++-- 15 files changed, 225 insertions(+), 182 deletions(-) create mode 100644 include/git2/sys/odb_backend.h diff --git a/include/git2/indexer.h b/include/git2/indexer.h index dfe6ae5aa..262dcd154 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -8,31 +8,11 @@ #define _INCLUDE_git_indexer_h__ #include "common.h" +#include "types.h" #include "oid.h" GIT_BEGIN_DECL -/** - * This is passed as the first argument to the callback to allow the - * user to see the progress. - */ -typedef struct git_transfer_progress { - unsigned int total_objects; - unsigned int indexed_objects; - unsigned int received_objects; - size_t received_bytes; -} git_transfer_progress; - - -/** - * Type for progress callbacks during indexing. Return a value less than zero - * to cancel the transfer. - * - * @param stats Structure containing information about the state of the transfer - * @param payload Payload provided by caller - */ -typedef int (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload); - typedef struct git_indexer_stream git_indexer_stream; /** diff --git a/include/git2/odb.h b/include/git2/odb.h index 8fd1a95be..b64436c4d 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -10,8 +10,6 @@ #include "common.h" #include "types.h" #include "oid.h" -#include "odb_backend.h" -#include "indexer.h" /** * @file git2/odb.h @@ -22,6 +20,11 @@ */ GIT_BEGIN_DECL +/** + * Function type for callbacks from git_odb_foreach. + */ +typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload); + /** * Create a new object database with no backends. * @@ -52,42 +55,6 @@ GIT_EXTERN(int) git_odb_new(git_odb **out); */ GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir); -/** - * Add a custom backend to an existing Object DB - * - * The backends are checked in relative ordering, based on the - * value of the `priority` parameter. - * - * Read for more information. - * - * @param odb database to add the backend to - * @param backend pointer to a git_odb_backend instance - * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority); - -/** - * Add a custom backend to an existing Object DB; this - * backend will work as an alternate. - * - * Alternate backends are always checked for objects *after* - * all the main backends have been exhausted. - * - * The backends are checked in relative ordering, based on the - * value of the `priority` parameter. - * - * Writing is disabled on alternate backends. - * - * Read for more information. - * - * @param odb database to add the backend to - * @param backend pointer to a git_odb_backend instance - * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority); - /** * Add an on-disk alternate to an existing Object DB. * @@ -406,6 +373,60 @@ GIT_EXTERN(size_t) git_odb_object_size(git_odb_object *object); */ GIT_EXTERN(git_otype) git_odb_object_type(git_odb_object *object); +/** + * Add a custom backend to an existing Object DB + * + * The backends are checked in relative ordering, based on the + * value of the `priority` parameter. + * + * Read for more information. + * + * @param odb database to add the backend to + * @param backend pointer to a git_odb_backend instance + * @param priority Value for ordering the backends queue + * @return 0 on success; error code otherwise + */ +GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority); + +/** + * Add a custom backend to an existing Object DB; this + * backend will work as an alternate. + * + * Alternate backends are always checked for objects *after* + * all the main backends have been exhausted. + * + * The backends are checked in relative ordering, based on the + * value of the `priority` parameter. + * + * Writing is disabled on alternate backends. + * + * Read for more information. + * + * @param odb database to add the backend to + * @param backend pointer to a git_odb_backend instance + * @param priority Value for ordering the backends queue + * @return 0 on success; error code otherwise + */ +GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority); + +/** + * Get the number of ODB backend objects + * + * @param odb object database + * @return number of backends in the ODB + */ +GIT_EXTERN(size_t) git_odb_num_backends(git_odb *odb); + +/** + * Lookup an ODB backend object by index + * + * @param out output pointer to ODB backend at pos + * @param odb object database + * @param pos index into object database backend list + * @return 0 on success; GIT_ENOTFOUND if pos is invalid; other errors < 0 + */ +GIT_EXTERN(int) git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos); + /** @} */ GIT_END_DECL #endif diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h index dbc3981f6..d38005d15 100644 --- a/include/git2/odb_backend.h +++ b/include/git2/odb_backend.h @@ -7,106 +7,24 @@ #ifndef INCLUDE_git_odb_backend_h__ #define INCLUDE_git_odb_backend_h__ -#include "common.h" -#include "types.h" -#include "oid.h" -#include "indexer.h" +#include "git2/common.h" +#include "git2/types.h" /** * @file git2/backend.h * @brief Git custom backend functions - * @defgroup git_backend Git custom backend API + * @defgroup git_odb Git object database routines * @ingroup Git * @{ */ GIT_BEGIN_DECL -struct git_odb_stream; -struct git_odb_writepack; - /** - * Function type for callbacks from git_odb_foreach. + * Constructors for in-box ODB backends. */ -typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload); - -/** - * An instance for a custom backend - */ -struct git_odb_backend { - unsigned int version; - git_odb *odb; - - /* read and read_prefix each return to libgit2 a buffer which - * will be freed later. The buffer should be allocated using - * the function git_odb_backend_malloc to ensure that it can - * be safely freed later. */ - int (* read)( - void **, size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *); - - /* To find a unique object given a prefix - * of its oid. - * The oid given must be so that the - * remaining (GIT_OID_HEXSZ - len)*4 bits - * are 0s. - */ - int (* read_prefix)( - git_oid *, - void **, size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *, - size_t); - - int (* read_header)( - size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *); - - /* The writer may assume that the object - * has already been hashed and is passed - * in the first parameter. - */ - int (* write)( - git_oid *, - struct git_odb_backend *, - const void *, - size_t, - git_otype); - - int (* writestream)( - struct git_odb_stream **, - struct git_odb_backend *, - size_t, - git_otype); - - int (* readstream)( - struct git_odb_stream **, - struct git_odb_backend *, - const git_oid *); - - int (* exists)( - struct git_odb_backend *, - const git_oid *); - - int (* refresh)(struct git_odb_backend *); - - int (* foreach)( - struct git_odb_backend *, - git_odb_foreach_cb cb, - void *payload); - - int (* writepack)( - struct git_odb_writepack **, - struct git_odb_backend *, - git_transfer_progress_callback progress_cb, - void *progress_payload); - - void (* free)(struct git_odb_backend *); -}; - -#define GIT_ODB_BACKEND_VERSION 1 -#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION} +GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir); +GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync); +GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file); /** Streaming mode */ enum { @@ -117,33 +35,24 @@ enum { /** A stream to read/write from a backend */ struct git_odb_stream { - struct git_odb_backend *backend; + git_odb_backend *backend; unsigned int mode; - int (*read)(struct git_odb_stream *stream, char *buffer, size_t len); - int (*write)(struct git_odb_stream *stream, const char *buffer, size_t len); - int (*finalize_write)(git_oid *oid_p, struct git_odb_stream *stream); - void (*free)(struct git_odb_stream *stream); + int (*read)(git_odb_stream *stream, char *buffer, size_t len); + int (*write)(git_odb_stream *stream, const char *buffer, size_t len); + int (*finalize_write)(git_oid *oid_p, git_odb_stream *stream); + void (*free)(git_odb_stream *stream); }; /** A stream to write a pack file to the ODB */ struct git_odb_writepack { - struct git_odb_backend *backend; + git_odb_backend *backend; - int (*add)(struct git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats); - int (*commit)(struct git_odb_writepack *writepack, git_transfer_progress *stats); - void (*free)(struct git_odb_writepack *writepack); + int (*add)(git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats); + int (*commit)(git_odb_writepack *writepack, git_transfer_progress *stats); + void (*free)(git_odb_writepack *writepack); }; -GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len); - -/** - * Constructors for in-box ODB backends. - */ -GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir); -GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync); -GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file); - GIT_END_DECL #endif diff --git a/include/git2/sys/config.h b/include/git2/sys/config.h index c9039e96e..1c9deba7c 100644 --- a/include/git2/sys/config.h +++ b/include/git2/sys/config.h @@ -4,8 +4,8 @@ * 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_sys_config_h__ -#define INCLUDE_git_sys_config_h__ +#ifndef INCLUDE_sys_git_config_backend_h__ +#define INCLUDE_sys_git_config_backend_h__ #include "git2/common.h" #include "git2/types.h" @@ -14,6 +14,7 @@ /** * @file git2/sys/config.h * @brief Git config backend routines + * @defgroup git_backend Git custom backend APIs * @ingroup Git * @{ */ diff --git a/include/git2/sys/odb_backend.h b/include/git2/sys/odb_backend.h new file mode 100644 index 000000000..3cd2734c0 --- /dev/null +++ b/include/git2/sys/odb_backend.h @@ -0,0 +1,86 @@ +/* + * 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_odb_backend_h__ +#define INCLUDE_sys_git_odb_backend_h__ + +#include "git2/common.h" +#include "git2/types.h" +#include "git2/oid.h" +#include "git2/odb.h" + +/** + * @file git2/sys/backend.h + * @brief Git custom backend implementors functions + * @defgroup git_backend Git custom backend APIs + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * An instance for a custom backend + */ +struct git_odb_backend { + unsigned int version; + git_odb *odb; + + /* read and read_prefix each return to libgit2 a buffer which + * will be freed later. The buffer should be allocated using + * the function git_odb_backend_malloc to ensure that it can + * be safely freed later. */ + int (* read)( + void **, size_t *, git_otype *, git_odb_backend *, const git_oid *); + + /* To find a unique object given a prefix + * of its oid. + * The oid given must be so that the + * remaining (GIT_OID_HEXSZ - len)*4 bits + * are 0s. + */ + int (* read_prefix)( + git_oid *, void **, size_t *, git_otype *, + git_odb_backend *, const git_oid *, size_t); + + int (* read_header)( + size_t *, git_otype *, git_odb_backend *, const git_oid *); + + /* The writer may assume that the object + * has already been hashed and is passed + * in the first parameter. + */ + int (* write)( + git_oid *, git_odb_backend *, const void *, size_t, git_otype); + + int (* writestream)( + git_odb_stream **, git_odb_backend *, size_t, git_otype); + + int (* readstream)( + git_odb_stream **, git_odb_backend *, const git_oid *); + + int (* exists)( + git_odb_backend *, const git_oid *); + + int (* refresh)(git_odb_backend *); + + int (* foreach)( + git_odb_backend *, git_odb_foreach_cb cb, void *payload); + + int (* writepack)( + git_odb_writepack **, git_odb_backend *, + git_transfer_progress_callback progress_cb, void *progress_payload); + + void (* free)(git_odb_backend *); +}; + +#define GIT_ODB_BACKEND_VERSION 1 +#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION} + +GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len); + +GIT_END_DECL + +#endif diff --git a/include/git2/types.h b/include/git2/types.h index bc15050ce..aca9ed927 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -196,6 +196,26 @@ typedef struct git_push git_push; typedef struct git_remote_head git_remote_head; typedef struct git_remote_callbacks git_remote_callbacks; +/** + * This is passed as the first argument to the callback to allow the + * user to see the progress. + */ +typedef struct git_transfer_progress { + unsigned int total_objects; + unsigned int indexed_objects; + unsigned int received_objects; + size_t received_bytes; +} git_transfer_progress; + +/** + * Type for progress callbacks during indexing. Return a value less than zero + * to cancel the transfer. + * + * @param stats Structure containing information about the state of the transfer + * @param payload Payload provided by caller + */ +typedef int (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload); + /** @} */ GIT_END_DECL diff --git a/src/blob.c b/src/blob.c index c0514fc13..11e1f4d77 100644 --- a/src/blob.c +++ b/src/blob.c @@ -8,6 +8,7 @@ #include "git2/common.h" #include "git2/object.h" #include "git2/repository.h" +#include "git2/odb_backend.h" #include "common.h" #include "blob.h" diff --git a/src/odb.c b/src/odb.c index c98df247c..ecdaf7ac2 100644 --- a/src/odb.c +++ b/src/odb.c @@ -8,6 +8,7 @@ #include "common.h" #include #include "git2/object.h" +#include "git2/sys/odb_backend.h" #include "fileops.h" #include "hash.h" #include "odb.h" @@ -403,6 +404,27 @@ int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority) return add_backend_internal(odb, backend, priority, 1); } +size_t git_odb_num_backends(git_odb *odb) +{ + assert(odb); + return odb->backends.length; +} + +int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos) +{ + backend_internal *internal; + + assert(odb && odb); + internal = git_vector_get(&odb->backends, pos); + + if (internal && internal->backend) { + *out = internal->backend; + return 0; + } + + return GIT_ENOTFOUND; +} + static int add_default_backends(git_odb *db, const char *objects_dir, int as_alternates, int alternate_depth) { git_odb_backend *loose, *packed; diff --git a/src/odb_loose.c b/src/odb_loose.c index 68083f7fd..e78172cf6 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -8,7 +8,7 @@ #include "common.h" #include #include "git2/object.h" -#include "git2/oid.h" +#include "git2/sys/odb_backend.h" #include "fileops.h" #include "hash.h" #include "odb.h" diff --git a/src/odb_pack.c b/src/odb_pack.c index 7240a4ac7..773e14974 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -8,7 +8,8 @@ #include "common.h" #include #include "git2/repository.h" -#include "git2/oid.h" +#include "git2/indexer.h" +#include "git2/sys/odb_backend.h" #include "fileops.h" #include "hash.h" #include "odb.h" diff --git a/src/tag.c b/src/tag.c index 735ba7e1d..c82decbe3 100644 --- a/src/tag.c +++ b/src/tag.c @@ -13,6 +13,7 @@ #include "git2/object.h" #include "git2/repository.h" #include "git2/signature.h" +#include "git2/odb_backend.h" void git_tag__free(git_tag *tag) { diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 8acedeb49..90851980c 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -5,6 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ #include "git2.h" +#include "git2/odb_backend.h" #include "smart.h" #include "refs.h" diff --git a/tests-clar/object/raw/write.c b/tests-clar/object/raw/write.c index 1b28d0df7..60aa31f6a 100644 --- a/tests-clar/object/raw/write.c +++ b/tests-clar/object/raw/write.c @@ -1,5 +1,6 @@ - #include "clar_libgit2.h" +#include "git2/odb_backend.h" + #include "fileops.h" #include "odb.h" diff --git a/tests-clar/odb/packed_one.c b/tests-clar/odb/packed_one.c index e9d246c23..4f9bde9ed 100644 --- a/tests-clar/odb/packed_one.c +++ b/tests-clar/odb/packed_one.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" -#include "odb.h" +#include "git2/odb_backend.h" + #include "pack_data_one.h" #include "pack.h" diff --git a/tests-clar/odb/sorting.c b/tests-clar/odb/sorting.c index b4f9e44bc..147a160c8 100644 --- a/tests-clar/odb/sorting.c +++ b/tests-clar/odb/sorting.c @@ -1,13 +1,12 @@ #include "clar_libgit2.h" -#include "git2/odb_backend.h" -#include "odb.h" +#include "git2/sys/odb_backend.h" typedef struct { git_odb_backend base; - int position; + size_t position; } fake_backend; -static git_odb_backend *new_backend(int position) +static git_odb_backend *new_backend(size_t position) { fake_backend *b; @@ -22,14 +21,13 @@ static git_odb_backend *new_backend(int position) static void check_backend_sorting(git_odb *odb) { - unsigned int i; - - for (i = 0; i < odb->backends.length; ++i) { - fake_backend *internal = - *((fake_backend **)git_vector_get(&odb->backends, i)); + size_t i, max_i = git_odb_num_backends(odb); + fake_backend *internal; + for (i = 0; i < max_i; ++i) { + cl_git_pass(git_odb_get_backend((git_odb_backend **)&internal, odb, i)); cl_assert(internal != NULL); - cl_assert(internal->position == (int)i); + cl_assert_equal_sz(i, internal->position); } } From 7cc3c9202722c53bf46e5a8f8d0d7180423a7632 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 29 Jan 2013 07:48:36 -0600 Subject: [PATCH 3/8] Added git_repository_new function --- include/git2/repository.h | 8 ++++++++ src/repository.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/include/git2/repository.h b/include/git2/repository.h index ed837b359..f55ab798f 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -136,6 +136,14 @@ GIT_EXTERN(int) git_repository_open_ext( */ GIT_EXTERN(int) git_repository_open_bare(git_repository **out, const char *bare_path); +/** + * Create a new repository with neither backends nor config object + * + * Note that this is only useful if you wish to associate the repository + * with a non-filesystem-backed object database and config store. + */ +GIT_EXTERN(int) git_repository_new(git_repository **out); + /** * Free a previously allocated repository * diff --git a/src/repository.c b/src/repository.c index 64ab2f4db..72b5a079a 100644 --- a/src/repository.c +++ b/src/repository.c @@ -129,6 +129,12 @@ static git_repository *repository_alloc(void) return repo; } +int git_repository_new(git_repository **out) +{ + *out = repository_alloc(); + return 0; +} + static int load_config_data(git_repository *repo) { int is_bare; From 1384b688d0bb5cd784c453fffef69d27e3db44ca Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Fri, 19 Apr 2013 13:00:12 -0700 Subject: [PATCH 4/8] Move some low-level repo fns to include/git2/sys --- include/git2/repository.h | 70 ----------------------- include/git2/sys/repository.h | 92 +++++++++++++++++++++++++++++++ src/repository.c | 1 + tests-clar/diff/patch.c | 2 + tests-clar/repo/setters.c | 2 + tests-clar/status/worktree_init.c | 6 +- 6 files changed, 101 insertions(+), 72 deletions(-) create mode 100644 include/git2/sys/repository.h diff --git a/include/git2/repository.h b/include/git2/repository.h index f55ab798f..08024cd89 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -136,14 +136,6 @@ GIT_EXTERN(int) git_repository_open_ext( */ GIT_EXTERN(int) git_repository_open_bare(git_repository **out, const char *bare_path); -/** - * Create a new repository with neither backends nor config object - * - * Note that this is only useful if you wish to associate the repository - * with a non-filesystem-backed object database and config store. - */ -GIT_EXTERN(int) git_repository_new(git_repository **out); - /** * Free a previously allocated repository * @@ -408,21 +400,6 @@ GIT_EXTERN(int) git_repository_is_bare(git_repository *repo); */ GIT_EXTERN(int) git_repository_config(git_config **out, git_repository *repo); -/** - * Set the configuration file for this repository - * - * This configuration file will be used for all configuration - * queries involving this repository. - * - * The repository will keep a reference to the config file; - * the user must still free the config after setting it - * to the repository, or it will leak. - * - * @param repo A repository object - * @param config A Config object - */ -GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *config); - /** * Get the Object Database for this repository. * @@ -439,21 +416,6 @@ GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *con */ GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo); -/** - * Set the Object Database for this repository - * - * The ODB will be used for all object-related operations - * involving this repository. - * - * The repository will keep a reference to the ODB; the user - * must still free the ODB object after setting it to the - * repository, or it will leak. - * - * @param repo A repository object - * @param odb An ODB object - */ -GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb); - /** * Get the Reference Database Backend for this repository. * @@ -470,23 +432,6 @@ GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb); */ 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. * @@ -503,21 +448,6 @@ GIT_EXTERN(void) git_repository_set_refdb( */ GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo); -/** - * Set the index file for this repository - * - * This index will be used for all index-related operations - * involving this repository. - * - * The repository will keep a reference to the index file; - * the user must still free the index after setting it - * to the repository, or it will leak. - * - * @param repo A repository object - * @param index An index object - */ -GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index); - /** * Retrieve git's prepared message * diff --git a/include/git2/sys/repository.h b/include/git2/sys/repository.h new file mode 100644 index 000000000..34bc17516 --- /dev/null +++ b/include/git2/sys/repository.h @@ -0,0 +1,92 @@ +/* + * 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_repository_h__ +#define INCLUDE_sys_git_repository_h__ + +/** + * @file git2/sys/repository.h + * @brief Git repository custom implementation routines + * @defgroup git_backend Git custom backend APIs + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Create a new repository with neither backends nor config object + * + * Note that this is only useful if you wish to associate the repository + * with a non-filesystem-backed object database and config store. + * + * @param out The blank repository + * @return 0 on success, or an error code + */ +GIT_EXTERN(int) git_repository_new(git_repository **out); + +/** + * Set the configuration file for this repository + * + * This configuration file will be used for all configuration + * queries involving this repository. + * + * The repository will keep a reference to the config file; + * the user must still free the config after setting it + * to the repository, or it will leak. + * + * @param repo A repository object + * @param config A Config object + */ +GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *config); + +/** + * Set the Object Database for this repository + * + * The ODB will be used for all object-related operations + * involving this repository. + * + * The repository will keep a reference to the ODB; the user + * must still free the ODB object after setting it to the + * repository, or it will leak. + * + * @param repo A repository object + * @param odb An ODB object + */ +GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb); + +/** + * 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); + +/** + * Set the index file for this repository + * + * This index will be used for all index-related operations + * involving this repository. + * + * The repository will keep a reference to the index file; + * the user must still free the index after setting it + * to the repository, or it will leak. + * + * @param repo A repository object + * @param index An index object + */ +GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index); + +/** @} */ +GIT_END_DECL +#endif diff --git a/src/repository.c b/src/repository.c index 72b5a079a..a16f69da4 100644 --- a/src/repository.c +++ b/src/repository.c @@ -9,6 +9,7 @@ #include "git2/object.h" #include "git2/refdb.h" +#include "git2/sys/repository.h" #include "common.h" #include "repository.h" diff --git a/tests-clar/diff/patch.c b/tests-clar/diff/patch.c index 4d17da468..d41f3f12d 100644 --- a/tests-clar/diff/patch.c +++ b/tests-clar/diff/patch.c @@ -1,4 +1,6 @@ #include "clar_libgit2.h" +#include "git2/sys/repository.h" + #include "diff_helpers.h" #include "repository.h" #include "buf_text.h" diff --git a/tests-clar/repo/setters.c b/tests-clar/repo/setters.c index 7e482dee1..063d76c8d 100644 --- a/tests-clar/repo/setters.c +++ b/tests-clar/repo/setters.c @@ -1,4 +1,6 @@ #include "clar_libgit2.h" +#include "git2/sys/repository.h" + #include "buffer.h" #include "posix.h" #include "util.h" diff --git a/tests-clar/status/worktree_init.c b/tests-clar/status/worktree_init.c index b67107aec..296c27c86 100644 --- a/tests-clar/status/worktree_init.c +++ b/tests-clar/status/worktree_init.c @@ -1,4 +1,6 @@ #include "clar_libgit2.h" +#include "git2/sys/repository.h" + #include "fileops.h" #include "ignore.h" #include "status_helpers.h" @@ -321,10 +323,10 @@ void test_status_worktree_init__new_staged_file_must_handle_crlf(void) cl_set_cleanup(&cleanup_new_repo, "getting_started"); cl_git_pass(git_repository_init(&repo, "getting_started", 0)); - // Ensure that repo has core.autocrlf=true + /* Ensure that repo has core.autocrlf=true */ cl_repo_set_bool(repo, "core.autocrlf", true); - cl_git_mkfile("getting_started/testfile.txt", "content\r\n"); // Content with CRLF + cl_git_mkfile("getting_started/testfile.txt", "content\r\n"); /* Content with CRLF */ cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_add_bypath(index, "testfile.txt")); From 9255039898bf4c625f678f390c8075c11d10cad0 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 29 Jan 2013 09:53:23 -0600 Subject: [PATCH 5/8] Added git_commit_create_oid --- include/git2/commit.h | 20 +++++++++++++++++ src/commit.c | 50 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/include/git2/commit.h b/include/git2/commit.h index 764053eaa..e7ef51816 100644 --- a/include/git2/commit.h +++ b/include/git2/commit.h @@ -287,6 +287,26 @@ GIT_EXTERN(int) git_commit_create_v( int parent_count, ...); +/** + * Create a new commit in the repository, as with `git_commit_create`, + * using `git_oid` instances as parameters instead of `git_object`. + * + * See documentation for `git_commit_create` for information about the + * parameters, as the meaning is identical excepting that `tree` and + * `parents` now take `git_oid`. + */ +GIT_EXTERN(int) git_commit_create_oid( + git_oid *oid, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_oid *tree, + int parent_count, + const git_oid *parents[]); + /** @} */ GIT_END_DECL #endif diff --git a/src/commit.c b/src/commit.c index c7b83ed43..e6bfd95ce 100644 --- a/src/commit.c +++ b/src/commit.c @@ -76,7 +76,7 @@ int git_commit_create_v( return res; } -int git_commit_create( +int git_commit_create_oid( git_oid *oid, git_repository *repo, const char *update_ref, @@ -84,22 +84,18 @@ int git_commit_create( const git_signature *committer, const char *message_encoding, const char *message, - const git_tree *tree, + const git_oid *tree, int parent_count, - const git_commit *parents[]) + const git_oid *parents[]) { git_buf commit = GIT_BUF_INIT; int i; git_odb *odb; - assert(git_object_owner((const git_object *)tree) == repo); + git_oid__writebuf(&commit, "tree ", tree); - git_oid__writebuf(&commit, "tree ", git_object_id((const git_object *)tree)); - - for (i = 0; i < parent_count; ++i) { - assert(git_object_owner((const git_object *)parents[i]) == repo); - git_oid__writebuf(&commit, "parent ", git_object_id((const git_object *)parents[i])); - } + for (i = 0; i < parent_count; ++i) + git_oid__writebuf(&commit, "parent ", parents[i]); git_signature__writebuf(&commit, "author ", author); git_signature__writebuf(&commit, "committer ", committer); @@ -131,6 +127,40 @@ on_error: return -1; } +int git_commit_create( + git_oid *oid, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + int parent_count, + const git_commit *parents[]) +{ + int retval, i; + const git_oid **parent_oids; + + assert(git_object_owner((const git_object *)tree) == repo); + + parent_oids = git__malloc(parent_count * sizeof(git_oid *)); + GITERR_CHECK_ALLOC(parent_oids); + + for (i = 0; i < parent_count; ++i) { + assert(git_object_owner((const git_object *)parents[i]) == repo); + parent_oids[i] = git_object_id((const git_object *)parents[i]); + } + + retval = git_commit_create_oid(oid, repo, update_ref, author, committer, + message_encoding, message, + git_object_id((const git_object *)tree), + parent_count, parent_oids); + + git__free((void *)parent_oids); + return retval; +} + int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len) { const char *buffer = data; From 9233b3de4ea264a8ae846c784acc70c505022d8b Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Fri, 19 Apr 2013 13:17:29 -0700 Subject: [PATCH 6/8] Move git_commit_create_from_oids into sys/commit.h Actually this renames git_commit_create_oid to git_commit_create_from_oids and moves the API declaration to include/git2/sys/commit.h since it is a dangerous API for general use (because it doesn't check that the OID list items actually refer to real objects). --- include/git2/commit.h | 108 +++++++++++++++----------------------- include/git2/sys/commit.h | 45 ++++++++++++++++ src/commit.c | 81 ++++++++++++++-------------- 3 files changed, 129 insertions(+), 105 deletions(-) create mode 100644 include/git2/sys/commit.h diff --git a/include/git2/commit.h b/include/git2/commit.h index e7ef51816..0f7601252 100644 --- a/include/git2/commit.h +++ b/include/git2/commit.h @@ -201,14 +201,12 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor( unsigned int n); /** - * Create a new commit in the repository using `git_object` - * instances as parameters. + * Create new commit in the repository from a list of `git_object` pointers * - * The message will not be cleaned up. This can be achieved - * through `git_message_prettify()`. + * The message will not be cleaned up automatically. You can do that with + * the `git_message_prettify()` function. * - * @param id Pointer where to store the OID of the - * newly created commit + * @param id Pointer in which to store the OID of the newly created commit * * @param repo Repository where to store the commit * @@ -219,93 +217,69 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor( * make it point to this commit. If the reference doesn't * exist yet, it will be created. * - * @param author Signature representing the author and the authory - * time of this commit + * @param author Signature with author and author time of commit * - * @param committer Signature representing the committer and the - * commit time of this commit + * @param committer Signature with committer and * commit time of commit * * @param message_encoding The encoding for the message in the - * commit, represented with a standard encoding name. - * E.g. "UTF-8". If NULL, no encoding header is written and - * UTF-8 is assumed. + * commit, represented with a standard encoding name. + * E.g. "UTF-8". If NULL, no encoding header is written and + * UTF-8 is assumed. * * @param message Full message for this commit * * @param tree An instance of a `git_tree` object that will - * be used as the tree for the commit. This tree object must - * also be owned by the given `repo`. + * be used as the tree for the commit. This tree object must + * also be owned by the given `repo`. * * @param parent_count Number of parents for this commit * * @param parents[] Array of `parent_count` pointers to `git_commit` - * objects that will be used as the parents for this commit. This - * array may be NULL if `parent_count` is 0 (root commit). All the - * given commits must be owned by the `repo`. + * objects that will be used as the parents for this commit. This + * array may be NULL if `parent_count` is 0 (root commit). All the + * given commits must be owned by the `repo`. * * @return 0 or an error code * The created commit will be written to the Object Database and * the given reference will be updated to point to it */ GIT_EXTERN(int) git_commit_create( - git_oid *id, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - const git_commit *parents[]); + git_oid *id, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + int parent_count, + const git_commit *parents[]); /** - * Create a new commit in the repository using a variable - * argument list. + * Create new commit in the repository using a variable argument list. * - * The message will be cleaned up from excess whitespace - * it will be made sure that the last line ends with a '\n'. + * The message will be cleaned up from excess whitespace and it will be made + * sure that the last line ends with a '\n'. * - * The parents for the commit are specified as a variable - * list of pointers to `const git_commit *`. Note that this - * is a convenience method which may not be safe to export - * for certain languages or compilers + * The parents for the commit are specified as a variable list of pointers + * to `const git_commit *`. Note that this is a convenience method which may + * not be safe to export for certain languages or compilers * - * All other parameters remain the same + * All other parameters remain the same at `git_commit_create()`. * * @see git_commit_create */ GIT_EXTERN(int) git_commit_create_v( - git_oid *id, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - ...); - -/** - * Create a new commit in the repository, as with `git_commit_create`, - * using `git_oid` instances as parameters instead of `git_object`. - * - * See documentation for `git_commit_create` for information about the - * parameters, as the meaning is identical excepting that `tree` and - * `parents` now take `git_oid`. - */ -GIT_EXTERN(int) git_commit_create_oid( - git_oid *oid, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_oid *tree, - int parent_count, - const git_oid *parents[]); + git_oid *id, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + int parent_count, + ...); /** @} */ GIT_END_DECL diff --git a/include/git2/sys/commit.h b/include/git2/sys/commit.h new file mode 100644 index 000000000..096e028c5 --- /dev/null +++ b/include/git2/sys/commit.h @@ -0,0 +1,45 @@ +/* + * 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_commit_h__ +#define INCLUDE_sys_git_commit_h__ + +#include "git2/common.h" +#include "git2/types.h" +#include "git2/oid.h" + +/** + * @file git2/sys/commit.h + * @brief Low-level Git commit creation + * @defgroup git_backend Git custom backend APIs + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Create new commit in the repository from a list of `git_oid` values + * + * See documentation for `git_commit_create()` for information about the + * parameters, as the meaning is identical excepting that `tree` and + * `parents` now take `git_oid`. This is a dangerous API in that the + * `parents` list of `git_oid`s in not checked for validity. + */ +GIT_EXTERN(int) git_commit_create_from_oids( + git_oid *oid, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_oid *tree, + int parent_count, + const git_oid *parents[]); + +/** @} */ +GIT_END_DECL +#endif diff --git a/src/commit.c b/src/commit.c index e6bfd95ce..dd416920d 100644 --- a/src/commit.c +++ b/src/commit.c @@ -9,6 +9,7 @@ #include "git2/object.h" #include "git2/repository.h" #include "git2/signature.h" +#include "git2/sys/commit.h" #include "common.h" #include "odb.h" @@ -44,16 +45,16 @@ void git_commit__free(git_commit *commit) } int git_commit_create_v( - git_oid *oid, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - ...) + git_oid *oid, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + int parent_count, + ...) { va_list ap; int i, res; @@ -76,22 +77,25 @@ int git_commit_create_v( return res; } -int git_commit_create_oid( - git_oid *oid, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_oid *tree, - int parent_count, - const git_oid *parents[]) +int git_commit_create_from_oids( + git_oid *oid, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_oid *tree, + int parent_count, + const git_oid *parents[]) { git_buf commit = GIT_BUF_INIT; int i; git_odb *odb; + assert(oid && repo && tree && parent_count >= 0); + assert(git_object_owner((const git_object *)tree) == repo); + git_oid__writebuf(&commit, "tree ", tree); for (i = 0; i < parent_count; ++i) @@ -128,21 +132,21 @@ on_error: } int git_commit_create( - git_oid *oid, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - const git_commit *parents[]) + git_oid *oid, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + int parent_count, + const git_commit *parents[]) { - int retval, i; + int retval, i; const git_oid **parent_oids; - assert(git_object_owner((const git_object *)tree) == repo); + assert(parent_count >= 0); parent_oids = git__malloc(parent_count * sizeof(git_oid *)); GITERR_CHECK_ALLOC(parent_oids); @@ -152,13 +156,14 @@ int git_commit_create( parent_oids[i] = git_object_id((const git_object *)parents[i]); } - retval = git_commit_create_oid(oid, repo, update_ref, author, committer, - message_encoding, message, - git_object_id((const git_object *)tree), - parent_count, parent_oids); + retval = git_commit_create_from_oids( + oid, repo, update_ref, author, committer, + message_encoding, message, + git_object_id((const git_object *)tree), parent_count, parent_oids); git__free((void *)parent_oids); - return retval; + + return retval; } int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len) From 4dcd87801972e1b880afa9cd0998842bae7af5b5 Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Fri, 19 Apr 2013 17:17:44 -0700 Subject: [PATCH 7/8] Move refdb_backend to include/git2/sys This moves most of the refdb stuff over to the include/git2/sys directory, with some minor shifts in function organization. While I was making the necessary updates, I also removed the trailing whitespace in a few files that I modified just because I was there and it was bugging me. --- include/git2/refdb.h | 14 ------ include/git2/{ => sys}/refdb_backend.h | 18 ++++++-- src/refdb.c | 9 ++-- src/refdb_fs.c | 30 ++++++------- src/refs.c | 45 +++++++++---------- src/util.h | 2 + tests-clar/refdb/inmemory.c | 62 ++++++++++++++------------ tests-clar/refdb/testdb.c | 48 +++++++++----------- tests-clar/refdb/testdb.h | 5 +++ 9 files changed, 119 insertions(+), 114 deletions(-) rename include/git2/{ => sys}/refdb_backend.h (86%) diff --git a/include/git2/refdb.h b/include/git2/refdb.h index 0e3ec5eaf..9278b1116 100644 --- a/include/git2/refdb.h +++ b/include/git2/refdb.h @@ -81,20 +81,6 @@ GIT_EXTERN(int) git_refdb_compress(git_refdb *refdb); */ GIT_EXTERN(void) git_refdb_free(git_refdb *refdb); -/** - * Sets the custom backend to an existing reference DB - * - * Read 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 diff --git a/include/git2/refdb_backend.h b/include/git2/sys/refdb_backend.h similarity index 86% rename from include/git2/refdb_backend.h rename to include/git2/sys/refdb_backend.h index 20eb6a9dd..dcdf7bcb8 100644 --- a/include/git2/refdb_backend.h +++ b/include/git2/sys/refdb_backend.h @@ -7,9 +7,9 @@ #ifndef INCLUDE_git_refdb_backend_h__ #define INCLUDE_git_refdb_backend_h__ -#include "common.h" -#include "types.h" -#include "oid.h" +#include "git2/common.h" +#include "git2/types.h" +#include "git2/oid.h" /** * @file git2/refdb_backend.h @@ -103,6 +103,18 @@ GIT_EXTERN(int) git_refdb_backend_fs( struct git_refdb_backend **backend_out, git_repository *repo); +/** + * Sets the custom backend to an existing reference DB + * + * @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/src/refdb.c b/src/refdb.c index 2a0fd702c..0675be638 100644 --- a/src/refdb.c +++ b/src/refdb.c @@ -7,15 +7,16 @@ #include "common.h" #include "posix.h" + #include "git2/object.h" #include "git2/refs.h" #include "git2/refdb.h" +#include "git2/sys/refdb_backend.h" + #include "hash.h" #include "refdb.h" #include "refs.h" -#include "git2/refdb_backend.h" - int git_refdb_new(git_refdb **out, git_repository *repo) { git_refdb *db; @@ -74,11 +75,11 @@ int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend) int git_refdb_compress(git_refdb *db) { assert(db); - + if (db->backend->compress) { return db->backend->compress(db->backend); } - + return 0; } diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 56b2b6a99..4d5d6006d 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include GIT__USE_STRMAP; @@ -61,7 +61,7 @@ static int reference_read( /* Determine the full path of the file */ if (git_buf_joinpath(&path, repo_path, ref_name) < 0) return -1; - + result = git_futils_readbuffer_updated(file_content, path.ptr, mtime, NULL, updated); git_buf_free(&path); @@ -174,7 +174,7 @@ static int packed_load(refdb_fs_backend *backend) ref_cache->packfile = git_strmap_alloc(); GITERR_CHECK_ALLOC(ref_cache->packfile); } - + result = reference_read(&packfile, &ref_cache->packfile_time, backend->path, GIT_PACKEDREFS_FILE, &updated); @@ -192,7 +192,7 @@ static int packed_load(refdb_fs_backend *backend) if (result < 0) return -1; - + if (!updated) return 0; @@ -433,7 +433,7 @@ static int loose_lookup( } else { if ((error = loose_parse_oid(&oid, &ref_file)) < 0) goto done; - + *out = git_reference__alloc(ref_name, &oid, NULL); } @@ -455,19 +455,19 @@ static int packed_map_entry( if (packed_load(backend) < 0) return -1; - + /* Look up on the packfile */ packfile_refs = backend->refcache.packfile; *pos = git_strmap_lookup_index(packfile_refs, ref_name); - + if (!git_strmap_valid_index(packfile_refs, *pos)) { giterr_set(GITERR_REFERENCE, "Reference '%s' not found", ref_name); return GIT_ENOTFOUND; } *entry = git_strmap_value_at(packfile_refs, *pos); - + return 0; } @@ -479,14 +479,14 @@ static int packed_lookup( struct packref *entry; khiter_t pos; int error = 0; - + if ((error = packed_map_entry(&entry, &pos, backend, ref_name)) < 0) return error; if ((*out = git_reference__alloc(ref_name, &entry->oid, &entry->peel)) == NULL) return -1; - + return 0; } @@ -582,7 +582,7 @@ static int refdb_fs_backend__foreach( git_buf refs_path = GIT_BUF_INIT; const char *ref_name; void *ref = NULL; - + GIT_UNUSED(ref); assert(_backend); @@ -590,7 +590,7 @@ static int refdb_fs_backend__foreach( if (packed_load(backend) < 0) return -1; - + /* list all the packed references first */ if (list_type & GIT_REF_OID) { git_strmap_foreach(backend->refcache.packfile, ref_name, ref, { @@ -924,7 +924,7 @@ static int refdb_fs_backend__delete( repo = backend->repo; /* If a loose reference exists, remove it from the filesystem */ - + if (git_buf_joinpath(&loose_path, repo->path_repository, ref->name) < 0) return -1; @@ -932,7 +932,7 @@ static int refdb_fs_backend__delete( error = p_unlink(loose_path.ptr); loose_deleted = 1; } - + git_buf_free(&loose_path); if (error != 0) @@ -946,7 +946,7 @@ static int refdb_fs_backend__delete( error = packed_write(backend); } - + if (pack_error == GIT_ENOTFOUND) error = loose_deleted ? 0 : GIT_ENOTFOUND; else diff --git a/src/refs.c b/src/refs.c index 5b5812aae..d9291e56f 100644 --- a/src/refs.c +++ b/src/refs.c @@ -19,7 +19,6 @@ #include #include #include -#include GIT__USE_STRMAP; @@ -255,10 +254,10 @@ int git_reference_lookup_resolved( max_nesting = MAX_NESTING_LEVEL; else if (max_nesting < 0) max_nesting = DEFAULT_NESTING_LEVEL; - + strncpy(scan_name, name, GIT_REFNAME_MAX); scan_type = GIT_REF_SYMBOLIC; - + if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) return -1; @@ -276,7 +275,7 @@ int git_reference_lookup_resolved( if ((error = git_refdb_lookup(&ref, refdb, scan_name)) < 0) return error; - + scan_type = ref->type; } @@ -354,7 +353,7 @@ static int reference__create( git_refdb *refdb; git_reference *ref = NULL; int error = 0; - + if (ref_out) *ref_out = NULL; @@ -369,7 +368,7 @@ static int reference__create( } else { ref = git_reference__alloc_symbolic(name, symbolic); } - + GITERR_CHECK_ALLOC(ref); ref->db = refdb; @@ -377,7 +376,7 @@ static int reference__create( git_reference_free(ref); return error; } - + if (ref_out == NULL) git_reference_free(ref); else @@ -397,17 +396,17 @@ int git_reference_create( int error = 0; assert(repo && name && oid); - + /* Sanity check the reference being created - target must exist. */ if ((error = git_repository_odb__weakptr(&odb, repo)) < 0) return error; - + if (!git_odb_exists(odb, oid)) { giterr_set(GITERR_REFERENCE, "Target OID for the reference doesn't exist on the repository"); return -1; } - + return reference__create(ref_out, repo, name, oid, NULL, force); } @@ -422,7 +421,7 @@ int git_reference_symbolic_create( int error = 0; assert(repo && name && target); - + if ((error = git_reference__normalize_name_lax( normalized, sizeof(normalized), target)) < 0) return error; @@ -436,7 +435,7 @@ int git_reference_set_target( const git_oid *id) { assert(out && ref && id); - + if (ref->type != GIT_REF_OID) { giterr_set(GITERR_REFERENCE, "Cannot set OID on symbolic reference"); return -1; @@ -451,13 +450,13 @@ int git_reference_symbolic_set_target( const char *target) { assert(out && ref && target); - + if (ref->type != GIT_REF_SYMBOLIC) { giterr_set(GITERR_REFERENCE, "Cannot set symbolic target on a direct reference"); return -1; } - + return git_reference_symbolic_create(out, ref->db->repo, ref->name, target, 1); } @@ -473,7 +472,7 @@ int git_reference_rename( git_reference *result = NULL; int error = 0; int reference_has_log; - + *out = NULL; normalization_flags = ref->type == GIT_REF_SYMBOLIC ? @@ -488,7 +487,7 @@ int git_reference_rename( * Create the new reference. */ if (ref->type == GIT_REF_OID) { - result = git_reference__alloc(new_name, &ref->target.oid, &ref->peel); + result = git_reference__alloc(new_name, &ref->target.oid, &ref->peel); } else if (ref->type == GIT_REF_SYMBOLIC) { result = git_reference__alloc_symbolic(new_name, ref->target.symbolic); } else { @@ -509,11 +508,11 @@ int git_reference_rename( /* Now delete the old ref and save the new one. */ if ((error = git_refdb_delete(ref->db, ref)) < 0) goto on_error; - + /* Save the new reference. */ if ((error = git_refdb_write(ref->db, result)) < 0) goto rollback; - + /* Update HEAD it was poiting to the reference being renamed. */ if (should_head_be_updated && (error = git_repository_set_head(ref->db->repo, new_name)) < 0) { giterr_set(GITERR_REFERENCE, "Failed to update HEAD after renaming reference"); @@ -547,7 +546,7 @@ int git_reference_resolve(git_reference **ref_out, const git_reference *ref) switch (git_reference_type(ref)) { case GIT_REF_OID: return git_reference_lookup(ref_out, ref->db->repo, ref->name); - + case GIT_REF_SYMBOLIC: return git_reference_lookup_resolved(ref_out, ref->db->repo, ref->target.symbolic, -1); @@ -846,7 +845,7 @@ static int reference__update_terminal( if (nesting > MAX_NESTING_LEVEL) return GIT_ENOTFOUND; - + error = git_reference_lookup(&ref, repo, ref_name); /* If we haven't found the reference at all, create a new reference. */ @@ -854,10 +853,10 @@ static int reference__update_terminal( giterr_clear(); return git_reference_create(NULL, repo, ref_name, oid, 0); } - + if (error < 0) return error; - + /* If the ref is a symbolic reference, follow its target. */ if (git_reference_type(ref) == GIT_REF_SYMBOLIC) { error = reference__update_terminal(repo, git_reference_symbolic_target(ref), oid, @@ -867,7 +866,7 @@ static int reference__update_terminal( git_reference_free(ref); error = git_reference_create(NULL, repo, ref_name, oid, 1); } - + return error; } diff --git a/src/util.h b/src/util.h index c0f271997..af3ef0b46 100644 --- a/src/util.h +++ b/src/util.h @@ -7,6 +7,8 @@ #ifndef INCLUDE_util_h__ #define INCLUDE_util_h__ +#include "common.h" + #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #define bitsizeof(x) (CHAR_BIT * sizeof(x)) #define MSB(x, bits) ((x) & (~0ULL << (bitsizeof(x) - (bits)))) diff --git a/tests-clar/refdb/inmemory.c b/tests-clar/refdb/inmemory.c index ea76172cf..2c76d4192 100644 --- a/tests-clar/refdb/inmemory.c +++ b/tests-clar/refdb/inmemory.c @@ -1,12 +1,15 @@ #include "clar_libgit2.h" -#include "refdb.h" -#include "repository.h" + +#include "buffer.h" +#include "posix.h" +#include "path.h" +#include "refs.h" + #include "testdb.h" #define TEST_REPO_PATH "testrepo" static git_repository *repo; -static git_refdb_backend *refdb_backend; int unlink_ref(void *payload, git_buf *file) { @@ -26,7 +29,7 @@ int ref_file_foreach(git_repository *repo, int (* cb)(void *payload, git_buf *fi const char *repo_path; git_buf repo_refs_dir = GIT_BUF_INIT; int error = 0; - + repo_path = git_repository_path(repo); git_buf_joinpath(&repo_refs_dir, repo_path, "HEAD"); @@ -38,7 +41,7 @@ int ref_file_foreach(git_repository *repo, int (* cb)(void *payload, git_buf *fi git_buf_joinpath(&repo_refs_dir, git_buf_cstr(&repo_refs_dir), "heads"); if (git_path_direach(&repo_refs_dir, cb, NULL) != 0) return -1; - + git_buf_joinpath(&repo_refs_dir, repo_path, "packed-refs"); if (git_path_exists(git_buf_cstr(&repo_refs_dir)) && cb(NULL, &repo_refs_dir) < 0) @@ -51,16 +54,17 @@ int ref_file_foreach(git_repository *repo, int (* cb)(void *payload, git_buf *fi void test_refdb_inmemory__initialize(void) { - git_refdb *refdb; - git_buf repo_refs_dir = GIT_BUF_INIT; + git_refdb *refdb; + git_refdb_backend *refdb_backend; repo = cl_git_sandbox_init(TEST_REPO_PATH); cl_git_pass(git_repository_refdb(&refdb, repo)); cl_git_pass(refdb_backend_test(&refdb_backend, repo)); cl_git_pass(git_refdb_set_backend(refdb, refdb_backend)); - + git_refdb_free(refdb); + ref_file_foreach(repo, unlink_ref); git_buf_free(&repo_refs_dir); @@ -76,10 +80,10 @@ void test_refdb_inmemory__doesnt_write_ref_file(void) { git_reference *ref; git_oid oid; - + cl_git_pass(git_oid_fromstr(&oid, "c47800c7266a2be04c571c04d5a6614691ea99bd")); cl_git_pass(git_reference_create(&ref, repo, GIT_REFS_HEADS_DIR "test1", &oid, 0)); - + ref_file_foreach(repo, empty); git_reference_free(ref); @@ -89,10 +93,10 @@ void test_refdb_inmemory__read(void) { git_reference *write1, *write2, *write3, *read1, *read2, *read3; git_oid oid1, oid2, oid3; - + cl_git_pass(git_oid_fromstr(&oid1, "c47800c7266a2be04c571c04d5a6614691ea99bd")); cl_git_pass(git_reference_create(&write1, repo, GIT_REFS_HEADS_DIR "test1", &oid1, 0)); - + cl_git_pass(git_oid_fromstr(&oid2, "e90810b8df3e80c413d903f631643c716887138d")); cl_git_pass(git_reference_create(&write2, repo, GIT_REFS_HEADS_DIR "test2", &oid2, 0)); @@ -139,7 +143,7 @@ int foreach_test(const char *ref_name, void *payload) cl_assert(git_oid_cmp(&expected, git_reference_target(ref)) == 0); ++(*i); - + git_reference_free(ref); return 0; @@ -150,19 +154,19 @@ void test_refdb_inmemory__foreach(void) git_reference *write1, *write2, *write3; git_oid oid1, oid2, oid3; size_t i = 0; - + cl_git_pass(git_oid_fromstr(&oid1, "c47800c7266a2be04c571c04d5a6614691ea99bd")); cl_git_pass(git_reference_create(&write1, repo, GIT_REFS_HEADS_DIR "test1", &oid1, 0)); - + cl_git_pass(git_oid_fromstr(&oid2, "e90810b8df3e80c413d903f631643c716887138d")); cl_git_pass(git_reference_create(&write2, repo, GIT_REFS_HEADS_DIR "test2", &oid2, 0)); - + cl_git_pass(git_oid_fromstr(&oid3, "763d71aadf09a7951596c9746c024e7eece7c7af")); cl_git_pass(git_reference_create(&write3, repo, GIT_REFS_HEADS_DIR "test3", &oid3, 0)); - + cl_git_pass(git_reference_foreach(repo, GIT_REF_LISTALL, foreach_test, &i)); cl_assert_equal_i(3, (int)i); - + git_reference_free(write1); git_reference_free(write2); git_reference_free(write3); @@ -175,14 +179,14 @@ int delete_test(const char *ref_name, void *payload) size_t *i = payload; cl_git_pass(git_reference_lookup(&ref, repo, ref_name)); - - cl_git_pass(git_oid_fromstr(&expected, "e90810b8df3e80c413d903f631643c716887138d")); + + cl_git_pass(git_oid_fromstr(&expected, "e90810b8df3e80c413d903f631643c716887138d")); cl_assert(git_oid_cmp(&expected, git_reference_target(ref)) == 0); - + ++(*i); - + git_reference_free(ref); - + return 0; } @@ -191,22 +195,22 @@ void test_refdb_inmemory__delete(void) git_reference *write1, *write2, *write3; git_oid oid1, oid2, oid3; size_t i = 0; - + cl_git_pass(git_oid_fromstr(&oid1, "c47800c7266a2be04c571c04d5a6614691ea99bd")); cl_git_pass(git_reference_create(&write1, repo, GIT_REFS_HEADS_DIR "test1", &oid1, 0)); - + cl_git_pass(git_oid_fromstr(&oid2, "e90810b8df3e80c413d903f631643c716887138d")); cl_git_pass(git_reference_create(&write2, repo, GIT_REFS_HEADS_DIR "test2", &oid2, 0)); - + cl_git_pass(git_oid_fromstr(&oid3, "763d71aadf09a7951596c9746c024e7eece7c7af")); cl_git_pass(git_reference_create(&write3, repo, GIT_REFS_HEADS_DIR "test3", &oid3, 0)); - + git_reference_delete(write1); git_reference_free(write1); - + git_reference_delete(write3); git_reference_free(write3); - + cl_git_pass(git_reference_foreach(repo, GIT_REF_LISTALL, delete_test, &i)); cl_assert_equal_i(1, (int)i); diff --git a/tests-clar/refdb/testdb.c b/tests-clar/refdb/testdb.c index 4bca39878..627254e44 100644 --- a/tests-clar/refdb/testdb.c +++ b/tests-clar/refdb/testdb.c @@ -1,14 +1,10 @@ -#include "common.h" #include "vector.h" #include "util.h" -#include -#include -#include -#include +#include "testdb.h" typedef struct refdb_test_backend { git_refdb_backend parent; - + git_repository *repo; git_vector refs; } refdb_test_backend; @@ -16,7 +12,7 @@ typedef struct refdb_test_backend { typedef struct refdb_test_entry { char *name; git_ref_t type; - + union { git_oid oid; char *symbolic; @@ -37,19 +33,19 @@ static int refdb_test_backend__exists( refdb_test_backend *backend; refdb_test_entry *entry; size_t i; - + assert(_backend); backend = (refdb_test_backend *)_backend; - + *exists = 0; - + git_vector_foreach(&backend->refs, i, entry) { if (strcmp(entry->name, ref_name) == 0) { *exists = 1; break; } } - + return 0; } @@ -59,18 +55,18 @@ static int refdb_test_backend__write( { refdb_test_backend *backend; refdb_test_entry *entry; - + assert(_backend); backend = (refdb_test_backend *)_backend; entry = git__calloc(1, sizeof(refdb_test_entry)); GITERR_CHECK_ALLOC(entry); - + entry->name = git__strdup(git_reference_name(ref)); GITERR_CHECK_ALLOC(entry->name); - + entry->type = git_reference_type(ref); - + if (entry->type == GIT_REF_OID) git_oid_cpy(&entry->target.oid, git_reference_target(ref)); else { @@ -79,7 +75,7 @@ static int refdb_test_backend__write( } git_vector_insert(&backend->refs, entry); - + return 0; } @@ -94,7 +90,7 @@ static int refdb_test_backend__lookup( assert(_backend); backend = (refdb_test_backend *)_backend; - + git_vector_foreach(&backend->refs, i, entry) { if (strcmp(entry->name, ref_name) == 0) { @@ -108,7 +104,7 @@ static int refdb_test_backend__lookup( if (*out == NULL) return -1; - + return 0; } } @@ -125,21 +121,21 @@ static int refdb_test_backend__foreach( refdb_test_backend *backend; refdb_test_entry *entry; size_t i; - + assert(_backend); backend = (refdb_test_backend *)_backend; git_vector_foreach(&backend->refs, i, entry) { if (entry->type == GIT_REF_OID && (list_flags & GIT_REF_OID) == 0) continue; - + if (entry->type == GIT_REF_SYMBOLIC && (list_flags & GIT_REF_SYMBOLIC) == 0) continue; - + if (callback(entry->name, payload) != 0) return GIT_EUSER; } - + return 0; } @@ -147,7 +143,7 @@ static void refdb_test_entry_free(refdb_test_entry *entry) { if (entry->type == GIT_REF_SYMBOLIC) git__free(entry->target.symbolic); - + git__free(entry->name); git__free(entry); } @@ -178,14 +174,14 @@ static void refdb_test_backend__free(git_refdb_backend *_backend) refdb_test_backend *backend; refdb_test_entry *entry; size_t i; - + assert(_backend); backend = (refdb_test_backend *)_backend; git_vector_foreach(&backend->refs, i, entry) refdb_test_entry_free(entry); - git_vector_free(&backend->refs); + git_vector_free(&backend->refs); git__free(backend); } @@ -197,7 +193,7 @@ int refdb_backend_test( backend = git__calloc(1, sizeof(refdb_test_backend)); GITERR_CHECK_ALLOC(backend); - + git_vector_init(&backend->refs, 0, ref_name_cmp); backend->repo = repo; diff --git a/tests-clar/refdb/testdb.h b/tests-clar/refdb/testdb.h index e38abd967..49d1cb1d0 100644 --- a/tests-clar/refdb/testdb.h +++ b/tests-clar/refdb/testdb.h @@ -1,3 +1,8 @@ +#include +#include +#include +#include + int refdb_backend_test( git_refdb_backend **backend_out, git_repository *repo); From 21ca045100337bcb2905a20a72d42721d18871f9 Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Sun, 21 Apr 2013 12:52:17 -0700 Subject: [PATCH 8/8] Move git_reference__alloc to include/git2/sys Create a new include/git2/sys/refs.h and move the reference alloc functions there. Also fix some documentation issues and some minor code cleanups. --- include/git2/refdb.h | 19 ---------------- include/git2/sys/refdb_backend.h | 36 +++++++++++++++++++----------- include/git2/sys/refs.h | 38 ++++++++++++++++++++++++++++++++ src/refdb.c | 28 ++++++++++------------- src/refdb.h | 2 +- src/refdb_fs.c | 1 + src/refs.c | 4 ++-- tests-clar/refdb/inmemory.c | 1 - tests-clar/refdb/testdb.h | 1 + 9 files changed, 78 insertions(+), 52 deletions(-) create mode 100644 include/git2/sys/refs.h diff --git a/include/git2/refdb.h b/include/git2/refdb.h index 9278b1116..a315876ae 100644 --- a/include/git2/refdb.h +++ b/include/git2/refdb.h @@ -21,25 +21,6 @@ */ 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_EXTERN(git_reference *) git_reference__alloc( - const char *name, - const git_oid *oid, - const git_oid *peel); - -GIT_EXTERN(git_reference *) git_reference__alloc_symbolic( - const char *name, - const char *target); - /** * Create a new reference database with no backends. * diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h index dcdf7bcb8..d5f599fec 100644 --- a/include/git2/sys/refdb_backend.h +++ b/include/git2/sys/refdb_backend.h @@ -4,8 +4,8 @@ * 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__ +#ifndef INCLUDE_sys_git_refdb_backend_h__ +#define INCLUDE_sys_git_refdb_backend_h__ #include "git2/common.h" #include "git2/types.h" @@ -30,7 +30,7 @@ struct git_refdb_backend { */ int (*exists)( int *exists, - struct git_refdb_backend *backend, + git_refdb_backend *backend, const char *ref_name); /** @@ -39,7 +39,7 @@ struct git_refdb_backend { */ int (*lookup)( git_reference **out, - struct git_refdb_backend *backend, + git_refdb_backend *backend, const char *ref_name); /** @@ -47,7 +47,7 @@ struct git_refdb_backend { * provide this function. */ int (*foreach)( - struct git_refdb_backend *backend, + git_refdb_backend *backend, unsigned int list_flags, git_reference_foreach_cb callback, void *payload); @@ -59,7 +59,7 @@ struct git_refdb_backend { * against the glob. */ int (*foreach_glob)( - struct git_refdb_backend *backend, + git_refdb_backend *backend, const char *glob, unsigned int list_flags, git_reference_foreach_cb callback, @@ -69,13 +69,13 @@ struct git_refdb_backend { * 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); + int (*write)(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); + int (*delete)(git_refdb_backend *backend, const git_reference *ref); /** * Suggests that the given refdb compress or optimize its references. @@ -84,31 +84,41 @@ struct git_refdb_backend { * implementation may provide this function; if it is not provided, * nothing will be done. */ - int (*compress)(struct git_refdb_backend *backend); + int (*compress)(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); + void (*free)(git_refdb_backend *backend); }; #define GIT_ODB_BACKEND_VERSION 1 #define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION} /** - * Constructors for default refdb backends. + * 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( - struct git_refdb_backend **backend_out, + 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 - * @param priority Value for ordering the backends queue * @return 0 on success; error code otherwise */ GIT_EXTERN(int) git_refdb_set_backend( diff --git a/include/git2/sys/refs.h b/include/git2/sys/refs.h new file mode 100644 index 000000000..85963258c --- /dev/null +++ b/include/git2/sys/refs.h @@ -0,0 +1,38 @@ +/* + * 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_h__ +#define INCLUDE_sys_git_refdb_h__ + +#include "git2/common.h" +#include "git2/types.h" +#include "git2/oid.h" + +/** + * Create a new direct reference from an OID. + * + * @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_EXTERN(git_reference *) git_reference__alloc( + const char *name, + const git_oid *oid, + const git_oid *peel); + +/** + * Create a new symbolic reference. + * + * @param name the reference name + * @param symbolic the target for a symbolic reference + * @return the created git_reference or NULL on error + */ +GIT_EXTERN(git_reference *) git_reference__alloc_symbolic( + const char *name, + const char *target); + +#endif diff --git a/src/refdb.c b/src/refdb.c index 0675be638..33a1934d1 100644 --- a/src/refdb.c +++ b/src/refdb.c @@ -58,15 +58,19 @@ int git_refdb_open(git_refdb **out, git_repository *repo) return 0; } -int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend) +static void refdb_free_backend(git_refdb *db) { if (db->backend) { - if(db->backend->free) + if (db->backend->free) db->backend->free(db->backend); else git__free(db->backend); } +} +int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend) +{ + refdb_free_backend(db); db->backend = backend; return 0; @@ -76,22 +80,15 @@ int git_refdb_compress(git_refdb *db) { assert(db); - if (db->backend->compress) { + if (db->backend->compress) return db->backend->compress(db->backend); - } return 0; } static void refdb_free(git_refdb *db) { - if (db->backend) { - if(db->backend->free) - db->backend->free(db->backend); - else - git__free(db->backend); - } - + refdb_free_backend(db); git__free(db); } @@ -115,14 +112,13 @@ int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name) git_reference *ref; int error; - assert(db && db->backend && ref_name); + assert(db && db->backend && out && ref_name); - *out = NULL; - - if ((error = db->backend->lookup(&ref, db->backend, ref_name)) == 0) - { + if (!(error = db->backend->lookup(&ref, db->backend, ref_name))) { ref->db = db; *out = ref; + } else { + *out = NULL; } return error; diff --git a/src/refdb.h b/src/refdb.h index 0969711b9..047113ac8 100644 --- a/src/refdb.h +++ b/src/refdb.h @@ -41,6 +41,6 @@ int git_refdb_foreach_glob( int git_refdb_write(git_refdb *refdb, const git_reference *ref); -int git_refdb_delete(struct git_refdb *refdb, const git_reference *ref); +int git_refdb_delete(git_refdb *refdb, const git_reference *ref); #endif diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 4d5d6006d..443871005 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -19,6 +19,7 @@ #include #include #include +#include GIT__USE_STRMAP; diff --git a/src/refs.c b/src/refs.c index d9291e56f..9c6684a5a 100644 --- a/src/refs.c +++ b/src/refs.c @@ -19,6 +19,7 @@ #include #include #include +#include GIT__USE_STRMAP; @@ -44,8 +45,7 @@ static git_reference *alloc_ref(const char *name) } git_reference *git_reference__alloc_symbolic( - const char *name, - const char *target) + const char *name, const char *target) { git_reference *ref; diff --git a/tests-clar/refdb/inmemory.c b/tests-clar/refdb/inmemory.c index 2c76d4192..243b5bb37 100644 --- a/tests-clar/refdb/inmemory.c +++ b/tests-clar/refdb/inmemory.c @@ -63,7 +63,6 @@ void test_refdb_inmemory__initialize(void) cl_git_pass(git_repository_refdb(&refdb, repo)); cl_git_pass(refdb_backend_test(&refdb_backend, repo)); cl_git_pass(git_refdb_set_backend(refdb, refdb_backend)); - git_refdb_free(refdb); ref_file_foreach(repo, unlink_ref); diff --git a/tests-clar/refdb/testdb.h b/tests-clar/refdb/testdb.h index 49d1cb1d0..a0d1bbc48 100644 --- a/tests-clar/refdb/testdb.h +++ b/tests-clar/refdb/testdb.h @@ -1,6 +1,7 @@ #include #include #include +#include #include int refdb_backend_test(