int py_str_to_git_oid_expand(git_repository *repo, PyObject *py_str, git_oid *oid) { int err; int len; git_odb *odb; git_odb_object *obj; len = py_str_to_git_oid(py_str, oid); if (len == GIT_OID_HEXSZ || len < 0) return len; err = git_repository_odb(&odb, repo); if (err < 0) { Error_set(err); return -1; } err = git_odb_read_prefix(&obj, odb, oid, len); if (err < 0) { git_odb_free(odb); Error_set(err); return err; } git_oid_cpy(oid, git_odb_object_id(obj)); git_odb_object_free(obj); git_odb_free(odb); return 0; }
int Repository_contains(Repository *self, PyObject *value) { git_oid oid; git_odb *odb; int err, len, exists; len = py_str_to_git_oid(value, &oid); if (len < 0) return -1; err = git_repository_odb(&odb, self->repo); if (err < 0) { Error_set(err); return -1; } if (len < GIT_OID_HEXSZ) { git_odb_object *obj = NULL; err = git_odb_read_prefix(&obj, odb, &oid, len); if (err < 0 && err != GIT_ENOTFOUND) { Error_set(err); exists = -1; } else { exists = (err == 0); if (obj) git_odb_object_free(obj); } } else { exists = git_odb_exists(odb, &oid); } git_odb_free(odb); return exists; }
int py_oid_to_git_oid_expand(git_repository *repo, PyObject *py_str, git_oid *oid) { int err; size_t len; git_odb *odb = NULL; git_odb_object *obj = NULL; len = py_oid_to_git_oid(py_str, oid); if (len == 0) return -1; if (len == GIT_OID_HEXSZ) return 0; /* Short oid */ err = git_repository_odb(&odb, repo); if (err < 0) goto error; err = git_odb_read_prefix(&obj, odb, oid, len); if (err < 0) goto error; git_oid_cpy(oid, git_odb_object_id(obj)); git_odb_object_free(obj); git_odb_free(odb); return 0; error: git_odb_object_free(obj); git_odb_free(odb); Error_set(err); return -1; }
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_mixed__dup_oid(void) { const char hex[] = "ce013625030ba8dba906f756967f9e9ca394464a"; const char short_hex[] = "ce01362"; git_oid oid; git_odb_object *obj; cl_git_pass(git_oid_fromstr(&oid, hex)); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, GIT_OID_HEXSZ)); git_odb_object_free(obj); cl_git_pass(git_odb_exists_prefix(NULL, _odb, &oid, GIT_OID_HEXSZ)); cl_git_pass(git_oid_fromstrn(&oid, short_hex, sizeof(short_hex) - 1)); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, sizeof(short_hex) - 1)); git_odb_object_free(obj); cl_git_pass(git_odb_exists_prefix(NULL, _odb, &oid, sizeof(short_hex) - 1)); }
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)); }
git_odb_object * Repository_read_raw(git_repository *repo, const git_oid *oid, size_t len) { git_odb *odb; git_odb_object *obj; int err; err = git_repository_odb(&odb, repo); if (err < 0) { Error_set(err); return NULL; } err = git_odb_read_prefix(&obj, odb, oid, (unsigned int)len); git_odb_free(odb); if (err < 0) { Error_set_oid(err, oid, len); return NULL; } return obj; }
int git_object_lookup_prefix( git_object **object_out, git_repository *repo, const git_oid *id, size_t len, git_otype type) { git_object *object = NULL; git_odb *odb = NULL; git_odb_object *odb_obj = NULL; int error = 0; assert(repo && object_out && id); if (len < GIT_OID_MINPREFIXLEN) { giterr_set(GITERR_OBJECT, "Ambiguous lookup - OID prefix is too short"); return GIT_EAMBIGUOUS; } error = git_repository_odb__weakptr(&odb, repo); if (error < 0) return error; if (len > GIT_OID_HEXSZ) len = GIT_OID_HEXSZ; if (len == GIT_OID_HEXSZ) { git_cached_obj *cached = NULL; /* We want to match the full id : we can first look up in the cache, * since there is no need to check for non ambiguousity */ cached = git_cache_get_any(&repo->objects, id); if (cached != NULL) { if (cached->flags == GIT_CACHE_STORE_PARSED) { object = (git_object *)cached; if (type != GIT_OBJ_ANY && type != object->cached.type) { git_object_free(object); giterr_set(GITERR_INVALID, "The requested type does not match the type in ODB"); return GIT_ENOTFOUND; } *object_out = object; return 0; } else if (cached->flags == GIT_CACHE_STORE_RAW) { odb_obj = (git_odb_object *)cached; } else { assert(!"Wrong caching type in the global object cache"); } } else { /* Object was not found in the cache, let's explore the backends. * We could just use git_odb_read_unique_short_oid, * it is the same cost for packed and loose object backends, * but it may be much more costly for sqlite and hiredis. */ error = git_odb_read(&odb_obj, odb, id); } } else { git_oid short_oid; /* We copy the first len*4 bits from id and fill the remaining with 0s */ memcpy(short_oid.id, id->id, (len + 1) / 2); if (len % 2) short_oid.id[len / 2] &= 0xF0; memset(short_oid.id + (len + 1) / 2, 0, (GIT_OID_HEXSZ - len) / 2); /* If len < GIT_OID_HEXSZ (a strict short oid was given), we have * 2 options : * - We always search in the cache first. If we find that short oid is * ambiguous, we can stop. But in all the other cases, we must then * explore all the backends (to find an object if there was match, * or to check that oid is not ambiguous if we have found 1 match in * the cache) * - We never explore the cache, go right to exploring the backends * We chose the latter : we explore directly the backends. */ error = git_odb_read_prefix(&odb_obj, odb, &short_oid, len); } if (error < 0) return error; error = git_object__from_odb_object(object_out, repo, odb_obj, type); git_odb_object_free(odb_obj); return error; }
void test_odb_mixed__dup_oid_prefix_0(void) { char hex[10]; git_oid oid, found; git_odb_object *obj; /* ambiguous in the same pack file */ strncpy(hex, "dea509d0", sizeof(hex)); cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); strncpy(hex, "dea509d09", sizeof(hex)); cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); cl_assert_equal_oid(&found, git_odb_object_id(obj)); git_odb_object_free(obj); strncpy(hex, "dea509d0b", sizeof(hex)); cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); git_odb_object_free(obj); /* ambiguous in different pack files */ strncpy(hex, "81b5bff5", sizeof(hex)); cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); strncpy(hex, "81b5bff5b", sizeof(hex)); cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); cl_assert_equal_oid(&found, git_odb_object_id(obj)); git_odb_object_free(obj); strncpy(hex, "81b5bff5f", sizeof(hex)); cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); git_odb_object_free(obj); /* ambiguous in pack file and loose */ strncpy(hex, "0ddeaded", sizeof(hex)); cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_assert_equal_i( GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); strncpy(hex, "0ddeaded9", sizeof(hex)); cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex))); cl_assert_equal_oid(&found, git_odb_object_id(obj)); git_odb_object_free(obj); strncpy(hex, "0ddeadede", sizeof(hex)); cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex))); cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex))); git_odb_object_free(obj); }