@@ -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,76 @@ 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 void 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
+ }
618
+
619
+ static void free_submodules_sha1s (struct string_list * submodules )
620
+ {
621
+ int i ;
622
+ for (i = 0 ; i < submodules -> nr ; i ++ ) {
623
+ struct string_list_item * item = & submodules -> items [i ];
624
+ struct sha1_array * hashes = (struct sha1_array * ) item -> util ;
625
+ sha1_array_clear (hashes );
626
+ }
627
+ string_list_clear (submodules , 1 );
628
+ }
629
+
630
+ static void append_hash_to_argv (const unsigned char sha1 [20 ],
631
+ void * data )
632
+ {
633
+ struct argv_array * argv = (struct argv_array * ) data ;
634
+ argv_array_push (argv , sha1_to_hex (sha1 ));
635
+ }
636
+
637
+ int find_unpushed_submodules (struct sha1_array * hashes ,
586
638
const char * remotes_name , struct string_list * needs_pushing )
587
639
{
588
640
struct rev_info rev ;
589
641
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 ;
642
+ int i ;
643
+ struct string_list submodules = STRING_LIST_INIT_DUP ;
644
+ struct argv_array argv = ARGV_ARRAY_INIT ;
595
645
596
- strbuf_addf (& remotes_arg , "--remotes=%s" , remotes_name );
597
646
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 );
647
+
648
+ /* argv.argv[0] will be ignored by setup_revisions */
649
+ argv_array_push (& argv , "find_unpushed_submodules" );
650
+ sha1_array_for_each_unique (hashes , append_hash_to_argv , & argv );
651
+ argv_array_push (& argv , "--not" );
652
+ argv_array_pushf (& argv , "--remotes=%s" , remotes_name );
653
+
654
+ setup_revisions (argv .argc , argv .argv , & rev , NULL );
602
655
if (prepare_revision_walk (& rev ))
603
656
die ("revision walk setup failed" );
604
657
605
658
while ((commit = get_revision (& rev )) != NULL )
606
- find_unpushed_submodule_commits (commit , needs_pushing );
659
+ find_unpushed_submodule_commits (commit , & submodules );
607
660
608
661
reset_revision_walk ();
609
- free (sha1_copy );
610
- strbuf_release (& remotes_arg );
662
+ argv_array_clear (& argv );
663
+
664
+ for (i = 0 ; i < submodules .nr ; i ++ ) {
665
+ struct string_list_item * item = & submodules .items [i ];
666
+ struct collect_submodule_from_sha1s_data data ;
667
+ data .submodule_path = item -> string ;
668
+ data .needs_pushing = needs_pushing ;
669
+ sha1_array_for_each_unique ((struct sha1_array * ) item -> util ,
670
+ collect_submodules_from_sha1s ,
671
+ & data );
672
+ }
673
+ free_submodules_sha1s (& submodules );
611
674
612
675
return needs_pushing -> nr ;
613
676
}
@@ -634,12 +697,12 @@ static int push_submodule(const char *path)
634
697
return 1 ;
635
698
}
636
699
637
- int push_unpushed_submodules (unsigned char new_sha1 [ 20 ] , const char * remotes_name )
700
+ int push_unpushed_submodules (struct sha1_array * hashes , const char * remotes_name )
638
701
{
639
702
int i , ret = 1 ;
640
703
struct string_list needs_pushing = STRING_LIST_INIT_DUP ;
641
704
642
- if (!find_unpushed_submodules (new_sha1 , remotes_name , & needs_pushing ))
705
+ if (!find_unpushed_submodules (hashes , remotes_name , & needs_pushing ))
643
706
return 1 ;
644
707
645
708
for (i = 0 ; i < needs_pushing .nr ; i ++ ) {
0 commit comments