multi-pack-index: read packfile list
authorDerrick Stolee <stolee@gmail.com>
Thu, 12 Jul 2018 19:39:26 +0000 (15:39 -0400)
committerJunio C Hamano <gitster@pobox.com>
Fri, 20 Jul 2018 18:27:28 +0000 (11:27 -0700)
When constructing a multi-pack-index file for a given object directory,
read the files within the enclosed pack directory and find matches that
end with ".idx" and find the correct paired packfile using
add_packed_git().

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
midx.c
t/t5319-multi-pack-index.sh

diff --git a/midx.c b/midx.c
index c1ff5ac..f742d7c 100644 (file)
--- a/midx.c
+++ b/midx.c
@@ -1,6 +1,8 @@
 #include "cache.h"
 #include "csum-file.h"
+#include "dir.h"
 #include "lockfile.h"
+#include "packfile.h"
 #include "object-store.h"
 #include "midx.h"
 
@@ -109,12 +111,41 @@ static size_t write_midx_header(struct hashfile *f,
        return MIDX_HEADER_SIZE;
 }
 
+struct pack_list {
+       struct packed_git **list;
+       uint32_t nr;
+       uint32_t alloc_list;
+};
+
+static void add_pack_to_midx(const char *full_path, size_t full_path_len,
+                            const char *file_name, void *data)
+{
+       struct pack_list *packs = (struct pack_list *)data;
+
+       if (ends_with(file_name, ".idx")) {
+               ALLOC_GROW(packs->list, packs->nr + 1, packs->alloc_list);
+
+               packs->list[packs->nr] = add_packed_git(full_path,
+                                                       full_path_len,
+                                                       0);
+               if (!packs->list[packs->nr]) {
+                       warning(_("failed to add packfile '%s'"),
+                               full_path);
+                       return;
+               }
+
+               packs->nr++;
+       }
+}
+
 int write_midx_file(const char *object_dir)
 {
        unsigned char num_chunks = 0;
        char *midx_name;
+       uint32_t i;
        struct hashfile *f = NULL;
        struct lock_file lk;
+       struct pack_list packs;
 
        midx_name = get_midx_filename(object_dir);
        if (safe_create_leading_directories(midx_name)) {
@@ -123,14 +154,29 @@ int write_midx_file(const char *object_dir)
                          midx_name);
        }
 
+       packs.nr = 0;
+       packs.alloc_list = 16;
+       packs.list = NULL;
+       ALLOC_ARRAY(packs.list, packs.alloc_list);
+
+       for_each_file_in_pack_dir(object_dir, add_pack_to_midx, &packs);
+
        hold_lock_file_for_update(&lk, midx_name, LOCK_DIE_ON_ERROR);
        f = hashfd(lk.tempfile->fd, lk.tempfile->filename.buf);
        FREE_AND_NULL(midx_name);
 
-       write_midx_header(f, num_chunks, 0);
+       write_midx_header(f, num_chunks, packs.nr);
 
        finalize_hashfile(f, NULL, CSUM_FSYNC | CSUM_HASH_IN_STREAM);
        commit_lock_file(&lk);
 
+       for (i = 0; i < packs.nr; i++) {
+               if (packs.list[i]) {
+                       close_pack(packs.list[i]);
+                       free(packs.list[i]);
+               }
+       }
+
+       free(packs.list);
        return 0;
 }
index 1240127..54117a7 100755 (executable)
@@ -4,8 +4,9 @@ test_description='multi-pack-indexes'
 . ./test-lib.sh
 
 midx_read_expect () {
+       NUM_PACKS=$1
        cat >expect <<-EOF
-       header: 4d494458 1 0 0
+       header: 4d494458 1 0 $NUM_PACKS
        object-dir: .
        EOF
        test-tool read-midx . >actual &&
@@ -15,7 +16,7 @@ midx_read_expect () {
 test_expect_success 'write midx with no packs' '
        test_when_finished rm -f pack/multi-pack-index &&
        git multi-pack-index --object-dir=. write &&
-       midx_read_expect
+       midx_read_expect 0
 '
 
 generate_objects () {
@@ -65,13 +66,13 @@ test_expect_success 'write midx with one v1 pack' '
        pack=$(git pack-objects --index-version=1 pack/test <obj-list) &&
        test_when_finished rm pack/test-$pack.pack pack/test-$pack.idx pack/multi-pack-index &&
        git multi-pack-index --object-dir=. write &&
-       midx_read_expect
+       midx_read_expect 1
 '
 
 test_expect_success 'write midx with one v2 pack' '
        git pack-objects --index-version=2,0x40 pack/test <obj-list &&
        git multi-pack-index --object-dir=. write &&
-       midx_read_expect
+       midx_read_expect 1
 '
 
 test_expect_success 'add more objects' '
@@ -85,7 +86,7 @@ test_expect_success 'add more objects' '
 test_expect_success 'write midx with two packs' '
        git pack-objects --index-version=1 pack/test-2 <obj-list &&
        git multi-pack-index --object-dir=. write &&
-       midx_read_expect
+       midx_read_expect 2
 '
 
 test_expect_success 'add more packs' '
@@ -93,13 +94,13 @@ test_expect_success 'add more packs' '
        do
                generate_objects $j &&
                commit_and_list_objects &&
-               git pack-objects --index-version=2 test-pack <obj-list
+               git pack-objects --index-version=2 pack/test-pack <obj-list
        done
 '
 
 test_expect_success 'write midx with twelve packs' '
        git multi-pack-index --object-dir=. write &&
-       midx_read_expect
+       midx_read_expect 12
 '
 
 test_done