]> git.proxmox.com Git - libgit2.git/commitdiff
odb_pack: handle duplicate objects from different packs
authorBrodie Rao <brodie@sf.io>
Thu, 6 Jun 2013 21:49:14 +0000 (14:49 -0700)
committerBrodie Rao <brodie@sf.io>
Thu, 8 Aug 2013 07:41:16 +0000 (00:41 -0700)
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
tests-clar/odb/mixed.c
tests-clar/resources/duplicate.git/objects/info/packs
tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.idx [new file with mode: 0644]
tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack [new file with mode: 0644]

index eec79259b857c2758b5ce46495aa27cca9acbe39..43880612a6c3950f1854a5856e7426ce17cb098c 100644 (file)
@@ -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;
 }
index 7f7120a6e8166cf922695d7b1dc250b28ad670a8..dd4587831f2c7b5de742891a838dd98ff9b13d6f 100644 (file)
@@ -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);
 }
 
index 3696a7d36d8553e5182a5edf19e623febcdefb85..d0fdf905e72979cfd363bc6f467c3dcc44254a99 100644 (file)
@@ -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 (file)
index 0000000..9f78f6e
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 (file)
index 0000000..d1dd3b6
Binary files /dev/null and b/tests-clar/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack differ