pack-objects: consider packs in multi-pack-index
authorDerrick Stolee <dstolee@microsoft.com>
Mon, 20 Aug 2018 16:52:08 +0000 (16:52 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 20 Aug 2018 22:31:40 +0000 (15:31 -0700)
When running 'git pack-objects --local', we want to avoid packing
objects that are in an alternate. Currently, we check for these
objects using the packed_git_mru list, which excludes the pack-files
covered by a multi-pack-index.

Add a new iteration over the multi-pack-indexes to find these
copies and mark them as unwanted.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/pack-objects.c
t/t5319-multi-pack-index.sh
index cf5cf45ac940565f0dcd65ed21e164ed98844873..807f0343653ada7dce87c11a376c6984ed838332 100644 (file)
@@ -31,6 +31,7 @@
 #include "packfile.h"
 #include "object-store.h"
 #include "dir.h"
+#include "midx.h"
 
 #define IN_PACK(obj) oe_in_pack(&to_pack, obj)
 #define SIZE(obj) oe_size(&to_pack, obj)
@@ -1040,6 +1041,7 @@ static int want_object_in_pack(const struct object_id *oid,
 {
        int want;
        struct list_head *pos;
+       struct multi_pack_index *m;
 
        if (!exclude && local && has_loose_object_nonlocal(oid))
                return 0;
@@ -1054,6 +1056,32 @@ static int want_object_in_pack(const struct object_id *oid,
                if (want != -1)
                        return want;
        }
+
+       for (m = get_multi_pack_index(the_repository); m; m = m->next) {
+               struct pack_entry e;
+               if (fill_midx_entry(oid, &e, m)) {
+                       struct packed_git *p = e.p;
+                       off_t offset;
+
+                       if (p == *found_pack)
+                               offset = *found_offset;
+                       else
+                               offset = find_pack_entry_one(oid->hash, p);
+
+                       if (offset) {
+                               if (!*found_pack) {
+                                       if (!is_pack_valid(p))
+                                               continue;
+                                       *found_offset = offset;
+                                       *found_pack = p;
+                               }
+                               want = want_found_object(exclude, p);
+                               if (want != -1)
+                                       return want;
+                       }
+               }
+       }
+
        list_for_each(pos, get_packed_git_mru(the_repository)) {
                struct packed_git *p = list_entry(pos, struct packed_git, mru);
                off_t offset;
index 424d0c640f5ee439db28e1683ffa1d72023735c0..6f56b38674fd62085e757cbc685436107a6bb9fe 100755 (executable)
@@ -176,7 +176,13 @@ test_expect_success 'multi-pack-index and alternates' '
 compare_results_with_midx "with alternate (local midx)"
 
 test_expect_success 'multi-pack-index in an alternate' '
-       mv .git/objects/pack/* alt.git/objects/pack
+       mv .git/objects/pack/* alt.git/objects/pack &&
+       test_commit add_local_objects &&
+       git repack --local &&
+       git multi-pack-index write &&
+       midx_read_expect 1 3 4 $objdir &&
+       git reset --hard HEAD~1 &&
+       rm -f .git/objects/pack/*
 '
 
 compare_results_with_midx "with alternate (remote midx)"