diff --git a/src/odb_pack.c b/src/odb_pack.c index eec79259b..43880612a 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -259,23 +259,26 @@ static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backen return git_odb__error_notfound("failed to find pack entry", oid); } -static unsigned pack_entry_find_prefix_inner( - struct git_pack_entry *e, - struct pack_backend *backend, - const git_oid *short_oid, - size_t len, - struct git_pack_file *last_found) +static int pack_entry_find_prefix( + struct git_pack_entry *e, + struct pack_backend *backend, + const git_oid *short_oid, + size_t len) { int error; size_t i; - unsigned found = 0; + git_oid found_full_oid = {{0}}; + bool found = false; + struct git_pack_file *last_found = backend->last_found; if (last_found) { error = git_pack_entry_find(e, last_found, short_oid, len); if (error == GIT_EAMBIGUOUS) return error; - if (!error) - found = 1; + if (!error) { + git_oid_cpy(&found_full_oid, &e->sha1); + found = true; + } } for (i = 0; i < backend->packs.length; ++i) { @@ -289,28 +292,16 @@ static unsigned pack_entry_find_prefix_inner( if (error == GIT_EAMBIGUOUS) return error; if (!error) { - if (++found > 1) - break; + if (found && git_oid_cmp(&e->sha1, &found_full_oid)) + return git_odb__error_ambiguous("found multiple pack entries"); + git_oid_cpy(&found_full_oid, &e->sha1); + found = true; backend->last_found = p; } } - return found; -} - -static int pack_entry_find_prefix( - struct git_pack_entry *e, - struct pack_backend *backend, - const git_oid *short_oid, - size_t len) -{ - struct git_pack_file *last_found = backend->last_found; - unsigned int found = pack_entry_find_prefix_inner(e, backend, short_oid, len, last_found); - if (!found) return git_odb__error_notfound("no matching pack entry for prefix", short_oid); - else if (found > 1) - return git_odb__error_ambiguous("found multiple pack entries"); else return 0; } diff --git a/tests-clar/odb/mixed.c b/tests-clar/odb/mixed.c index 7f7120a6e..dd4587831 100644 --- a/tests-clar/odb/mixed.c +++ b/tests-clar/odb/mixed.c @@ -16,11 +16,14 @@ void test_odb_mixed__cleanup(void) 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)); + 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); } diff --git a/tests-clar/resources/duplicate.git/objects/info/packs b/tests-clar/resources/duplicate.git/objects/info/packs index 3696a7d36..d0fdf905e 100644 --- a/tests-clar/resources/duplicate.git/objects/info/packs +++ b/tests-clar/resources/duplicate.git/objects/info/packs @@ -1,2 +1,3 @@ P pack-e87994ad581c9af946de0eb890175c08cd005f38.pack +P pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack diff --git a/tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.idx b/tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.idx new file mode 100644 index 000000000..9f78f6e0f Binary files /dev/null and b/tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.idx differ diff --git a/tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack b/tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack new file mode 100644 index 000000000..d1dd3b61a Binary files /dev/null and b/tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack differ