@@ -442,7 +442,7 @@ static int module_name(int argc, const char **argv, const char *prefix)
442
442
}
443
443
444
444
static int clone_submodule (const char * path , const char * gitdir , const char * url ,
445
- const char * depth , const char * reference , int quiet )
445
+ const char * depth , struct string_list * reference , int quiet )
446
446
{
447
447
struct child_process cp = CHILD_PROCESS_INIT ;
448
448
@@ -452,8 +452,12 @@ static int clone_submodule(const char *path, const char *gitdir, const char *url
452
452
argv_array_push (& cp .args , "--quiet" );
453
453
if (depth && * depth )
454
454
argv_array_pushl (& cp .args , "--depth" , depth , NULL );
455
- if (reference && * reference )
456
- argv_array_pushl (& cp .args , "--reference" , reference , NULL );
455
+ if (reference -> nr ) {
456
+ struct string_list_item * item ;
457
+ for_each_string_list_item (item , reference )
458
+ argv_array_pushl (& cp .args , "--reference" ,
459
+ item -> string , NULL );
460
+ }
457
461
if (gitdir && * gitdir )
458
462
argv_array_pushl (& cp .args , "--separate-git-dir" , gitdir , NULL );
459
463
@@ -467,15 +471,114 @@ static int clone_submodule(const char *path, const char *gitdir, const char *url
467
471
return run_command (& cp );
468
472
}
469
473
474
+ struct submodule_alternate_setup {
475
+ const char * submodule_name ;
476
+ enum SUBMODULE_ALTERNATE_ERROR_MODE {
477
+ SUBMODULE_ALTERNATE_ERROR_DIE ,
478
+ SUBMODULE_ALTERNATE_ERROR_INFO ,
479
+ SUBMODULE_ALTERNATE_ERROR_IGNORE
480
+ } error_mode ;
481
+ struct string_list * reference ;
482
+ };
483
+ #define SUBMODULE_ALTERNATE_SETUP_INIT { NULL, \
484
+ SUBMODULE_ALTERNATE_ERROR_IGNORE, NULL }
485
+
486
+ static int add_possible_reference_from_superproject (
487
+ struct alternate_object_database * alt , void * sas_cb )
488
+ {
489
+ struct submodule_alternate_setup * sas = sas_cb ;
490
+
491
+ /* directory name, minus trailing slash */
492
+ size_t namelen = alt -> name - alt -> base - 1 ;
493
+ struct strbuf name = STRBUF_INIT ;
494
+ strbuf_add (& name , alt -> base , namelen );
495
+
496
+ /*
497
+ * If the alternate object store is another repository, try the
498
+ * standard layout with .git/modules/<name>/objects
499
+ */
500
+ if (ends_with (name .buf , ".git/objects" )) {
501
+ char * sm_alternate ;
502
+ struct strbuf sb = STRBUF_INIT ;
503
+ struct strbuf err = STRBUF_INIT ;
504
+ strbuf_add (& sb , name .buf , name .len - strlen ("objects" ));
505
+ /*
506
+ * We need to end the new path with '/' to mark it as a dir,
507
+ * otherwise a submodule name containing '/' will be broken
508
+ * as the last part of a missing submodule reference would
509
+ * be taken as a file name.
510
+ */
511
+ strbuf_addf (& sb , "modules/%s/" , sas -> submodule_name );
512
+
513
+ sm_alternate = compute_alternate_path (sb .buf , & err );
514
+ if (sm_alternate ) {
515
+ string_list_append (sas -> reference , xstrdup (sb .buf ));
516
+ free (sm_alternate );
517
+ } else {
518
+ switch (sas -> error_mode ) {
519
+ case SUBMODULE_ALTERNATE_ERROR_DIE :
520
+ die (_ ("submodule '%s' cannot add alternate: %s" ),
521
+ sas -> submodule_name , err .buf );
522
+ case SUBMODULE_ALTERNATE_ERROR_INFO :
523
+ fprintf (stderr , _ ("submodule '%s' cannot add alternate: %s" ),
524
+ sas -> submodule_name , err .buf );
525
+ case SUBMODULE_ALTERNATE_ERROR_IGNORE :
526
+ ; /* nothing */
527
+ }
528
+ }
529
+ strbuf_release (& sb );
530
+ }
531
+
532
+ strbuf_release (& name );
533
+ return 0 ;
534
+ }
535
+
536
+ static void prepare_possible_alternates (const char * sm_name ,
537
+ struct string_list * reference )
538
+ {
539
+ char * sm_alternate = NULL , * error_strategy = NULL ;
540
+ struct submodule_alternate_setup sas = SUBMODULE_ALTERNATE_SETUP_INIT ;
541
+
542
+ git_config_get_string ("submodule.alternateLocation" , & sm_alternate );
543
+ if (!sm_alternate )
544
+ return ;
545
+
546
+ git_config_get_string ("submodule.alternateErrorStrategy" , & error_strategy );
547
+
548
+ if (!error_strategy )
549
+ error_strategy = xstrdup ("die" );
550
+
551
+ sas .submodule_name = sm_name ;
552
+ sas .reference = reference ;
553
+ if (!strcmp (error_strategy , "die" ))
554
+ sas .error_mode = SUBMODULE_ALTERNATE_ERROR_DIE ;
555
+ else if (!strcmp (error_strategy , "info" ))
556
+ sas .error_mode = SUBMODULE_ALTERNATE_ERROR_INFO ;
557
+ else if (!strcmp (error_strategy , "ignore" ))
558
+ sas .error_mode = SUBMODULE_ALTERNATE_ERROR_IGNORE ;
559
+ else
560
+ die (_ ("Value '%s' for submodule.alternateErrorStrategy is not recognized" ), error_strategy );
561
+
562
+ if (!strcmp (sm_alternate , "superproject" ))
563
+ foreach_alt_odb (add_possible_reference_from_superproject , & sas );
564
+ else if (!strcmp (sm_alternate , "no" ))
565
+ ; /* do nothing */
566
+ else
567
+ die (_ ("Value '%s' for submodule.alternateLocation is not recognized" ), sm_alternate );
568
+
569
+ free (sm_alternate );
570
+ free (error_strategy );
571
+ }
572
+
470
573
static int module_clone (int argc , const char * * argv , const char * prefix )
471
574
{
472
- const char * name = NULL , * url = NULL ;
473
- const char * reference = NULL , * depth = NULL ;
575
+ const char * name = NULL , * url = NULL , * depth = NULL ;
474
576
int quiet = 0 ;
475
577
FILE * submodule_dot_git ;
476
578
char * p , * path = NULL , * sm_gitdir ;
477
579
struct strbuf rel_path = STRBUF_INIT ;
478
580
struct strbuf sb = STRBUF_INIT ;
581
+ struct string_list reference = STRING_LIST_INIT_NODUP ;
479
582
480
583
struct option module_clone_options [] = {
481
584
OPT_STRING (0 , "prefix" , & prefix ,
@@ -490,8 +593,8 @@ static int module_clone(int argc, const char **argv, const char *prefix)
490
593
OPT_STRING (0 , "url" , & url ,
491
594
N_ ("string" ),
492
595
N_ ("url where to clone the submodule from" )),
493
- OPT_STRING (0 , "reference" , & reference ,
494
- N_ ("string " ),
596
+ OPT_STRING_LIST (0 , "reference" , & reference ,
597
+ N_ ("repo " ),
495
598
N_ ("reference repository" )),
496
599
OPT_STRING (0 , "depth" , & depth ,
497
600
N_ ("string" ),
@@ -527,7 +630,10 @@ static int module_clone(int argc, const char **argv, const char *prefix)
527
630
if (!file_exists (sm_gitdir )) {
528
631
if (safe_create_leading_directories_const (sm_gitdir ) < 0 )
529
632
die (_ ("could not create directory '%s'" ), sm_gitdir );
530
- if (clone_submodule (path , sm_gitdir , url , depth , reference , quiet ))
633
+
634
+ prepare_possible_alternates (name , & reference );
635
+
636
+ if (clone_submodule (path , sm_gitdir , url , depth , & reference , quiet ))
531
637
die (_ ("clone of '%s' into submodule path '%s' failed" ),
532
638
url , path );
533
639
} else {
@@ -579,7 +685,7 @@ struct submodule_update_clone {
579
685
/* configuration parameters which are passed on to the children */
580
686
int quiet ;
581
687
int recommend_shallow ;
582
- const char * reference ;
688
+ struct string_list references ;
583
689
const char * depth ;
584
690
const char * recursive_prefix ;
585
691
const char * prefix ;
@@ -595,7 +701,8 @@ struct submodule_update_clone {
595
701
int failed_clones_nr , failed_clones_alloc ;
596
702
};
597
703
#define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
598
- SUBMODULE_UPDATE_STRATEGY_INIT, 0, -1, NULL, NULL, NULL, NULL, \
704
+ SUBMODULE_UPDATE_STRATEGY_INIT, 0, -1, STRING_LIST_INIT_DUP, \
705
+ NULL, NULL, NULL, \
599
706
STRING_LIST_INIT_DUP, 0, NULL, 0, 0}
600
707
601
708
@@ -705,8 +812,11 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
705
812
argv_array_pushl (& child -> args , "--path" , sub -> path , NULL );
706
813
argv_array_pushl (& child -> args , "--name" , sub -> name , NULL );
707
814
argv_array_pushl (& child -> args , "--url" , url , NULL );
708
- if (suc -> reference )
709
- argv_array_push (& child -> args , suc -> reference );
815
+ if (suc -> references .nr ) {
816
+ struct string_list_item * item ;
817
+ for_each_string_list_item (item , & suc -> references )
818
+ argv_array_pushl (& child -> args , "--reference" , item -> string , NULL );
819
+ }
710
820
if (suc -> depth )
711
821
argv_array_push (& child -> args , suc -> depth );
712
822
@@ -829,7 +939,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)
829
939
OPT_STRING (0 , "update" , & update ,
830
940
N_ ("string" ),
831
941
N_ ("rebase, merge, checkout or none" )),
832
- OPT_STRING (0 , "reference" , & suc .reference , N_ ("repo" ),
942
+ OPT_STRING_LIST (0 , "reference" , & suc .references , N_ ("repo" ),
833
943
N_ ("reference repository" )),
834
944
OPT_STRING (0 , "depth" , & suc .depth , "<depth>" ,
835
945
N_ ("Create a shallow clone truncated to the "
0 commit comments