]> git.ipfire.org Git - thirdparty/git.git/commitdiff
odb/source-packed: start converting to a proper `struct odb_source`
authorPatrick Steinhardt <ps@pks.im>
Wed, 17 Jun 2026 06:39:48 +0000 (08:39 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 17 Jun 2026 12:00:00 +0000 (05:00 -0700)
Start converting `struct odb_source_packed` into a proper pluggable
`struct odb_source` by embedding the base struct and assigning it the
new `ODB_SOURCE_PACKED` type. Furthermore, wire up lifecycle management
of this source by implementing the `free` callback and taking ownership
of the chdir notifications.

Note that the packed source is not yet functional as a standalone `struct
odb_source`, as it's missing all of the callback implementations. These
will be wired up in subsequent commits.

Further note that we're also registering a `chdir_notify` callback to
reparent our path. This wasn't previously necessary (and still isn't at
this point in time) because all paths are taken from the owning "files"
source, and that source already handles the reparenting for us. But a
subsequent commit will change that so that we're using the path of the
"packed" source, and once that happens we'll need it to be updated when
changing the working directory.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
odb/source-files.c
odb/source-packed.c
odb/source-packed.h
odb/source.h
packfile.c
packfile.h

index e04525fb08be97bd9e11c8d5479b986eaf943b61..3608808e7c6f3a72ec6606cfb8065df88c06c521 100644 (file)
@@ -29,7 +29,7 @@ static void odb_source_files_free(struct odb_source *source)
        struct odb_source_files *files = odb_source_files_downcast(source);
        chdir_notify_unregister(NULL, odb_source_files_reparent, files);
        odb_source_free(&files->loose->base);
-       packfile_store_free(files->packed);
+       odb_source_free(&files->packed->base);
        odb_source_release(&files->base);
        free(files);
 }
index 12e785be48498a4fb51ca25bb9c9d7b09019ca80..f81a990cbde757689ed1767346ec919212e8547b 100644 (file)
@@ -1,11 +1,50 @@
 #include "git-compat-util.h"
+#include "abspath.h"
+#include "chdir-notify.h"
 #include "odb/source-packed.h"
+#include "packfile.h"
+
+static void odb_source_packed_reparent(const char *name UNUSED,
+                                      const char *old_cwd,
+                                      const char *new_cwd,
+                                      void *cb_data)
+{
+       struct odb_source_packed *packed = cb_data;
+       char *path = reparent_relative_path(old_cwd, new_cwd,
+                                           packed->base.path);
+       free(packed->base.path);
+       packed->base.path = path;
+}
+
+static void odb_source_packed_free(struct odb_source *source)
+{
+       struct odb_source_packed *packed = odb_source_packed_downcast(source);
+
+       chdir_notify_unregister(NULL, odb_source_packed_reparent, packed);
+
+       for (struct packfile_list_entry *e = packed->packs.head; e; e = e->next)
+               free(e->pack);
+       packfile_list_clear(&packed->packs);
+
+       strmap_clear(&packed->packs_by_path, 0);
+       odb_source_release(&packed->base);
+       free(packed);
+}
 
 struct odb_source_packed *odb_source_packed_new(struct odb_source_files *parent)
 {
-       struct odb_source_packed *store;
-       CALLOC_ARRAY(store, 1);
-       store->files = parent;
-       strmap_init(&store->packs_by_path);
-       return store;
+       struct odb_source_packed *packed;
+
+       CALLOC_ARRAY(packed, 1);
+       odb_source_init(&packed->base, parent->base.odb, ODB_SOURCE_PACKED,
+                       parent->base.path, parent->base.local);
+       packed->files = parent;
+       strmap_init(&packed->packs_by_path);
+
+       packed->base.free = odb_source_packed_free;
+
+       if (!is_absolute_path(parent->base.path))
+               chdir_notify_register(NULL, odb_source_packed_reparent, packed);
+
+       return packed;
 }
index 3c2d229a174749ce91c6bab09254dddde53e9203..68e64cabab5186dbcb9fc84d40b17bd850eadef8 100644 (file)
@@ -9,6 +9,7 @@
  * A store that manages packfiles for a given object database.
  */
 struct odb_source_packed {
+       struct odb_source base;
        struct odb_source_files *files;
 
        /*
@@ -69,4 +70,15 @@ struct odb_source_packed {
  */
 struct odb_source_packed *odb_source_packed_new(struct odb_source_files *parent);
 
+/*
+ * Cast the given object database source to the packed backend. This will cause
+ * a BUG in case the source doesn't use this backend.
+ */
+static inline struct odb_source_packed *odb_source_packed_downcast(struct odb_source *source)
+{
+       if (source->type != ODB_SOURCE_PACKED)
+               BUG("trying to downcast source of type '%d' to packed", source->type);
+       return container_of(source, struct odb_source_packed, base);
+}
+
 #endif
index 8bcb67787ebafd5fd53fa51ac7620b4497ad993a..6865e1f71acfdc91b94fee63bb3816975b551ba0 100644 (file)
@@ -17,6 +17,9 @@ enum odb_source_type {
        /* The "loose" backend that uses loose objects, only. */
        ODB_SOURCE_LOOSE,
 
+       /* The "packed" backend that uses packfiles. */
+       ODB_SOURCE_PACKED,
+
        /* The "in-memory" backend that stores objects in memory. */
        ODB_SOURCE_INMEMORY,
 };
index 862a24ad49bd784e56005b2d84f7d7ce369e8302..6d492216de356a6867818fb6248e137e7fed67d8 100644 (file)
@@ -2749,16 +2749,6 @@ int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *l
        return 0;
 }
 
-void packfile_store_free(struct odb_source_packed *store)
-{
-       for (struct packfile_list_entry *e = store->packs.head; e; e = e->next)
-               free(e->pack);
-       packfile_list_clear(&store->packs);
-
-       strmap_clear(&store->packs_by_path, 0);
-       free(store);
-}
-
 void packfile_store_close(struct odb_source_packed *store)
 {
        for (struct packfile_list_entry *e = store->packs.head; e; e = e->next) {
index 2d0bb7adbe83c61c9be8c34948c58560d9f4b66e..e8bc9349f8d0dc63ff150a7797272a4a7c345156 100644 (file)
@@ -55,12 +55,6 @@ struct packed_git {
        char pack_name[FLEX_ARRAY]; /* more */
 };
 
-/*
- * Free the packfile store and all its associated state. All packfiles
- * tracked by the store will be closed.
- */
-void packfile_store_free(struct odb_source_packed *store);
-
 /*
  * Close all packfiles associated with this store. The packfiles won't be
  * free'd, so they can be re-opened at a later point in time.