]> git.ipfire.org Git - thirdparty/git.git/commitdiff
builtin/repack.c: remove "repack_promisor_objects()" from the builtin
authorTaylor Blau <me@ttaylorr.com>
Wed, 15 Oct 2025 22:28:35 +0000 (18:28 -0400)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Oct 2025 17:08:55 +0000 (10:08 -0700)
Now that we have properly factored the portion of the builtin which is
responsible for repacking promisor objects, we can move that function
(and associated dependencies) out of the builtin entirely.

Similar to previous extractions, this function is declared in repack.h,
but implemented in a separate repack-promisor.c file. This is done to
separate promisor-specific repacking functionality from generic repack
utilities (like "existing_packs", and "generated_pack" APIs).

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

index c0df6da2371ab6745ae6738f2c29cc36e2afa46f..2a01bd92dc740c61d306b83176ffd9d95be47db8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1137,6 +1137,7 @@ LIB_OBJS += refs/ref-cache.o
 LIB_OBJS += refspec.o
 LIB_OBJS += remote.o
 LIB_OBJS += repack.o
+LIB_OBJS += repack-promisor.o
 LIB_OBJS += replace-object.o
 LIB_OBJS += repo-settings.o
 LIB_OBJS += repository.o
index 2c67111b33337dea0838081103abba0dfd8ef8af..24b5e5049bbe0f0a3b0b91dc67a5069872796364 100644 (file)
@@ -107,101 +107,6 @@ static int repack_config(const char *var, const char *value,
        return git_default_config(var, value, ctx, cb);
 }
 
