338
return 0;
339
}
340
341
-static int compute_and_write_prerequisites(int bundle_fd,
342
- struct rev_info *revs,
343
- int argc, const char **argv)
344
-{
345
- struct child_process rls = CHILD_PROCESS_INIT;
346
- struct strbuf buf = STRBUF_INIT;
347
- FILE *rls_fout;
348
- int i;
349
-
350
- strvec_pushl(&rls.args,
351
- "rev-list", "--boundary", "--pretty=oneline",
352
- NULL);
353
- for (i = 1; i < argc; i++)
354
- strvec_push(&rls.args, argv[i]);
355
- rls.out = -1;
356
- rls.git_cmd = 1;
357
- if (start_command(&rls))
358
- return -1;
359
- rls_fout = xfdopen(rls.out, "r");
360
- while (strbuf_getwholeline(&buf, rls_fout, '\n') != EOF) {
361
- struct object_id oid;
362
- if (buf.len > 0 && buf.buf[0] == '-') {
363
- write_or_die(bundle_fd, buf.buf, buf.len);
364
- if (!get_oid_hex(buf.buf + 1, &oid)) {
365
- struct object *object = parse_object_or_die(&oid,
366
- buf.buf);
367
- object->flags |= UNINTERESTING;
368
- add_pending_object(revs, object, buf.buf);
369
- }
370
- } else if (!get_oid_hex(buf.buf, &oid)) {
371
- struct object *object = parse_object_or_die(&oid,
372
- buf.buf);
373
- object->flags |= SHOWN;
374
- }
375
- }
376
- strbuf_release(&buf);
377
- fclose(rls_fout);
378
- if (finish_command(&rls))
379
- return error(_("rev-list died"));
380
- return 0;
381
-}
382
-
341
/*
342
* Write out bundle refs based on the tips already
343
* parsed into revs.pending. As a side effect, may
432
return ref_count;
433
}
434
435
+struct bundle_prerequisites_info {
436
+ struct object_array *pending;
437
+ int fd;
438
+};
439
+
440
+static void write_bundle_prerequisites(struct commit *commit, void *data)
441
+{
442
+ struct bundle_prerequisites_info *bpi = data;
443
+ struct object *object;
444
+ struct pretty_print_context ctx = { 0 };
445
+ struct strbuf buf = STRBUF_INIT;
446
+
447
+ if (!(commit->object.flags & BOUNDARY))
448
+ return;
449
+ strbuf_addf(&buf, "-%s ", oid_to_hex(&commit->object.oid));
450
+ write_or_die(bpi->fd, buf.buf, buf.len);
451
+
452
+ ctx.fmt = CMIT_FMT_ONELINE;
453
+ ctx.output_encoding = get_log_output_encoding();
454
+ strbuf_reset(&buf);
455
+ pretty_print_commit(&ctx, commit, &buf);
456
+ strbuf_trim(&buf);
457
+
458
+ object = (struct object *)commit;
459
+ object->flags |= UNINTERESTING;
460
+ add_object_array_with_path(object, buf.buf, bpi->pending, S_IFINVALID,
461
+ NULL);
462
+ strbuf_addch(&buf, '\n');
463
+ write_or_die(bpi->fd, buf.buf, buf.len);
464
+ strbuf_release(&buf);
465
+}
466
+
467
int create_bundle(struct repository *r, const char *path,
468
int argc, const char **argv, struct strvec *pack_options, int version)
469
{
471
int bundle_fd = -1;
472
int bundle_to_stdout;
473
int ref_count = 0;
484
- struct rev_info revs;
474
+ struct rev_info revs, revs_copy;
475
int min_version = the_hash_algo == &hash_algos[GIT_HASH_SHA1] ? 2 : 3;
476
+ struct bundle_prerequisites_info bpi;
477
+ int i;
478
479
bundle_to_stdout = !strcmp(path, "-");
480
if (bundle_to_stdout)
504
save_commit_buffer = 0;
505
repo_init_revisions(r, &revs, NULL);
506
515
- /* write prerequisites */
516
- if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))
517
- goto err;
518
-
507
argc = setup_revisions(argc, argv, &revs, NULL);
508
509
if (argc > 1) {
511
goto err;
512
}
513
526
- object_array_remove_duplicates(&revs.pending);
514
+ /* save revs.pending in revs_copy for later use */
515
+ memcpy(&revs_copy, &revs, sizeof(revs));
516
+ revs_copy.pending.nr = 0;
517
+ revs_copy.pending.alloc = 0;
518
+ revs_copy.pending.objects = NULL;
519
+ for (i = 0; i < revs.pending.nr; i++) {
520
+ struct object_array_entry *e = revs.pending.objects + i;
521
+ if (e)
522
+ add_object_array_with_path(e->item, e->name,
523
+ &revs_copy.pending,
524
+ e->mode, e->path);
525
+ }
526
528
- ref_count = write_bundle_refs(bundle_fd, &revs);
527
+ /* write prerequisites */
528
+ revs.boundary = 1;
529
+ if (prepare_revision_walk(&revs))
530
+ die("revision walk setup failed");
531
+ bpi.fd = bundle_fd;
532
+ bpi.pending = &revs_copy.pending;
533
+ traverse_commit_list(&revs, write_bundle_prerequisites, NULL, &bpi);
534
+ object_array_remove_duplicates(&revs_copy.pending);
535
+
536
+ /* write bundle refs */
537
+ ref_count = write_bundle_refs(bundle_fd, &revs_copy);
538
if (!ref_count)
539
die(_("Refusing to create empty bundle."));
540
else if (ref_count < 0)
541
goto err;
542
543
/* write pack */
535
- if (write_pack_data(bundle_fd, &revs, pack_options))
544
+ if (write_pack_data(bundle_fd, &revs_copy, pack_options))
545
goto err;
546
547
if (!bundle_to_stdout) {