From: Junio C Hamano <gitster@pobox.com>
To: Patrick Steinhardt <ps@pks.im>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 5/5] bundle: generate packfiles via the object database
Date: Thu, 13 Aug 2026 11:00:34 -0700 [thread overview]
Message-ID: <xmqqmrupsxx9.fsf@gitster.g> (raw)
In-Reply-To: <20260807-b4-pks-odb-generate-pack-v1-5-7dec431ae7cd@pks.im> (Patrick Steinhardt's message of "Fri, 07 Aug 2026 12:45:11 +0200")
Patrick Steinhardt <ps@pks.im> writes:
> git-bundle(1) spawns git-pack-objects(1) directly to generate the pack
> data that gets appended to the bundle header. While bundles are not
> part of the wire protocol, they are a transfer mechanism for packs all
> the same, so convert them to use the pack generation interface of the
> object database as well.
>
> This makes the pack generator the single spawn point for all pack
> streams that leave the repository, leaving only local maintenance tasks
> like git-repack(1) with direct knowledge of git-pack-objects(1).
Nice to see that the series aims for completeness.
> diff --git a/builtin/bundle.c b/builtin/bundle.c
> index bfafadc984..de86e092a6 100644
> --- a/builtin/bundle.c
> +++ b/builtin/bundle.c
> @@ -69,7 +69,6 @@ static int parse_options_cmd_bundle(int argc,
>
> static int cmd_bundle_create(int argc, const char **argv, const char *prefix,
> struct repository *repo UNUSED) {
> - struct strvec pack_opts = STRVEC_INIT;
> int progress = isatty(STDERR_FILENO);
> int version = -1;
> struct option options[] = {
> @@ -92,16 +91,9 @@ static int cmd_bundle_create(int argc, const char **argv, const char *prefix,
> builtin_bundle_create_usage, options, &bundle_file);
> /* bundle internals use argv[1] as further parameters */
>
> - if (progress)
> - strvec_push(&pack_opts, "--progress");
> - else
> - strvec_push(&pack_opts, "--quiet");
> - strvec_push(&pack_opts, "--all-progress-implied");
> -
> if (!startup_info->have_repository)
> die(_("Need a repository to create a bundle."));
> - ret = !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts, version);
> - strvec_clear(&pack_opts);
> + ret = !!create_bundle(the_repository, bundle_file, argc, argv, version, progress);
> free(bundle_file);
> return ret;
> }
At this point after we determined startup_info->have_repository is
true, we should be able to rely on "repo", not "the_repository".
But the callchain starting at the create_bundle() function might not
be ready yet. Let's keep reading.
> diff --git a/bundle.c b/bundle.c
> index b64716f252..09afc465c0 100644
> --- a/bundle.c
> +++ b/bundle.c
> @@ -325,50 +325,52 @@ static int is_tag_in_date_range(struct object *tag, struct rev_info *revs)
>
>
> /* Write the pack data to bundle_fd */
> -static int write_pack_data(int bundle_fd, struct rev_info *revs, struct strvec *pack_options)
> +static int write_pack_data(int bundle_fd, struct rev_info *revs, int progress)
> {
> - struct child_process pack_objects = CHILD_PROCESS_INIT;
> + struct odb_generate_pack_options opts = ODB_GENERATE_PACK_OPTIONS_INIT;
> + struct odb_pack_generator *generator;
> + int ret = 0;
> int i;
>
> - strvec_pushl(&pack_objects.args,
> - "pack-objects",
> - "--stdout", "--thin", "--delta-base-offset",
> - NULL);
> - strvec_pushv(&pack_objects.args, pack_options->v);
> + opts.thin = 1;
> + opts.ofs_delta = 1;
> + if (progress)
> + opts.progress = ODB_GENERATE_PACK_PROGRESS_VERBOSE;
> if (revs->filter.choice)
> - strvec_pushf(&pack_objects.args, "--filter=%s",
> - list_objects_filter_spec(&revs->filter));
> - pack_objects.in = -1;
> - pack_objects.out = bundle_fd;
> - pack_objects.git_cmd = 1;
> + opts.filter_spec = list_objects_filter_spec(&revs->filter);
>
> /*
> - * start_command() will close our descriptor if it's >1. Duplicate it
> - * to avoid surprising the caller.
> + * The pack generator will consume our descriptor if it's >1.
> + * Duplicate it to avoid surprising the caller.
> */
> - if (pack_objects.out > 1) {
> - pack_objects.out = dup(pack_objects.out);
> - if (pack_objects.out < 0) {
> - error_errno(_("unable to dup bundle descriptor"));
> - child_process_clear(&pack_objects);
> - return -1;
> - }
> + opts.pack_fd = bundle_fd;
> + if (opts.pack_fd > 1) {
> + opts.pack_fd = dup(bundle_fd);
> + if (opts.pack_fd < 0)
> + return error_errno(_("unable to dup bundle descriptor"));
> }
>
> - if (start_command(&pack_objects))
> - return error(_("Could not spawn pack-objects"));
> -
> for (i = 0; i < revs->pending.nr; i++) {
> struct object *object = revs->pending.objects[i].item;
> if (object->flags & UNINTERESTING)
> - write_or_die(pack_objects.in, "^", 1);
> - write_or_die(pack_objects.in, oid_to_hex(&object->oid), the_hash_algo->hexsz);
> - write_or_die(pack_objects.in, "\n", 1);
> + oid_array_append(&opts.haves, &object->oid);
> + else
> + oid_array_append(&opts.wants, &object->oid);
> }
> - close(pack_objects.in);
> - if (finish_command(&pack_objects))
> - return error(_("pack-objects died"));
> - return 0;
> +
> + if (odb_generate_pack(the_repository->objects, &generator, &opts)) {
> + ret = error(_("Could not spawn pack-objects"));
> + goto out;
> + }
> +
> + if (odb_pack_generator_finish(generator)) {
> + ret = error(_("pack-objects died"));
> + goto out;
> + }
> +
> +out:
> + odb_generate_pack_options_release(&opts);
> + return ret;
> }
This function uses the_repository, both directly and through
the_hash_algo macro. I think we could use revs->repo here. An
obvious alternative is to give this function a new parameter "struct
repository *repo" but then we would have to worry about what should
happen when it and revs->repo go out of sync.
> @@ -476,7 +478,7 @@ static void write_bundle_prerequisites(struct commit *commit, void *data)
> }
>
> int create_bundle(struct repository *r, const char *path,
> - int argc, const char **argv, struct strvec *pack_options, int version)
> + int argc, const char **argv, int version, int progress)
> {
> struct lock_file lock = LOCK_INIT;
> int bundle_fd = -1;
> @@ -584,7 +586,7 @@ int create_bundle(struct repository *r, const char *path,
> }
>
> /* write pack */
> - if (write_pack_data(bundle_fd, &revs_copy, pack_options)) {
> + if (write_pack_data(bundle_fd, &revs_copy, progress)) {
> ret = -1;
> goto out;
> }
> diff --git a/bundle.h b/bundle.h
> index d664b2f2d6..471da23d1b 100644
> --- a/bundle.h
> +++ b/bundle.h
> @@ -27,8 +27,7 @@ int read_bundle_header(const char *path, struct bundle_header *header);
> int read_bundle_header_fd(int fd, struct bundle_header *header,
> const char *report_path);
> int create_bundle(struct repository *r, const char *path,
> - int argc, const char **argv, struct strvec *pack_options,
> - int version);
> + int argc, const char **argv, int version, int progress);
>
> enum verify_bundle_flags {
> VERIFY_BUNDLE_VERBOSE = (1 << 0),
next prev parent reply other threads:[~2026-08-13 18:00 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 10:45 [PATCH 0/5] odb: make packfile generation pluggable Patrick Steinhardt
2026-08-07 10:45 ` [PATCH 1/5] odb: introduce interface to generate packfiles Patrick Steinhardt
2026-08-07 10:45 ` [PATCH 2/5] upload-pack: generate packfiles via the object database Patrick Steinhardt
2026-08-07 10:45 ` [PATCH 3/5] send-pack: " Patrick Steinhardt
2026-08-07 10:45 ` [PATCH 4/5] builtin/bundle: refactor option handling for progress meter Patrick Steinhardt
2026-08-07 10:45 ` [PATCH 5/5] bundle: generate packfiles via the object database Patrick Steinhardt
2026-08-13 18:00 ` Junio C Hamano [this message]
2026-08-07 21:05 ` [PATCH 0/5] odb: make packfile generation pluggable Junio C Hamano
2026-08-10 5:25 ` Patrick Steinhardt
2026-08-12 23:41 ` Taylor Blau
[not found] ` <an1ajMjVRUsfu-lv@pks.im>
2026-08-13 17:35 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqmrupsxx9.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=ps@pks.im \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox