@@ -434,19 +434,38 @@ static int submodule_needs_pushing(const char *path, const unsigned char sha1[20
434
434
return 0 ;
435
435
}
436
436
437
+ static struct sha1_array * get_sha1s_from_list (struct string_list * submodules ,
438
+ const char * path )
439
+ {
440
+ struct string_list_item * item ;
441
+ struct sha1_array * hashes ;
442
+
443
+ item = string_list_insert (submodules , path );
444
+ if (item -> util )
445
+ return (struct sha1_array * ) item -> util ;
446
+
447
+ hashes = (struct sha1_array * ) xmalloc (sizeof (struct sha1_array ));
448
+ /* NEEDSWORK: should we add an initializer function for
449
+ * sha1_array ? */
450
+ memset (hashes , 0 , sizeof (struct sha1_array ));
451
+ item -> util = hashes ;
452
+ return hashes ;
453
+ }
454
+
437
455
static void collect_submodules_from_diff (struct diff_queue_struct * q ,
438
456
struct diff_options * options ,
439
457
void * data )
440
458
{
441
459
int i ;
442
- struct string_list * needs_pushing = data ;
460
+ struct string_list * submodules = data ;
443
461
444
462
for (i = 0 ; i < q -> nr ; i ++ ) {
445
463
struct diff_filepair * p = q -> queue [i ];
464
+ struct sha1_array * hashes ;
446
465
if (!S_ISGITLINK (p -> two -> mode ))
447
466
continue ;
448
- if ( submodule_needs_pushing ( p -> two -> path , p -> two -> oid . hash ))
449
- string_list_insert ( needs_pushing , p -> two -> path );
467
+ hashes = get_sha1s_from_list ( submodules , p -> two -> path );
468
+ sha1_array_append ( hashes , p -> two -> oid . hash );
450
469
}
451
470
}
452
471
@@ -462,14 +481,41 @@ static void find_unpushed_submodule_commits(struct commit *commit,
462
481
diff_tree_combined_merge (commit , 1 , & rev );
463
482
}
464
483
484
+ struct collect_submodule_from_sha1s_data {
485
+ char * submodule_path ;
486
+ struct string_list * needs_pushing ;
487
+ };
488
+
489
+ static void collect_submodules_from_sha1s (const unsigned char sha1 [20 ],
490
+ void * data )
491
+ {
492
+ struct collect_submodule_from_sha1s_data * me =
493
+ (struct collect_submodule_from_sha1s_data * ) data ;
494
+
495
+ if (submodule_needs_pushing (me -> submodule_path , sha1 ))
496
+ string_list_insert (me -> needs_pushing , me -> submodule_path );
497
+ }
498
+
499
+ static void free_submodules_sha1s (struct string_list * submodules )
500
+ {
501
+ int i ;
502
+ for (i = 0 ; i < submodules -> nr ; i ++ ) {
503
+ struct string_list_item * item = & submodules -> items [i ];
504
+ struct sha1_array * hashes = (struct sha1_array * ) item -> util ;
505
+ sha1_array_clear (hashes );
506
+ }
507
+ string_list_clear (submodules , 1 );
508
+ }
509
+
465
510
int find_unpushed_submodules (unsigned char new_sha1 [20 ],
466
511
const char * remotes_name , struct string_list * needs_pushing )
467
512
{
468
513
struct rev_info rev ;
469
514
struct commit * commit ;
470
515
const char * argv [] = {NULL , NULL , "--not" , "NULL" , NULL };
471
- int argc = ARRAY_SIZE (argv ) - 1 ;
516
+ int argc = ARRAY_SIZE (argv ) - 1 , i ;
472
517
char * sha1_copy ;
518
+ struct string_list submodules = STRING_LIST_INIT_DUP ;
473
519
474
520
struct strbuf remotes_arg = STRBUF_INIT ;
475
521
@@ -483,12 +529,23 @@ int find_unpushed_submodules(unsigned char new_sha1[20],
483
529
die ("revision walk setup failed" );
484
530
485
531
while ((commit = get_revision (& rev )) != NULL )
486
- find_unpushed_submodule_commits (commit , needs_pushing );
532
+ find_unpushed_submodule_commits (commit , & submodules );
487
533
488
534
reset_revision_walk ();
489
535
free (sha1_copy );
490
536
strbuf_release (& remotes_arg );
491
537
538
+ for (i = 0 ; i < submodules .nr ; i ++ ) {
539
+ struct string_list_item * item = & submodules .items [i ];
540
+ struct collect_submodule_from_sha1s_data data ;
541
+ data .submodule_path = item -> string ;
542
+ data .needs_pushing = needs_pushing ;
543
+ sha1_array_for_each_unique ((struct sha1_array * ) item -> util ,
544
+ collect_submodules_from_sha1s ,
545
+ & data );
546
+ }
547
+ free_submodules_sha1s (& submodules );
548
+
492
549
return needs_pushing -> nr ;
493
550
}
494
551
0 commit comments