-struct write_oid_context {
-       struct child_process *cmd;
-       const struct git_hash_algo *algop;
-};
-
-/*
- * Write oid to the given struct child_process's stdin, starting it first if
- * necessary.
- */
-static int write_oid(const struct object_id *oid,
-                    struct packed_git *pack UNUSED,
-                    uint32_t pos UNUSED, void *data)
-{
-       struct write_oid_context *ctx = data;
-       struct child_process *cmd = ctx->cmd;
-
-       if (cmd->in == -1) {
-               if (start_command(cmd))
-                       die(_("could not start pack-objects to repack promisor objects"));
-       }
-
-       if (write_in_full(cmd->in, oid_to_hex(oid), ctx->algop->hexsz) < 0 ||
-           write_in_full(cmd->in, "\n", 1) < 0)
-               die(_("failed to feed promisor objects to pack-objects"));
-       return 0;
-}
-
-static void repack_promisor_objects(struct repository *repo,
-                                   const struct pack_objects_args *args,
-                                   struct string_list *names,
-                                   const char *packtmp)
-{
-       struct write_oid_context ctx;
-       struct child_process cmd = CHILD_PROCESS_INIT;
-       FILE *out;
-       struct strbuf line = STRBUF_INIT;
-
-       prepare_pack_objects(&cmd, args, packtmp);
-       cmd.in = -1;
-
-       /*
-        * NEEDSWORK: Giving pack-objects only the OIDs without any ordering
-        * hints may result in suboptimal deltas in the resulting pack. See if
-        * the OIDs can be sent with fake paths such that pack-objects can use a
-        * {type -> existing pack order} ordering when computing deltas instead
-        * of a {type -> size} ordering, which may produce better deltas.
-        */
-       ctx.cmd = &cmd;
-       ctx.algop = repo->hash_algo;
-       for_each_packed_object(repo, write_oid, &ctx,
-                              FOR_EACH_OBJECT_PROMISOR_ONLY);
-
-       if (cmd.in == -1) {
-               /* No packed objects; cmd was never started */
-               child_process_clear(&cmd);
-               return;
-       }
-
-       close(cmd.in);
-
-       out = xfdopen(cmd.out, "r");
-       while (strbuf_getline_lf(&line, out) != EOF) {
-               struct string_list_item *item;
-               char *promisor_name;
-
-               if (line.len != repo->hash_algo->hexsz)
-                       die(_("repack: Expecting full hex object ID lines only from pack-objects."));
-               item = string_list_append(names, line.buf);
-
-               /*
-                * pack-objects creates the .pack and .idx files, but not the
-                * .promisor file. Create the .promisor file, which is empty.
-                *
-                * NEEDSWORK: fetch-pack sometimes generates non-empty
-                * .promisor files containing the ref names and associated
-                * hashes at the point of generation of the corresponding
-                * packfile, but this would not preserve their contents. Maybe
-                * concatenate the contents of all .promisor files instead of
-                * just creating a new empty file.
-                */
-               promisor_name = mkpathdup("%s-%s.promisor", packtmp,
-                                         line.buf);
-               write_promisor_file(promisor_name, NULL, 0);
-
-               item->util = generated_pack_populate(item->string, packtmp);
-
-               free(promisor_name);
-       }
-
-       fclose(out);
-       if (finish_command(&cmd))
-               die(_("could not finish pack-objects to repack promisor objects"));
-       strbuf_release(&line);
-}
-
 struct pack_geometry {
        struct packed_git **pack;
        uint32_t pack_nr, pack_alloc;
index 993e8f368ffac1ad56e8782451ad96c9124ee6fa..1fbb8c52a645b4932f06e850d928d366a27db34e 100644 (file)
@@ -463,6 +463,7 @@ libgit_sources = [
   'reftable/writer.c',
   'remote.c',
   'repack.c',
+  'repack-promisor.c',
   'replace-object.c',
   'repo-settings.c',
   'repository.c',
diff --git a/repack-promisor.c b/repack-promisor.c
new file mode 100644 (file)
index 0000000..ee6e066
--- /dev/null
@@ -0,0 +1,102 @@
+#include "git-compat-util.h"
+#include "repack.h"
+#include "hex.h"
+#include "pack.h"
+#include "packfile.h"
+#include "path.h"
+#include "repository.h"
+#include "run-command.h"
+
+struct write_oid_context {
+       struct child_process *cmd;
+       const struct git_hash_algo *algop;
+};
+
+/*
+ * Write oid to the given struct child_process's stdin, starting it first if
+ * necessary.
+ */
+static int write_oid(const struct object_id *oid,
+                    struct packed_git *pack UNUSED,
+                    uint32_t pos UNUSED, void *data)
+{
+       struct write_oid_context *ctx = data;
+       struct child_process *cmd = ctx->cmd;
+
+       if (cmd->in == -1) {
+               if (start_command(cmd))
+                       die(_("could not start pack-objects to repack promisor objects"));
+       }
+
+       if (write_in_full(cmd->in, oid_to_hex(oid), ctx->algop->hexsz) < 0 ||
+           write_in_full(cmd->in, "\n", 1) < 0)
+               die(_("failed to feed promisor objects to pack-objects"));
+       return 0;
+}
+
+void repack_promisor_objects(struct repository *repo,
+                            const struct pack_objects_args *args,
+                            struct string_list *names, const char *packtmp)
+{
+       struct write_oid_context ctx;
+       struct child_process cmd = CHILD_PROCESS_INIT;
+       FILE *out;
+       struct strbuf line = STRBUF_INIT;
+
+       prepare_pack_objects(&cmd, args, packtmp);
+       cmd.in = -1;
+
+       /*
+        * NEEDSWORK: Giving pack-objects only the OIDs without any ordering
+        * hints may result in suboptimal deltas in the resulting pack. See if
+        * the OIDs can be sent with fake paths such that pack-objects can use a
+        * {type -> existing pack order} ordering when computing deltas instead
+        * of a {type -> size} ordering, which may produce better deltas.
+        */
+       ctx.cmd = &cmd;
+       ctx.algop = repo->hash_algo;
+       for_each_packed_object(repo, write_oid, &ctx,
+                              FOR_EACH_OBJECT_PROMISOR_ONLY);
+
+       if (cmd.in == -1) {
+               /* No packed objects; cmd was never started */
+               child_process_clear(&cmd);
+               return;
+       }
+
+       close(cmd.in);
+
+       out = xfdopen(cmd.out, "r");
+       while (strbuf_getline_lf(&line, out) != EOF) {
+               struct string_list_item *item;
+               char *promisor_name;
+
+               if (line.len != repo->hash_algo->hexsz)
+                       die(_("repack: Expecting full hex object ID lines only from pack-objects."));
+               item = string_list_append(names, line.buf);
+
+               /*
+                * pack-objects creates the .pack and .idx files, but not the
+                * .promisor file. Create the .promisor file, which is empty.
+                *
+                * NEEDSWORK: fetch-pack sometimes generates non-empty
+                * .promisor files containing the ref names and associated
+                * hashes at the point of generation of the corresponding
+                * packfile, but this would not preserve their contents. Maybe
+                * concatenate the contents of all .promisor files instead of
+                * just creating a new empty file.
+                */
+               promisor_name = mkpathdup("%s-%s.promisor", packtmp,
+                                         line.buf);
+               write_promisor_file(promisor_name, NULL, 0);
+
+               item->util = generated_pack_populate(item->string, packtmp);
+
+               free(promisor_name);
+       }
+
+       fclose(out);
+       if (finish_command(&cmd))
+               die(_("could not finish pack-objects to repack promisor objects"));
+       strbuf_release(&line);
+}
index f37eb4952495a1e108c8876aa981bc7165b5a8ca..19dc4fd738dcc16a356e2632a22d3d3cac968cd5 100644 (file)
--- a/repack.h
+++ b/repack.h
@@ -74,4 +74,8 @@ int generated_pack_has_ext(const struct generated_pack *pack, const char *ext);
 void generated_pack_install(struct generated_pack *pack, const char *name,
                            const char *packdir, const char *packtmp);
 
+void repack_promisor_objects(struct repository *repo,
+                            const struct pack_objects_args *args,
+                            struct string_list *names, const char *packtmp);
+
 #endif /* REPACK_H */