Skip to content

Commit d1288f4

Browse files
pks-tgitster
authored andcommitted
midx: load multi-pack indices via their source
To load a multi-pack index the caller is expected to pass both the repository and the object directory where the multi-pack index is located. While this works, this layout has a couple of downsides: - We need to pass in information reduntant with the owning source, namely its object directory and whether the source is local or not. - We don't have access to the source when loading the multi-pack index. If we had that access, we could store a pointer to the owning source in the MIDX and thus deduplicate some information. - Multi-pack indices are inherently specific to the object source and its format. With the goal of pluggable object backends in mind we will eventually want the backends to own the logic of reading and writing multi-pack indices. Making the logic work on top of object sources is a step into that direction. Refactor loading of multi-pack indices accordingly. This surfaces one small problem though: git-multi-pack-index(1) and our MIDX test helper both know to read and write multi-pack-indices located in a different object directory. This issue is addressed by adding the user-provided object directory as an in-memory alternate. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b3a99a2 commit d1288f4

File tree

5 files changed

+62
-52
lines changed

5 files changed

+62
-52
lines changed

builtin/multi-pack-index.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,20 @@ static int parse_object_dir(const struct option *opt, const char *arg,
6464
char **value = opt->value;
6565
free(*value);
6666
if (unset)
67-
*value = xstrdup(repo_get_object_directory(the_repository));
67+
*value = xstrdup(the_repository->objects->sources->path);
6868
else
6969
*value = real_pathdup(arg, 1);
7070
return 0;
7171
}
7272

73+
static struct odb_source *handle_object_dir_option(struct repository *repo)
74+
{
75+
struct odb_source *source = odb_find_source(repo->objects, opts.object_dir);
76+
if (!source)
77+
source = odb_add_to_alternates_memory(repo->objects, opts.object_dir);
78+
return source;
79+
}
80+
7381
static struct option common_opts[] = {
7482
OPT_CALLBACK(0, "object-dir", &opts.object_dir,
7583
N_("directory"),
@@ -157,6 +165,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
157165
if (argc)
158166
usage_with_options(builtin_multi_pack_index_write_usage,
159167
options);
168+
handle_object_dir_option(repo);
160169

161170
FREE_AND_NULL(options);
162171

@@ -193,6 +202,8 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv,
193202
N_("force progress reporting"), MIDX_PROGRESS),
194203
OPT_END(),
195204
};
205+
struct odb_source *source;
206+
196207
options = add_common_options(builtin_multi_pack_index_verify_options);
197208

198209
trace2_cmd_mode(argv[0]);
@@ -205,10 +216,11 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv,
205216
if (argc)
206217
usage_with_options(builtin_multi_pack_index_verify_usage,
207218
options);
219+
source = handle_object_dir_option(the_repository);
208220

209221
FREE_AND_NULL(options);
210222

211-
return verify_midx_file(the_repository, opts.object_dir, opts.flags);
223+
return verify_midx_file(source, opts.flags);
212224
}
213225

