]> git.ipfire.org Git - thirdparty/git.git/commitdiff
packfile: split up responsibilities of `reprepare_packed_git()`
authorPatrick Steinhardt <ps@pks.im>
Tue, 23 Sep 2025 10:17:08 +0000 (12:17 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 24 Sep 2025 18:53:50 +0000 (11:53 -0700)
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>
13 files changed:
builtin/backfill.c
builtin/gc.c
builtin/receive-pack.c
builtin/repack.c
bulk-checkin.c
connected.c
fetch-pack.c
object-name.c
odb.c
odb.h
packfile.c
packfile.h
transport-helper.c

index 80056abe4730ae6c81da5c6ad9e432be37f6dccc..e80fc1b694df616115ac4b6a538ed22a4e7a772b 100644 (file)
@@ -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,
index 03ae4926b209820a9cd83520d18b067bc714500c..aeca06a08bec5d6299588df97a5ca64eee31c90a 100644 (file)
@@ -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;
index 1113137a6f0b3f961fd02822154a41bcdedb6657..c9288a9c7e382bd19193d8b94268e0d0bec2c7f8 100644 (file)
@@ -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;
 }
index c490a51e9192da493dffcbd9b3051bb1fcd90b7b..5ff27fc8e29a9b426fbcbdf427a662829ab64116 100644 (file)
@@ -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;
index b2809ab0398136ea0bd18b5d1c90f6a5729415ab..f65439a748a4ece5371b244008d135e7ae809f5d 100644 (file)
@@ -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);
 }
 
 /*
index 18c13245d8e40c66a22fa5d7c2d139b85e5113c2..d6e9682fd93ce9f8beb1b1693d31fca40eb0cc1e 100644 (file)
@@ -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;
 
index 6ed566295189dcfa57291e55fc452b1a28d39e4e..fe7a84bf2f97fa89882bbfda079d346c7de21ddd 100644 (file)
@@ -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;
index 732056ff5e305b7d79d3f272e321824a9107f0a2..df9e0c5f020a917ecbcfb1264482a1b493fd81c9 100644 (file)
@@ -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 32e982bf0b98cb7eb36f5b4865deb554ccb03319..65a6cc67b61ccf99e7b7293906e6772f2927da9b 100644 (file)
--- 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 9dd7bb6bc3e5f897e68a35543c26ce4d25a1452c..ab39e3605d541997d8b12fbf14bc9e78def515a5 100644 (file)
--- a/odb.h
+++ b/odb.h
@@ -161,6 +161,12 @@ struct object_database {
 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.
index 095c85919b6c7c2ef17da08ddf6524b630cf7c9d..950b98aac51c3fbe7980ac61dd5fb92b1f424453 100644 (file)
@@ -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.
                 */
index bf66211986e436f417f52d9be7b8549d42ffc2dc..a85ff607febe54816253a30b9ab356638663aabb 100644 (file)
@@ -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);
index 0789e5bca53282d29f30eea9a2eca129e115f40f..4d95d84f9e4d05db5117016bcdacadf3a4fe46b2 100644 (file)
@@ -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;
 }