.callback = callback,
.payload = _payload,
};
- struct bitmap_index *bitmap = prepare_bitmap_git(the_repository);
+ struct bitmap_index *bitmap = NULL;
+ struct odb_source *source;
- for_each_loose_object(the_repository->objects, batch_one_object_loose, &payload, 0);
+ odb_prepare_alternates(the_repository->objects);
+ for (source = the_repository->objects->sources; source; source = source->next) {
+ int ret = odb_source_loose_for_each_object(source, NULL, batch_one_object_oi,
+ &payload, flags);
+ if (ret)
+ break;
+ }
- if (bitmap && !for_each_bitmapped_object(bitmap, &opt->objects_filter,
- batch_one_object_bitmapped, &payload)) {
+ if (opt->objects_filter.choice != LOFC_DISABLED &&
+ (bitmap = prepare_bitmap_git(the_repository)) &&
+ !for_each_bitmapped_object(bitmap, &opt->objects_filter,
+ batch_one_object_bitmapped, &payload)) {
struct packed_git *pack;
repo_for_each_pack(the_repository, pack) {
if (check_references)
fsck_refs(the_repository);
+ /*
+ * Take a snapshot of the refs before walking objects to avoid looking
+ * at a set of refs that may be changed by the user while we are walking
+ * objects. We can still walk over new objects that are added during the
+ * execution of fsck but won't miss any objects that were reachable.
+ */
+ snapshot_refs(&snap, argc, argv);
+
+ /* Ensure we get a "fresh" view of the odb */
+ odb_reprepare(the_repository->objects);
+
if (connectivity_only) {
- for_each_loose_object(the_repository->objects,
- mark_loose_for_connectivity, NULL, 0);
- for_each_packed_object(the_repository,
- mark_packed_for_connectivity, NULL, 0);
+ odb_for_each_object(the_repository->objects, NULL,
+ mark_object_for_connectivity, NULL, 0);
} else {
odb_prepare_alternates(the_repository->objects);
for (source = the_repository->objects->sources; source; source = source->next)
die(_("could not finish pack-objects to repack promisor objects"));
strbuf_release(&line);
}
- for_each_packed_object(repo, write_oid, &ctx,
- FOR_EACH_OBJECT_PROMISOR_ONLY);
+
+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);
+}