@@ -338,48 +338,6 @@ static int write_pack_data(int bundle_fd, struct rev_info *revs, struct strvec *
338338 return 0 ;
339339}
340340
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-
383341/*
384342 * Write out bundle refs based on the tips already
385343 * parsed into revs.pending. As a side effect, may
@@ -474,15 +432,49 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
474432 return ref_count ;
475433}
476434
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+
477467int create_bundle (struct repository * r , const char * path ,
478468 int argc , const char * * argv , struct strvec * pack_options , int version )
479469{
480470 struct lock_file lock = LOCK_INIT ;
481471 int bundle_fd = -1 ;
482472 int bundle_to_stdout ;
483473 int ref_count = 0 ;
484- struct rev_info revs ;
474+ struct rev_info revs , revs_copy ;
485475 int min_version = the_hash_algo == & hash_algos [GIT_HASH_SHA1 ] ? 2 : 3 ;
476+ struct bundle_prerequisites_info bpi ;
477+ int i ;
486478
487479 bundle_to_stdout = !strcmp (path , "-" );
488480 if (bundle_to_stdout )
@@ -512,27 +504,44 @@ int create_bundle(struct repository *r, const char *path,
512504 save_commit_buffer = 0 ;
513505 repo_init_revisions (r , & revs , NULL );
514506
515- /* write prerequisites */
516- if (compute_and_write_prerequisites (bundle_fd , & revs , argc , argv ))
517- goto err ;
518-
519507 argc = setup_revisions (argc , argv , & revs , NULL );
520508
521509 if (argc > 1 ) {
522510 error (_ ("unrecognized argument: %s" ), argv [1 ]);
523511 goto err ;
524512 }
525513
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+ }
527526
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 );
529538 if (!ref_count )
530539 die (_ ("Refusing to create empty bundle." ));
531540 else if (ref_count < 0 )
532541 goto err ;
533542
534543 /* write pack */
535- if (write_pack_data (bundle_fd , & revs , pack_options ))
544+ if (write_pack_data (bundle_fd , & revs_copy , pack_options ))
536545 goto err ;
537546
538547 if (!bundle_to_stdout ) {
0 commit comments