@@ -500,27 +500,56 @@ static int has_remote(const char *refname, const struct object_id *oid,
500
500
return 1 ;
501
501
}
502
502
503
- static int submodule_needs_pushing (const char * path , const unsigned char sha1 [20 ])
503
+ static int append_hash_to_argv (const unsigned char sha1 [20 ], void * data )
504
504
{
505
- if (add_submodule_odb (path ) || !lookup_commit_reference (sha1 ))
505
+ struct argv_array * argv = (struct argv_array * ) data ;
506
+ argv_array_push (argv , sha1_to_hex (sha1 ));
507
+ return 0 ;
508
+ }
509
+
510
+ static int check_has_hash (const unsigned char sha1 [20 ], void * data )
511
+ {
512
+ int * has_hash = (int * ) data ;
513
+
514
+ if (!lookup_commit_reference (sha1 ))
515
+ * has_hash = 0 ;
516
+
517
+ return 0 ;
518
+ }
519
+
520
+ static int submodule_has_hashes (const char * path , struct sha1_array * hashes )
521
+ {
522
+ int has_hash = 1 ;
523
+
524
+ if (add_submodule_odb (path ))
525
+ return 0 ;
526
+
527
+ sha1_array_for_each_unique (hashes , check_has_hash , & has_hash );
528
+ return has_hash ;
529
+ }
530
+
531
+ static int submodule_needs_pushing (const char * path , struct sha1_array * hashes )
532
+ {
533
+ if (!submodule_has_hashes (path , hashes ))
506
534
return 0 ;
507
535
508
536
if (for_each_remote_ref_submodule (path , has_remote , NULL ) > 0 ) {
509
537
struct child_process cp = CHILD_PROCESS_INIT ;
510
- const char * argv [] = {"rev-list" , NULL , "--not" , "--remotes" , "-n" , "1" , NULL };
511
538
struct strbuf buf = STRBUF_INIT ;
512
539
int needs_pushing = 0 ;
513
540
514
- argv [1 ] = sha1_to_hex (sha1 );
515
- cp .argv = argv ;
541
+ argv_array_push (& cp .args , "rev-list" );
542
+ sha1_array_for_each_unique (hashes , append_hash_to_argv , & cp .args );
543
+ argv_array_pushl (& cp .args , "--not" , "--remotes" , "-n" , "1" , NULL );
544
+
516
545
prepare_submodule_repo_env (& cp .env_array );
517
546
cp .git_cmd = 1 ;
518
547
cp .no_stdin = 1 ;
519
548
cp .out = -1 ;
520
549
cp .dir = path ;
521
550
if (start_command (& cp ))
522
- die ("Could not run 'git rev-list %s --not --remotes -n 1' command in submodule %s" ,
523
- sha1_to_hex ( sha1 ), path );
551
+ die ("Could not run 'git rev-list <hashes> --not --remotes -n 1' command in submodule %s" ,
552
+ path );
524
553
if (strbuf_read (& buf , cp .out , 41 ))
525
554
needs_pushing = 1 ;
526
555
finish_command (& cp );
@@ -532,19 +561,34 @@ static int submodule_needs_pushing(const char *path, const unsigned char sha1[20
532
561
return 0 ;
533
562
}
534
563
564
+ static struct sha1_array * get_sha1s_from_list (struct string_list * submodules ,
565
+ const char * path )
566
+ {
567
+ struct string_list_item * item ;
568
+
569
+ item = string_list_insert (submodules , path );
570
+ if (item -> util )
571
+ return (struct sha1_array * ) item -> util ;
572
+
573
+ /* NEEDSWORK: should we have sha1_array_init()? */
574
+ item -> util = xcalloc (1 , sizeof (struct sha1_array ));
575
+ return (struct sha1_array * ) item -> util ;
576
+ }
577
+
535
578
static void collect_submodules_from_diff (struct diff_queue_struct * q ,
536
579
struct diff_options * options ,
537
580
void * data )
538
581
{
539
582
int i ;
540
- struct string_list * needs_pushing = data ;
583
+ struct string_list * submodules = data ;
541
584
542
585
for (i = 0 ; i < q -> nr ; i ++ ) {
543
586
struct diff_filepair * p = q -> queue [i ];
587
+ struct sha1_array * hashes ;
544
588
if (!S_ISGITLINK (p -> two -> mode ))
545
589
continue ;
546
- if ( submodule_needs_pushing ( p -> two -> path , p -> two -> oid . hash ))
547
- string_list_insert ( needs_pushing , p -> two -> path );
590
+ hashes = get_sha1s_from_list ( submodules , p -> two -> path );
591
+ sha1_array_append ( hashes , p -> two -> oid . hash );
548
592
}
549
593
}
550
594
@@ -560,32 +604,52 @@ static void find_unpushed_submodule_commits(struct commit *commit,
560
604
diff_tree_combined_merge (commit , 1 , & rev );
561
605
}
562
606
563
- int find_unpushed_submodules (unsigned char new_sha1 [20 ],
607
+ static void free_submodules_sha1s (struct string_list * submodules )
608
+ {
609
+ int i ;
610
+ for (i = 0 ; i < submodules -> nr ; i ++ ) {
611
+ struct string_list_item * item = & submodules -> items [i ];
612
+ struct sha1_array * hashes = (struct sha1_array * ) item -> util ;
613
+ sha1_array_clear (hashes );
614
+ }
615
+ string_list_clear (submodules , 1 );
616
+ }
617
+
618
+ int find_unpushed_submodules (struct sha1_array * hashes ,
564
619
const char * remotes_name , struct string_list * needs_pushing )
565
620
{
566
621
struct rev_info rev ;
567
622
struct commit * commit ;
568
- const char * argv [] = {NULL , NULL , "--not" , "NULL" , NULL };
569
- int argc = ARRAY_SIZE (argv ) - 1 ;
570
- char * sha1_copy ;
571
-
572
- struct strbuf remotes_arg = STRBUF_INIT ;
623
+ int i ;
624
+ struct string_list submodules = STRING_LIST_INIT_DUP ;
625
+ struct argv_array argv = ARGV_ARRAY_INIT ;
573
626
574
- strbuf_addf (& remotes_arg , "--remotes=%s" , remotes_name );
575
627
init_revisions (& rev , NULL );
576
- sha1_copy = xstrdup (sha1_to_hex (new_sha1 ));
577
- argv [1 ] = sha1_copy ;
578
- argv [3 ] = remotes_arg .buf ;
579
- setup_revisions (argc , argv , & rev , NULL );
628
+
629
+ /* argv.argv[0] will be ignored by setup_revisions */
630
+ argv_array_push (& argv , "find_unpushed_submodules" );
631
+ sha1_array_for_each_unique (hashes , append_hash_to_argv , & argv );
632
+ argv_array_push (& argv , "--not" );
633
+ argv_array_pushf (& argv , "--remotes=%s" , remotes_name );
634
+
635
+ setup_revisions (argv .argc , argv .argv , & rev , NULL );
580
636
if (prepare_revision_walk (& rev ))
581
637
die ("revision walk setup failed" );
582
638
583
639
while ((commit = get_revision (& rev )) != NULL )
584
- find_unpushed_submodule_commits (commit , needs_pushing );
640
+ find_unpushed_submodule_commits (commit , & submodules );
585
641
586
642
reset_revision_walk ();
587
- free (sha1_copy );
588
- strbuf_release (& remotes_arg );
643
+ argv_array_clear (& argv );
644
+
645
+ for (i = 0 ; i < submodules .nr ; i ++ ) {
646
+ struct string_list_item * submodule = & submodules .items [i ];
647
+ struct sha1_array * hashes = (struct sha1_array * ) submodule -> util ;
648
+
649
+ if (submodule_needs_pushing (submodule -> string , hashes ))
650
+ string_list_insert (needs_pushing , submodule -> string );
651
+ }
652
+ free_submodules_sha1s (& submodules );
589
653
590
654
return needs_pushing -> nr ;
591
655
}
@@ -612,12 +676,12 @@ static int push_submodule(const char *path)
612
676
return 1 ;
613
677
}
614
678
615
- int push_unpushed_submodules (unsigned char new_sha1 [ 20 ] , const char * remotes_name )
679
+ int push_unpushed_submodules (struct sha1_array * hashes , const char * remotes_name )
616
680
{
617
681
int i , ret = 1 ;
618
682
struct string_list needs_pushing = STRING_LIST_INIT_DUP ;
619
683
620
- if (!find_unpushed_submodules (new_sha1 , remotes_name , & needs_pushing ))
684
+ if (!find_unpushed_submodules (hashes , remotes_name , & needs_pushing ))
621
685
return 1 ;
622
686
623
687
for (i = 0 ; i < needs_pushing .nr ; i ++ ) {
0 commit comments