@@ -554,19 +554,38 @@ static int submodule_needs_pushing(const char *path, const unsigned char sha1[20
554
554
return 0 ;
555
555
}
556
556
557
+ static struct sha1_array * get_sha1s_from_list (struct string_list * submodules ,
558
+ const char * path )
559
+ {
560
+ struct string_list_item * item ;
561
+ struct sha1_array * hashes ;
562
+
563
+ item = string_list_insert (submodules , path );
564
+ if (item -> util )
565
+ return (struct sha1_array * ) item -> util ;
566
+
567
+ hashes = (struct sha1_array * ) xmalloc (sizeof (struct sha1_array ));
568
+ /* NEEDSWORK: should we add an initializer function for
569
+ * sha1_array ? */
570
+ memset (hashes , 0 , sizeof (struct sha1_array ));
571
+ item -> util = hashes ;
572
+ return hashes ;
573
+ }
574
+
557
575
static void collect_submodules_from_diff (struct diff_queue_struct * q ,
558
576
struct diff_options * options ,
559
577
void * data )
560
578
{
561
579
int i ;
562
- struct string_list * needs_pushing = data ;
580
+ struct string_list * submodules = data ;
563
581
564
582
for (i = 0 ; i < q -> nr ; i ++ ) {
565
583
struct diff_filepair * p = q -> queue [i ];
584
+ struct sha1_array * hashes ;
566
585
if (!S_ISGITLINK (p -> two -> mode ))
567
586
continue ;
568
- if ( submodule_needs_pushing ( p -> two -> path , p -> two -> oid . hash ))
569
- string_list_insert ( needs_pushing , p -> two -> path );
587
+ hashes = get_sha1s_from_list ( submodules , p -> two -> path );
588
+ sha1_array_append ( hashes , p -> two -> oid . hash );
570
589
}
571
590
}
572
591
@@ -582,32 +601,78 @@ static void find_unpushed_submodule_commits(struct commit *commit,
582
601
diff_tree_combined_merge (commit , 1 , & rev );
583
602
}
584
603
585
- int find_unpushed_submodules (unsigned char new_sha1 [20 ],
604
+ struct collect_submodule_from_sha1s_data {
605
+ char * submodule_path ;
606
+ struct string_list * needs_pushing ;
607
+ };
608
+
609
+ static int collect_submodules_from_sha1s (const unsigned char sha1 [20 ],
610
+ void * data )
611
+ {
612
+ struct collect_submodule_from_sha1s_data * me =
613
+ (struct collect_submodule_from_sha1s_data * ) data ;
614
+
615
+ if (submodule_needs_pushing (me -> submodule_path , sha1 ))
616
+ string_list_insert (me -> needs_pushing , me -> submodule_path );
617
+ return 0 ;
618
+ }
619
+
620
+ static void free_submodules_sha1s (struct string_list * submodules )
621
+ {
622
+ int i ;
623
+ for (i = 0 ; i < submodules -> nr ; i ++ ) {
624
+ struct string_list_item * item = & submodules -> items [i ];
625
+ struct sha1_array * hashes = (struct sha1_array * ) item -> util ;
626
+ sha1_array_clear (hashes );
627
+ }
628
+ string_list_clear (submodules , 1 );
629
+ }
630
+
631
+ static int append_hash_to_argv (const unsigned char sha1 [20 ],
632
+ void * data )
633
+ {
634
+ struct argv_array * argv = (struct argv_array * ) data ;
635
+ argv_array_push (argv , sha1_to_hex (sha1 ));
636
+ return 0 ;
637
+ }
638
+
639
+ int find_unpushed_submodules (struct sha1_array * hashes ,
586
640
const char * remotes_name , struct string_list * needs_pushing )
587
641
{
588
642
struct rev_info rev ;
589
643
struct commit * commit ;
590
- const char * argv [] = {NULL , NULL , "--not" , "NULL" , NULL };
591
- int argc = ARRAY_SIZE (argv ) - 1 ;
592
- char * sha1_copy ;
593
-
594
- struct strbuf remotes_arg = STRBUF_INIT ;
644
+ int i ;
645
+ struct string_list submodules = STRING_LIST_INIT_DUP ;
646
+ struct argv_array argv = ARGV_ARRAY_INIT ;
595
647
596
- strbuf_addf (& remotes_arg , "--remotes=%s" , remotes_name );
597
648
init_revisions (& rev , NULL );
598
- sha1_copy = xstrdup (sha1_to_hex (new_sha1 ));
599
- argv [1 ] = sha1_copy ;
600
- argv [3 ] = remotes_arg .buf ;
601
- setup_revisions (argc , argv , & rev , NULL );
649
+
650
+ /* argv.argv[0] will be ignored by setup_revisions */
651
+ argv_array_push (& argv , "find_unpushed_submodules" );
652
+ sha1_array_for_each_unique (hashes , append_hash_to_argv , & argv );
653
+ argv_array_push (& argv , "--not" );
654
+ argv_array_pushf (& argv , "--remotes=%s" , remotes_name );
655
+
656
+ setup_revisions (argv .argc , argv .argv , & rev , NULL );
602
657
if (prepare_revision_walk (& rev ))
603
658
die ("revision walk setup failed" );
604
659
605
660
while ((commit = get_revision (& rev )) != NULL )
606
- find_unpushed_submodule_commits (commit , needs_pushing );
661
+ find_unpushed_submodule_commits (commit , & submodules );
607
662
608
663
reset_revision_walk ();
609
- free (sha1_copy );
610
- strbuf_release (& remotes_arg );
664
+ argv_array_clear (& argv );
665
+
666
+ for (i = 0 ; i < submodules .nr ; i ++ ) {
667
+ struct string_list_item * item = & submodules .items [i ];
668
+ struct collect_submodule_from_sha1s_data data ;
669
+ data .submodule_path = item -> string ;
670
+ data .needs_pushing = needs_pushing ;
671
+ sha1_array_for_each_unique ((struct sha1_array * ) item -> util ,
672
+ collect_submodules_from_sha1s ,
673
+ & data );
674
+ }
675
+ free_submodules_sha1s (& submodules );
611
676
612
677
return needs_pushing -> nr ;
613
678
}
@@ -634,12 +699,12 @@ static int push_submodule(const char *path)
634
699
return 1 ;
635
700
}
636
701
637
- int push_unpushed_submodules (unsigned char new_sha1 [ 20 ] , const char * remotes_name )
702
+ int push_unpushed_submodules (struct sha1_array * hashes , const char * remotes_name )
638
703
{
639
704
int i , ret = 1 ;
640
705
struct string_list needs_pushing = STRING_LIST_INIT_DUP ;
641
706
642
- if (!find_unpushed_submodules (new_sha1 , remotes_name , & needs_pushing ))
707
+ if (!find_unpushed_submodules (hashes , remotes_name , & needs_pushing ))
643
708
return 1 ;
644
709
645
710
for (i = 0 ; i < needs_pushing .nr ; i ++ ) {
0 commit comments