Initial commit - full huishou project

This commit is contained in:
jiapengyu
2026-07-27 14:07:26 +08:00
commit 60790ad1b3
39127 changed files with 5989265 additions and 0 deletions
+159
View File
@@ -0,0 +1,159 @@
#include "clar_libgit2.h"
#include "git2/sys/odb_backend.h"
#include "backend_helpers.h"
static int search_object(const fake_object **out, fake_backend *fake, const git_oid *oid, size_t len)
{
const fake_object *obj = fake->objects, *found = NULL;
while (obj && obj->oid) {
git_oid current_oid;
git_oid_fromstr(&current_oid, obj->oid);
if (git_oid_ncmp(&current_oid, oid, len) == 0) {
if (found)
return GIT_EAMBIGUOUS;
found = obj;
}
obj++;
}
if (found && out)
*out = found;
return found ? GIT_OK : GIT_ENOTFOUND;
}
static int fake_backend__exists(git_odb_backend *backend, const git_oid *oid)
{
fake_backend *fake;
fake = (fake_backend *)backend;
fake->exists_calls++;
return search_object(NULL, fake, oid, GIT_OID_HEXSZ) == GIT_OK;
}
static int fake_backend__exists_prefix(
git_oid *out, git_odb_backend *backend, const git_oid *oid, size_t len)
{
const fake_object *obj;
fake_backend *fake;
int error;
fake = (fake_backend *)backend;
fake->exists_prefix_calls++;
if ((error = search_object(&obj, fake, oid, len)) < 0)
return error;
if (out)
git_oid_fromstr(out, obj->oid);
return 0;
}
static int fake_backend__read(
void **buffer_p, size_t *len_p, git_object_t *type_p,
git_odb_backend *backend, const git_oid *oid)
{
const fake_object *obj;
fake_backend *fake;
int error;
fake = (fake_backend *)backend;
fake->read_calls++;
if ((error = search_object(&obj, fake, oid, GIT_OID_HEXSZ)) < 0)
return error;
*len_p = strlen(obj->content);
*buffer_p = git__strdup(obj->content);
*type_p = GIT_OBJECT_BLOB;
return 0;
}
static int fake_backend__read_header(
size_t *len_p, git_object_t *type_p,
git_odb_backend *backend, const git_oid *oid)
{
const fake_object *obj;
fake_backend *fake;
int error;
fake = (fake_backend *)backend;
fake->read_header_calls++;
if ((error = search_object(&obj, fake, oid, GIT_OID_HEXSZ)) < 0)
return error;
*len_p = strlen(obj->content);
*type_p = GIT_OBJECT_BLOB;
return 0;
}
static int fake_backend__read_prefix(
git_oid *out_oid, void **buffer_p, size_t *len_p, git_object_t *type_p,
git_odb_backend *backend, const git_oid *short_oid, size_t len)
{
const fake_object *obj;
fake_backend *fake;
int error;
fake = (fake_backend *)backend;
fake->read_prefix_calls++;
if ((error = search_object(&obj, fake, short_oid, len)) < 0)
return error;
git_oid_fromstr(out_oid, obj->oid);
*len_p = strlen(obj->content);
*buffer_p = git__strdup(obj->content);
*type_p = GIT_OBJECT_BLOB;
return 0;
}
static void fake_backend__free(git_odb_backend *_backend)
{
fake_backend *backend;
backend = (fake_backend *)_backend;
git__free(backend);
}
int build_fake_backend(
git_odb_backend **out,
const fake_object *objects)
{
fake_backend *backend;
backend = git__calloc(1, sizeof(fake_backend));
GIT_ERROR_CHECK_ALLOC(backend);
backend->parent.version = GIT_ODB_BACKEND_VERSION;
backend->parent.refresh = NULL;
backend->objects = objects;
backend->parent.read = fake_backend__read;
backend->parent.read_prefix = fake_backend__read_prefix;
backend->parent.read_header = fake_backend__read_header;
backend->parent.exists = fake_backend__exists;
backend->parent.exists_prefix = fake_backend__exists_prefix;
backend->parent.free = &fake_backend__free;
*out = (git_odb_backend *)backend;
return 0;
}
@@ -0,0 +1,22 @@
#include "git2/sys/odb_backend.h"
typedef struct {
const char *oid;
const char *content;
} fake_object;
typedef struct {
git_odb_backend parent;
int exists_calls;
int exists_prefix_calls;
int read_calls;
int read_header_calls;
int read_prefix_calls;
const fake_object *objects;
} fake_backend;
int build_fake_backend(
git_odb_backend **out,
const fake_object *objects);
+60
View File
@@ -0,0 +1,60 @@
#include "clar_libgit2.h"
#include "repository.h"
#include "backend_helpers.h"
#include "git2/sys/mempack.h"
static git_odb *_odb;
static git_oid _oid;
static git_odb_object *_obj;
static git_repository *_repo;
void test_odb_backend_mempack__initialize(void)
{
git_odb_backend *backend;
cl_git_pass(git_mempack_new(&backend));
cl_git_pass(git_odb_new(&_odb));
cl_git_pass(git_odb_add_backend(_odb, backend, 10));
cl_git_pass(git_repository_wrap_odb(&_repo, _odb));
}
void test_odb_backend_mempack__cleanup(void)
{
git_odb_object_free(_obj);
git_odb_free(_odb);
git_repository_free(_repo);
}
void test_odb_backend_mempack__write_succeeds(void)
{
const char *data = "data";
cl_git_pass(git_odb_write(&_oid, _odb, data, strlen(data) + 1, GIT_OBJECT_BLOB));
cl_git_pass(git_odb_read(&_obj, _odb, &_oid));
}
void test_odb_backend_mempack__read_of_missing_object_fails(void)
{
cl_git_pass(git_oid_fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633"));
cl_git_fail_with(GIT_ENOTFOUND, git_odb_read(&_obj, _odb, &_oid));
}
void test_odb_backend_mempack__exists_of_missing_object_fails(void)
{
cl_git_pass(git_oid_fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633"));
cl_assert(git_odb_exists(_odb, &_oid) == 0);
}
void test_odb_backend_mempack__exists_with_existing_objects_succeeds(void)
{
const char *data = "data";
cl_git_pass(git_odb_write(&_oid, _odb, data, strlen(data) + 1, GIT_OBJECT_BLOB));
cl_assert(git_odb_exists(_odb, &_oid) == 1);
}
void test_odb_backend_mempack__blob_create_from_buffer_succeeds(void)
{
const char *data = "data";
cl_git_pass(git_blob_create_from_buffer(&_oid, _repo, data, strlen(data) + 1));
cl_assert(git_odb_exists(_odb, &_oid) == 1);
}
+121
View File
@@ -0,0 +1,121 @@
#include "clar_libgit2.h"
#include "repository.h"
#include "backend_helpers.h"
#define EXISTING_HASH "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
static git_repository *_repo;
static git_odb_object *_obj;
static fake_backend *_fake_empty;
static fake_backend *_fake_filled;
static git_oid _existing_oid;
static const fake_object _objects_filled[] = {
{ EXISTING_HASH, "" },
{ NULL, NULL }
};
static const fake_object _objects_empty[] = {
{ NULL, NULL }
};
void test_odb_backend_multiple__initialize(void)
{
git_odb_backend *backend;
git_oid_fromstr(&_existing_oid, EXISTING_HASH);
_obj = NULL;
_repo = cl_git_sandbox_init("testrepo.git");
cl_git_pass(build_fake_backend(&backend, _objects_filled));
_fake_filled = (fake_backend *)backend;
cl_git_pass(build_fake_backend(&backend, _objects_empty));
_fake_empty = (fake_backend *)backend;
}
void test_odb_backend_multiple__cleanup(void)
{
git_odb_object_free(_obj);
cl_git_sandbox_cleanup();
}
void test_odb_backend_multiple__read_with_empty_first_succeeds(void)
{
git_odb *odb;
cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
cl_git_pass(git_odb_add_backend(odb, (git_odb_backend *)_fake_filled, 10));
cl_git_pass(git_odb_add_backend(odb, (git_odb_backend *)_fake_empty, 50));
cl_git_pass(git_odb_read(&_obj, odb, &_existing_oid));
cl_assert_equal_i(1, _fake_filled->read_calls);
cl_assert_equal_i(1, _fake_empty->read_calls);
}
void test_odb_backend_multiple__read_with_first_matching_stops(void)
{
git_odb *odb;
cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
cl_git_pass(git_odb_add_backend(odb, (git_odb_backend *)_fake_empty, 10));
cl_git_pass(git_odb_add_backend(odb, (git_odb_backend *)_fake_filled, 50));
cl_git_pass(git_odb_read(&_obj, odb, &_existing_oid));
cl_assert_equal_i(1, _fake_filled->read_calls);
cl_assert_equal_i(0, _fake_empty->read_calls);
}
void test_odb_backend_multiple__read_prefix_with_first_empty_succeeds(void)
{
git_odb *odb;
cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
cl_git_pass(git_odb_add_backend(odb, (git_odb_backend *)_fake_filled, 10));
cl_git_pass(git_odb_add_backend(odb, (git_odb_backend *)_fake_empty, 50));
cl_git_pass(git_odb_read_prefix(&_obj, odb, &_existing_oid, 7));
cl_assert_equal_i(1, _fake_filled->read_prefix_calls);
cl_assert_equal_i(1, _fake_empty->read_prefix_calls);
}
void test_odb_backend_multiple__read_prefix_with_first_matching_reads_both(void)
{
git_odb *odb;
cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
cl_git_pass(git_odb_add_backend(odb, (git_odb_backend *)_fake_empty, -10));
cl_git_pass(git_odb_add_backend(odb, (git_odb_backend *)_fake_filled, 50));
cl_git_pass(git_odb_read_prefix(&_obj, odb, &_existing_oid, 7));
cl_assert_equal_i(1, _fake_filled->read_prefix_calls);
cl_assert_equal_i(1, _fake_empty->read_prefix_calls);
}
void test_odb_backend_multiple__read_prefix_with_first_matching_succeeds_without_hash_verification(void)
{
git_odb *odb;
git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0);
cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
cl_git_pass(git_odb_add_backend(odb, (git_odb_backend *)_fake_empty, -10));
cl_git_pass(git_odb_add_backend(odb, (git_odb_backend *)_fake_filled, 50));
cl_git_pass(git_odb_read_prefix(&_obj, odb, &_existing_oid, 7));
/*
* Both backends should be checked as we have to check
* for collisions
*/
cl_assert_equal_i(1, _fake_filled->read_prefix_calls);
cl_assert_equal_i(1, _fake_empty->read_prefix_calls);
git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 1);
}
+46
View File
@@ -0,0 +1,46 @@
#include "clar_libgit2.h"
#include "repository.h"
#include "git2/sys/repository.h"
static git_repository *_repo;
void test_odb_backend_nobackend__initialize(void)
{
git_config *config;
git_odb *odb;
git_refdb *refdb;
cl_git_pass(git_repository_new(&_repo));
cl_git_pass(git_config_new(&config));
cl_git_pass(git_odb_new(&odb));
cl_git_pass(git_refdb_new(&refdb, _repo));
git_repository_set_config(_repo, config);
git_repository_set_odb(_repo, odb);
git_repository_set_refdb(_repo, refdb);
/* The set increases the refcount and we don't want them anymore */
git_config_free(config);
git_odb_free(odb);
git_refdb_free(refdb);
}
void test_odb_backend_nobackend__cleanup(void)
{
git_repository_free(_repo);
}
void test_odb_backend_nobackend__write_fails_gracefully(void)
{
git_oid id;
git_odb *odb;
const git_error *err;
git_repository_odb(&odb, _repo);
cl_git_fail(git_odb_write(&id, odb, "Hello world!\n", 13, GIT_OBJECT_BLOB));
err = git_error_last();
cl_assert_equal_s(err->message, "cannot write object - unsupported in the loaded odb backends");
git_odb_free(odb);
}
+147
View File
@@ -0,0 +1,147 @@
#include "clar_libgit2.h"
#include "repository.h"
#include "backend_helpers.h"
static git_repository *_repo;
static fake_backend *_fake;
#define NONEXISTING_HASH "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
#define EXISTING_HASH "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
static const fake_object _objects[] = {
{ EXISTING_HASH, "" },
{ NULL, NULL }
};
static git_oid _nonexisting_oid;
static git_oid _existing_oid;
static void setup_repository_and_backend(void)
{
git_odb *odb = NULL;
git_odb_backend *backend = NULL;
_repo = cl_git_sandbox_init("testrepo.git");
cl_git_pass(build_fake_backend(&backend, _objects));
cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
cl_git_pass(git_odb_add_backend(odb, backend, 10));
_fake = (fake_backend *)backend;
}
void test_odb_backend_nonrefreshing__initialize(void)
{
git_oid_fromstr(&_nonexisting_oid, NONEXISTING_HASH);
git_oid_fromstr(&_existing_oid, EXISTING_HASH);
setup_repository_and_backend();
}
void test_odb_backend_nonrefreshing__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_odb_backend_nonrefreshing__exists_is_invoked_once_on_failure(void)
{
git_odb *odb;
cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
cl_assert_equal_b(false, git_odb_exists(odb, &_nonexisting_oid));
cl_assert_equal_i(1, _fake->exists_calls);
}
void test_odb_backend_nonrefreshing__read_is_invoked_once_on_failure(void)
{
git_object *obj;
cl_git_fail_with(
git_object_lookup(&obj, _repo, &_nonexisting_oid, GIT_OBJECT_ANY),
GIT_ENOTFOUND);
cl_assert_equal_i(1, _fake->read_calls);
}
void test_odb_backend_nonrefreshing__readprefix_is_invoked_once_on_failure(void)
{
git_object *obj;
cl_git_fail_with(
git_object_lookup_prefix(&obj, _repo, &_nonexisting_oid, 7, GIT_OBJECT_ANY),
GIT_ENOTFOUND);
cl_assert_equal_i(1, _fake->read_prefix_calls);
}
void test_odb_backend_nonrefreshing__readheader_is_invoked_once_on_failure(void)
{
git_odb *odb;
size_t len;
git_object_t type;
cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
cl_git_fail_with(
git_odb_read_header(&len, &type, odb, &_nonexisting_oid),
GIT_ENOTFOUND);
cl_assert_equal_i(1, _fake->read_header_calls);
}
void test_odb_backend_nonrefreshing__exists_is_invoked_once_on_success(void)
{
git_odb *odb;
cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
cl_assert_equal_b(true, git_odb_exists(odb, &_existing_oid));
cl_assert_equal_i(1, _fake->exists_calls);
}
void test_odb_backend_nonrefreshing__read_is_invoked_once_on_success(void)
{
git_object *obj;
cl_git_pass(git_object_lookup(&obj, _repo, &_existing_oid, GIT_OBJECT_ANY));
cl_assert_equal_i(1, _fake->read_calls);
git_object_free(obj);
}
void test_odb_backend_nonrefreshing__readprefix_is_invoked_once_on_success(void)
{
git_object *obj;
cl_git_pass(git_object_lookup_prefix(&obj, _repo, &_existing_oid, 7, GIT_OBJECT_ANY));
cl_assert_equal_i(1, _fake->read_prefix_calls);
git_object_free(obj);
}
void test_odb_backend_nonrefreshing__readheader_is_invoked_once_on_success(void)
{
git_odb *odb;
size_t len;
git_object_t type;
cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
cl_git_pass(git_odb_read_header(&len, &type, odb, &_existing_oid));
cl_assert_equal_i(1, _fake->read_header_calls);
}
void test_odb_backend_nonrefreshing__read_is_invoked_once_when_revparsing_a_full_oid(void)
{
git_object *obj;
cl_git_fail_with(
git_revparse_single(&obj, _repo, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
GIT_ENOTFOUND);
cl_assert_equal_i(1, _fake->read_calls);
}
+250
View File
@@ -0,0 +1,250 @@
#include "clar_libgit2.h"
#include "repository.h"
#include "backend_helpers.h"
#define EMPTY_HASH "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
static git_repository *_repo;
static git_odb *_odb;
static git_odb_object *_obj;
static git_oid _oid;
static void setup_backend(const fake_object *objs)
{
git_odb_backend *backend;
cl_git_pass(build_fake_backend(&backend, objs));
cl_git_pass(git_repository_odb__weakptr(&_odb, _repo));
cl_git_pass(git_odb_add_backend(_odb, backend, 10));
}
static void assert_object_contains(git_odb_object *obj, const char *expected)
{
const char *actual = (const char *) git_odb_object_data(obj);
cl_assert_equal_s(actual, expected);
}
void test_odb_backend_simple__initialize(void)
{
_repo = cl_git_sandbox_init("testrepo.git");
_odb = NULL;
_obj = NULL;
}
void test_odb_backend_simple__cleanup(void)
{
git_odb_object_free(_obj);
cl_git_sandbox_cleanup();
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 1));
}
void test_odb_backend_simple__read_of_object_succeeds(void)
{
const fake_object objs[] = {
{ "f6ea0495187600e7b2288c8ac19c5886383a4632", "foobar" },
{ NULL, NULL }
};
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid));
cl_git_pass(git_odb_read(&_obj, _odb, &_oid));
assert_object_contains(_obj, objs[0].content);
}
void test_odb_backend_simple__read_of_nonexisting_object_fails(void)
{
const fake_object objs[] = {
{ "f6ea0495187600e7b2288c8ac19c5886383a4632", "foobar" },
{ NULL, NULL }
};
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633"));
cl_git_fail_with(GIT_ENOTFOUND, git_odb_read(&_obj, _odb, &_oid));
}
void test_odb_backend_simple__read_with_hash_mismatch_fails(void)
{
const fake_object objs[] = {
{ "1234567890123456789012345678901234567890", "nonmatching content" },
{ NULL, NULL }
};
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid));
cl_git_fail_with(GIT_EMISMATCH, git_odb_read(&_obj, _odb, &_oid));
}
void test_odb_backend_simple__read_with_hash_mismatch_succeeds_without_verification(void)
{
const fake_object objs[] = {
{ "1234567890123456789012345678901234567890", "nonmatching content" },
{ NULL, NULL }
};
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid));
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0));
cl_git_pass(git_odb_read(&_obj, _odb, &_oid));
assert_object_contains(_obj, objs[0].content);
}
void test_odb_backend_simple__read_prefix_succeeds(void)
{
const fake_object objs[] = {
{ "f6ea0495187600e7b2288c8ac19c5886383a4632", "foobar" },
{ NULL, NULL }
};
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4632"));
cl_git_pass(git_odb_read(&_obj, _odb, &_oid));
assert_object_contains(_obj, objs[0].content);
}
void test_odb_backend_simple__read_prefix_of_nonexisting_object_fails(void)
{
const fake_object objs[] = {
{ "f6ea0495187600e7b2288c8ac19c5886383a4632", "foobar" },
{ NULL, NULL }
};
char *hash = "f6ea0495187600e8";
setup_backend(objs);
cl_git_pass(git_oid_fromstrn(&_oid, hash, strlen(hash)));
cl_git_fail_with(GIT_ENOTFOUND, git_odb_read(&_obj, _odb, &_oid));
}
void test_odb_backend_simple__read_with_ambiguous_prefix_fails(void)
{
const fake_object objs[] = {
{ "1234567890111111111111111111111111111111", "first content" },
{ "1234567890222222222222222222222222222222", "second content" },
{ NULL, NULL }
};
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid));
cl_git_fail_with(GIT_EAMBIGUOUS, git_odb_read_prefix(&_obj, _odb, &_oid, 7));
}
void test_odb_backend_simple__read_with_highly_ambiguous_prefix(void)
{
const fake_object objs[] = {
{ "1234567890111111111111111111111111111111", "first content" },
{ "1234567890111111111111111111111111111112", "second content" },
{ NULL, NULL }
};
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid));
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0));
cl_git_fail_with(GIT_EAMBIGUOUS, git_odb_read_prefix(&_obj, _odb, &_oid, 39));
cl_git_pass(git_odb_read_prefix(&_obj, _odb, &_oid, 40));
assert_object_contains(_obj, objs[0].content);
}
void test_odb_backend_simple__exists_succeeds(void)
{
const fake_object objs[] = {
{ "f6ea0495187600e7b2288c8ac19c5886383a4632", "foobar" },
{ NULL, NULL }
};
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid));
cl_assert(git_odb_exists(_odb, &_oid));
}
void test_odb_backend_simple__exists_fails_for_nonexisting_object(void)
{
const fake_object objs[] = {
{ "f6ea0495187600e7b2288c8ac19c5886383a4632", "foobar" },
{ NULL, NULL }
};
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, "f6ea0495187600e7b2288c8ac19c5886383a4633"));
cl_assert(git_odb_exists(_odb, &_oid) == 0);
}
void test_odb_backend_simple__exists_prefix_succeeds(void)
{
const fake_object objs[] = {
{ "1234567890111111111111111111111111111111", "first content" },
{ "1234567890222222222222222222222222222222", "second content" },
{ NULL, NULL }
};
git_oid found;
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid));
cl_git_pass(git_odb_exists_prefix(&found, _odb, &_oid, 12));
cl_assert(git_oid_equal(&found, &_oid));
}
void test_odb_backend_simple__exists_with_ambiguous_prefix_fails(void)
{
const fake_object objs[] = {
{ "1234567890111111111111111111111111111111", "first content" },
{ "1234567890222222222222222222222222222222", "second content" },
{ NULL, NULL }
};
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid));
cl_git_fail_with(GIT_EAMBIGUOUS, git_odb_exists_prefix(NULL, _odb, &_oid, 7));
}
void test_odb_backend_simple__exists_with_highly_ambiguous_prefix(void)
{
const fake_object objs[] = {
{ "1234567890111111111111111111111111111111", "first content" },
{ "1234567890111111111111111111111111111112", "second content" },
{ NULL, NULL }
};
git_oid found;
setup_backend(objs);
cl_git_pass(git_oid_fromstr(&_oid, objs[0].oid));
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0));
cl_git_fail_with(GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &_oid, 39));
cl_git_pass(git_odb_exists_prefix(&found, _odb, &_oid, 40));
cl_assert(git_oid_equal(&found, &_oid));
}
void test_odb_backend_simple__null_oid_is_ignored(void)
{
const fake_object objs[] = {
{ "0000000000000000000000000000000000000000", "null oid content" },
{ NULL, NULL }
};
git_oid null_oid = {{0}};
git_odb_object *obj;
setup_backend(objs);
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0));
cl_assert(!git_odb_exists(_odb, &null_oid));
cl_git_fail_with(GIT_ENOTFOUND, git_odb_read(&obj, _odb, &null_oid));
cl_assert(git_error_last() && strstr(git_error_last()->message, "null OID"));
}