aboutsummaryrefslogtreecommitdiffstats
path: root/midx.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2025-08-11 15:46:47 +0200
committerJunio C Hamano <gitster@pobox.com>2025-08-11 09:22:22 -0700
commit017db7bb14246dea55b678fc20e34ce91c28968a (patch)
tree7805df854b8f84f3ef717c7b2be9ce1ba3c4a687 /midx.c
parent9ff212961506679c1e2c1541b17ab2bd8563ff15 (diff)
downloadgit-017db7bb14246dea55b678fc20e34ce91c28968a.tar.gz
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 <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'midx.c')
-rw-r--r--midx.c57
1 files changed, 25 insertions, 32 deletions
diff --git a/midx.c b/midx.c
index 8459dda8c9..831a7e9b5f 100644
--- a/midx.c
+++ b/midx.c
@@ -95,11 +95,10 @@ static int midx_read_object_offsets(const unsigned char *chunk_start,
return 0;
}
-static struct multi_pack_index *load_multi_pack_index_one(struct repository *r,
- const char *object_dir,
- const char *midx_name,
- int local)
+static struct multi_pack_index *load_multi_pack_index_one(struct odb_source *source,
+ const char *midx_name)
{
+ struct repository *r = source->odb->repo;
struct multi_pack_index *m = NULL;
int fd;
struct stat st;
@@ -129,10 +128,10 @@ static struct multi_pack_index *load_multi_pack_index_one(struct repository *r,
midx_map = xmmap(NULL, midx_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
- FLEX_ALLOC_STR(m, object_dir, object_dir);
+ FLEX_ALLOC_STR(m, object_dir, source->path);
m->data = midx_map;
m->data_len = midx_size;
- m->local = local;
+ m->local = source->local;
m->repo = r;
m->signature = get_be32(m->data);
@@ -297,19 +296,18 @@ static int add_midx_to_chain(struct multi_pack_index *midx,
return 1;
}
-static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r,
- const char *object_dir,
- int local,
+static struct multi_pack_index *load_midx_chain_fd_st(struct odb_source *source,
int fd, struct stat *st,
int *incomplete_chain)
{
+ const struct git_hash_algo *hash_algo = source->odb->repo->hash_algo;
struct multi_pack_index *midx_chain = NULL;
struct strbuf buf = STRBUF_INIT;
int valid = 1;
uint32_t i, count;
FILE *fp = xfdopen(fd, "r");
- count = st->st_size / (r->hash_algo->hexsz + 1);
+ count = st->st_size / (hash_algo->hexsz + 1);
for (i = 0; i < count; i++) {
struct multi_pack_index *m;
@@ -318,7 +316,7 @@ static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r,
if (strbuf_getline_lf(&buf, fp) == EOF)
break;
- if (get_oid_hex_algop(buf.buf, &layer, r->hash_algo)) {
+ if (get_oid_hex_algop(buf.buf, &layer, hash_algo)) {
warning(_("invalid multi-pack-index chain: line '%s' "
"not a hash"),
buf.buf);
@@ -329,9 +327,9 @@ static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r,
valid = 0;
strbuf_reset(&buf);
- get_split_midx_filename_ext(r->hash_algo, &buf, object_dir,
+ get_split_midx_filename_ext(hash_algo, &buf, source->path,
layer.hash, MIDX_EXT_MIDX);
- m = load_multi_pack_index_one(r, object_dir, buf.buf, local);
+ m = load_multi_pack_index_one(source, buf.buf);
if (m) {
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,
return midx_chain;
}
-static struct multi_pack_index *load_multi_pack_index_chain(struct repository *r,
- const char *object_dir,
- int local)
+static struct multi_pack_index *load_multi_pack_index_chain(struct odb_source *source)
{
struct strbuf chain_file = STRBUF_INIT;
struct stat st;
int fd;
struct multi_pack_index *m = NULL;
- get_midx_chain_filename(&chain_file, object_dir);
- if (open_multi_pack_index_chain(r->hash_algo, chain_file.buf, &fd, &st)) {
+ get_midx_chain_filename(&chain_file, source->path);
+ if (open_multi_pack_index_chain(source->odb->repo->hash_algo, chain_file.buf, &fd, &st)) {
int incomplete;
/* ownership of fd is taken over by load function */
- m = load_midx_chain_fd_st(r, object_dir, local, fd, &st,
- &incomplete);
+ m = load_midx_chain_fd_st(source, fd, &st, &incomplete);
}
strbuf_release(&chain_file);
return m;
}
-struct multi_pack_index *load_multi_pack_index(struct repository *r,
- const char *object_dir,
- int local)
+struct multi_pack_index *load_multi_pack_index(struct odb_source *source)
{
struct strbuf midx_name = STRBUF_INIT;
struct multi_pack_index *m;
- get_midx_filename(r->hash_algo, &midx_name, object_dir);
+ get_midx_filename(source->odb->repo->hash_algo, &midx_name,
+ source->path);
- m = load_multi_pack_index_one(r, object_dir,
- midx_name.buf, local);
+ m = load_multi_pack_index_one(source, midx_name.buf);
if (!m)
- m = load_multi_pack_index_chain(r, object_dir, local);
+ m = load_multi_pack_index_chain(source);
strbuf_release(&midx_name);
@@ -734,8 +727,7 @@ int prepare_multi_pack_index_one(struct odb_source *source)
if (source->midx)
return 1;
- source->midx = load_multi_pack_index(r, source->path,
- source->local);
+ source->midx = load_multi_pack_index(source);
return !!source->midx;
}
@@ -880,12 +872,13 @@ static int compare_pair_pos_vs_id(const void *_a, const void *_b)
display_progress(progress, _n); \
} while (0)
-int verify_midx_file(struct repository *r, const char *object_dir, unsigned flags)
+int verify_midx_file(struct odb_source *source, unsigned flags)
{
+ struct repository *r = source->odb->repo;
struct pair_pos_vs_id *pairs = NULL;
uint32_t i;
struct progress *progress = NULL;
- struct multi_pack_index *m = load_multi_pack_index(r, object_dir, 1);
+ struct multi_pack_index *m = load_multi_pack_index(source);
struct multi_pack_index *curr;
verify_midx_error = 0;
@@ -894,7 +887,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
struct stat sb;
struct strbuf filename = STRBUF_INIT;
- get_midx_filename(r->hash_algo, &filename, object_dir);
+ get_midx_filename(r->hash_algo, &filename, source->path);
if (!stat(filename.buf, &sb)) {
error(_("multi-pack-index file exists, but failed to parse"));