diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b5a2842c..cf3b62246 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,9 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") # Build options # +# Experimental features +option(EXPERIMENTAL_SHA256 "Enable experimental SHA256 support (for R&D/testing)" OFF) + # Optional subsystems option(BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON) option(BUILD_TESTS "Build Tests using the Clar suite" ON) @@ -107,6 +110,7 @@ include(IdeSplitSources) include(FeatureSummary) include(EnableWarnings) include(DefaultCFlags) +include(ExperimentalFeatures) # diff --git a/cmake/ExperimentalFeatures.cmake b/cmake/ExperimentalFeatures.cmake new file mode 100644 index 000000000..f23bfe376 --- /dev/null +++ b/cmake/ExperimentalFeatures.cmake @@ -0,0 +1,12 @@ +if(EXPERIMENTAL_SHA256) + add_feature_info("SHA256 API" ON "experimental SHA256 APIs") + + set(EXPERIMENTAL 1) + set(GIT_EXPERIMENTAL_SHA256 1) +else() + add_feature_info("SHA256 API" OFF "experimental SHA256 APIs") +endif() + +if(EXPERIMENTAL) + set(LIBGIT2_FILENAME "${LIBGIT2_FILENAME}-experimental") +endif() diff --git a/include/git2.h b/include/git2.h index 2961cc3e5..3457e5f04 100644 --- a/include/git2.h +++ b/include/git2.h @@ -28,6 +28,7 @@ #include "git2/diff.h" #include "git2/email.h" #include "git2/errors.h" +#include "git2/experimental.h" #include "git2/filter.h" #include "git2/global.h" #include "git2/graph.h" diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index c32abeeb7..52864ebe1 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -777,6 +777,12 @@ typedef git_trace_cb git_trace_callback; */ /**@{*/ +#ifndef GIT_EXPERIMENTAL_SHA256 +# define GIT_OID_RAWSZ GIT_OID_SHA1_SIZE +# define GIT_OID_HEXSZ GIT_OID_SHA1_HEXSIZE +# define GIT_OID_HEX_ZERO GIT_OID_SHA1_HEXZERO +#endif + GIT_EXTERN(int) git_oid_iszero(const git_oid *id); /**@}*/ diff --git a/include/git2/oid.h b/include/git2/oid.h index 6136e2858..3e828ae70 100644 --- a/include/git2/oid.h +++ b/include/git2/oid.h @@ -9,6 +9,7 @@ #include "common.h" #include "types.h" +#include "experimental.h" /** * @file git2/oid.h @@ -21,22 +22,74 @@ GIT_BEGIN_DECL /** The type of object id. */ typedef enum { + +#ifdef GIT_EXPERIMENTAL_SHA256 GIT_OID_SHA1 = 1, /**< SHA1 */ GIT_OID_SHA256 = 2 /**< SHA256 */ +#else + GIT_OID_SHA1 = 1 /**< SHA1 */ +#endif + } git_oid_t; +/* + * SHA1 is currently the only supported object ID type. + */ + /** SHA1 is currently libgit2's default oid type. */ #define GIT_OID_DEFAULT GIT_OID_SHA1 -/** Size (in bytes) of a raw/binary oid */ +/** Size (in bytes) of a raw/binary sha1 oid */ #define GIT_OID_SHA1_SIZE 20 -#define GIT_OID_SHA256_SIZE 32 -#define GIT_OID_MAX_SIZE GIT_OID_SHA256_SIZE - -/** Size (in bytes) of a hex formatted oid */ +/** Size (in bytes) of a hex formatted sha1 oid */ #define GIT_OID_SHA1_HEXSIZE (GIT_OID_SHA1_SIZE * 2) -#define GIT_OID_SHA256_HEXSIZE (GIT_OID_SHA256_SIZE * 2) -#define GIT_OID_MAX_HEXSIZE GIT_OID_SHA256_HEXSIZE + +/** + * The binary representation of the null sha1 object ID. + */ +#ifndef GIT_EXPERIMENTAL_SHA256 +# define GIT_OID_SHA1_ZERO { { 0 } } +#else +# define GIT_OID_SHA1_ZERO { GIT_OID_SHA1, { 0 } } +#endif + +/** + * The string representation of the null sha1 object ID. + */ +#define GIT_OID_SHA1_HEXZERO "0000000000000000000000000000000000000000" + +/* + * Experimental SHA256 support is a breaking change to the API. + * This exists for application compatibility testing. + */ + +#ifdef GIT_EXPERIMENTAL_SHA256 + +/** Size (in bytes) of a raw/binary sha256 oid */ +# define GIT_OID_SHA256_SIZE 32 +/** Size (in bytes) of a hex formatted sha256 oid */ +# define GIT_OID_SHA256_HEXSIZE (GIT_OID_SHA256_SIZE * 2) + +/** + * The binary representation of the null sha256 object ID. + */ +# define GIT_OID_SHA256_ZERO { GIT_OID_SHA256, { 0 } } + +/** + * The string representation of the null sha256 object ID. + */ +# define GIT_OID_SHA256_HEXZERO "0000000000000000000000000000000000000000000000000000000000000000" + +#endif + +/* Maximum possible object ID size in raw / hex string format. */ +#ifndef GIT_EXPERIMENTAL_SHA256 +# define GIT_OID_MAX_SIZE GIT_OID_SHA1_SIZE +# define GIT_OID_MAX_HEXSIZE GIT_OID_SHA1_HEXSIZE +#else +# define GIT_OID_MAX_SIZE GIT_OID_SHA256_SIZE +# define GIT_OID_MAX_HEXSIZE GIT_OID_SHA256_HEXSIZE +#endif /** Minimum length (in number of hex characters, * i.e. packets of 4 bits) of an oid prefix */ @@ -44,25 +97,16 @@ typedef enum { /** Unique identity of any object (commit, tree, blob, tag). */ typedef struct git_oid { + +#ifdef GIT_EXPERIMENTAL_SHA256 /** type of object id */ unsigned char type; +#endif /** raw binary formatted id */ unsigned char id[GIT_OID_MAX_SIZE]; } git_oid; -/** - * The binary representation of the null object ID. - */ -#define GIT_OID_SHA1_ZERO { GIT_OID_SHA1, { 0 } } -#define GIT_OID_SHA256_ZERO { GIT_OID_SHA256, { 0 } } - -/** - * The string representation of the null object ID. - */ -#define GIT_OID_SHA1_HEXZERO "0000000000000000000000000000000000000000" -#define GIT_OID_SHA256_HEXZERO "0000000000000000000000000000000000000000000000000000000000000000" - /** * Parse a hex formatted object id into a git_oid. * diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index 5274ab086..46f4d63b5 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -1,5 +1,7 @@ set(CLI_INCLUDES "${libgit2_BINARY_DIR}/src/util" + "${libgit2_BINARY_DIR}/include" + "${libgit2_BINARY_DIR}/include/git2" "${libgit2_SOURCE_DIR}/src/util" "${libgit2_SOURCE_DIR}/src/cli" "${libgit2_SOURCE_DIR}/include") @@ -39,6 +41,7 @@ target_link_libraries(git2_cli ${CLI_LIBGIT2_LIBRARY} ${LIBGIT2_SYSTEM_LIBS}) set_target_properties(git2_cli PROPERTIES C_STANDARD 90) set_target_properties(git2_cli PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) +set_target_properties(git2_cli PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME}) ide_split_sources(git2_cli) diff --git a/src/libgit2/CMakeLists.txt b/src/libgit2/CMakeLists.txt index 5fbb03d9f..3462b795e 100644 --- a/src/libgit2/CMakeLists.txt +++ b/src/libgit2/CMakeLists.txt @@ -9,6 +9,8 @@ include(PkgBuildConfig) set(LIBGIT2_INCLUDES "${PROJECT_BINARY_DIR}/src/util" + "${PROJECT_BINARY_DIR}/include" + "${PROJECT_BINARY_DIR}/include/git2" "${PROJECT_SOURCE_DIR}/src/libgit2" "${PROJECT_SOURCE_DIR}/src/util" "${PROJECT_SOURCE_DIR}/include") @@ -109,7 +111,7 @@ if(SONAME) endif() endif() -pkg_build_config(NAME libgit2 +pkg_build_config(NAME "${LIBGIT2_FILENAME}" VERSION ${libgit2_VERSION} DESCRIPTION "The git library, take 2" LIBS_SELF git2 @@ -122,10 +124,26 @@ if(MSVC_IDE) set_source_files_properties(win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h") endif() +# support experimental features and functionality + +configure_file(experimental.h.in "${PROJECT_BINARY_DIR}/include/git2/experimental.h") + +# translate filenames in the git2.h so that they match the install directory +# (allows for side-by-side installs of libgit2 and libgit2-experimental.) + +FILE(READ "${PROJECT_SOURCE_DIR}/include/git2.h" LIBGIT2_INCLUDE) +STRING(REGEX REPLACE "#include \"git2\/" "#include \"${LIBGIT2_FILENAME}/" LIBGIT2_INCLUDE "${LIBGIT2_INCLUDE}") +FILE(WRITE "${PROJECT_BINARY_DIR}/include/${LIBGIT2_FILENAME}.h" ${LIBGIT2_INCLUDE}) + # Install + install(TARGETS libgit2package RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install(FILES ${PROJECT_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/git2/ + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBGIT2_FILENAME}") +install(FILES ${PROJECT_BINARY_DIR}/include/git2/experimental.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBGIT2_FILENAME}") +install(FILES "${PROJECT_BINARY_DIR}/include/${LIBGIT2_FILENAME}.h" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/libgit2/diff.c b/src/libgit2/diff.c index 91931e75b..20a18c4b9 100644 --- a/src/libgit2/diff.c +++ b/src/libgit2/diff.c @@ -381,7 +381,10 @@ int git_diff_patchid(git_oid *out, git_diff *diff, git_diff_patchid_options *opt if ((error = (flush_hunk(&args.result, &args.ctx))) < 0) goto out; +#ifdef GIT_EXPERIMENTAL_SHA256 args.result.type = GIT_OID_SHA1; +#endif + git_oid_cpy(out, &args.result); out: diff --git a/src/libgit2/experimental.h.in b/src/libgit2/experimental.h.in new file mode 100644 index 000000000..3d6e931e2 --- /dev/null +++ b/src/libgit2/experimental.h.in @@ -0,0 +1,6 @@ +#ifndef INCLUDE_experimental_h__ +#define INCLUDE_experimental_h__ + +#cmakedefine GIT_EXPERIMENTAL_SHA256 1 + +#endif diff --git a/src/libgit2/indexer.c b/src/libgit2/indexer.c index c35e659e5..ace73386c 100644 --- a/src/libgit2/indexer.c +++ b/src/libgit2/indexer.c @@ -444,7 +444,10 @@ static int store_object(git_indexer *idx) git__free(pentry); goto on_error; } + +#ifdef GIT_EXPERIMENTAL_SHA256 oid.type = GIT_OID_SHA1; +#endif entry_size = idx->off - entry_start; if (entry_start > UINT31_MAX) { diff --git a/src/libgit2/object.c b/src/libgit2/object.c index 3794e5c23..1e939384c 100644 --- a/src/libgit2/object.c +++ b/src/libgit2/object.c @@ -520,7 +520,10 @@ static int git_object__short_id(git_str *out, const git_object *obj) memcpy(&id.id, &obj->cached.oid.id, (len + 1) / 2); if (len & 1) id.id[len / 2] &= 0xf0; + +#ifdef GIT_EXPERIMENTAL_SHA256 id.type = GIT_OID_SHA1; +#endif error = git_odb_exists_prefix(NULL, odb, &id, len); if (error != GIT_EAMBIGUOUS) @@ -635,7 +638,7 @@ int git_object__write_oid_header( const char *header, const git_oid *oid) { - size_t hex_size = git_oid_hexsize(oid->type); + size_t hex_size = git_oid_hexsize(git_oid_type(oid)); char hex_oid[GIT_OID_MAX_HEXSIZE]; if (!hex_size) { diff --git a/src/libgit2/odb.c b/src/libgit2/odb.c index b41ab4a03..00d68d6f4 100644 --- a/src/libgit2/odb.c +++ b/src/libgit2/odb.c @@ -140,7 +140,10 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj, git_oid_t oid_type) vec[1].data = obj->data; vec[1].len = obj->len; +#ifdef GIT_EXPERIMENTAL_SHA256 id->type = oid_type; +#endif + return git_hash_vec(id->id, vec, 2, algorithm); } @@ -254,7 +257,10 @@ int git_odb__hashfd( } error = git_hash_final(out->id, &ctx); + +#ifdef GIT_EXPERIMENTAL_SHA256 out->type = oid_type; +#endif done: git_hash_ctx_cleanup(&ctx); @@ -1332,7 +1338,7 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id) error = odb_read_1(out, db, id, true); if (error == GIT_ENOTFOUND) - return git_odb__error_notfound("no match for id", id, git_oid_hexsize(id->type)); + return git_odb__error_notfound("no match for id", id, git_oid_hexsize(git_oid_type(id))); return error; } @@ -1679,7 +1685,10 @@ int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream) "stream_finalize_write()"); git_hash_final(out->id, stream->hash_ctx); + +#ifdef GIT_EXPERIMENTAL_SHA256 out->type = stream->oid_type; +#endif if (git_odb__freshen(stream->backend->odb, out)) return 0; @@ -1858,8 +1867,8 @@ int git_odb__error_mismatch(const git_oid *expected, const git_oid *actual) char expected_oid[GIT_OID_MAX_HEXSIZE + 1], actual_oid[GIT_OID_MAX_HEXSIZE + 1]; - git_oid_tostr(expected_oid, git_oid_hexsize(expected->type) + 1, expected); - git_oid_tostr(actual_oid, git_oid_hexsize(actual->type) + 1, actual); + git_oid_tostr(expected_oid, git_oid_hexsize(git_oid_type(expected)) + 1, expected); + git_oid_tostr(actual_oid, git_oid_hexsize(git_oid_type(actual)) + 1, actual); git_error_set(GIT_ERROR_ODB, "object hash mismatch - expected %s but got %s", expected_oid, actual_oid); diff --git a/src/libgit2/odb_loose.c b/src/libgit2/odb_loose.c index f47ed50b8..49180bbd1 100644 --- a/src/libgit2/odb_loose.c +++ b/src/libgit2/odb_loose.c @@ -737,7 +737,9 @@ GIT_INLINE(int) filename_to_oid(struct loose_backend *backend, git_oid *oid, con oid->id[1 + i/2] = (unsigned char) v; } +#ifdef GIT_EXPERIMENTAL_SHA256 oid->type = backend->options.oid_type; +#endif return 0; } diff --git a/src/libgit2/oid.c b/src/libgit2/oid.c index 7521dd27e..cea70c3b3 100644 --- a/src/libgit2/oid.c +++ b/src/libgit2/oid.c @@ -14,13 +14,13 @@ #include const git_oid git_oid__empty_blob_sha1 = - { GIT_OID_SHA1, + GIT_OID_INIT(GIT_OID_SHA1, { 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, - 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 }}; + 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 }); const git_oid git_oid__empty_tree_sha1 = - { GIT_OID_SHA1, + GIT_OID_INIT(GIT_OID_SHA1, { 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, - 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }}; + 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }); static int oid_error_invalid(const char *msg) { @@ -49,7 +49,9 @@ int git_oid_fromstrn( if (length > git_oid_hexsize(type)) return oid_error_invalid("too long"); +#ifdef GIT_EXPERIMENTAL_SHA256 out->type = type; +#endif memset(out->id, 0, size); for (p = 0; p < length; p++) { @@ -82,7 +84,7 @@ int git_oid_nfmt(char *str, size_t n, const git_oid *oid) return 0; } - if (!(hex_size = git_oid_hexsize(oid->type))) + if (!(hex_size = git_oid_hexsize(git_oid_type(oid)))) return oid_error_invalid("unknown type"); if (n > hex_size) { @@ -96,14 +98,14 @@ int git_oid_nfmt(char *str, size_t n, const git_oid *oid) int git_oid_fmt(char *str, const git_oid *oid) { - return git_oid_nfmt(str, git_oid_hexsize(oid->type), oid); + return git_oid_nfmt(str, git_oid_hexsize(git_oid_type(oid)), oid); } int git_oid_pathfmt(char *str, const git_oid *oid) { size_t hex_size; - if (!(hex_size = git_oid_hexsize(oid->type))) + if (!(hex_size = git_oid_hexsize(git_oid_type(oid)))) return oid_error_invalid("unknown type"); git_oid_fmt_substr(str, oid, 0, 2); @@ -115,13 +117,13 @@ int git_oid_pathfmt(char *str, const git_oid *oid) char *git_oid_tostr_s(const git_oid *oid) { char *str = GIT_THREADSTATE->oid_fmt; - git_oid_nfmt(str, git_oid_hexsize(oid->type) + 1, oid); + git_oid_nfmt(str, git_oid_hexsize(git_oid_type(oid)) + 1, oid); return str; } char *git_oid_allocfmt(const git_oid *oid) { - size_t hex_size = git_oid_hexsize(oid->type); + size_t hex_size = git_oid_hexsize(git_oid_type(oid)); char *str = git__malloc(hex_size + 1); if (!hex_size || !str) @@ -142,7 +144,7 @@ char *git_oid_tostr(char *out, size_t n, const git_oid *oid) if (!out || n == 0) return ""; - hex_size = oid ? git_oid_hexsize(oid->type) : 0; + hex_size = oid ? git_oid_hexsize(git_oid_type(oid)) : 0; if (n > hex_size + 1) n = hex_size + 1; @@ -160,7 +162,9 @@ int git_oid_fromraw(git_oid *out, const unsigned char *raw, git_oid_t type) if (!(size = git_oid_size(type))) return oid_error_invalid("unknown type"); +#ifdef GIT_EXPERIMENTAL_SHA256 out->type = type; +#endif memcpy(out->id, raw, size); return 0; } @@ -169,10 +173,13 @@ int git_oid_cpy(git_oid *out, const git_oid *src) { size_t size; - if (!(size = git_oid_size(src->type))) + if (!(size = git_oid_size(git_oid_type(src)))) return oid_error_invalid("unknown type"); +#ifdef GIT_EXPERIMENTAL_SHA256 out->type = src->type; +#endif + return git_oid_raw_cpy(out->id, src->id, size); } @@ -188,8 +195,10 @@ int git_oid_equal(const git_oid *a, const git_oid *b) int git_oid_ncmp(const git_oid *oid_a, const git_oid *oid_b, size_t len) { +#ifdef GIT_EXPERIMENTAL_SHA256 if (oid_a->type != oid_b->type) return oid_a->type - oid_b->type; +#endif return git_oid_raw_ncmp(oid_a->id, oid_b->id, len); } @@ -198,7 +207,7 @@ int git_oid_strcmp(const git_oid *oid_a, const char *str) { const unsigned char *a; unsigned char strval; - long size = (long)git_oid_size(oid_a->type); + long size = (long)git_oid_size(git_oid_type(oid_a)); int hexval; for (a = oid_a->id; *str && (a - oid_a->id) < size; ++a) { @@ -225,12 +234,14 @@ int git_oid_streq(const git_oid *oid_a, const char *str) int git_oid_is_zero(const git_oid *oid_a) { const unsigned char *a = oid_a->id; - size_t size = git_oid_size(oid_a->type), i; + size_t size = git_oid_size(git_oid_type(oid_a)), i; +#ifdef GIT_EXPERIMENTAL_SHA256 if (!oid_a->type) return 1; else if (!size) return 0; +#endif for (i = 0; i < size; ++i, ++a) if (*a != 0) diff --git a/src/libgit2/oid.h b/src/libgit2/oid.h index 64b6796c8..47d2327e9 100644 --- a/src/libgit2/oid.h +++ b/src/libgit2/oid.h @@ -9,21 +9,42 @@ #include "common.h" +#include "git2/experimental.h" #include "git2/oid.h" #include "hash.h" -#define GIT_OID_NONE { 0, { 0 } } +#ifdef GIT_EXPERIMENTAL_SHA256 +# define GIT_OID_NONE { 0, { 0 } } +# define GIT_OID_INIT(type, ...) { type, __VA_ARGS__ } +#else +# define GIT_OID_NONE { { 0 } } +# define GIT_OID_INIT(type, ...) { __VA_ARGS__ } +#endif extern const git_oid git_oid__empty_blob_sha1; extern const git_oid git_oid__empty_tree_sha1; +GIT_INLINE(git_oid_t) git_oid_type(const git_oid *oid) +{ +#ifdef GIT_EXPERIMENTAL_SHA256 + return oid->type; +#else + GIT_UNUSED(oid); + return GIT_OID_SHA1; +#endif +} + GIT_INLINE(size_t) git_oid_size(git_oid_t type) { switch (type) { case GIT_OID_SHA1: return GIT_OID_SHA1_SIZE; + +#ifdef GIT_EXPERIMENTAL_SHA256 case GIT_OID_SHA256: return GIT_OID_SHA256_SIZE; +#endif + } return 0; @@ -34,8 +55,12 @@ GIT_INLINE(size_t) git_oid_hexsize(git_oid_t type) switch (type) { case GIT_OID_SHA1: return GIT_OID_SHA1_HEXSIZE; + +#ifdef GIT_EXPERIMENTAL_SHA256 case GIT_OID_SHA256: return GIT_OID_SHA256_HEXSIZE; +#endif + } return 0; @@ -46,8 +71,12 @@ GIT_INLINE(git_hash_algorithm_t) git_oid_algorithm(git_oid_t type) switch (type) { case GIT_OID_SHA1: return GIT_HASH_ALGORITHM_SHA1; + +#ifdef GIT_EXPERIMENTAL_SHA256 case GIT_OID_SHA256: return GIT_HASH_ALGORITHM_SHA256; +#endif + } return 0; @@ -142,16 +171,23 @@ GIT_INLINE(int) git_oid_raw_cpy( */ GIT_INLINE(int) git_oid__cmp(const git_oid *a, const git_oid *b) { +#ifdef GIT_EXPERIMENTAL_SHA256 if (a->type != b->type) return a->type - b->type; return git_oid_raw_cmp(a->id, b->id, git_oid_size(a->type)); +#else + return git_oid_raw_cmp(a->id, b->id, git_oid_size(GIT_OID_SHA1)); +#endif } GIT_INLINE(void) git_oid__cpy_prefix( git_oid *out, const git_oid *id, size_t len) { +#ifdef GIT_EXPERIMENTAL_SHA256 out->type = id->type; +#endif + memcpy(&out->id, id->id, (len + 1) / 2); if (len & 1) @@ -173,7 +209,10 @@ GIT_INLINE(bool) git_oid__is_hexstr(const char *str, git_oid_t type) GIT_INLINE(void) git_oid_clear(git_oid *out, git_oid_t type) { memset(out->id, 0, git_oid_size(type)); + +#ifdef GIT_EXPERIMENTAL_SHA256 out->type = type; +#endif } #endif diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index bf62870fb..b12ce409b 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -8,6 +8,8 @@ configure_file(git2_features.h.in git2_features.h) set(UTIL_INCLUDES "${PROJECT_BINARY_DIR}/src/util" + "${PROJECT_BINARY_DIR}/include" + "${PROJECT_BINARY_DIR}/include/git2" "${PROJECT_SOURCE_DIR}/src/util" "${PROJECT_SOURCE_DIR}/include") diff --git a/tests/clar/clar_libgit2.h b/tests/clar/clar_libgit2.h index e0aff43ba..d2d9da0aa 100644 --- a/tests/clar/clar_libgit2.h +++ b/tests/clar/clar_libgit2.h @@ -5,6 +5,7 @@ #include #include "common.h" #include "posix.h" +#include "oid.h" /** * Replace for `clar_must_pass` that passes the last library error as the @@ -140,17 +141,18 @@ GIT_INLINE(void) clar__assert_equal_oid( if (git_oid_equal(one, two)) return; - if (one->type != two->type) { + if (git_oid_type(one) != git_oid_type(two)) { char err[64]; - snprintf(err, 64, "different oid types: %d vs %d", one->type, two->type); + snprintf(err, 64, "different oid types: %d vs %d", git_oid_type(one), git_oid_type(two)); clar__fail(file, func, line, desc, err, 1); - } else if (one->type == GIT_OID_SHA1) { + } else if (git_oid_type(one) == GIT_OID_SHA1) { char err[] = "\"........................................\" != \"........................................\""; git_oid_fmt(&err[1], one); git_oid_fmt(&err[47], two); clar__fail(file, func, line, desc, err, 1); +#ifdef GIT_EXPERIMENTAL_SHA256 } else if (one->type == GIT_OID_SHA256) { char err[] = "\"................................................................\" != \"................................................................\""; @@ -158,6 +160,7 @@ GIT_INLINE(void) clar__assert_equal_oid( git_oid_fmt(&err[71], one); clar__fail(file, func, line, desc, err, 1); +#endif } else { clar__fail(file, func, line, desc, "unknown oid types", 1); } diff --git a/tests/libgit2/core/oid.c b/tests/libgit2/core/oid.c index f17054d55..dc93f738c 100644 --- a/tests/libgit2/core/oid.c +++ b/tests/libgit2/core/oid.c @@ -9,6 +9,7 @@ const char *str_oid_sha1 = "ae90f12eea699729ed24555e40b9fd669da12a12"; const char *str_oid_sha1_p = "ae90f12eea699729ed"; const char *str_oid_sha1_m = "ae90f12eea699729ed24555e40b9fd669da12a12THIS IS EXTRA TEXT THAT SHOULD GET IGNORED"; +#ifdef GIT_EXPERIMENTAL_SHA256 static git_oid id_sha256; static git_oid idp_sha256; static git_oid idm_sha256; @@ -16,6 +17,7 @@ static git_oid idm_sha256; const char *str_oid_sha256 = "d3e63d2f2e43d1fee23a74bf19a0ede156cba2d1bd602eba13de433cea1bb512"; const char *str_oid_sha256_p = "d3e63d2f2e43d1fee2"; const char *str_oid_sha256_m = "d3e63d2f2e43d1fee23a74bf19a0ede156cba2d1bd602eba13de433cea1bb512 GARBAGE EXTRA TEXT AT THE END"; +#endif void test_core_oid__initialize(void) { @@ -23,9 +25,11 @@ void test_core_oid__initialize(void) cl_git_pass(git_oid_fromstrp(&idp_sha1, str_oid_sha1_p, GIT_OID_SHA1)); cl_git_fail(git_oid_fromstrp(&idm_sha1, str_oid_sha1_m, GIT_OID_SHA1)); +#ifdef GIT_EXPERIMENTAL_SHA256 cl_git_pass(git_oid_fromstr(&id_sha256, str_oid_sha256, GIT_OID_SHA256)); cl_git_pass(git_oid_fromstrp(&idp_sha256, str_oid_sha256_p, GIT_OID_SHA256)); cl_git_fail(git_oid_fromstrp(&idm_sha256, str_oid_sha256_m, GIT_OID_SHA256)); +#endif } void test_core_oid__streq_sha1(void) @@ -48,6 +52,7 @@ void test_core_oid__streq_sha1(void) void test_core_oid__streq_sha256(void) { +#ifdef GIT_EXPERIMENTAL_SHA256 cl_assert_equal_i(0, git_oid_streq(&id_sha256, str_oid_sha256)); cl_assert_equal_i(-1, git_oid_streq(&id_sha256, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); @@ -62,6 +67,7 @@ void test_core_oid__streq_sha256(void) cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "deadbeef")); cl_assert_equal_i(-1, git_oid_streq(&idp_sha1, "I'm not an oid.... :)")); +#endif } void test_core_oid__strcmp_sha1(void) @@ -84,6 +90,7 @@ void test_core_oid__strcmp_sha1(void) void test_core_oid__strcmp_sha256(void) { +#ifdef GIT_EXPERIMENTAL_SHA256 cl_assert_equal_i(0, git_oid_strcmp(&id_sha256, str_oid_sha256)); cl_assert(git_oid_strcmp(&id_sha256, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0); @@ -98,6 +105,7 @@ void test_core_oid__strcmp_sha256(void) cl_assert(git_oid_strcmp(&idp_sha256, "deadbeef") < 0); cl_assert_equal_i(-1, git_oid_strcmp(&idp_sha256, "I'm not an oid.... :)")); +#endif } void test_core_oid__ncmp_sha1(void) @@ -121,6 +129,7 @@ void test_core_oid__ncmp_sha1(void) void test_core_oid__ncmp_sha256(void) { +#ifdef GIT_EXPERIMENTAL_SHA256 cl_assert(!git_oid_ncmp(&id_sha256, &idp_sha256, 0)); cl_assert(!git_oid_ncmp(&id_sha256, &idp_sha256, 1)); cl_assert(!git_oid_ncmp(&id_sha256, &idp_sha256, 2)); @@ -142,6 +151,7 @@ void test_core_oid__ncmp_sha256(void) cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 63)); cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 64)); cl_assert(!git_oid_ncmp(&id_sha256, &id_sha256, 65)); +#endif } void test_core_oid__is_hexstr(void) @@ -154,25 +164,25 @@ void test_core_oid__is_hexstr(void) void test_core_oid__fmt_substr_sha1(void) { - char buf[GIT_OID_MAX_HEXSIZE]; + char buf[GIT_OID_MAX_HEXSIZE + 1]; - memset(buf, 0, GIT_OID_MAX_HEXSIZE); + memset(buf, 0, GIT_OID_MAX_HEXSIZE + 1); git_oid_fmt_substr(buf, &id_sha1, 0, 40); cl_assert_equal_s(buf, str_oid_sha1); - memset(buf, 0, GIT_OID_MAX_HEXSIZE); + memset(buf, 0, GIT_OID_MAX_HEXSIZE + 1); git_oid_fmt_substr(buf, &id_sha1, 0, 18); cl_assert_equal_s(buf, str_oid_sha1_p); - memset(buf, 0, GIT_OID_MAX_HEXSIZE); + memset(buf, 0, GIT_OID_MAX_HEXSIZE + 1); git_oid_fmt_substr(buf, &id_sha1, 0, 5); cl_assert_equal_s(buf, "ae90f"); - memset(buf, 0, GIT_OID_MAX_HEXSIZE); + memset(buf, 0, GIT_OID_MAX_HEXSIZE + 1); git_oid_fmt_substr(buf, &id_sha1, 5, 5); cl_assert_equal_s(buf, "12eea"); - memset(buf, 0, GIT_OID_MAX_HEXSIZE); + memset(buf, 0, GIT_OID_MAX_HEXSIZE + 1); git_oid_fmt_substr(buf, &id_sha1, 5, 6); cl_assert_equal_s(buf, "12eea6"); } diff --git a/tests/libgit2/core/oidmap.c b/tests/libgit2/core/oidmap.c index 317631c4e..34374ceef 100644 --- a/tests/libgit2/core/oidmap.c +++ b/tests/libgit2/core/oidmap.c @@ -28,7 +28,9 @@ void test_core_oidmap__initialize(void) test_oids[i].oid.id[ 9] = (unsigned char)(i >> 8); test_oids[i].oid.id[10] = (unsigned char)(i >> 16); test_oids[i].oid.id[11] = (unsigned char)(i >> 24); +#ifdef GIT_EXPERIMENTAL_SHA256 test_oids[i].oid.type = GIT_OID_SHA1; +#endif } cl_git_pass(git_oidmap_new(&g_map)); @@ -94,9 +96,9 @@ void test_core_oidmap__get_fails_with_nonexisting_key(void) void test_core_oidmap__setting_oid_persists(void) { git_oid oids[] = { - { GIT_OID_SHA1, { 0x01 }}, - { GIT_OID_SHA1, { 0x02 }}, - { GIT_OID_SHA1, { 0x03 }} + GIT_OID_INIT(GIT_OID_SHA1, { 0x01 }), + GIT_OID_INIT(GIT_OID_SHA1, { 0x02 }), + GIT_OID_INIT(GIT_OID_SHA1, { 0x03 }) }; cl_git_pass(git_oidmap_set(g_map, &oids[0], "one")); @@ -111,9 +113,9 @@ void test_core_oidmap__setting_oid_persists(void) void test_core_oidmap__setting_existing_key_updates(void) { git_oid oids[] = { - { GIT_OID_SHA1, { 0x01 }}, - { GIT_OID_SHA1, { 0x02 }}, - { GIT_OID_SHA1, { 0x03 }} + GIT_OID_INIT(GIT_OID_SHA1, { 0x01 }), + GIT_OID_INIT(GIT_OID_SHA1, { 0x02 }), + GIT_OID_INIT(GIT_OID_SHA1, { 0x03 }) }; cl_git_pass(git_oidmap_set(g_map, &oids[0], "one")); diff --git a/tests/libgit2/core/pool.c b/tests/libgit2/core/pool.c index 21aad3275..e16d85202 100644 --- a/tests/libgit2/core/pool.c +++ b/tests/libgit2/core/pool.c @@ -27,7 +27,12 @@ void test_core_pool__oid(void) #ifndef GIT_DEBUG_POOL /* with fixed page size, allocation must end up with these values */ + +# ifdef GIT_EXPERIMENTAL_SHA256 cl_assert_equal_i(sizeof(void *) == 8 ? 90 : 82, git_pool__open_pages(&p)); +# else + cl_assert_equal_i(sizeof(void *) == 8 ? 55 : 45, git_pool__open_pages(&p)); +# endif #endif git_pool_clear(&p); } diff --git a/tests/libgit2/odb/loose.c b/tests/libgit2/odb/loose.c index 9f57a6866..9651ebab6 100644 --- a/tests/libgit2/odb/loose.c +++ b/tests/libgit2/odb/loose.c @@ -160,6 +160,7 @@ void test_odb_loose__exists_sha1(void) void test_odb_loose__exists_sha256(void) { +#ifdef GIT_EXPERIMENTAL_SHA256 git_oid id, id2; git_odb *odb; git_odb_options odb_opts = GIT_ODB_OPTIONS_INIT; @@ -184,6 +185,7 @@ void test_odb_loose__exists_sha256(void) cl_assert_equal_i(GIT_ENOTFOUND, git_odb_exists_prefix(&id2, odb, &id, 8)); git_odb_free(odb); +#endif } void test_odb_loose__simple_reads_sha1(void) @@ -199,6 +201,7 @@ void test_odb_loose__simple_reads_sha1(void) void test_odb_loose__simple_reads_sha256(void) { +#ifdef GIT_EXPERIMENTAL_SHA256 test_read_object(&commit_sha256); test_read_object(&tree_sha256); test_read_object(&tag_sha256); @@ -206,6 +209,7 @@ void test_odb_loose__simple_reads_sha256(void) test_read_object(&one_sha256); test_read_object(&two_sha256); test_read_object(&some_sha256); +#endif } void test_odb_loose__streaming_reads_sha1(void) @@ -226,6 +230,7 @@ void test_odb_loose__streaming_reads_sha1(void) void test_odb_loose__streaming_reads_sha256(void) { +#ifdef GIT_EXPERIMENTAL_SHA256 size_t blocksizes[] = { 1, 2, 4, 16, 99, 1024, 123456789 }; size_t i; @@ -238,6 +243,7 @@ void test_odb_loose__streaming_reads_sha256(void) test_readstream_object(&two_sha256, blocksizes[i]); test_readstream_object(&some_sha256, blocksizes[i]); } +#endif } void test_odb_loose__read_header_sha1(void) @@ -253,6 +259,7 @@ void test_odb_loose__read_header_sha1(void) void test_odb_loose__read_header_sha256(void) { +#ifdef GIT_EXPERIMENTAL_SHA256 test_read_header(&commit_sha256); test_read_header(&tree_sha256); test_read_header(&tag_sha256); @@ -260,6 +267,7 @@ void test_odb_loose__read_header_sha256(void) test_read_header(&one_sha256); test_read_header(&two_sha256); test_read_header(&some_sha256); +#endif } static void test_write_object_permission( diff --git a/tests/libgit2/odb/loose_data.h b/tests/libgit2/odb/loose_data.h index 97681a014..1a830740d 100644 --- a/tests/libgit2/odb/loose_data.h +++ b/tests/libgit2/odb/loose_data.h @@ -35,6 +35,7 @@ static object_data one = { sizeof(one_data), }; +#ifdef GIT_EXPERIMENTAL_SHA256 static object_data one_sha256 = { one_bytes, sizeof(one_bytes), @@ -46,6 +47,7 @@ static object_data one_sha256 = { one_data, sizeof(one_data), }; +#endif /* @@ -84,6 +86,7 @@ static unsigned char commit_bytes[] = { 0x1f, 0x78, 0x35, }; +#ifdef GIT_EXPERIMENTAL_SHA256 static unsigned char commit_bytes_sha256[] = { 0x78, 0x01, 0x85, 0x90, 0xc1, 0x4e, 0xc3, 0x30, 0x0c, 0x86, 0x39, 0xe7, 0x29, 0x7c, 0x87, 0x4e, @@ -117,6 +120,7 @@ static unsigned char commit_bytes_sha256[] = { 0x22, 0x98, 0x42, 0x6d, 0xcf, 0x7f, 0xbf, 0x83, 0x7d, 0x03, 0x6d, 0x1e, 0x7e, 0xa9 }; +#endif static unsigned char commit_data[] = { 0x74, 0x72, 0x65, 0x65, 0x20, 0x64, 0x66, 0x66, @@ -166,6 +170,7 @@ static unsigned char commit_data[] = { 0x3e, 0x0a, }; +#ifdef GIT_EXPERIMENTAL_SHA256 static unsigned char commit_data_sha256[] = { 0x74, 0x72, 0x65, 0x65, 0x20, 0x33, 0x34, 0x61, 0x34, 0x38, 0x35, 0x34, 0x62, 0x35, 0x34, 0x32, @@ -216,6 +221,7 @@ static unsigned char commit_data_sha256[] = { 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x0a }; +#endif static object_data commit = { commit_bytes, @@ -229,6 +235,7 @@ static object_data commit = { sizeof(commit_data), }; +#ifdef GIT_EXPERIMENTAL_SHA256 static object_data commit_sha256 = { commit_bytes_sha256, sizeof(commit_bytes_sha256), @@ -240,6 +247,7 @@ static object_data commit_sha256 = { commit_data_sha256, sizeof(commit_data_sha256), }; +#endif /* * tree == dff2da90b254e1beb889d1f1f1288be1803782df (sha1) @@ -284,6 +292,7 @@ static unsigned char tree_data[] = { 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91, }; +#ifdef GIT_EXPERIMENTAL_SHA256 static unsigned char tree_bytes_sha256[] = { 0x78, 0x01, 0x2b, 0x29, 0x4a, 0x4d, 0x55, 0x30, 0x32, 0x32, 0x66, 0x30, 0x34, 0x30, 0x30, 0x33, @@ -346,6 +355,7 @@ static unsigned char tree_data_sha256[] = { 0xa7, 0xcd, 0x2a, 0xc9, 0xb4, 0x4a, 0xda, 0xf7, 0xed, 0x3e, 0xdc, 0x0d, 0x08, 0xdd, 0x78 }; +#endif static object_data tree = { tree_bytes, @@ -359,6 +369,7 @@ static object_data tree = { sizeof(tree_data), }; +#ifdef GIT_EXPERIMENTAL_SHA256 static object_data tree_sha256 = { tree_bytes_sha256, sizeof(tree_bytes_sha256), @@ -370,6 +381,7 @@ static object_data tree_sha256 = { tree_data_sha256, sizeof(tree_data_sha256), }; +#endif /* * tag == 09d373e1dfdc16b129ceec6dd649739911541e05 (sha1) @@ -422,6 +434,7 @@ static unsigned char tag_data[] = { 0x2e, 0x30, 0x2e, 0x31, 0x0a, }; +#ifdef GIT_EXPERIMENTAL_SHA256 static unsigned char tag_bytes_sha256[] = { 0x78, 0x01, 0x55, 0x8f, 0xd1, 0x4e, 0x84, 0x30, 0x10, 0x45, 0x7d, 0xee, 0x57, 0xcc, 0xbb, 0x2e, @@ -509,6 +522,7 @@ static unsigned char tag_data_sha256[] = { 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x0a }; +#endif static object_data tag = { tag_bytes, @@ -522,6 +536,7 @@ static object_data tag = { sizeof(tag_data), }; +#ifdef GIT_EXPERIMENTAL_SHA256 static object_data tag_sha256 = { tag_bytes_sha256, sizeof(tag_bytes_sha256), @@ -533,6 +548,7 @@ static object_data tag_sha256 = { tag_data_sha256, sizeof(tag_data_sha256), }; +#endif /* * zero == e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 (sha1) @@ -559,6 +575,7 @@ static object_data zero = { 0, }; +#ifdef GIT_EXPERIMENTAL_SHA256 static object_data zero_sha256 = { zero_bytes, sizeof(zero_bytes), @@ -570,6 +587,7 @@ static object_data zero_sha256 = { zero_data, 0, }; +#endif /* * two == 78981922613b2afb6025042ff6bd878ac1994e85 (sha1) @@ -597,6 +615,7 @@ static object_data two = { sizeof(two_data), }; +#ifdef GIT_EXPERIMENTAL_SHA256 static object_data two_sha256 = { two_bytes, sizeof(two_bytes), @@ -608,6 +627,7 @@ static object_data two_sha256 = { two_data, sizeof(two_data), }; +#endif /* * some == fd8430bc864cfcd5f10e5590f8a447e01b942bfe (sha1) @@ -858,6 +878,7 @@ static object_data some = { sizeof(some_data), }; +#ifdef GIT_EXPERIMENTAL_SHA256 static object_data some_sha256 = { some_bytes, sizeof(some_bytes), @@ -869,3 +890,4 @@ static object_data some_sha256 = { some_data, sizeof(some_data), }; +#endif