]> git.ipfire.org Git - thirdparty/git.git/commitdiff
builtin/repack.c: remove ref snapshotting from builtin
authorTaylor Blau <me@ttaylorr.com>
Wed, 15 Oct 2025 22:28:50 +0000 (18:28 -0400)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Oct 2025 17:08:55 +0000 (10:08 -0700)
When writing a MIDX, 'git repack' takes a snapshot of the repository's
references and writes the result out to a file, which it then passes to
'git multi-pack-index write' via the '--refs-snapshot'.

This is done in order to make bitmap selections with respect to what we
are packing, thus avoiding a race where an incoming reference update
causes us to try and write a bitmap for a commit not present in the
MIDX.

Extract this functionality out into a new repack-midx.c compilation
unit, and expose the necessary functions via the repack.h API.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Makefile
builtin/repack.c
meson.build
repack-midx.c [new file with mode: 0644]
repack.h

index 3ee8d27dba24b8c46edbe71d4e5a6a7dc5ac6dc2..b2142771635c3120c3443620b9c30a7c393d88e5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1138,6 +1138,7 @@ LIB_OBJS += refspec.o
 LIB_OBJS += remote.o
 LIB_OBJS += repack.o
 LIB_OBJS += repack-geometry.o
+LIB_OBJS += repack-midx.o
 LIB_OBJS += repack-promisor.o
 LIB_OBJS += replace-object.o
 LIB_OBJS += repo-settings.o
index e2313c80c3901894798ad761d62d3208325f40ec..771372182647f2943f7317550a27263f164be8b5 100644 (file)
@@ -178,74 +178,6 @@ static int midx_has_unknown_packs(char **midx_pack_names,
        return 0;
 }
 
-struct midx_snapshot_ref_data {
-       struct repository *repo;
-       struct tempfile *f;
-       struct oidset seen;
-       int preferred;
-};
-
-static int midx_snapshot_ref_one(const char *refname UNUSED,
-                                const char *referent UNUSED,
-                                const struct object_id *oid,
-                                int flag UNUSED, void *_data)
-{
-       struct midx_snapshot_ref_data *data = _data;
-       struct object_id peeled;
-
-       if (!peel_iterated_oid(data->repo, oid, &peeled))
-               oid = &peeled;
-
-       if (oidset_insert(&data->seen, oid))
-               return 0; /* already seen */
-
-       if (odb_read_object_info(data->repo->objects, oid, NULL) != OBJ_COMMIT)
-               return 0;
-
-       fprintf(data->f->fp, "%s%s\n", data->preferred ? "+" : "",
-               oid_to_hex(oid));
-
-       return 0;
-}
-
-static void midx_snapshot_refs(struct repository *repo, struct tempfile *f)
-{
-       struct midx_snapshot_ref_data data;
-       const struct string_list *preferred = bitmap_preferred_tips(repo);
-
-       data.repo = repo;
-       data.f = f;
-       data.preferred = 0;
-       oidset_init(&data.seen, 0);
-
-       if (!fdopen_tempfile(f, "w"))
-                die(_("could not open tempfile %s for writing"),
-                    get_tempfile_path(f));
-
-       if (preferred) {
-               struct string_list_item *item;
-
-               data.preferred = 1;
-               for_each_string_list_item(item, preferred)
-                       refs_for_each_ref_in(get_main_ref_store(repo),
-                                            item->string,
-                                            midx_snapshot_ref_one, &data);
-               data.preferred = 0;
-       }
-
-       refs_for_each_ref(get_main_ref_store(repo),
-                         midx_snapshot_ref_one, &data);
-
-       if (close_tempfile_gently(f)) {
-               int save_errno = errno;
-               delete_tempfile(&f);
-               errno = save_errno;
-               die_errno(_("could not close refs snapshot tempfile"));
-       }
-
-       oidset_clear(&data.seen);
-}
-
 static void midx_included_packs(struct string_list *include,
                                struct existing_packs *existing,
                                char **midx_pack_names,
index 47b05089eeceeeeb4002734c9f11528988b498bd..0423ed30c41d6425072270dda6b0b94cc6cabe19 100644 (file)
@@ -464,6 +464,7 @@ libgit_sources = [
   'remote.c',
   'repack.c',
   'repack-geometry.c',
+  'repack-midx.c',
   'repack-promisor.c',
   'replace-object.c',
   'repo-settings.c',
diff --git a/repack-midx.c b/repack-midx.c
new file mode 100644 (file)
index 0000000..354df72
--- /dev/null
@@ -0,0 +1,77 @@
+#include "git-compat-util.h"
+#include "repack.h"
+#include "hash.h"
+#include "hex.h"
+#include "odb.h"
+#include "oidset.h"
+#include "pack-bitmap.h"
+#include "refs.h"
+#include "tempfile.h"
+
+struct midx_snapshot_ref_data {
+       struct repository *repo;
+       struct tempfile *f;
+       struct oidset seen;
+       int preferred;
+};
+
+static int midx_snapshot_ref_one(const char *refname UNUSED,
+                                const char *referent UNUSED,
+                                const struct object_id *oid,
+                                int flag UNUSED, void *_data)
+{
+       struct midx_snapshot_ref_data *data = _data;
+       struct object_id peeled;
+
+       if (!peel_iterated_oid(data->repo, oid, &peeled))
+               oid = &peeled;
+
+       if (oidset_insert(&data->seen, oid))
+               return 0; /* already seen */
+
+       if (odb_read_object_info(data->repo->objects, oid, NULL) != OBJ_COMMIT)
+               return 0;
+
+       fprintf(data->f->fp, "%s%s\n", data->preferred ? "+" : "",
+               oid_to_hex(oid));
+
+       return 0;
+}
+
+void midx_snapshot_refs(struct repository *repo, struct tempfile *f)
+{
+       struct midx_snapshot_ref_data data;
+       const struct string_list *preferred = bitmap_preferred_tips(repo);
+
+       data.repo = repo;
+       data.f = f;
+       data.preferred = 0;
+       oidset_init(&data.seen, 0);
+
+       if (!fdopen_tempfile(f, "w"))
+                die(_("could not open tempfile %s for writing"),
+                    get_tempfile_path(f));
+
+       if (preferred) {
+               struct string_list_item *item;
+
+               data.preferred = 1;
+               for_each_string_list_item(item, preferred)
+                       refs_for_each_ref_in(get_main_ref_store(repo),
+                                            item->string,
+                                            midx_snapshot_ref_one, &data);
+               data.preferred = 0;
+       }
+
+       refs_for_each_ref(get_main_ref_store(repo),
+                         midx_snapshot_ref_one, &data);
+
+       if (close_tempfile_gently(f)) {
+               int save_errno = errno;
+               delete_tempfile(&f);
+               errno = save_errno;
+               die_errno(_("could not close refs snapshot tempfile"));
+       }
+
+       oidset_clear(&data.seen);
+}
index cea7969ae47b19c71bd8fd0bcafb27281b54cca6..803e1292240887464f2829e7491ce1208b42b2ca 100644 (file)
--- a/repack.h
+++ b/repack.h
@@ -98,4 +98,8 @@ void pack_geometry_remove_redundant(struct pack_geometry *geometry,
                                    const char *packdir);
 void pack_geometry_release(struct pack_geometry *geometry);
 
+struct tempfile;
+
+void midx_snapshot_refs(struct repository *repo, struct tempfile *f);
+
 #endif /* REPACK_H */