From d19bcb335256fddc5dd1289f1772d4d864b54ec0 Mon Sep 17 00:00:00 2001 From: Brodie Rao Date: Thu, 6 Jun 2013 14:49:14 -0700 Subject: [PATCH] odb_pack: handle duplicate objects from different packs This is based on 24634c6fd02b2240e4a93fad70a08220f8fb793a. This also corrects an issue with error codes being mixed up with the number of found objects. --- src/odb_pack.c | 41 +++++++----------- tests-clar/odb/mixed.c | 3 ++ .../duplicate.git/objects/info/packs | 1 + ...ef1aa326265de7d05018ee51acc0a8717fe1ea.idx | Bin 0 -> 1100 bytes ...f1aa326265de7d05018ee51acc0a8717fe1ea.pack | Bin 0 -> 47 bytes 5 files changed, 20 insertions(+), 25 deletions(-) create mode 100644 tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.idx create mode 100644 tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack 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 0000000000000000000000000000000000000000..9f78f6e0f7d243f298189b35f19af590295b7011 GIT binary patch literal 1100 zcmexg;-AdGz`z8=qhK@yMniz~5MTsq8S?lXqnRo*_lnyq*}jKOtDiS#@f0_&pedrD w(BQepBIF?NH7}mkQQqa%&l9+4fd?z5f_^jYoP9{cY0JI1iG5`Po literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d1dd3b61af11b23c05d779832d773633a48462f5 GIT binary patch literal 47 zcmWG=boORoU|<4bMze}Jr#;S|Jo%i7fy0|g{vL~vgS^+gcveSwmsdYe