From d12299fe22e549a20e632668fdbe13cab9def9df Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Fri, 3 Dec 2010 22:22:10 +0200 Subject: [PATCH] Change include structure for the project The maze with include dependencies has been fixed. There is now a global include: #include The git_odb_backend API has been exposed. Signed-off-by: Vicent Marti --- src/blob.c | 2 +- src/commit.c | 2 +- src/git.h | 49 +++++++++++++++++++ src/git/blob.h | 4 +- src/git/commit.h | 6 +-- src/git/common.h | 10 ---- src/git/errors.h | 2 - src/git/index.h | 6 +-- src/git/object.h | 108 ++++++++++++++++++++++++++++++++++++++++++ src/git/odb.h | 59 +---------------------- src/git/odb_backend.h | 40 ++++++++++++++++ src/git/oid.h | 18 ++----- src/git/repository.h | 69 ++------------------------- src/git/revwalk.h | 5 +- src/git/tag.h | 6 +-- src/git/tree.h | 9 +--- src/git/types.h | 64 +++++++++++++++++++++++++ src/git/zlib.h | 1 - src/odb.c | 59 ++++------------------- src/odb.h | 28 ----------- src/odb_loose.c | 10 ++-- src/odb_pack.c | 3 ++ src/oid.c | 15 ++++++ src/repository.c | 65 +++++++++++++++++++++---- src/tag.c | 4 +- src/tree.c | 1 + tests/t0102-objtype.c | 69 ++++++++++++++------------- tests/test_helpers.c | 4 +- tests/test_helpers.h | 2 +- wscript | 1 + 30 files changed, 408 insertions(+), 313 deletions(-) create mode 100644 src/git.h create mode 100644 src/git/object.h create mode 100644 src/git/odb_backend.h create mode 100644 src/git/types.h diff --git a/src/blob.c b/src/blob.c index 65e1dd947..28d48da2a 100644 --- a/src/blob.c +++ b/src/blob.c @@ -24,7 +24,7 @@ */ #include "git/common.h" -#include "git/odb.h" +#include "git/object.h" #include "git/repository.h" #include "common.h" diff --git a/src/commit.c b/src/commit.c index 7d21b88dc..9e3cd3301 100644 --- a/src/commit.c +++ b/src/commit.c @@ -24,7 +24,7 @@ */ #include "git/common.h" -#include "git/odb.h" +#include "git/object.h" #include "git/repository.h" #include "common.h" diff --git a/src/git.h b/src/git.h new file mode 100644 index 000000000..02ccf77d1 --- /dev/null +++ b/src/git.h @@ -0,0 +1,49 @@ +/* + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, + * as published by the Free Software Foundation. + * + * In addition to the permissions in the GNU General Public License, + * the authors give you unlimited permission to link the compiled + * version of this file into combinations with other programs, + * and to distribute those combinations without any restriction + * coming from the use of this file. (The General Public License + * restrictions do apply in other respects; for example, they cover + * modification of the file, and distribution when not linked into + * a combined executable.) + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDE_git_git_h__ +#define INCLUDE_git_git_h__ + +#include "git/common.h" +#include "git/errors.h" +#include "git/zlib.h" + +#include "git/types.h" + +#include "git/oid.h" +#include "git/odb.h" + +#include "git/repository.h" +#include "git/revwalk.h" + +#include "git/object.h" +#include "git/blob.h" +#include "git/commit.h" +#include "git/tag.h" +#include "git/tree.h" + +#include "git/index.h" + +#endif diff --git a/src/git/blob.h b/src/git/blob.h index 93ced42ee..f94b1f963 100644 --- a/src/git/blob.h +++ b/src/git/blob.h @@ -2,6 +2,7 @@ #define INCLUDE_git_blob_h__ #include "common.h" +#include "types.h" #include "oid.h" /** @@ -13,9 +14,6 @@ */ GIT_BEGIN_DECL -/** In-memory representation of a blob object. */ -typedef struct git_blob git_blob; - /** * Lookup a blob object from a repository. * The generated blob object is owned by the revision diff --git a/src/git/commit.h b/src/git/commit.h index 056997f45..54ecb622e 100644 --- a/src/git/commit.h +++ b/src/git/commit.h @@ -2,9 +2,8 @@ #define INCLUDE_git_commit_h__ #include "common.h" +#include "types.h" #include "oid.h" -#include "tree.h" -#include "repository.h" /** * @file git/commit.h @@ -15,9 +14,6 @@ */ GIT_BEGIN_DECL -/** Parsed representation of a commit object. */ -typedef struct git_commit git_commit; - /** * Lookup a commit object from a repository. * The generated commit object is owned by the revision diff --git a/src/git/common.h b/src/git/common.h index cb1684863..0a7de41ea 100644 --- a/src/git/common.h +++ b/src/git/common.h @@ -113,16 +113,6 @@ GIT_BEGIN_DECL -/** - * Representation of an existing git repository, - * including all its object contents - */ -typedef struct git_repository git_repository; - -/** Representation of a generic object in a repository */ -typedef struct git_object git_object; - - /** Parsed representation of a person */ typedef struct git_person git_person; diff --git a/src/git/errors.h b/src/git/errors.h index 8e9e423ed..f4720bebe 100644 --- a/src/git/errors.h +++ b/src/git/errors.h @@ -1,8 +1,6 @@ #ifndef INCLUDE_git_errors_h__ #define INCLUDE_git_errors_h__ -#include "common.h" - /** * @file git/errors.h * @brief Git error handling routines and variables diff --git a/src/git/index.h b/src/git/index.h index fd5710622..8bdced6a3 100644 --- a/src/git/index.h +++ b/src/git/index.h @@ -2,7 +2,7 @@ #define INCLUDE_git_index_h__ #include "common.h" -#include "oid.h" +#include "types.h" /** * @file git/index.h @@ -19,10 +19,6 @@ GIT_BEGIN_DECL #define GIT_IDXENTRY_VALID (0x8000) #define GIT_IDXENTRY_STAGESHIFT 12 -/** Memory representation of an index file. */ -typedef struct git_index git_index; - - /** Time used in a git index entry */ typedef struct { unsigned int seconds; diff --git a/src/git/object.h b/src/git/object.h new file mode 100644 index 000000000..516591729 --- /dev/null +++ b/src/git/object.h @@ -0,0 +1,108 @@ +#ifndef INCLUDE_git_object_h__ +#define INCLUDE_git_object_h__ + +#include "common.h" +#include "types.h" +#include "oid.h" + +/** + * @file git/object.h + * @brief Git revision object management routines + * @defgroup git_object Git revision object management routines + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Write back an object to disk. + * + * The object will be written to its corresponding + * repository. + * + * If the object has no changes since it was first + * read from the repository, no actions will take place. + * + * If the object has been modified since it was read from + * the repository, or it has been created from scratch + * in memory, it will be written to the repository and + * its SHA1 ID will be updated accordingly. + * + * @param object Git object to write back + * @return 0 on success; otherwise an error code + */ +GIT_EXTERN(int) git_object_write(git_object *object); + +/** + * Get the id (SHA1) of a repository object + * + * In-memory objects created by git_object_new() do not + * have a SHA1 ID until they are written on a repository. + * + * @param obj the repository object + * @return the SHA1 id + */ +GIT_EXTERN(const git_oid *) git_object_id(git_object *obj); + +/** + * Get the object type of an object + * + * @param obj the repository object + * @return the object's type + */ +GIT_EXTERN(git_otype) git_object_type(git_object *obj); + +/** + * Get the repository that owns this object + * + * @param obj the object + * @return the repository who owns this object + */ +GIT_EXTERN(git_repository *) git_object_owner(git_object *obj); + +/** + * Free a reference to one of the objects in the repository. + * + * Repository objects are managed automatically by the library, + * but this method can be used to force freeing one of the + * objects. + * + * Careful: freeing objects in the middle of a repository + * traversal will most likely cause errors. + * + * @param object the object to free + */ +GIT_EXTERN(void) git_object_free(git_object *object); + +/** + * Convert an object type to it's string representation. + * + * The result is a pointer to a string in static memory and + * should not be free()'ed. + * + * @param type object type to convert. + * @return the corresponding string representation. + */ +GIT_EXTERN(const char *) git_object_type2string(git_otype type); + +/** + * Convert a string object type representation to it's git_otype. + * + * @param str the string to convert. + * @return the corresponding git_otype. + */ +GIT_EXTERN(git_otype) git_object_string2type(const char *str); + +/** + * Determine if the given git_otype is a valid loose object type. + * + * @param type object type to test. + * @return true if the type represents a valid loose object type, + * false otherwise. + */ +GIT_EXTERN(int) git_object_typeisloose(git_otype type); + +/** @} */ +GIT_END_DECL + +#endif diff --git a/src/git/odb.h b/src/git/odb.h index 584a848c5..6be6ea2cf 100644 --- a/src/git/odb.h +++ b/src/git/odb.h @@ -2,8 +2,8 @@ #define INCLUDE_git_odb_h__ #include "common.h" +#include "types.h" #include "oid.h" -#include /** * @file git/odb.h @@ -14,12 +14,6 @@ */ GIT_BEGIN_DECL -/** An open object database handle. */ -typedef struct git_odb git_odb; - -/** A custom backend in an ODB */ -typedef struct git_odb_backend git_odb_backend; - /** * Create a new object database with no backends. * @@ -69,20 +63,6 @@ GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend); */ GIT_EXTERN(void) git_odb_close(git_odb *db); -/** Basic type (loose or packed) of any Git object. */ -typedef enum { - GIT_OBJ_ANY = -2, /**< Object can be any of the following */ - GIT_OBJ_BAD = -1, /**< Object is invalid. */ - GIT_OBJ__EXT1 = 0, /**< Reserved for future use. */ - GIT_OBJ_COMMIT = 1, /**< A commit object. */ - GIT_OBJ_TREE = 2, /**< A tree (directory listing) object. */ - GIT_OBJ_BLOB = 3, /**< A file revision object. */ - GIT_OBJ_TAG = 4, /**< An annotated tag object. */ - GIT_OBJ__EXT2 = 5, /**< Reserved for future use. */ - GIT_OBJ_OFS_DELTA = 6, /**< A delta, base is given by an offset. */ - GIT_OBJ_REF_DELTA = 7, /**< A delta, base is given by object id. */ -} git_otype; - /** An object read from the database. */ typedef struct { void *data; /**< Raw, decompressed object data. */ @@ -173,42 +153,7 @@ GIT_EXTERN(int) git_rawobj_hash(git_oid *id, git_rawobj *obj); * * @param obj object descriptor to free. */ -GIT_INLINE(void) git_rawobj_close(git_rawobj *obj) -{ - free(obj->data); - obj->data = NULL; -} - - - - -/** - * Convert an object type to it's string representation. - * - * The result is a pointer to a string in static memory and - * should not be free()'ed. - * - * @param type object type to convert. - * @return the corresponding string representation. - */ -GIT_EXTERN(const char *) git_otype_tostring(git_otype type); - -/** - * Convert a string object type representation to it's git_otype. - * - * @param str the string to convert. - * @return the corresponding git_otype. - */ -GIT_EXTERN(git_otype) git_otype_fromstring(const char *str); - -/** - * Determine if the given git_otype is a valid loose object type. - * - * @param type object type to test. - * @return true if the type represents a valid loose object type, - * false otherwise. - */ -GIT_EXTERN(int) git_otype_is_loose(git_otype type); +GIT_EXTERN(void) git_rawobj_close(git_rawobj *obj); /** @} */ GIT_END_DECL diff --git a/src/git/odb_backend.h b/src/git/odb_backend.h new file mode 100644 index 000000000..747f4e97a --- /dev/null +++ b/src/git/odb_backend.h @@ -0,0 +1,40 @@ +#ifndef INCLUDE_git_odb_backend_h__ +#define INCLUDE_git_odb_backend_h__ + +#include "common.h" +#include "types.h" +#include "oid.h" + +GIT_BEGIN_DECL + +struct git_odb_backend { + git_odb *odb; + + int priority; + + int (* read)( + git_rawobj *, + struct git_odb_backend *, + const git_oid *); + + int (* read_header)( + git_rawobj *, + struct git_odb_backend *, + const git_oid *); + + int (* write)( + git_oid *id, + struct git_odb_backend *, + git_rawobj *obj); + + int (* exists)( + struct git_odb_backend *, + const git_oid *); + + void (* free)(struct git_odb_backend *); + +}; + +GIT_END_DECL + +#endif diff --git a/src/git/oid.h b/src/git/oid.h index fe3c74b75..f0e39da68 100644 --- a/src/git/oid.h +++ b/src/git/oid.h @@ -1,9 +1,6 @@ #ifndef INCLUDE_git_oid_h__ #define INCLUDE_git_oid_h__ -#include "common.h" -#include - /** * @file git/oid.h * @brief Git object id routines @@ -40,10 +37,7 @@ GIT_EXTERN(int) git_oid_mkstr(git_oid *out, const char *str); * @param out oid structure the result is written into. * @param raw the raw input bytes to be copied. */ -GIT_INLINE(void) git_oid_mkraw(git_oid *out, const unsigned char *raw) -{ - memcpy(out->id, raw, sizeof(out->id)); -} +GIT_EXTERN(void) git_oid_mkraw(git_oid *out, const unsigned char *raw); /** * Format a git_oid into a hex string. @@ -101,10 +95,7 @@ GIT_EXTERN(char *) git_oid_to_string(char *out, size_t n, const git_oid *oid); * @param out oid structure the result is written into. * @param src oid structure to copy from. */ -GIT_INLINE(void) git_oid_cpy(git_oid *out, const git_oid *src) -{ - memcpy(out->id, src->id, sizeof(out->id)); -} +GIT_EXTERN(void) git_oid_cpy(git_oid *out, const git_oid *src); /** * Compare two oid structures. @@ -112,10 +103,7 @@ GIT_INLINE(void) git_oid_cpy(git_oid *out, const git_oid *src) * @param b second oid structure. * @return <0, 0, >0 if a < b, a == b, a > b. */ -GIT_INLINE(int) git_oid_cmp(const git_oid *a, const git_oid *b) -{ - return memcmp(a->id, b->id, sizeof(a->id)); -} +GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b); /** @} */ GIT_END_DECL diff --git a/src/git/repository.h b/src/git/repository.h index 661034719..683e78fc9 100644 --- a/src/git/repository.h +++ b/src/git/repository.h @@ -2,14 +2,13 @@ #define INCLUDE_git_repository_h__ #include "common.h" -#include "odb.h" -#include "commit.h" -#include "index.h" +#include "types.h" +#include "oid.h" /** * @file git/repository.h - * @brief Git revision object management routines - * @defgroup git_repository Git revision object management routines + * @brief Git repository management routines + * @defgroup git_repository Git repository management routines * @ingroup Git * @{ */ @@ -133,66 +132,6 @@ GIT_EXTERN(git_index *) git_repository_index(git_repository *rpeo); */ GIT_EXTERN(int) git_repository_newobject(git_object **object, git_repository *repo, git_otype type); -/** - * Write back an object to disk. - * - * The object will be written to its corresponding - * repository. - * - * If the object has no changes since it was first - * read from the repository, no actions will take place. - * - * If the object has been modified since it was read from - * the repository, or it has been created from scratch - * in memory, it will be written to the repository and - * its SHA1 ID will be updated accordingly. - * - * @param object Git object to write back - * @return 0 on success; otherwise an error code - */ -GIT_EXTERN(int) git_object_write(git_object *object); - -/** - * Get the id (SHA1) of a repository object - * - * In-memory objects created by git_object_new() do not - * have a SHA1 ID until they are written on a repository. - * - * @param obj the repository object - * @return the SHA1 id - */ -GIT_EXTERN(const git_oid *) git_object_id(git_object *obj); - -/** - * Get the object type of an object - * - * @param obj the repository object - * @return the object's type - */ -GIT_EXTERN(git_otype) git_object_type(git_object *obj); - -/** - * Get the repository that owns this object - * - * @param obj the object - * @return the repository who owns this object - */ -GIT_EXTERN(git_repository *) git_object_owner(git_object *obj); - -/** - * Free a reference to one of the objects in the repository. - * - * Repository objects are managed automatically by the library, - * but this method can be used to force freeing one of the - * objects. - * - * Careful: freeing objects in the middle of a repository - * traversal will most likely cause errors. - * - * @param object the object to free - */ -GIT_EXTERN(void) git_object_free(git_object *object); - /** * Free a previously allocated repository * @param repo repository handle to close. If NULL nothing occurs. diff --git a/src/git/revwalk.h b/src/git/revwalk.h index 49fd32174..6a761088a 100644 --- a/src/git/revwalk.h +++ b/src/git/revwalk.h @@ -2,8 +2,7 @@ #define INCLUDE_git_revwalk_h__ #include "common.h" -#include "odb.h" -#include "commit.h" +#include "types.h" /** * @file git/revwalk.h @@ -43,8 +42,6 @@ GIT_BEGIN_DECL */ #define GIT_SORT_REVERSE (1 << 2) -typedef struct git_revwalk git_revwalk; - /** * Allocate a new revision walker to iterate through a repo. * diff --git a/src/git/tag.h b/src/git/tag.h index cc15651ab..d57009870 100644 --- a/src/git/tag.h +++ b/src/git/tag.h @@ -2,9 +2,8 @@ #define INCLUDE_git_tag_h__ #include "common.h" +#include "types.h" #include "oid.h" -#include "tree.h" -#include "repository.h" /** * @file git/tag.h @@ -15,9 +14,6 @@ */ GIT_BEGIN_DECL -/** Parsed representation of a tag object. */ -typedef struct git_tag git_tag; - /** * Lookup a tag object from the repository. * The generated tag object is owned by the revision diff --git a/src/git/tree.h b/src/git/tree.h index f471113a8..d935169d8 100644 --- a/src/git/tree.h +++ b/src/git/tree.h @@ -2,8 +2,8 @@ #define INCLUDE_git_tree_h__ #include "common.h" +#include "types.h" #include "oid.h" -#include "repository.h" /** * @file git/tree.h @@ -14,13 +14,6 @@ */ GIT_BEGIN_DECL - -/** Representation of each one of the entries in a tree object. */ -typedef struct git_tree_entry git_tree_entry; - -/** Representation of a tree object. */ -typedef struct git_tree git_tree; - /** * Lookup a tree object from the repository. * The generated tree object is owned by the revision diff --git a/src/git/types.h b/src/git/types.h new file mode 100644 index 000000000..18684e13d --- /dev/null +++ b/src/git/types.h @@ -0,0 +1,64 @@ +#ifndef INCLUDE_git_types_h__ +#define INCLUDE_git_types_h__ + +/** + * @file git/types.h + * @brief libgit2 base types + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** Basic type (loose or packed) of any Git object. */ +typedef enum { + GIT_OBJ_ANY = -2, /**< Object can be any of the following */ + GIT_OBJ_BAD = -1, /**< Object is invalid. */ + GIT_OBJ__EXT1 = 0, /**< Reserved for future use. */ + GIT_OBJ_COMMIT = 1, /**< A commit object. */ + GIT_OBJ_TREE = 2, /**< A tree (directory listing) object. */ + GIT_OBJ_BLOB = 3, /**< A file revision object. */ + GIT_OBJ_TAG = 4, /**< An annotated tag object. */ + GIT_OBJ__EXT2 = 5, /**< Reserved for future use. */ + GIT_OBJ_OFS_DELTA = 6, /**< A delta, base is given by an offset. */ + GIT_OBJ_REF_DELTA = 7, /**< A delta, base is given by object id. */ +} git_otype; + +/** An open object database handle. */ +typedef struct git_odb git_odb; + +/** A custom backend in an ODB */ +typedef struct git_odb_backend git_odb_backend; + +/** + * Representation of an existing git repository, + * including all its object contents + */ +typedef struct git_repository git_repository; + +/** Representation of a generic object in a repository */ +typedef struct git_object git_object; + +typedef struct git_revwalk git_revwalk; + +/** Parsed representation of a tag object. */ +typedef struct git_tag git_tag; + +/** In-memory representation of a blob object. */ +typedef struct git_blob git_blob; + +/** Parsed representation of a commit object. */ +typedef struct git_commit git_commit; + +/** Representation of each one of the entries in a tree object. */ +typedef struct git_tree_entry git_tree_entry; + +/** Representation of a tree object. */ +typedef struct git_tree git_tree; + +/** Memory representation of an index file. */ +typedef struct git_index git_index; + +/** @} */ +GIT_END_DECL + +#endif diff --git a/src/git/zlib.h b/src/git/zlib.h index 1fec05920..b68db9bc1 100644 --- a/src/git/zlib.h +++ b/src/git/zlib.h @@ -1,7 +1,6 @@ #ifndef INCLUDE_git_zlib_h__ #define INCLUDE_git_zlib_h__ -#include "common.h" #include /** diff --git a/src/odb.c b/src/odb.c index 1dbda1a3c..1595e5f9f 100644 --- a/src/odb.c +++ b/src/odb.c @@ -25,62 +25,17 @@ #include "common.h" #include "git/zlib.h" +#include "git/object.h" #include "fileops.h" #include "hash.h" #include "odb.h" #include "delta-apply.h" -static struct { - const char *str; /* type name string */ - int loose; /* valid loose object type flag */ -} obj_type_table[] = { - { "", 0 }, /* 0 = GIT_OBJ__EXT1 */ - { "commit", 1 }, /* 1 = GIT_OBJ_COMMIT */ - { "tree", 1 }, /* 2 = GIT_OBJ_TREE */ - { "blob", 1 }, /* 3 = GIT_OBJ_BLOB */ - { "tag", 1 }, /* 4 = GIT_OBJ_TAG */ - { "", 0 }, /* 5 = GIT_OBJ__EXT2 */ - { "OFS_DELTA", 0 }, /* 6 = GIT_OBJ_OFS_DELTA */ - { "REF_DELTA", 0 } /* 7 = GIT_OBJ_REF_DELTA */ -}; - -/*********************************************************** - * - * MISCELANEOUS HELPER FUNCTIONS - * - ***********************************************************/ - -const char *git_otype_tostring(git_otype type) -{ - if (type < 0 || ((size_t) type) >= ARRAY_SIZE(obj_type_table)) - return ""; - return obj_type_table[type].str; -} - -git_otype git_otype_fromstring(const char *str) -{ - size_t i; - - if (!str || !*str) - return GIT_OBJ_BAD; - - for (i = 0; i < ARRAY_SIZE(obj_type_table); i++) - if (!strcmp(str, obj_type_table[i].str)) - return (git_otype) i; - - return GIT_OBJ_BAD; -} - -int git_otype_is_loose(git_otype type) -{ - if (type < 0 || ((size_t) type) >= ARRAY_SIZE(obj_type_table)) - return 0; - return obj_type_table[type].loose; -} +#include "git/odb_backend.h" static int format_object_header(char *hdr, size_t n, git_rawobj *obj) { - const char *type_str = git_otype_tostring(obj->type); + const char *type_str = git_object_type2string(obj->type); int len = snprintf(hdr, n, "%s %"PRIuZ, type_str, obj->len); assert(len > 0); /* otherwise snprintf() is broken */ @@ -98,7 +53,7 @@ int git_odb__hash_obj(git_oid *id, char *hdr, size_t n, int *len, git_rawobj *ob assert(id && hdr && len && obj); - if (!git_otype_is_loose(obj->type)) + if (!git_object_typeisloose(obj->type)) return GIT_ERROR; if (!obj->data && obj->len != 0) @@ -119,6 +74,12 @@ int git_odb__hash_obj(git_oid *id, char *hdr, size_t n, int *len, git_rawobj *ob return GIT_SUCCESS; } +void git_rawobj_close(git_rawobj *obj) +{ + free(obj->data); + obj->data = NULL; +} + int git_rawobj_hash(git_oid *id, git_rawobj *obj) { char hdr[64]; diff --git a/src/odb.h b/src/odb.h index 2726cbb46..72f0ea2b3 100644 --- a/src/odb.h +++ b/src/odb.h @@ -11,34 +11,6 @@ struct git_odb { git_vector backends; }; -struct git_odb_backend { - git_odb *odb; - - int priority; - - int (* read)( - git_rawobj *, - struct git_odb_backend *, - const git_oid *); - - int (* read_header)( - git_rawobj *, - struct git_odb_backend *, - const git_oid *); - - int (* write)( - git_oid *id, - struct git_odb_backend *, - git_rawobj *obj); - - int (* exists)( - struct git_odb_backend *, - const git_oid *); - - void (* free)(struct git_odb_backend *); - -}; - int git_odb__hash_obj(git_oid *id, char *hdr, size_t n, int *len, git_rawobj *obj); int git_odb__inflate_buffer(void *in, size_t inlen, void *out, size_t outlen); diff --git a/src/odb_loose.c b/src/odb_loose.c index 52430467b..a7d0d5c8a 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -25,11 +25,13 @@ #include "common.h" #include "git/zlib.h" +#include "git/object.h" #include "fileops.h" #include "hash.h" #include "odb.h" #include "delta-apply.h" +#include "git/odb_backend.h" typedef struct { /* object header data */ git_otype type; /* object type */ @@ -148,7 +150,7 @@ static size_t get_object_header(obj_hdr *hdr, unsigned char *data) typename[used] = 0; if (used == 0) return 0; - hdr->type = git_otype_fromstring(typename); + hdr->type = git_object_string2type(typename); used++; /* consume the space */ /* @@ -357,7 +359,7 @@ static int inflate_packlike_loose_disk_obj(git_rawobj *out, gitfo_buf *obj) if ((used = get_binary_object_header(&hdr, obj)) == 0) return GIT_ERROR; - if (!git_otype_is_loose(hdr.type)) + if (!git_object_typeisloose(hdr.type)) return GIT_ERROR; /* @@ -406,7 +408,7 @@ static int inflate_disk_obj(git_rawobj *out, gitfo_buf *obj) if ((used = get_object_header(&hdr, head)) == 0) return GIT_ERROR; - if (!git_otype_is_loose(hdr.type)) + if (!git_object_typeisloose(hdr.type)) return GIT_ERROR; /* @@ -489,7 +491,7 @@ static int read_header_loose(git_rawobj *out, const char *loc) if ((z_return != Z_STREAM_END && z_return != Z_BUF_ERROR) || get_object_header(&header_obj, inflated_buffer) == 0 - || git_otype_is_loose(header_obj.type) == 0) { + || git_object_typeisloose(header_obj.type) == 0) { error = GIT_EOBJCORRUPTED; goto cleanup; } diff --git a/src/odb_pack.c b/src/odb_pack.c index f97e216c5..82b8f147a 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -25,11 +25,14 @@ #include "common.h" #include "git/zlib.h" +#include "git/repository.h" #include "fileops.h" #include "hash.h" #include "odb.h" #include "delta-apply.h" +#include "git/odb_backend.h" + /** First 4 bytes of a pack-*.idx file header. * * Note this header exists only in idx v2 and later. The idx v1 diff --git a/src/oid.c b/src/oid.c index f86098d3e..f40dd14ec 100644 --- a/src/oid.c +++ b/src/oid.c @@ -151,3 +151,18 @@ int git__write_oid(git_odb_source *src, const char *header, const git_oid *oid) return git__source_printf(src, "%s %s\n", header, hex_oid); } + +void git_oid_mkraw(git_oid *out, const unsigned char *raw) +{ + memcpy(out->id, raw, sizeof(out->id)); +} + +void git_oid_cpy(git_oid *out, const git_oid *src) +{ + memcpy(out->id, src->id, sizeof(out->id)); +} + +int git_oid_cmp(const git_oid *a, const git_oid *b) +{ + return memcmp(a->id, b->id, sizeof(a->id)); +} diff --git a/src/repository.c b/src/repository.c index 9b23ed74e..9a3563710 100644 --- a/src/repository.c +++ b/src/repository.c @@ -24,6 +24,8 @@ */ #include +#include "git/object.h" + #include "common.h" #include "repository.h" #include "commit.h" @@ -41,14 +43,28 @@ static const double max_load_factor = 0.65; static const int OBJECT_BASE_SIZE = 4096; -static const size_t object_sizes[] = { - 0, - sizeof(git_commit), - sizeof(git_tree), - sizeof(git_blob), - sizeof(git_tag) +static struct { + const char *str; /* type name string */ + int loose; /* valid loose object type flag */ + size_t size; /* size in bytes of the object structure */ +} git_objects_table[] = { + { "", 0, 0 }, /* 0 = GIT_OBJ__EXT1 */ + { "commit", 1, sizeof(git_commit)}, /* 1 = GIT_OBJ_COMMIT */ + { "tree", 1, sizeof(git_tree) }, /* 2 = GIT_OBJ_TREE */ + { "blob", 1, sizeof(git_blob) }, /* 3 = GIT_OBJ_BLOB */ + { "tag", 1, sizeof(git_tag) }, /* 4 = GIT_OBJ_TAG */ + { "", 0, 0 }, /* 5 = GIT_OBJ__EXT2 */ + { "OFS_DELTA", 0, 0 }, /* 6 = GIT_OBJ_OFS_DELTA */ + { "REF_DELTA", 0, 0 } /* 7 = GIT_OBJ_REF_DELTA */ }; +/*********************************************************** + * + * MISCELANEOUS HELPER FUNCTIONS + * + ***********************************************************/ + + uint32_t git__objtable_hash(const void *key) { @@ -570,12 +586,12 @@ int git_repository_newobject(git_object **object_out, git_repository *repo, git_ return GIT_EINVALIDTYPE; } - object = git__malloc(object_sizes[type]); + object = git__malloc(git_objects_table[type].size); if (object == NULL) return GIT_ENOMEM; - memset(object, 0x0, object_sizes[type]); + memset(object, 0x0, git_objects_table[type].size); object->repo = repo; object->in_memory = 1; object->modified = 1; @@ -609,12 +625,12 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g type = obj_file.type; - object = git__malloc(object_sizes[type]); + object = git__malloc(git_objects_table[type].size); if (object == NULL) return GIT_ENOMEM; - memset(object, 0x0, object_sizes[type]); + memset(object, 0x0, git_objects_table[type].size); /* Initialize parent object */ git_oid_cpy(&object->id, id); @@ -668,3 +684,32 @@ GIT_NEWOBJECT_TEMPLATE(tree, TREE) GIT_NEWOBJECT_TEMPLATE(blob, BLOB) +const char *git_object_type2string(git_otype type) +{ + if (type < 0 || ((size_t) type) >= ARRAY_SIZE(git_objects_table)) + return ""; + + return git_objects_table[type].str; +} + +git_otype git_object_string2type(const char *str) +{ + size_t i; + + if (!str || !*str) + return GIT_OBJ_BAD; + + for (i = 0; i < ARRAY_SIZE(git_objects_table); i++) + if (!strcmp(str, git_objects_table[i].str)) + return (git_otype)i; + + return GIT_OBJ_BAD; +} + +int git_object_typeisloose(git_otype type) +{ + if (type < 0 || ((size_t) type) >= ARRAY_SIZE(git_objects_table)) + return 0; + + return git_objects_table[type].loose; +} diff --git a/src/tag.c b/src/tag.c index 82d80b4b8..23542999d 100644 --- a/src/tag.c +++ b/src/tag.c @@ -28,7 +28,7 @@ #include "tag.h" #include "person.h" #include "revwalk.h" -#include "git/odb.h" +#include "git/object.h" #include "git/repository.h" void git_tag__free(git_tag *tag) @@ -215,7 +215,7 @@ int git_tag__writeback(git_tag *tag, git_odb_source *src) return GIT_EMISSINGOBJDATA; git__write_oid(src, "object", git_object_id(tag->target)); - git__source_printf(src, "type %s\n", git_otype_tostring(tag->type)); + git__source_printf(src, "type %s\n", git_object_type2string(tag->type)); git__source_printf(src, "tag %s\n", tag->tag_name); git_person__write(src, "tagger", tag->tagger); diff --git a/src/tree.c b/src/tree.c index a0138ca5f..0fc309209 100644 --- a/src/tree.c +++ b/src/tree.c @@ -28,6 +28,7 @@ #include "revwalk.h" #include "tree.h" #include "git/repository.h" +#include "git/object.h" int entry_search_cmp(const void *key, const void *array_member) { diff --git a/tests/t0102-objtype.c b/tests/t0102-objtype.c index a234798ea..ec4e15d44 100644 --- a/tests/t0102-objtype.c +++ b/tests/t0102-objtype.c @@ -1,50 +1,51 @@ #include "test_lib.h" #include +#include BEGIN_TEST(type_to_string) - must_be_true(!strcmp(git_otype_tostring(GIT_OBJ_BAD), "")); - must_be_true(!strcmp(git_otype_tostring(GIT_OBJ__EXT1), "")); - must_be_true(!strcmp(git_otype_tostring(GIT_OBJ_COMMIT), "commit")); - must_be_true(!strcmp(git_otype_tostring(GIT_OBJ_TREE), "tree")); - must_be_true(!strcmp(git_otype_tostring(GIT_OBJ_BLOB), "blob")); - must_be_true(!strcmp(git_otype_tostring(GIT_OBJ_TAG), "tag")); - must_be_true(!strcmp(git_otype_tostring(GIT_OBJ__EXT2), "")); - must_be_true(!strcmp(git_otype_tostring(GIT_OBJ_OFS_DELTA), "OFS_DELTA")); - must_be_true(!strcmp(git_otype_tostring(GIT_OBJ_REF_DELTA), "REF_DELTA")); + must_be_true(!strcmp(git_object_type2string(GIT_OBJ_BAD), "")); + must_be_true(!strcmp(git_object_type2string(GIT_OBJ__EXT1), "")); + must_be_true(!strcmp(git_object_type2string(GIT_OBJ_COMMIT), "commit")); + must_be_true(!strcmp(git_object_type2string(GIT_OBJ_TREE), "tree")); + must_be_true(!strcmp(git_object_type2string(GIT_OBJ_BLOB), "blob")); + must_be_true(!strcmp(git_object_type2string(GIT_OBJ_TAG), "tag")); + must_be_true(!strcmp(git_object_type2string(GIT_OBJ__EXT2), "")); + must_be_true(!strcmp(git_object_type2string(GIT_OBJ_OFS_DELTA), "OFS_DELTA")); + must_be_true(!strcmp(git_object_type2string(GIT_OBJ_REF_DELTA), "REF_DELTA")); - must_be_true(!strcmp(git_otype_tostring(-2), "")); - must_be_true(!strcmp(git_otype_tostring(8), "")); - must_be_true(!strcmp(git_otype_tostring(1234), "")); + must_be_true(!strcmp(git_object_type2string(-2), "")); + must_be_true(!strcmp(git_object_type2string(8), "")); + must_be_true(!strcmp(git_object_type2string(1234), "")); END_TEST BEGIN_TEST(string_to_type) - must_be_true(git_otype_fromstring(NULL) == GIT_OBJ_BAD); - must_be_true(git_otype_fromstring("") == GIT_OBJ_BAD); - must_be_true(git_otype_fromstring("commit") == GIT_OBJ_COMMIT); - must_be_true(git_otype_fromstring("tree") == GIT_OBJ_TREE); - must_be_true(git_otype_fromstring("blob") == GIT_OBJ_BLOB); - must_be_true(git_otype_fromstring("tag") == GIT_OBJ_TAG); - must_be_true(git_otype_fromstring("OFS_DELTA") == GIT_OBJ_OFS_DELTA); - must_be_true(git_otype_fromstring("REF_DELTA") == GIT_OBJ_REF_DELTA); + must_be_true(git_object_string2type(NULL) == GIT_OBJ_BAD); + must_be_true(git_object_string2type("") == GIT_OBJ_BAD); + must_be_true(git_object_string2type("commit") == GIT_OBJ_COMMIT); + must_be_true(git_object_string2type("tree") == GIT_OBJ_TREE); + must_be_true(git_object_string2type("blob") == GIT_OBJ_BLOB); + must_be_true(git_object_string2type("tag") == GIT_OBJ_TAG); + must_be_true(git_object_string2type("OFS_DELTA") == GIT_OBJ_OFS_DELTA); + must_be_true(git_object_string2type("REF_DELTA") == GIT_OBJ_REF_DELTA); - must_be_true(git_otype_fromstring("CoMmIt") == GIT_OBJ_BAD); - must_be_true(git_otype_fromstring("hohoho") == GIT_OBJ_BAD); + must_be_true(git_object_string2type("CoMmIt") == GIT_OBJ_BAD); + must_be_true(git_object_string2type("hohoho") == GIT_OBJ_BAD); END_TEST BEGIN_TEST(loose_object) - must_be_true(git_otype_is_loose(GIT_OBJ_BAD) == 0); - must_be_true(git_otype_is_loose(GIT_OBJ__EXT1) == 0); - must_be_true(git_otype_is_loose(GIT_OBJ_COMMIT) == 1); - must_be_true(git_otype_is_loose(GIT_OBJ_TREE) == 1); - must_be_true(git_otype_is_loose(GIT_OBJ_BLOB) == 1); - must_be_true(git_otype_is_loose(GIT_OBJ_TAG) == 1); - must_be_true(git_otype_is_loose(GIT_OBJ__EXT2) == 0); - must_be_true(git_otype_is_loose(GIT_OBJ_OFS_DELTA) == 0); - must_be_true(git_otype_is_loose(GIT_OBJ_REF_DELTA) == 0); + must_be_true(git_object_typeisloose(GIT_OBJ_BAD) == 0); + must_be_true(git_object_typeisloose(GIT_OBJ__EXT1) == 0); + must_be_true(git_object_typeisloose(GIT_OBJ_COMMIT) == 1); + must_be_true(git_object_typeisloose(GIT_OBJ_TREE) == 1); + must_be_true(git_object_typeisloose(GIT_OBJ_BLOB) == 1); + must_be_true(git_object_typeisloose(GIT_OBJ_TAG) == 1); + must_be_true(git_object_typeisloose(GIT_OBJ__EXT2) == 0); + must_be_true(git_object_typeisloose(GIT_OBJ_OFS_DELTA) == 0); + must_be_true(git_object_typeisloose(GIT_OBJ_REF_DELTA) == 0); - must_be_true(git_otype_is_loose(-2) == 0); - must_be_true(git_otype_is_loose(8) == 0); - must_be_true(git_otype_is_loose(1234) == 0); + must_be_true(git_object_typeisloose(-2) == 0); + must_be_true(git_object_typeisloose(8) == 0); + must_be_true(git_object_typeisloose(1234) == 0); END_TEST diff --git a/tests/test_helpers.c b/tests/test_helpers.c index cd14c0e29..5fd9a565a 100644 --- a/tests/test_helpers.c +++ b/tests/test_helpers.c @@ -26,8 +26,6 @@ #include "common.h" #include "test_helpers.h" #include "fileops.h" -#include "git/oid.h" -#include "git/repository.h" int write_object_data(char *file, void *data, size_t len) { @@ -125,7 +123,7 @@ int remove_loose_object(const char *repository_folder, git_object *object) int cmp_objects(git_rawobj *o, object_data *d) { - if (o->type != git_otype_fromstring(d->type)) + if (o->type != git_object_string2type(d->type)) return -1; if (o->len != d->dlen) return -1; diff --git a/tests/test_helpers.h b/tests/test_helpers.h index 7085c645e..d6d32140e 100644 --- a/tests/test_helpers.h +++ b/tests/test_helpers.h @@ -27,7 +27,7 @@ #define INCLUDE_test_helpers_h__ #include "test_lib.h" -#include +#include #define ODB_FOLDER "../resources/testrepo.git/objects/" #define REPOSITORY_FOLDER "../resources/testrepo.git/" diff --git a/wscript b/wscript index 68b755e5b..db41dbf53 100644 --- a/wscript +++ b/wscript @@ -131,6 +131,7 @@ def build_library(bld, lib_str): ) # Install headers + bld.install_files('${PREFIX}/include', directory.find_node('src/git.h')) bld.install_files('${PREFIX}/include/git', directory.ant_glob('src/git/*.h')) def grep_test_header(text, test_file):