8
8
#include "diffcore.h"
9
9
#include "refs.h"
10
10
#include "string-list.h"
11
+ #include "sha1-array.h"
11
12
12
13
static struct string_list config_name_for_path ;
13
14
static struct string_list config_fetch_recurse_submodules_for_name ;
14
15
static struct string_list config_ignore_for_name ;
15
16
static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND ;
16
17
static struct string_list changed_submodule_paths ;
18
+ static int initialized_fetch_ref_tips ;
19
+ static struct sha1_array ref_tips_before_fetch ;
20
+ static struct sha1_array ref_tips_after_fetch ;
21
+
17
22
/*
18
23
* The following flag is set if the .gitmodules file is unmerged. We then
19
24
* disable recursion for all submodules where .git/config doesn't have a
@@ -474,20 +479,76 @@ static void submodule_collect_changed_cb(struct diff_queue_struct *q,
474
479
}
475
480
}
476
481
482
+ static int add_sha1_to_array (const char * ref , const unsigned char * sha1 ,
483
+ int flags , void * data )
484
+ {
485
+ sha1_array_append (data , sha1 );
486
+ return 0 ;
487
+ }
488
+
477
489
void check_for_new_submodule_commits (unsigned char new_sha1 [20 ])
490
+ {
491
+ if (!initialized_fetch_ref_tips ) {
492
+ for_each_ref (add_sha1_to_array , & ref_tips_before_fetch );
493
+ initialized_fetch_ref_tips = 1 ;
494
+ }
495
+
496
+ sha1_array_append (& ref_tips_after_fetch , new_sha1 );
497
+ }
498
+
499
+ struct argv_array {
500
+ const char * * argv ;
501
+ unsigned int argc ;
502
+ unsigned int alloc ;
503
+ };
504
+
505
+ static void init_argv (struct argv_array * array )
506
+ {
507
+ array -> argv = NULL ;
508
+ array -> argc = 0 ;
509
+ array -> alloc = 0 ;
510
+ }
511
+
512
+ static void push_argv (struct argv_array * array , const char * value )
513
+ {
514
+ ALLOC_GROW (array -> argv , array -> argc + 2 , array -> alloc );
515
+ array -> argv [array -> argc ++ ] = xstrdup (value );
516
+ array -> argv [array -> argc ] = NULL ;
517
+ }
518
+
519
+ static void clear_argv (struct argv_array * array )
520
+ {
521
+ int i ;
522
+ for (i = 0 ; i < array -> argc ; i ++ )
523
+ free ((char * * )array -> argv [i ]);
524
+ free (array -> argv );
525
+ init_argv (array );
526
+ }
527
+
528
+ static void add_sha1_to_argv (const unsigned char sha1 [20 ], void * data )
529
+ {
530
+ push_argv (data , sha1_to_hex (sha1 ));
531
+ }
532
+
533
+ static void calculate_changed_submodule_paths (void )
478
534
{
479
535
struct rev_info rev ;
480
536
struct commit * commit ;
481
- const char * argv [] = {NULL , NULL , "--not" , "--all" , NULL };
482
- int argc = ARRAY_SIZE (argv ) - 1 ;
537
+ struct argv_array argv ;
483
538
484
539
/* No need to check if there are no submodules configured */
485
540
if (!config_name_for_path .nr )
486
541
return ;
487
542
488
543
init_revisions (& rev , NULL );
489
- argv [1 ] = xstrdup (sha1_to_hex (new_sha1 ));
490
- setup_revisions (argc , argv , & rev , NULL );
544
+ init_argv (& argv );
545
+ push_argv (& argv , "--" ); /* argv[0] program name */
546
+ sha1_array_for_each_unique (& ref_tips_after_fetch ,
547
+ add_sha1_to_argv , & argv );
548
+ push_argv (& argv , "--not" );
549
+ sha1_array_for_each_unique (& ref_tips_before_fetch ,
550
+ add_sha1_to_argv , & argv );
551
+ setup_revisions (argv .argc , argv .argv , & rev , NULL );
491
552
if (prepare_revision_walk (& rev ))
492
553
die ("revision walk setup failed" );
493
554
@@ -511,7 +572,11 @@ void check_for_new_submodule_commits(unsigned char new_sha1[20])
511
572
parent = parent -> next ;
512
573
}
513
574
}
514
- free ((char * )argv [1 ]);
575
+
576
+ clear_argv (& argv );
577
+ sha1_array_clear (& ref_tips_before_fetch );
578
+ sha1_array_clear (& ref_tips_after_fetch );
579
+ initialized_fetch_ref_tips = 0 ;
515
580
}
516
581
517
582
int fetch_populated_submodules (int num_options , const char * * options ,
@@ -545,6 +610,8 @@ int fetch_populated_submodules(int num_options, const char **options,
545
610
cp .git_cmd = 1 ;
546
611
cp .no_stdin = 1 ;
547
612
613
+ calculate_changed_submodule_paths ();
614
+
548
615
for (i = 0 ; i < active_nr ; i ++ ) {
549
616
struct strbuf submodule_path = STRBUF_INIT ;
550
617
struct strbuf submodule_git_dir = STRBUF_INIT ;
0 commit comments