summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2025-09-23 12:17:08 +0200
committerJunio C Hamano <gitster@pobox.com>2025-09-24 11:53:50 -0700
commit78237ea53d6546aeab7adb2c7547a1177311ccde (patch)
treebfc9bf24d14901380ec2c81b9d44ca342ad12fa4
parentc36ecc0685a75f913fe4871766715221c71f4b09 (diff)
packfile: split up responsibilities of `reprepare_packed_git()`
In `reprepare_packed_git()` we perform a couple of operations: - We reload alternate object directories. - We clear the loose object cache. - We reprepare packfiles. While the logic is hosted in "packfile.c", it clearly reaches into other subsystems that aren't related to packfiles. Split up the responsibility and introduce `odb_reprepare()` which now becomes responsible for repreparing the whole object database. The existing `reprepare_packed_git()` function is refactored accordingly and only cares about reloading the packfile store now. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/backfill.c2
-rw-r--r--builtin/gc.c4
-rw-r--r--builtin/receive-pack.c2
-rw-r--r--builtin/repack.c2
-rw-r--r--bulk-checkin.c2
-rw-r--r--connected.c2
-rw-r--r--fetch-pack.c4
-rw-r--r--object-name.c2
-rw-r--r--odb.c27
-rw-r--r--odb.h6
-rw-r--r--packfile.c26
-rw-r--r--packfile.h9
-rw-r--r--transport-helper.c2
13 files changed, 55 insertions, 35 deletions
diff --git a/builtin/backfill.c b/builtin/backfill.c
index 80056abe47..e80fc1b694 100644
--- a/builtin/backfill.c
+++ b/builtin/backfill.c
@@ -53,7 +53,7 @@ static void download_batch(struct backfill_context *ctx)
* We likely have a new packfile. Add it to the packed list to
* avoid possible duplicate downloads of the same objects.
*/
- reprepare_packed_git(ctx->repo);
+ odb_reprepare(ctx->repo->objects);
}
static int fill_missing_blobs(const char *path UNUSED,
diff --git a/builtin/gc.c b/builtin/gc.c
index 03ae4926b2..aeca06a08b 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -1042,7 +1042,7 @@ int cmd_gc(int argc,
die(FAILED_RUN, "rerere");
report_garbage = report_pack_garbage;
- reprepare_packed_git(the_repository);
+ odb_reprepare(the_repository->objects);
if (pack_garbage.nr > 0) {
close_object_store(the_repository->objects);
clean_pack_garbage();
@@ -1491,7 +1491,7 @@ static off_t get_auto_pack_size(void)
struct packed_git *p;
struct repository *r = the_repository;
- reprepare_packed_git(r);
+ odb_reprepare(r->objects);
for (p = get_all_packs(r); p; p = p->next) {
if (p->pack_size > max_size) {
second_largest_size = max_size;
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 1113137a6f..c9288a9c7e 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -2389,7 +2389,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
status = finish_command(&child);
if (status)
return "index-pack abnormal exit";
- reprepare_packed_git(the_repository);
+ odb_reprepare(the_repository->objects);
}
return NULL;
}
diff --git a/builtin/repack.c b/builtin/repack.c
index c490a51e91..5ff27fc8e2 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -1685,7 +1685,7 @@ int cmd_repack(int argc,
goto cleanup;
}
- reprepare_packed_git(the_repository);
+ odb_reprepare(the_repository->objects);
if (delete_redundant) {
int opts = 0;
diff --git a/bulk-checkin.c b/bulk-checkin.c
index b2809ab039..f65439a748 100644
--- a/bulk-checkin.c
+++ b/bulk-checkin.c
@@ -90,7 +90,7 @@ clear_exit:
strbuf_release(&packname);
/* Make objects we just wrote available to ourselves */
- reprepare_packed_git(the_repository);
+ odb_reprepare(the_repository->objects);
}
/*
diff --git a/connected.c b/connected.c
index 18c13245d8..d6e9682fd9 100644
--- a/connected.c
+++ b/connected.c
@@ -72,7 +72,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
* Before checking for promisor packs, be sure we have the
* latest pack-files loaded into memory.
*/
- reprepare_packed_git(the_repository);
+ odb_reprepare(the_repository->objects);
do {
struct packed_git *p;
diff --git a/fetch-pack.c b/fetch-pack.c
index 6ed5662951..fe7a84bf2f 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -1983,7 +1983,7 @@ static void update_shallow(struct fetch_pack_args *args,
* remote is shallow, but this is a clone, there are
* no objects in repo to worry about. Accept any
* shallow points that exist in the pack (iow in repo
- * after get_pack() and reprepare_packed_git())
+ * after get_pack() and odb_reprepare())
*/
struct oid_array extra = OID_ARRAY_INIT;
struct object_id *oid = si->shallow->oid;
@@ -2108,7 +2108,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
&si, pack_lockfiles);
}
- reprepare_packed_git(the_repository);
+ odb_reprepare(the_repository->objects);
if (!args->cloning && args->deepen) {
struct check_connected_options opt = CHECK_CONNECTED_INIT;
diff --git a/object-name.c b/object-name.c
index 732056ff5e..df9e0c5f02 100644
--- a/object-name.c
+++ b/object-name.c
@@ -596,7 +596,7 @@ static enum get_oid_result get_short_oid(struct repository *r,
* or migrated from loose to packed.
*/
if (status == MISSING_OBJECT) {
- reprepare_packed_git(r);
+ odb_reprepare(r->objects);
find_short_object_filename(&ds);
find_short_packed_object(&ds);
status = finish_object_disambiguation(&ds, oid);
diff --git a/odb.c b/odb.c
index 32e982bf0b..65a6cc67b6 100644
--- a/odb.c
+++ b/odb.c
@@ -694,7 +694,7 @@ static int do_oid_object_info_extended(struct object_database *odb,
/* Not a loose object; someone else may have just packed it. */
if (!(flags & OBJECT_INFO_QUICK)) {
- reprepare_packed_git(odb->repo);
+ odb_reprepare(odb->repo->objects);
if (find_pack_entry(odb->repo, real, &e))
break;
}
@@ -1040,3 +1040,28 @@ void odb_clear(struct object_database *o)
string_list_clear(&o->submodule_source_paths, 0);
}
+
+void odb_reprepare(struct object_database *o)
+{
+ struct odb_source *source;
+
+ obj_read_lock();
+
+ /*
+ * Reprepare alt odbs, in case the alternates file was modified
+ * during the course of this process. This only _adds_ odbs to
+ * the linked list, so existing odbs will continue to exist for
+ * the lifetime of the process.
+ */
+ o->loaded_alternates = 0;
+ odb_prepare_alternates(o);
+
+ for (source = o->sources; source; source = source->next)
+ odb_clear_loose_cache(source);
+
+ o->approximate_object_count_valid = 0;
+
+ packfile_store_reprepare(o->packfiles);
+
+ obj_read_unlock();
+}
diff --git a/odb.h b/odb.h
index 9dd7bb6bc3..ab39e3605d 100644
--- a/odb.h
+++ b/odb.h
@@ -162,6 +162,12 @@ struct object_database *odb_new(struct repository *repo);
void odb_clear(struct object_database *o);
/*
+ * Clear caches, reload alternates and then reload object sources so that new
+ * objects may become accessible.
+ */
+void odb_reprepare(struct object_database *o);
+
+/*
* Find source by its object directory path. Returns a `NULL` pointer in case
* the source could not be found.
*/
diff --git a/packfile.c b/packfile.c
index 095c85919b..950b98aac5 100644
--- a/packfile.c
+++ b/packfile.c
@@ -1002,28 +1002,10 @@ static void packfile_store_prepare(struct packfile_store *store)
store->initialized = true;
}
-void reprepare_packed_git(struct repository *r)
+void packfile_store_reprepare(struct packfile_store *store)
{
- struct odb_source *source;
-
- obj_read_lock();
-
- /*
- * Reprepare alt odbs, in case the alternates file was modified
- * during the course of this process. This only _adds_ odbs to
- * the linked list, so existing odbs will continue to exist for
- * the lifetime of the process.
- */
- r->objects->loaded_alternates = 0;
- odb_prepare_alternates(r->objects);
-
- for (source = r->objects->sources; source; source = source->next)
- odb_clear_loose_cache(source);
-
- r->objects->approximate_object_count_valid = 0;
- r->objects->packfiles->initialized = false;
- packfile_store_prepare(r->objects->packfiles);
- obj_read_unlock();
+ store->initialized = false;
+ packfile_store_prepare(store);
}
struct packed_git *get_packed_git(struct repository *r)
@@ -1144,7 +1126,7 @@ unsigned long get_size_from_delta(struct packed_git *p,
*
* Other worrying sections could be the call to close_pack_fd(),
* which can close packs even with in-use windows, and to
- * reprepare_packed_git(). Regarding the former, mmap doc says:
+ * odb_reprepare(). Regarding the former, mmap doc says:
* "closing the file descriptor does not unmap the region". And
* for the latter, it won't re-open already available packs.
*/
diff --git a/packfile.h b/packfile.h
index bf66211986..a85ff607fe 100644
--- a/packfile.h
+++ b/packfile.h
@@ -112,6 +112,14 @@ void packfile_store_free(struct packfile_store *store);
*/
void packfile_store_close(struct packfile_store *store);
+/*
+ * Clear the packfile caches and try to look up any new packfiles that have
+ * appeared since last preparing the packfiles store.
+ *
+ * This function must be called under the `odb_read_lock()`.
+ */
+void packfile_store_reprepare(struct packfile_store *store);
+
struct pack_window {
struct pack_window *next;
unsigned char *base;
@@ -188,7 +196,6 @@ int for_each_packed_object(struct repository *repo, each_packed_object_fn cb,
#define PACKDIR_FILE_GARBAGE 4
extern void (*report_garbage)(unsigned seen_bits, const char *path);
-void reprepare_packed_git(struct repository *r);
void install_packed_git(struct repository *r, struct packed_git *pack);
struct packed_git *get_packed_git(struct repository *r);
diff --git a/transport-helper.c b/transport-helper.c
index 0789e5bca5..4d95d84f9e 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -450,7 +450,7 @@ static int fetch_with_fetch(struct transport *transport,
}
strbuf_release(&buf);
- reprepare_packed_git(the_repository);
+ odb_reprepare(the_repository->objects);
return 0;
}