multi-pack-index: read packfile list

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>

Derrick Stolee committed Jul 12, 2018 at 15:39 UTC 396f257018a6031c4eb0803d4693441ad8a9fd10
2 files changed +55 -8
midx.c
+47 -1
@@ -1,6 +1,8 @@
1 #include "cache.h"
2 #include "csum-file.h"
3 +#include "dir.h"
4 #include "lockfile.h"
5 +#include "packfile.h"
6 #include "object-store.h"
7 #include "midx.h"
8
@@ -109,12 +111,41 @@ static size_t write_midx_header(struct hashfile *f,
111 return MIDX_HEADER_SIZE;
112 }
113
114 +struct pack_list {
115 + struct packed_git **list;
116 + uint32_t nr;
117 + uint32_t alloc_list;
118 +};
119 +
120 +static void add_pack_to_midx(const char *full_path, size_t full_path_len,
121 + const char *file_name, void *data)
122 +{
123 + struct pack_list *packs = (struct pack_list *)data;
124 +
125 + if (ends_with(file_name, ".idx")) {
126 + ALLOC_GROW(packs->list, packs->nr + 1, packs->alloc_list);
127 +
128 + packs->list[packs->nr] = add_packed_git(full_path,
129 + full_path_len,
130 + 0);
131 + if (!packs->list[packs->nr]) {
132 + warning(_("failed to add packfile '%s'"),
133 + full_path);
134 + return;
135 + }
136 +
137 + packs->nr++;
138 + }
139 +}
140 +
141 int write_midx_file(const char *object_dir)
142 {
143 unsigned char num_chunks = 0;
144 char *midx_name;
145 + uint32_t i;
146 struct hashfile *f = NULL;
147 struct lock_file lk;
148 + struct pack_list packs;
149
150 midx_name = get_midx_filename(object_dir);
151 if (safe_create_leading_directories(midx_name)) {
@@ -123,14 +154,29 @@ int write_midx_file(const char *object_dir)
154 midx_name);
155 }
156
157 + packs.nr = 0;
158 + packs.alloc_list = 16;
159 + packs.list = NULL;
160 + ALLOC_ARRAY(packs.list, packs.alloc_list);
161 +
162 + for_each_file_in_pack_dir(object_dir, add_pack_to_midx, &packs);
163 +
164 hold_lock_file_for_update(&lk, midx_name, LOCK_DIE_ON_ERROR);
165 f = hashfd(lk.tempfile->fd, lk.tempfile->filename.buf);
166 FREE_AND_NULL(midx_name);
167
130 - write_midx_header(f, num_chunks, 0);
168 + write_midx_header(f, num_chunks, packs.nr);
169
170 finalize_hashfile(f, NULL, CSUM_FSYNC | CSUM_HASH_IN_STREAM);
171 commit_lock_file(&lk);
172
173 + for (i = 0; i < packs.nr; i++) {
174 + if (packs.list[i]) {
175 + close_pack(packs.list[i]);
176 + free(packs.list[i]);
177 + }
178 + }
179 +
180 + free(packs.list);
181 return 0;
182 }
t/t5319-multi-pack-index.sh
+8 -7
@@ -4,8 +4,9 @@ test_description='multi-pack-indexes'
4 . ./test-lib.sh
5
6 midx_read_expect () {
7 + NUM_PACKS=$1
8 cat >expect <<-EOF
8 - header: 4d494458 1 0 0
9 + header: 4d494458 1 0 $NUM_PACKS
10 object-dir: .
11 EOF
12 test-tool read-midx . >actual &&
@@ -15,7 +16,7 @@ midx_read_expect () {
16 test_expect_success 'write midx with no packs' '
17 test_when_finished rm -f pack/multi-pack-index &&
18 git multi-pack-index --object-dir=. write &&
18 - midx_read_expect
19 + midx_read_expect 0
20 '
21
22 generate_objects () {
@@ -65,13 +66,13 @@ test_expect_success 'write midx with one v1 pack' '
66 pack=$(git pack-objects --index-version=1 pack/test <obj-list) &&
67 test_when_finished rm pack/test-$pack.pack pack/test-$pack.idx pack/multi-pack-index &&
68 git multi-pack-index --object-dir=. write &&
68 - midx_read_expect
69 + midx_read_expect 1
70 '
71
72 test_expect_success 'write midx with one v2 pack' '
73 git pack-objects --index-version=2,0x40 pack/test <obj-list &&
74 git multi-pack-index --object-dir=. write &&
74 - midx_read_expect
75 + midx_read_expect 1
76 '
77
78 test_expect_success 'add more objects' '
@@ -85,7 +86,7 @@ test_expect_success 'add more objects' '
86 test_expect_success 'write midx with two packs' '
87 git pack-objects --index-version=1 pack/test-2 <obj-list &&
88 git multi-pack-index --object-dir=. write &&
88 - midx_read_expect
89 + midx_read_expect 2
90 '
91
92 test_expect_success 'add more packs' '
@@ -93,13 +94,13 @@ test_expect_success 'add more packs' '
94 do
95 generate_objects $j &&
96 commit_and_list_objects &&
96 - git pack-objects --index-version=2 test-pack <obj-list
97 + git pack-objects --index-version=2 pack/test-pack <obj-list
98 done
99 '
100
101 test_expect_success 'write midx with twelve packs' '
102 git multi-pack-index --object-dir=. write &&
102 - midx_read_expect
103 + midx_read_expect 12
104 '
105
106 test_done