aboutsummaryrefslogtreecommitdiff
path: root/repack-promisor.c
diff options
context:
space:
mode:
Diffstat (limited to 'repack-promisor.c')
-rw-r--r--repack-promisor.c101
1 files changed, 69 insertions, 32 deletions
diff --git a/repack-promisor.c b/repack-promisor.c
index ee6e0669f6..90318ce150 100644
--- a/repack-promisor.c
+++ b/repack-promisor.c
@@ -17,8 +17,8 @@ struct write_oid_context {
* necessary.
*/
static int write_oid(const struct object_id *oid,
- struct packed_git *pack UNUSED,
- uint32_t pos UNUSED, void *data)
+ struct object_info *oi UNUSED,
+ void *data)
{
struct write_oid_context *ctx = data;
struct child_process *cmd = ctx->cmd;
@@ -34,39 +34,17 @@ static int write_oid(const struct object_id *oid,
return 0;
}
-void repack_promisor_objects(struct repository *repo,
- const struct pack_objects_args *args,
- struct string_list *names, const char *packtmp)
+static void finish_repacking_promisor_objects(struct repository *repo,
+ struct child_process *cmd,
+ 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;
+ FILE *out;
- 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);
+ close(cmd->in);
- out = xfdopen(cmd.out, "r");
+ out = xfdopen(cmd->out, "r");
while (strbuf_getline_lf(&line, out) != EOF) {
struct string_list_item *item;
char *promisor_name;
@@ -96,7 +74,66 @@ void repack_promisor_objects(struct repository *repo,
}
fclose(out);
- if (finish_command(&cmd))
+ if (finish_command(cmd))
die(_("could not finish pack-objects to repack promisor objects"));
strbuf_release(&line);
}
+
+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;
+
+ 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;
+ odb_for_each_object(repo->objects, NULL, write_oid, &ctx,
+ ODB_FOR_EACH_OBJECT_PROMISOR_ONLY);
+
+ if (cmd.in == -1) {
+ /* No packed objects; cmd was never started */
+ child_process_clear(&cmd);
+ return;
+ }
+
+ finish_repacking_promisor_objects(repo, &cmd, names, packtmp);
+}
+
+void pack_geometry_repack_promisors(struct repository *repo,
+ const struct pack_objects_args *args,
+ const struct pack_geometry *geometry,
+ struct string_list *names,
+ const char *packtmp)
+{
+ struct child_process cmd = CHILD_PROCESS_INIT;
+ FILE *in;
+
+ if (!geometry->promisor_split)
+ return;
+
+ prepare_pack_objects(&cmd, args, packtmp);
+ strvec_push(&cmd.args, "--stdin-packs");
+ cmd.in = -1;
+ if (start_command(&cmd))
+ die(_("could not start pack-objects to repack promisor packs"));
+
+ in = xfdopen(cmd.in, "w");
+ for (size_t i = 0; i < geometry->promisor_split; i++)
+ fprintf(in, "%s\n", pack_basename(geometry->promisor_pack[i]));
+ for (size_t i = geometry->promisor_split; i < geometry->promisor_pack_nr; i++)
+ fprintf(in, "^%s\n", pack_basename(geometry->promisor_pack[i]));
+ fclose(in);
+
+ finish_repacking_promisor_objects(repo, &cmd, names, packtmp);
+}