214226
static int cmd_multi_pack_index_expire(int argc, const char **argv,
@@ -233,6 +245,7 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv,
233245
if (argc)
234246
usage_with_options(builtin_multi_pack_index_expire_usage,
235247
options);
248+
handle_object_dir_option(the_repository);
236249

237250
FREE_AND_NULL(options);
238251

@@ -265,6 +278,7 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv,
265278
if (argc)
266279
usage_with_options(builtin_multi_pack_index_repack_usage,
267280
options);
281+
handle_object_dir_option(the_repository);
268282

269283
FREE_AND_NULL(options);
270284

midx.c

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,10 @@ static int midx_read_object_offsets(const unsigned char *chunk_start,
9595
return 0;
9696
}
9797

98-
static struct multi_pack_index *load_multi_pack_index_one(struct repository *r,
99-
const char *object_dir,
100-
const char *midx_name,
101-
int local)
98+
static struct multi_pack_index *load_multi_pack_index_one(struct odb_source *source,
99+
const char *midx_name)
102100
{
101+
struct repository *r = source->odb->repo;
103102
struct multi_pack_index *m = NULL;
104103
int fd;
105104
struct stat st;
@@ -129,10 +128,10 @@ static struct multi_pack_index *load_multi_pack_index_one(struct repository *r,
129128
midx_map = xmmap(NULL, midx_size, PROT_READ, MAP_PRIVATE, fd, 0);
130129
close(fd);
131130

132-
FLEX_ALLOC_STR(m, object_dir, object_dir);
131+
FLEX_ALLOC_STR(m, object_dir, source->path);
133132
m->data = midx_map;
134133
m->data_len = midx_size;
135-
m->local = local;
134+
m->local = source->local;
136135
m->repo = r;
137136

138137
m->signature = get_be32(m->data);
@@ -297,19 +296,18 @@ static int add_midx_to_chain(struct multi_pack_index *midx,
297296
return 1;
298297
}
299298

300-
static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r,
301-
const char *object_dir,
302-
int local,
299+
static struct multi_pack_index *load_midx_chain_fd_st(struct odb_source *source,
303300
int fd, struct stat *st,
304301
int *incomplete_chain)
305302
{
303+
const struct git_hash_algo *hash_algo = source->odb->repo->hash_algo;
306304
struct multi_pack_index *midx_chain = NULL;
307305
struct strbuf buf = STRBUF_INIT;
308306
int valid = 1;
309307
uint32_t i, count;
310308
FILE *fp = xfdopen(fd, "r");
311309

312-
count = st->st_size / (r->hash_algo->hexsz + 1);
310+
count = st->st_size / (hash_algo->hexsz + 1);
313311

314312
for (i = 0; i < count; i++) {
315313
struct multi_pack_index *m;
@@ -318,7 +316,7 @@ static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r,
318316
if (strbuf_getline_lf(&buf, fp) == EOF)
319317
break;
320318

321-
if (get_oid_hex_algop(buf.buf, &layer, r->hash_algo)) {
319+
if (get_oid_hex_algop(buf.buf, &layer, hash_algo)) {
322320
warning(_("invalid multi-pack-index chain: line '%s' "
323321
"not a hash"),
324322
buf.buf);
@@ -329,9 +327,9 @@ static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r,
329327
valid = 0;
330328

331329
strbuf_reset(&buf);
332-
get_split_midx_filename_ext(r->hash_algo, &buf, object_dir,
330+
get_split_midx_filename_ext(hash_algo, &buf, source->path,
333331
layer.hash, MIDX_EXT_MIDX);
334-
m = load_multi_pack_index_one(r, object_dir, buf.buf, local);
332+
m = load_multi_pack_index_one(source, buf.buf);
335333

336334
if (m) {
337335
if (add_midx_to_chain(m, midx_chain)) {
@@ -354,40 +352,35 @@ static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r,
354352
return midx_chain;
355353
}
356354

357-
static struct multi_pack_index *load_multi_pack_index_chain(struct repository *r,
358-
const char *object_dir,
359-
int local)
355+
static struct multi_pack_index *load_multi_pack_index_chain(struct odb_source *source)
360356
{
361357
struct strbuf chain_file = STRBUF_INIT;
362358
struct stat st;
363359
int fd;
364360
struct multi_pack_index *m = NULL;
365361

366-
get_midx_chain_filename(&chain_file, object_dir);
367-
if (open_multi_pack_index_chain(r->hash_algo, chain_file.buf, &fd, &st)) {
362+
get_midx_chain_filename(&chain_file, source->path);
363+
if (open_multi_pack_index_chain(source->odb->repo->hash_algo, chain_file.buf, &fd, &st)) {
368364
int incomplete;
369365
/* ownership of fd is taken over by load function */
370-
m = load_midx_chain_fd_st(r, object_dir, local, fd, &st,
371-
&incomplete);
366+
m = load_midx_chain_fd_st(source, fd, &st, &incomplete);
372367
}
373368

374369
strbuf_release(&chain_file);
375370
return m;
376371
}
377372

378-
struct multi_pack_index *load_multi_pack_index(struct repository *r,
379-
const char *object_dir,
380-
int local)
373+
struct multi_pack_index *load_multi_pack_index(struct odb_source *source)
381374
{
382375
struct strbuf midx_name = STRBUF_INIT;
383376
struct multi_pack_index *m;
384377

385-
get_midx_filename(r->hash_algo, &midx_name, object_dir);
378+
get_midx_filename(source->odb->repo->hash_algo, &midx_name,
379+
source->path);
386380

387-
m = load_multi_pack_index_one(r, object_dir,
388-
midx_name.buf, local);
381+
m = load_multi_pack_index_one(source, midx_name.buf);
389382
if (!m)
390-
m = load_multi_pack_index_chain(r, object_dir, local);
383+
m = load_multi_pack_index_chain(source);
391384

392385
strbuf_release(&midx_name);
393386

@@ -734,8 +727,7 @@ int prepare_multi_pack_index_one(struct odb_source *source)
734727
if (source->midx)
735728
return 1;
736729

737-
source->midx = load_multi_pack_index(r, source->path,
738-
source->local);
730+
source->midx = load_multi_pack_index(source);
739731

740732
return !!source->midx;
741733
}
@@ -880,12 +872,13 @@ static int compare_pair_pos_vs_id(const void *_a, const void *_b)
880872
display_progress(progress, _n); \
881873
} while (0)
882874

883-
int verify_midx_file(struct repository *r, const char *object_dir, unsigned flags)
875+
int verify_midx_file(struct odb_source *source, unsigned flags)
884876
{
877+
struct repository *r = source->odb->repo;
885878
struct pair_pos_vs_id *pairs = NULL;
886879
uint32_t i;
887880
struct progress *progress = NULL;
888-
struct multi_pack_index *m = load_multi_pack_index(r, object_dir, 1);
881+
struct multi_pack_index *m = load_multi_pack_index(source);
889882
struct multi_pack_index *curr;
890883
verify_midx_error = 0;
891884

@@ -894,7 +887,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
894887
struct stat sb;
895888
struct strbuf filename = STRBUF_INIT;
896889

897-
get_midx_filename(r->hash_algo, &filename, object_dir);
890+
get_midx_filename(r->hash_algo, &filename, source->path);
898891

899892
if (!stat(filename.buf, &sb)) {
900893
error(_("multi-pack-index file exists, but failed to parse"));

midx.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,7 @@ void get_split_midx_filename_ext(const struct git_hash_algo *hash_algo,
100100
struct strbuf *buf, const char *object_dir,
101101
const unsigned char *hash, const char *ext);
102102

103-
struct multi_pack_index *load_multi_pack_index(struct repository *r,
104-
const char *object_dir,
105-
int local);
103+
struct multi_pack_index *load_multi_pack_index(struct odb_source *source);
106104
int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id);
107105
struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
108106
uint32_t pack_int_id);
@@ -136,7 +134,7 @@ int write_midx_file_only(struct repository *r, const char *object_dir,
136134
const char *preferred_pack_name,
137135
const char *refs_snapshot, unsigned flags);
138136
void clear_midx_file(struct repository *r);
139-
int verify_midx_file(struct repository *r, const char *object_dir, unsigned flags);
137+
int verify_midx_file(struct odb_source *source, unsigned flags);
140138
int expire_midx_packs(struct repository *r, const char *object_dir, unsigned flags);
141139
int midx_repack(struct repository *r, const char *object_dir, size_t batch_size, unsigned flags);
142140

t/helper/test-read-midx.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,24 @@
1111
#include "gettext.h"
1212
#include "pack-revindex.h"
1313

14+
static struct multi_pack_index *setup_midx(const char *object_dir)
15+
{
16+
struct odb_source *source;
17+
setup_git_directory();
18+
source = odb_find_source(the_repository->objects, object_dir);
19+
if (!source)
20+
source = odb_add_to_alternates_memory(the_repository->objects,
21+
object_dir);
22+
return load_multi_pack_index(source);
23+
}
24+
1425
static int read_midx_file(const char *object_dir, const char *checksum,
1526
int show_objects)
1627
{
1728
uint32_t i;
1829
struct multi_pack_index *m;
1930

20-
setup_git_directory();
21-
m = load_multi_pack_index(the_repository, object_dir, 1);
31+
m = setup_midx(object_dir);
2232

2333
if (!m)
2434
return 1;
@@ -81,8 +91,7 @@ static int read_midx_checksum(const char *object_dir)
8191
{
8292
struct multi_pack_index *m;
8393

84-
setup_git_directory();
85-
m = load_multi_pack_index(the_repository, object_dir, 1);
94+
m = setup_midx(object_dir);
8695
if (!m)
8796
return 1;
8897
printf("%s\n", hash_to_hex(get_midx_checksum(m)));
@@ -96,9 +105,7 @@ static int read_midx_preferred_pack(const char *object_dir)
96105
struct multi_pack_index *midx = NULL;
97106
uint32_t preferred_pack;
98107

99-
setup_git_directory();
100-
101-
midx = load_multi_pack_index(the_repository, object_dir, 1);
108+
midx = setup_midx(object_dir);
102109
if (!midx)
103110
return 1;
104111

@@ -119,9 +126,7 @@ static int read_midx_bitmapped_packs(const char *object_dir)
119126
struct bitmapped_pack pack;
120127
uint32_t i;
121128

122-
setup_git_directory();
123-
124-
midx = load_multi_pack_index(the_repository, object_dir, 1);
129+
midx = setup_midx(object_dir);
125130
if (!midx)
126131
return 1;
127132

t/t5319-multi-pack-index.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ midx_read_expect () {
2828
EOF
2929
if test $NUM_PACKS -ge 1
3030
then
31-
ls $OBJECT_DIR/pack/ | grep idx | sort
31+
ls "$OBJECT_DIR"/pack/ | grep idx | sort
3232
fi &&
3333
printf "object-dir: $OBJECT_DIR\n"
3434
} >expect &&
35-
test-tool read-midx $OBJECT_DIR >actual &&
35+
test-tool read-midx "$OBJECT_DIR" >actual &&
3636
test_cmp expect actual
3737
}
3838

@@ -305,7 +305,7 @@ test_expect_success 'midx picks objects from preferred pack' '
305305
306306
ofs=$(git show-index <objects/pack/test-BC-$bc.idx | grep $b |
307307
cut -d" " -f1) &&
308-
printf "%s %s\tobjects/pack/test-BC-%s.pack\n" \
308+
printf "%s %s\t./objects/pack/test-BC-%s.pack\n" \
309309
"$b" "$ofs" "$bc" >expect &&
310310
grep ^$b out >actual &&
311311
@@ -639,7 +639,7 @@ test_expect_success 'force some 64-bit offsets with pack-objects' '
639639
( cd ../objects64 && pwd ) >.git/objects/info/alternates &&
640640
midx64=$(git multi-pack-index --object-dir=../objects64 write)
641641
) &&
642-
midx_read_expect 1 63 5 objects64 " large-offsets"
642+
midx_read_expect 1 63 5 "$(pwd)/objects64" " large-offsets"
643643
'
644644

645645
test_expect_success 'verify multi-pack-index with 64-bit offsets' '

0 commit comments

Comments
 (0)