Skip to content

Commit 5176dd3

Browse files
pks-tgitster
authored andcommitted
bundle: generate packfiles via the object database
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). Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 9e8558a commit 5176dd3

3 files changed

Lines changed: 39 additions & 46 deletions

File tree

builtin/bundle.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ static int parse_options_cmd_bundle(int argc,
6868
}
6969

7070
static int cmd_bundle_create(int argc, const char **argv, const char *prefix,
71-
struct repository *repo UNUSED) {
72-
struct strvec pack_opts = STRVEC_INIT;
71+
struct repository *repo UNUSED)
72+
{
7373
int progress = isatty(STDERR_FILENO);
7474
int version = -1;
7575
struct option options[] = {
@@ -92,16 +92,9 @@ static int cmd_bundle_create(int argc, const char **argv, const char *prefix,
9292
builtin_bundle_create_usage, options, &bundle_file);
9393
/* bundle internals use argv[1] as further parameters */
9494

95-
if (progress)
96-
strvec_push(&pack_opts, "--progress");
97-
else
98-
strvec_push(&pack_opts, "--quiet");
99-
strvec_push(&pack_opts, "--all-progress-implied");
100-
10195
if (!startup_info->have_repository)
10296
die(_("Need a repository to create a bundle."));
103-
ret = !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts, version);
104-
strvec_clear(&pack_opts);
97+
ret = !!create_bundle(the_repository, bundle_file, argc, argv, version, progress);
10598
free(bundle_file);
10699
return ret;
107100
}

bundle.c

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -332,51 +332,52 @@ static int is_tag_in_date_range(struct repository *repo,
332332

333333

334334
/* Write the pack data to bundle_fd */
335-
static int write_pack_data(int bundle_fd, struct rev_info *revs, struct strvec *pack_options)
335+
static int write_pack_data(int bundle_fd, struct rev_info *revs, int progress)
336336
{
337-
struct child_process pack_objects = CHILD_PROCESS_INIT;
337+
struct odb_generate_pack_options opts = ODB_GENERATE_PACK_OPTIONS_INIT;
338+
struct odb_pack_generator *generator;
339+
int ret = 0;
338340
int i;
339341

340-
strvec_pushl(&pack_objects.args,
341-
"pack-objects",
342-
"--stdout", "--thin", "--delta-base-offset",
343-
NULL);
344-
strvec_pushv(&pack_objects.args, pack_options->v);
342+
opts.thin = 1;
343+
opts.ofs_delta = 1;
344+
if (progress)
345+
opts.progress = ODB_GENERATE_PACK_PROGRESS_VERBOSE;
345346
if (revs->filter.choice)
346-
strvec_pushf(&pack_objects.args, "--filter=%s",
347-
list_objects_filter_spec(&revs->filter));
348-
pack_objects.in = -1;
349-
pack_objects.out = bundle_fd;
350-
pack_objects.git_cmd = 1;
347+
opts.filter_spec = list_objects_filter_spec(&revs->filter);
351348

352349
/*
353-
* start_command() will close our descriptor if it's >1. Duplicate it
354-
* to avoid surprising the caller.
350+
* The pack generator will consume our descriptor if it's >1.
351+
* Duplicate it to avoid surprising the caller.
355352
*/
356-
if (pack_objects.out > 1) {
357-
pack_objects.out = dup(pack_objects.out);
358-
if (pack_objects.out < 0) {
359-
error_errno(_("unable to dup bundle descriptor"));
360-
child_process_clear(&pack_objects);
361-
return -1;
362-
}
353+
opts.pack_fd = bundle_fd;
354+
if (opts.pack_fd > 1) {
355+
opts.pack_fd = dup(bundle_fd);
356+
if (opts.pack_fd < 0)
357+
return error_errno(_("unable to dup bundle descriptor"));
363358
}
364359

365-
if (start_command(&pack_objects))
366-
return error(_("Could not spawn pack-objects"));
367-
368360
for (i = 0; i < revs->pending.nr; i++) {
369361
struct object *object = revs->pending.objects[i].item;
370362
if (object->flags & UNINTERESTING)
371-
write_or_die(pack_objects.in, "^", 1);
372-
write_or_die(pack_objects.in, oid_to_hex(&object->oid),
373-
revs->repo->hash_algo->hexsz);
374-
write_or_die(pack_objects.in, "\n", 1);
363+
oid_array_append(&opts.haves, &object->oid);
364+
else
365+
oid_array_append(&opts.wants, &object->oid);
375366
}
376-
close(pack_objects.in);
377-
if (finish_command(&pack_objects))
378-
return error(_("pack-objects died"));
379-
return 0;
367+
368+
if (odb_generate_pack(revs->repo->objects, &generator, &opts)) {
369+
ret = error(_("Could not spawn pack-objects"));
370+
goto out;
371+
}
372+
373+
if (odb_pack_generator_finish(generator)) {
374+
ret = error(_("pack-objects died"));
375+
goto out;
376+
}
377+
378+
out:
379+
odb_generate_pack_options_release(&opts);
380+
return ret;
380381
}
381382

382383
/*
@@ -485,7 +486,7 @@ static void write_bundle_prerequisites(struct commit *commit, void *data)
485486
}
486487

487488
int create_bundle(struct repository *r, const char *path,
488-
int argc, const char **argv, struct strvec *pack_options, int version)
489+
int argc, const char **argv, int version, int progress)
489490
{
490491
struct lock_file lock = LOCK_INIT;
491492
int bundle_fd = -1;
@@ -594,7 +595,7 @@ int create_bundle(struct repository *r, const char *path,
594595
}
595596

596597
/* write pack */
597-
if (write_pack_data(bundle_fd, &revs_copy, pack_options)) {
598+
if (write_pack_data(bundle_fd, &revs_copy, progress)) {
598599
ret = -1;
599600
goto out;
600601
}

bundle.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ int read_bundle_header(const char *path, struct bundle_header *header);
2727
int read_bundle_header_fd(int fd, struct bundle_header *header,
2828
const char *report_path);
2929
int create_bundle(struct repository *r, const char *path,
30-
int argc, const char **argv, struct strvec *pack_options,
31-
int version);
30+
int argc, const char **argv, int version, int progress);
3231

3332
enum verify_bundle_flags {
3433
VERIFY_BUNDLE_VERBOSE = (1 << 0),

0 commit comments

Comments
 (0)