aboutsummaryrefslogtreecommitdiffstats
path: root/packfile.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2025-09-23 12:17:10 +0200
committerJunio C Hamano <gitster@pobox.com>2025-09-24 11:53:50 -0700
commitd67530f6bbe56f1951b8fd2fcdaae255bf552e2d (patch)
tree1f26edfb6f83c3b97496ab46f4a025a69c4fc089 /packfile.c
parentf6f236d926915411eca28cb1c47619fdacf6eafb (diff)
downloadgit-d67530f6bbe56f1951b8fd2fcdaae255bf552e2d.tar.gz
packfile: introduce function to load and add packfiles
We have a recurring pattern where we essentially perform an upsert of a packfile in case it isn't yet known by the packfile store. The logic to do so is non-trivial as we have to reconstruct the packfile's key, check the map of packfiles, then create the new packfile and finally add it to the store. Introduce a new function that does this dance for us. Refactor callsites to use it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'packfile.c')
-rw-r--r--packfile.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/packfile.c b/packfile.c
index af806aba09..9224ca424c 100644
--- a/packfile.c
+++ b/packfile.c
@@ -792,6 +792,33 @@ void packfile_store_add_pack(struct packfile_store *store,
hashmap_add(&store->map, &pack->packmap_ent);
}
+struct packed_git *packfile_store_load_pack(struct packfile_store *store,
+ const char *idx_path, int local)
+{
+ struct strbuf key = STRBUF_INIT;
+ struct packed_git *p;
+
+ /*
+ * We're being called with the path to the index file, but `pack_map`
+ * holds the path to the packfile itself.
+ */
+ strbuf_addstr(&key, idx_path);
+ strbuf_strip_suffix(&key, ".idx");
+ strbuf_addstr(&key, ".pack");
+
+ p = hashmap_get_entry_from_hash(&store->map, strhash(key.buf), key.buf,
+ struct packed_git, packmap_ent);
+ if (!p) {
+ p = add_packed_git(store->odb->repo, idx_path,
+ strlen(idx_path), local);
+ if (p)
+ packfile_store_add_pack(store, p);
+ }
+
+ strbuf_release(&key);
+ return p;
+}
+
void (*report_garbage)(unsigned seen_bits, const char *path);
static void report_helper(const struct string_list *list,
@@ -891,23 +918,14 @@ static void prepare_pack(const char *full_name, size_t full_name_len,
const char *file_name, void *_data)
{
struct prepare_pack_data *data = (struct prepare_pack_data *)_data;
- struct packed_git *p;
size_t base_len = full_name_len;
if (strip_suffix_mem(full_name, &base_len, ".idx") &&
!(data->m && midx_contains_pack(data->m, file_name))) {
- struct hashmap_entry hent;
- char *pack_name = xstrfmt("%.*s.pack", (int)base_len, full_name);
- unsigned int hash = strhash(pack_name);
- hashmap_entry_init(&hent, hash);
-
- /* Don't reopen a pack we already have. */
- if (!hashmap_get(&data->r->objects->packfiles->map, &hent, pack_name)) {
- p = add_packed_git(data->r, full_name, full_name_len, data->local);
- if (p)
- packfile_store_add_pack(data->r->objects->packfiles, p);
- }
- free(pack_name);
+ char *trimmed_path = xstrndup(full_name, full_name_len);
+ packfile_store_load_pack(data->r->objects->packfiles,
+ trimmed_path, data->local);
+ free(trimmed_path);
}
if (!report_garbage)